from __future__ import annotations import os import os.path import toml from watchdog.events import FileSystemEventHandler from watchdog.observers import Observer config_observer = Observer() class Config: file_name: str values: dict = {} @staticmethod def load_config(file): global config_observer Config.file_name = file Config.reload() if config_observer.is_alive(): config_observer.stop() config_observer.join() config_observer.schedule(Config.ConfigEventHandler(), file) config_observer.start() @staticmethod def reload(): with open(Config.file_name, "r", encoding="utf-8") as f: Config.values = toml.load(f) @staticmethod def get(key: str, default=None, type=None, empty_is_none=False): key_path = key.split(".") value = Config.values for k in key_path: if k in value: value = value[k] else: return default if empty_is_none and value == "": return None if type == bool: if isinstance(value, bool): return value elif isinstance(value, int) or isinstance(value, float): return value != 0 else: return str(value).lower() in ("yes", "true", "1") elif type == int: return int(value) elif type == float: return float(value) elif type == str: return str(value) elif type == list: if not isinstance(value, list): return [] elif type == dict: if not isinstance(value, dict): return {} else: return value @staticmethod def set(key: str, value): key_path = key.split(".") obj = Config.values for k in key_path[:-1]: if k not in obj: obj[k] = {} obj = obj[k] obj[key_path[-1]] = value @staticmethod def unload(): global config_observer if config_observer.is_alive(): config_observer.stop() config_observer.join() class ConfigEventHandler(FileSystemEventHandler): def on_modified(self, event): if os.path.basename(event.src_path) == os.path.basename(Config.file_name): print("Config file changed, reloading...") Config.reload()