diff options
Diffstat (limited to 'gamechest/gamemanager.py')
-rw-r--r-- | gamechest/gamemanager.py | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/gamechest/gamemanager.py b/gamechest/gamemanager.py new file mode 100644 index 0000000..2e9b06c --- /dev/null +++ b/gamechest/gamemanager.py @@ -0,0 +1,183 @@ +#!python3 + +import contextlib +from logging import debug, info, warning, critical +from enum import Enum, auto as enum_auto + +import yaml + +#from . import utils +from stepper import Stepper +import steps_install, steps_remove + +def strip_tar_ext(name): + ext = '.tar.lzip' + return name[:-len(ext)] if name.lower().endswith(ext) else name + + + +_installer_steps_dict = { + 'download': steps_install.step_rsync, + 'extract': steps_install.step_extract, + 'clean': steps_install.step_clean, +} +_remover_steps_dict = { + 'remove': steps_remove.step_remove, +} +_updater_steps_dict = dict(**_remover_steps_dict, **_installer_steps_dict) + + +class GameStepper: + + def __init__(self, conf): + self.game_installer = Stepper(conf, installer_steps_dict) + self.game_remover = Stepper(conf, remover_steps_dict) + self.game_updater = Stepper(conf, updater_steps_dict) + self.curent = None + + def install(self, game_id): + if self.current: + return + self.current = self.game_installer + self.game_installer.start(self.conf.get_status(game_id)) + + def remove(self, game_id): + if self.current: + return + self.current = self.game_remover + self.game_remover.start(self.conf.get_status(game_id)) + + def update(self, game_id): + if self.current: + return + self.current = self.game_updater + self.game_updater.start(self.conf.get_status(game_id)) + + def stop(self): + if self.current: + self.current.stop() + self.current = None + + def poll(self): + if self.current: + return self.current.poll() + + +class GameManager: + + class State(Enum): + IDLE = enum_auto() + ONGOING = enum_auto() + + def __init__(self, conf): + self.game_installer = Stepper(conf, installer_steps_dict) + self.game_remover = Stepper(conf, remover_steps_dict) + self.game_updater = Stepper(conf, updater_steps_dict) + + #def __init__(self, games_data_yaml_path, games_dir): + # self.games_data_yaml_path = games_data_yaml_path + # self.games_dir = games_dir + # self.state = self.State.IDLE + # self.update_state = self.State.IDLE + # self.current_game_name = None + # self.current_game_item = None + # self.current_game_status = {} + + # with open(games_data_yaml_path) as stream: + # self.games_data = yaml.safe_load(stream) + + # self.game_installer = GameInstaller( + # self.games_data['repository']['host'], + # self.games_data['repository']['path'], + # self.games_dir, + # ) + # self.game_remover = GameRemover( + # self.games_data['repository']['host'], + # self.games_data['repository']['path'], + # self.games_dir, + # ) + + def get_game_item(self, name): + self.current_game_item = next( + item + for item in self.games_data['games'] + if item['name'] == name + ) + return self.current_game_item + + def get_game_status(self, name): + self.current_game_status = {} + with contextlib.suppress(FileNotFoundError): + with open(f'{self.conf.gamedir}/{name}.yaml') as stream: + self.current_game_status = yaml.safe_load(stream) + return self.current_game_status + + def is_game_updatable(self, name): + #self. ### FIXME: Stopped here ? + if not self.current_game_name: + return False + ivers = self.current_game_status.get('installed_version', None) + # only call "updatable" if there was at least a version installed + # else, this is just an "installable" package. + if ivers is not None and ivers < self.current_game_item['version']: + return True + return False + + def set_current_game(self, game_id): + if self.current_game_name == name: + return + self.current_game_name = name + self.get_game_item(name) + self.get_game_status(name) + + def start_install(self, game_id): + if self.state != self.State.IDLE: + return + self.status = self.State.INSTALLING + self.set_current_game(name) + self.game_installer.start( + self.current_game_item, + game_status=self.current_game_status, + ) + + def start_remove(self, name): + if self.state != self.State.IDLE: + return + self.status = self.State.REMOVING + self.set_current_game(name) + self.game_remover.start( + self.current_game_item, + game_status=self.current_game_status, + ) + + def start_update(self, name): + if self.state != self.State.IDLE: + return + self.status = self.State.UPDATING_REMOVING + self.set_current_game(name) + self.game_remover.start( + self.current_game_item, + game_status=self.current_game_status, + ) + + def stop(self): + self.state = self.State.IDLE + self.game_remover.stop() + self.game_installer.stop() + + def poll(self): + entry_state = self.state + return_value = { + self.State.IDLE: (lambda: GameManagerBase.State.IDLE, 0, 0), + self.State.INSTALLING: self.game_installer.poll, + self.State.REMOVING: self.game_remover.poll, + self.State.UPDATING_REMOVING: self.game_remover.poll, + self.State.UPDATING_INSTALLING: self.game_installer.poll, + }[entry_state]() + if return_value[0] == GameManagerBase.Sate.IDLE: + self.state = self.State.IDLE + if entry_state == self.State.UPDATING_REMOVING: + self.start_install(self.current_game_name) + return_value = self.poll() + return self.state, return_value[1], return_value[2] + |