summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvg <vgm+dev@devys.org>2022-09-19 18:30:16 +0200
committervg <vgm+dev@devys.org>2022-09-19 18:30:16 +0200
commit7b656127e3fc0139f13820ddbffc3840924d7dcb (patch)
treeb73074e268d130013257b8c35ef6e0e16ca5ee3a
parent21908c97c1e897554751070d08e2b35694529bc0 (diff)
downloadgamechest-7b656127e3fc0139f13820ddbffc3840924d7dcb.tar.gz
gamechest-7b656127e3fc0139f13820ddbffc3840924d7dcb.tar.bz2
gamechest-7b656127e3fc0139f13820ddbffc3840924d7dcb.zip
git-sync on seele
-rwxr-xr-xgamechestcli/__main__.py20
-rw-r--r--gamechestcli/gamechest/cliactions/install.py7
-rw-r--r--gamechestcli/gamechest/cliactions/remove.py7
-rw-r--r--gamechestcli/gamechest/cliactions/run.py3
-rw-r--r--gamechestcli/gamechest/gameconfig.py99
-rw-r--r--gamechestcli/gamechest/gamedb.py10
-rw-r--r--gamechestcli/gamechest/paths.py36
-rw-r--r--gamechestcli/gamechest/processor.py4
-rw-r--r--gamechestcli/gamechest/runners/install.py4
9 files changed, 135 insertions, 55 deletions
diff --git a/gamechestcli/__main__.py b/gamechestcli/__main__.py
index 1497e40..8fe912d 100755
--- a/gamechestcli/__main__.py
+++ b/gamechestcli/__main__.py
@@ -4,12 +4,17 @@ Manage games. Install, remove, run them.
Usage: gamechest install <GAME_ID>
gamechest remove <GAME_ID>
- gamechest run --profile_id=<PROFILE_ID> <GAME_ID>
+ gamechest run [--profile_id=<PROFILE_ID>] <GAME_ID>
+ gamechest set [--profile_id=<PROFILE_ID>] [--remote_basedir=<BASEDIR>] [--gamesaves_path]
+
'''
+import sys
+
import docopt
from gamechest.cliactions import install, remove, run
+from gamechest.gameconfig import config
def main():
@@ -21,7 +26,18 @@ def main():
elif args['remove']:
remove.remove(args['<GAME_ID>'])
elif args['run']:
- run.run(args['<GAME_ID>'], args['--profile_id'])
+ profile_id = args['--profile_id'] or config.get_profile_id()
+ if not profile_id:
+ print('profile_id must be not null', file=sys.stderr)
+ run.run(args['<GAME_ID>'], profile_id)
+ elif args['set']:
+ if args['--profile_id']:
+ config.set_profile_id(args['--profile_id'])
+ if args['--remote_basedir']:
+ config.set_remote_basedir(args['--remote_basedir'])
+ if args['--gamesaves_path']
+ config.set_gamesaves_path(args['--gamesaves_path'])
+ config.save()
if __name__ == "__main__":
diff --git a/gamechestcli/gamechest/cliactions/install.py b/gamechestcli/gamechest/cliactions/install.py
index 8584d35..508dd48 100644
--- a/gamechestcli/gamechest/cliactions/install.py
+++ b/gamechestcli/gamechest/cliactions/install.py
@@ -1,14 +1,15 @@
import functools
-from .. import gamedb, paths, processor
+from .. import gamedb, processor
+from ..gameconfig import config
from ..runners.install import Install
from ..statusdb import StatusDB
def install_game(status_db, game_info):
- remote_basedir = paths.get_remote_basedir()
+ remote_basedir = config.get_remote_basedir()
source = f'{remote_basedir}/{game_info["package_name"]}'
- dest = paths.get_games_install_basedir() / game_info['id']
+ dest = config.get_games_install_basedir() / game_info['id']
dest.mkdir(parents=True, exist_ok=True)
title = 'Installing game...'
task = functools.partial(Install, source, dest)
diff --git a/gamechestcli/gamechest/cliactions/remove.py b/gamechestcli/gamechest/cliactions/remove.py
index d5452d5..6573aff 100644
--- a/gamechestcli/gamechest/cliactions/remove.py
+++ b/gamechestcli/gamechest/cliactions/remove.py
@@ -5,15 +5,16 @@ import selectors
from rich import print
from rich.progress import Progress as RichProgress
-from .. import gamedb, paths, processor
+from .. import gamedb, processor
+from ..gameconfig import config
from ..runners.remove import Remove
from ..statusdb import StatusDB
def remove_game(status_db, game_info):
- remote_basedir = paths.get_remote_basedir()
+ remote_basedir = config.get_remote_basedir()
path = (
- paths.get_games_install_basedir()
+ config.get_games_install_basedir()
/ game_info['id']
)
title = 'Removing game...'
diff --git a/gamechestcli/gamechest/cliactions/run.py b/gamechestcli/gamechest/cliactions/run.py
index b5369aa..d6791d0 100644
--- a/gamechestcli/gamechest/cliactions/run.py
+++ b/gamechestcli/gamechest/cliactions/run.py
@@ -1,14 +1,13 @@
import subprocess
import sys
-from .. import paths
from ..gamedb import GameDB
from ..statusdb import StatusDB
def run_game(game_db, profile_id, game_info):
command = game_db.get_game_command(profile_id, game_info['id'])
- #tools_bin_path = paths.get_games_saves_tools_bin_path()
+ #tools_bin_path = config.get_games_saves_tools_bin_path()
#new_env = dict(os.environ)
#new_env['PATH'] = f'{tools_bin_path}:{new_env["PATH"]}'
# path to mod/run scripts are already prepended by get_game_command, no
diff --git a/gamechestcli/gamechest/gameconfig.py b/gamechestcli/gamechest/gameconfig.py
new file mode 100644
index 0000000..effacd0
--- /dev/null
+++ b/gamechestcli/gamechest/gameconfig.py
@@ -0,0 +1,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()
diff --git a/gamechestcli/gamechest/gamedb.py b/gamechestcli/gamechest/gamedb.py
index 2000c52..99d3c9a 100644
--- a/gamechestcli/gamechest/gamedb.py
+++ b/gamechestcli/gamechest/gamedb.py
@@ -1,12 +1,12 @@
import yaml
-from . import paths
+from .gameconfig import config
class GameDB:
def __init__(self):
- database_path = paths.get_games_database_path()
+ database_path = config.get_games_database_path()
with open(database_path, 'rb') as fdin:
self.db = yaml.safe_load(fdin)
self.last_game_info = None
@@ -25,12 +25,12 @@ class GameDB:
game_mods = game_info.get('mods', [])
game_mods += ['locked-run-profiledir']
- game_dir = paths.get_games_install_basedir() / game_info['id']
+ game_dir = config.get_games_install_basedir() / game_info['id']
# note: glob('*/') globs regular files too, thus I filter on is_dir.
game_dir = next(item for item in game_dir.glob('*') if item.is_dir())
- tools_bin_path = paths.get_games_saves_tools_bin_path()
- profile_dir = paths.get_profile_dir(profile_id)
+ tools_bin_path = config.get_games_saves_tools_bin_path()
+ profile_dir = config.get_profile_dir(profile_id)
command = [
*[f'{tools_bin_path}/mod-{item}' for item in game_mods],
diff --git a/gamechestcli/gamechest/paths.py b/gamechestcli/gamechest/paths.py
deleted file mode 100644
index 5e009a6..0000000
--- a/gamechestcli/gamechest/paths.py
+++ /dev/null
@@ -1,36 +0,0 @@
-import os
-from pathlib import Path
-
-from xdg import xdg_data_home
-
-from . import consts
-
-
-def get_remote_basedir():
- # TODO: unhardcode this
- return 'jibril:/storage/games'
-
-
-def get_games_saves_path():
- # TODO: unhardcode this
- return Path(os.path.expanduser('~/games/.saves'))
- #return Path(os.path.expanduser('~/game-saves'))
-
-
-def get_games_saves_tools_bin_path():
- return get_games_saves_path() / 'tools' / 'bin'
-
-
-def get_profile_dir(profile_id):
- return get_games_saves_path() / 'profiles' / profile_id
-
-
-def get_games_database_path():
- return get_games_saves_path() / 'gamedata.yaml'
-
-
-def get_games_install_basedir():
- games_install_path = xdg_data_home() / consts.XDG_RESOURCE_NAME / 'games'
- games_install_path.mkdir(parents=True, exist_ok=True)
- return games_install_path
-
diff --git a/gamechestcli/gamechest/processor.py b/gamechestcli/gamechest/processor.py
index 89a340c..e31d023 100644
--- a/gamechestcli/gamechest/processor.py
+++ b/gamechestcli/gamechest/processor.py
@@ -36,6 +36,6 @@ def process_task(title, task):
rich_progress.update(global_id, completed=known_total)
#rich_progress.console.print('installation ended with code:', rc)
if rc != 0:
- # success, update db to say installed
- status_db.set_installed(game_info)
+ print('Process failed, aborting')
+ raise SystemExit(1)
print('ended with code:', rc)
diff --git a/gamechestcli/gamechest/runners/install.py b/gamechestcli/gamechest/runners/install.py
index 36b0153..7b2ff7c 100644
--- a/gamechestcli/gamechest/runners/install.py
+++ b/gamechestcli/gamechest/runners/install.py
@@ -1,5 +1,6 @@
import functools
import os
+from pathlib import Path
from .download import Download
from .extract import Extract
@@ -10,8 +11,7 @@ from .runnermulti import MultiSequencialRunnerBase
class Install(MultiSequencialRunnerBase):
def __init__(self, source, dest):
- filename = os.path.split(source)[1]
- tmpdest = os.path.join(dest, f'{filename}.rsynctmp')
+ tmpdest = Path(dest) / 'archive.rsynctmp'
runners = [
functools.partial(Download, source, tmpdest),
functools.partial(Extract, tmpdest, dest),