summaryrefslogtreecommitdiffstats
path: root/gamechest/gamemanager.py
diff options
context:
space:
mode:
Diffstat (limited to 'gamechest/gamemanager.py')
-rw-r--r--gamechest/gamemanager.py183
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]
+