summaryrefslogtreecommitdiffstats
path: root/gamechestcli/gamechest/gameconfig.py
blob: 3a538379622e7315a3d218f20e5285413ff53cc5 (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
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()