summaryrefslogtreecommitdiffstats
path: root/gamechestcli/gamechest/gameconfig.py
blob: 5e46efa3cfbca8bbe5b0119abb5f19a620dc241e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import contextlib
from pathlib import Path

import yaml
from xdg import xdg_data_home, xdg_config_home

from . import consts


DEFAULT_CONFIG_DICT = {
    'remote_basedir': 'jibril:/storage/games',
    'gamesaves_path': Path('~/syncthing/gamesaves').expanduser(),

    # profile_id: no default for this, only set by user.
    'profile_id': None,
}


def path_relative_to_user(path):
    # first ensure the path is a Path
    path = Path(path)
    with contextlib.suppress(ValueError):
        return '~' / path.relative_to(Path.home())
    # in case the path is not relative to the user home ValueError is raised,
    # thus we return a fallback value (the path unmodified).
    return path


class GameConfig:

    def __init__(self):
        self.config = {}
        game_config_path = xdg_config_home() / consts.XDG_RESOURCE_NAME
        game_config_path.mkdir(parents=True, exist_ok=True)
        game_config_filepath = game_config_path / 'config.yaml'
        self.game_config_filepath = game_config_filepath
        with contextlib.ExitStack() as stack:
            stack.enter_context(contextlib.suppress(FileNotFoundError))
            fdin = stack.enter_context(open(game_config_filepath, 'r',
                                            encoding='utf8'))
            self.config = yaml.safe_load(fdin)
        self.config = {
            **DEFAULT_CONFIG_DICT,
            **self.config,
        }
        # convert game_saves_path to a path if not already the case (in case
        # loaded from yaml file).
        self.config['gamesaves_path'] = (
            Path(self.config['gamesaves_path'])
            .expanduser()
        )

    def get_remote_basedir(self):
        return self.config['remote_basedir']

    def get_gamesaves_path(self):
        return self.config['gamesaves_path']

    def get_games_saves_tools_bin_path(self):
        return self.get_gamesaves_path() / 'tools' / 'bin'

    def get_profile_dir(self, profile_id):
        return self.get_gamesaves_path() / 'profiles' / profile_id

    def get_games_database_path(self):
        return self.get_gamesaves_path() / 'gamedata.yaml'

    def get_data_d(self):
        return self.get_gamesaves_path() / 'gamedata.yaml.d'

    def get_profile_id(self):
        return self.config['profile_id']

    def save(self):
        dict_transformed_for_save = { **self.config }
        dict_transformed_for_save['gamesaves_path'] = str(
            path_relative_to_user(
                self.config['gamesaves_path']
            )
        )
        with open(self.game_config_filepath, 'w', encoding='utf8') as fdout:
            yaml.safe_dump(dict_transformed_for_save, fdout)

    def set_profile_id(self, profile_id):
        self.config['profile_id'] = profile_id

    def set_remote_basedir(self, remote_basedir):
        self.config['remote_basedir'] = remote_basedir

    def set_gamesaves_path(self, path):
        self.config['gamesaves_path'] = Path(path).expanduser()

    def get_games_install_basedir(self):
        games_install_path = (
            xdg_data_home() / consts.XDG_RESOURCE_NAME / 'games'
        )
        games_install_path.mkdir(parents=True, exist_ok=True)
        return games_install_path

    def print_config(self):
        print(self.config)


# default instance of gameconfig, same instance intended to be shared through
# all modules which needs it.
config = GameConfig()

class GameStatus:

    def load_yaml(self):
        with contextlib.ExitStack() as stack:
            stack.enter_context(contextlib.suppress(FileNotFoundError))
            fdin = stack.enter_context(open(self.yaml_path, 'r',
                                            encoding='utf8'))
            data = yaml.safe_load(fdin)
            self.last_loaded_profile = data.get('last_loaded_profile',
                                                self.last_loaded_profile)
            self.last_loaded_game = data.get('last_loaded_game',
                                             self.last_loaded_game)

    def write_yaml(self):
        with contextlib.ExitStack() as stack:
            stack.enter_context(contextlib.suppress(FileNotFoundError))
            fdout = stack.enter_context(open(self.yaml_path, 'w',
                                            encoding='utf8'))
            data = {
                'last_loaded_profile': self.last_loaded_profile,
                'last_loaded_game': self.last_loaded_game,
            }
            yaml.safe_dump(data, fdout)

    def __init__(self):
        self.yaml_path = (
            xdg_data_home() / consts.XDG_RESOURCE_NAME / 'status.yaml'
        )
        self.last_loaded_profile = config.get_profile_id()
        self.last_loaded_game = None
        self.load_yaml()

    def set_last_loaded_profile(self, profile):
        self.last_loaded_profile = profile
        self.write_yaml()

    def set_last_loaded_game(self, game):
        self.last_loaded_game = game
        self.write_yaml()

status = GameStatus()