From 639df8ce5ba8b70520c3a2f6be212cb15f338c15 Mon Sep 17 00:00:00 2001 From: Adam Saudagar Date: Mon, 29 Mar 2021 16:01:12 +0530 Subject: [PATCH] moved config code into 2 parts, class (Config) and singleton (config)... singleton needs to be initlaized and stopped in main, now config backups the config file every 5 minutes in temp folder, if the file gets corrupted, it restores the backup and continues working --- fishy/__main__.py | 2 + fishy/gui/splash.py | 10 +-- fishy/helper/config.py | 138 +++++++++++++++++++++++++++++------------ requirements.txt | 3 +- 4 files changed, 109 insertions(+), 44 deletions(-) diff --git a/fishy/__main__.py b/fishy/__main__.py index ed47f79..8c80208 100644 --- a/fishy/__main__.py +++ b/fishy/__main__.py @@ -68,6 +68,7 @@ def initialize(window_to_hide): def main(): + config.init() splash.start() print("launching please wait...") @@ -90,6 +91,7 @@ def main(): gui_window.start() bot.start_event_handler() + config.stop() if __name__ == "__main__": diff --git a/fishy/gui/splash.py b/fishy/gui/splash.py index 5c30e9d..6ead4cf 100644 --- a/fishy/gui/splash.py +++ b/fishy/gui/splash.py @@ -7,7 +7,7 @@ from fishy.helper.config import config from fishy.helper import helper -def show(): +def show(win_loc): dim=(300,200) top = Tk() @@ -25,8 +25,10 @@ def show(): canvas.create_image(0, 0, anchor=NW, image=top.image) # Position splash at the center of the main window - win_loc = config.get("win_loc", str(top.winfo_reqwidth())+"+"+str(top.winfo_reqheight())+"+"+"0"+"0").split("+")[1:] - top.geometry("{}x{}+{}+{}".format(dim[0], dim[1], int(win_loc[0])+int(dim[0]/2), int(win_loc[1])+int(dim[1]/2))) + + default_loc = (str(top.winfo_reqwidth())+"+"+str(top.winfo_reqheight())+"+"+"0"+"0") + loc = (win_loc or default_loc).split("+")[1:] + top.geometry("{}x{}+{}+{}".format(dim[0], dim[1], int(loc[0])+int(dim[0]/2), int(loc[1])+int(dim[1]/2))) top.update() time.sleep(3) @@ -34,4 +36,4 @@ def show(): def start(): - Process(target=show).start() + Process(target=show, args=(config.get("win_loc"),)).start() diff --git a/fishy/helper/config.py b/fishy/helper/config.py index 3af9187..34706ae 100644 --- a/fishy/helper/config.py +++ b/fishy/helper/config.py @@ -3,9 +3,12 @@ config.py Saves configuration in file as json file """ import json +import logging import os # path to save the configuration file +from typing import Optional +from event_scheduler import EventScheduler def filename(): @@ -18,53 +21,60 @@ def filename(): return os.path.join(get_documents(), name) +temp_file = os.path.join(os.environ["TEMP"], "fishy_config.BAK") + + class Config: def __init__(self): - """ - cache the configuration in a dict for faster access, - if file is not found initialize the dict - """ - self.config_dict = json.loads(open(filename()).read()) if os.path.exists(filename()) else dict() + self._config_dict: Optional[dict] = None + self._scheduler: Optional[EventScheduler] = None - def get(self, key, default=None): - """ - gets a value from configuration, - if it is not found, return the default configuration - :param key: key of the config - :param default: default value to return if key is not found - :return: config value - """ - return self.config_dict[key] if key in self.config_dict else default + def __getitem__(self, item): + return self._config_dict.get(item) - def set(self, key, value, save=True): - """ - saves the configuration is cache (and saves it in file if needed) - :param key: key to save - :param value: value to save - :param save: False if don't want to save right away - """ - self.config_dict[key] = value - if save: - self.save_config() + def __setitem__(self, key, value): + self._config_dict[key] = value - def delete(self, key): - """ - deletes a key from config - :param key: key to delete - """ - try: - del self.config_dict[key] - self.save_config() - except KeyError: - pass + def __delitem__(self, key): + del self._config_dict[key] + def initialize(self): + self._scheduler = EventScheduler() + if os.path.exists(filename()): + + try: + self._config_dict = json.loads(open(filename()).read()) + except json.JSONDecodeError: + try: + print("Config file got corrupted, trying to restore backup") + self._config_dict = json.loads(open(temp_file).read()) + self.save_config() + except (FileNotFoundError, json.JSONDecodeError): + print("couldn't restore, creating new") + os.remove(filename()) + self._config_dict = dict() + + else: + self._config_dict = dict() + + self._create_backup() + self._scheduler.start() + self._scheduler.enter_recurring(5 * 60, 1, self._create_backup) + + def stop(self): + self._scheduler.stop(True) + + def _create_backup(self): + with open(temp_file, 'w') as f: + f.write(json.dumps(self._config_dict)) + print("created backup") def _sort_dict(self): tmpdict = dict() - for key in sorted(self.config_dict.keys()): - tmpdict[key] = self.config_dict[key] - self.config_dict = tmpdict + for key in sorted(self._config_dict.keys()): + tmpdict[key] = self._config_dict[key] + self._config_dict = tmpdict def save_config(self): """ @@ -72,7 +82,57 @@ class Config: """ self._sort_dict() with open(filename(), 'w') as f: - f.write(json.dumps(self.config_dict)) + f.write(json.dumps(self._config_dict)) -config = Config() +# noinspection PyPep8Naming +class config: + _instance = None + + @staticmethod + def init(): + config._instance = Config() + config._instance.initialize() + + @staticmethod + def stop(): + config._instance.stop() + + @staticmethod + def get(key, default=None): + """ + gets a value from configuration, + if it is not found, return the default configuration + :param key: key of the config + :param default: default value to return if key is not found + :return: config value + """ + return config._instance[key] or default + + @staticmethod + def set(key, value, save=True): + """ + saves the configuration is cache (and saves it in file if needed) + :param key: key to save + :param value: value to save + :param save: False if don't want to save right away + """ + config._instance[key] = value + if save: + config.save_config() + + @staticmethod + def delete(key): + """ + deletes a key from config + :param key: key to delete + """ + try: + del config._instance[key] + config.save_config() + except KeyError: + pass + + @staticmethod + def save_config(): + config._instance.save_config() diff --git a/requirements.txt b/requirements.txt index 84400ba..59394a0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,4 +12,5 @@ whatsmyip pynput pytesseract keyboard -playsound \ No newline at end of file +playsound +event-scheduler \ No newline at end of file