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
|
import contextlib
from pathlib import Path
import yaml
from xdg import xdg_data_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, 'rb'))
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_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, 'wb') 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
# default instance of gameconfig, same instance intended to be shared through
# all modules which needs it.
config = GameConfig()
|