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()
|