diff options
Diffstat (limited to 'gamechestcli')
| -rwxr-xr-x | gamechestcli/__main__.py | 28 | ||||
| -rw-r--r-- | gamechestcli/gamechest/cli.py | 1 | ||||
| -rw-r--r-- | gamechestcli/gamechest/cliactions/install.py | 5 | ||||
| -rw-r--r-- | gamechestcli/gamechest/cliactions/remove.py | 4 | ||||
| -rw-r--r-- | gamechestcli/gamechest/cliactions/run.py | 31 | ||||
| -rw-r--r-- | gamechestcli/gamechest/gamedb.py | 34 | ||||
| -rw-r--r-- | gamechestcli/gamechest/paths.py | 23 | ||||
| -rw-r--r-- | gamechestcli/gamechest/statusdb.py | 24 | ||||
| -rw-r--r-- | gamechestcli/requirements.txt | 3 | 
9 files changed, 126 insertions, 27 deletions
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 <GAME_ID> +       gamechest remove <GAME_ID> +       gamechest run --profile_id=<PROFILE_ID> <GAME_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['<GAME_ID>']) +    elif args['remove']: +        remove.remove(args['<GAME_ID>']) +    elif args['run']: +        run.run(args['<GAME_ID>'], 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  | 
