From 21908c97c1e897554751070d08e2b35694529bc0 Mon Sep 17 00:00:00 2001 From: vg Date: Sun, 18 Sep 2022 20:23:17 +0200 Subject: git-sync on seele --- Makefile | 8 +++++++ gamechestcli/__main__.py | 28 +++++++++++++++++++++++ gamechestcli/gamechest/cli.py | 1 - gamechestcli/gamechest/cliactions/install.py | 5 ++-- gamechestcli/gamechest/cliactions/remove.py | 4 ++-- gamechestcli/gamechest/cliactions/run.py | 31 +++++++++++++++++++++++++ gamechestcli/gamechest/gamedb.py | 34 ++++++++++++++++++++++++---- gamechestcli/gamechest/paths.py | 23 +++++++++++++++---- gamechestcli/gamechest/statusdb.py | 24 ++++++++++---------- gamechestcli/requirements.txt | 3 ++- 10 files changed, 134 insertions(+), 27 deletions(-) create mode 100755 gamechestcli/__main__.py delete mode 100644 gamechestcli/gamechest/cli.py diff --git a/Makefile b/Makefile index 6dde37e..a7c6f06 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,11 @@ static-fix: isort --order-by-type --atomic gamechestcli +zipapp: + mkdir /tmp/gamechest.zipapp + pip3 install --target /tmp/gamechest.zipapp -r gamechestcli/requirements.txt + #pip3 install --target /tmp/gamechest.zipapp gamechestcli + rsync -Pa gamechestcli/. /tmp/gamechest.zipapp/. + python3 -m zipapp -p "/usr/bin/env python3" /tmp/gamechest.zipapp + rm -r /tmp/gamechest.zipapp + if [ -e ~/games/.saves ]; then mv /tmp/gamechest.pyz ~/games/.saves/tools/bin/. ; elif [ -e ~/game-saves ]; then mv /tmp/gamechest.pyz ~/game-saves/tools/bin/. ; fi diff --git a/gamechestcli/__main__.py b/gamechestcli/__main__.py new file mode 100755 index 0000000..1497e40 --- /dev/null +++ b/gamechestcli/__main__.py @@ -0,0 +1,28 @@ +#!/usr/bin/python3 +''' +Manage games. Install, remove, run them. + +Usage: gamechest install + gamechest remove + gamechest run --profile_id= +''' + +import docopt + +from gamechest.cliactions import install, remove, run + + +def main(): + args = docopt.docopt(__doc__) + #print(args); raise SystemExit(0) + + if args['install']: + install.install(args['']) + elif args['remove']: + remove.remove(args['']) + elif args['run']: + run.run(args[''], args['--profile_id']) + + +if __name__ == "__main__": + main() diff --git a/gamechestcli/gamechest/cli.py b/gamechestcli/gamechest/cli.py deleted file mode 100644 index 8b13789..0000000 --- a/gamechestcli/gamechest/cli.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/gamechestcli/gamechest/cliactions/install.py b/gamechestcli/gamechest/cliactions/install.py index ed2437f..8584d35 100644 --- a/gamechestcli/gamechest/cliactions/install.py +++ b/gamechestcli/gamechest/cliactions/install.py @@ -8,7 +8,8 @@ from ..statusdb import StatusDB def install_game(status_db, game_info): remote_basedir = paths.get_remote_basedir() source = f'{remote_basedir}/{game_info["package_name"]}' - dest = paths.get_games_install_basedir() + dest = paths.get_games_install_basedir() / game_info['id'] + dest.mkdir(parents=True, exist_ok=True) title = 'Installing game...' task = functools.partial(Install, source, dest) processor.process_task(title, task) @@ -16,7 +17,7 @@ def install_game(status_db, game_info): def install(game_id): - game_db = gamdb.GameDB() + game_db = gamedb.GameDB() game_info = game_db.get_game_info(game_id) status_db = StatusDB() if status_db.is_installed(game_info): diff --git a/gamechestcli/gamechest/cliactions/remove.py b/gamechestcli/gamechest/cliactions/remove.py index 1668e63..d5452d5 100644 --- a/gamechestcli/gamechest/cliactions/remove.py +++ b/gamechestcli/gamechest/cliactions/remove.py @@ -14,7 +14,7 @@ def remove_game(status_db, game_info): remote_basedir = paths.get_remote_basedir() path = ( paths.get_games_install_basedir() - / status_db.get_installed_game_name(game_info['id']) + / game_info['id'] ) title = 'Removing game...' task = functools.partial(Remove, path) @@ -23,7 +23,7 @@ def remove_game(status_db, game_info): def remove(game_id): - game_db = gamdb.GameDB() + game_db = gamedb.GameDB() game_info = game_db.get_game_info(game_id) status_db = StatusDB() if status_db.is_installed(game_info): diff --git a/gamechestcli/gamechest/cliactions/run.py b/gamechestcli/gamechest/cliactions/run.py index e69de29..b5369aa 100644 --- a/gamechestcli/gamechest/cliactions/run.py +++ b/gamechestcli/gamechest/cliactions/run.py @@ -0,0 +1,31 @@ +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() + #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 + # need to modify the path environment variable. + subprocess.run(command) + + +def run(game_id, profile_id): + game_db = GameDB() + status_db = StatusDB() + game_info = game_db.get_game_info(game_id) + if not status_db.is_installed(game_info): + # games is already installed + print('Game', game_id, 'is not installed, aborting.', file=sys.stderr) + return + run_game(game_db, profile_id, game_info) + + +if __name__ == "__main__": + run(*sys.argv[1:]) diff --git a/gamechestcli/gamechest/gamedb.py b/gamechestcli/gamechest/gamedb.py index d932438..2000c52 100644 --- a/gamechestcli/gamechest/gamedb.py +++ b/gamechestcli/gamechest/gamedb.py @@ -9,9 +9,35 @@ class GameDB: database_path = paths.get_games_database_path() with open(database_path, 'rb') as fdin: self.db = yaml.safe_load(fdin) + self.last_game_info = None + def get_game_info(self, game_id=None): + if self.last_game_info and self.last_game_info['id'] == game_id: + return self.last_game_info + game_info = next(game_info + for game_info in self.db['games'] + if game_info['id'] == game_id) + self.last_game_info = game_info + return game_info - def get_game_info(self, game_id): - return next(game_info - for game_info in self.db['games'] - if game_info['id'] == game_id) + def get_game_command(self, profile_id, game_id=None): + game_info = self.get_game_info(game_id) + game_mods = game_info.get('mods', []) + game_mods += ['locked-run-profiledir'] + + game_dir = paths.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) + + command = [ + *[f'{tools_bin_path}/mod-{item}' for item in game_mods], + profile_dir, + game_dir, + *[item if index > 0 else f'{tools_bin_path}/{item}' + for index, item in enumerate(game_info['command'])], + ] + + return command diff --git a/gamechestcli/gamechest/paths.py b/gamechestcli/gamechest/paths.py index 53cafe0..5e009a6 100644 --- a/gamechestcli/gamechest/paths.py +++ b/gamechestcli/gamechest/paths.py @@ -1,19 +1,32 @@ import os +from pathlib import Path from xdg import xdg_data_home from . import consts -def get_games_database_path(): +def get_remote_basedir(): # TODO: unhardcode this - #return os.path.expanduser('~/games/.saves/gamedata.yaml') - return os.path.expanduser('~/game-saves/gamedata.yaml') + return 'jibril:/storage/games' -def get_remote_basedir(): +def get_games_saves_path(): # TODO: unhardcode this - return 'jibril:/storage/games' + 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(): diff --git a/gamechestcli/gamechest/statusdb.py b/gamechestcli/gamechest/statusdb.py index a41fe32..e343d8e 100644 --- a/gamechestcli/gamechest/statusdb.py +++ b/gamechestcli/gamechest/statusdb.py @@ -66,18 +66,18 @@ class StatusDB: game_info['id'], )) - def get_installed_game_name(self, game_id): - row = ( - self.conn - .execute('SELECT version_installed FROM status WHERE game_id = ?', - (game_id, )) - .fetchone() - ) - if row is None: - #return False - raise ValueError('Game not found') - version_installed = row[0] - return f'{game_id}_v{version_installed}' + #def get_installed_game_name(self, game_id): + # row = ( + # self.conn + # .execute('SELECT version_installed FROM status WHERE game_id = ?', + # (game_id, )) + # .fetchone() + # ) + # if row is None: + # #return False + # raise ValueError('Game not found') + # version_installed = row[0] + # return f'{game_id}_v{version_installed}' def set_uninstalled(self, game_info): return self.set_installed(game_info, installed=False) diff --git a/gamechestcli/requirements.txt b/gamechestcli/requirements.txt index 576e0b3..638d583 100644 --- a/gamechestcli/requirements.txt +++ b/gamechestcli/requirements.txt @@ -1,4 +1,5 @@ +docopt humanfriendly pyyaml -xdg rich +xdg -- cgit v1.2.3