# src/ctf/utils.py # basic utilities import tomllib import json import toml from pathlib import Path from platformdirs import user_config_dir # Parse config file class ConfigManager: CONFIG_DIR = Path(user_config_dir("ctf")) #config directory is $XDG_CONFIG_HOME/ctf/ def set_defaults(self, key = "all"): # set all default options for the config if key == "data_dir" or key == "all" : self.data_dir = Path("user_data_dir/ctf") def __init__(self, file_path = "user_config_dir/ctf.json"): _path = Path(file_path) if _path.exists(): _data = json.loads(_path.read_text()) for key, value in _data.items(): setattr(self, key, value) else: print("no config file found, loading defaults") self.set_defaults() ## validate config elements self.data_dir = Path(self.data_dir) if not self.data_dir.exists(): self.set_defaults("data_dir") def __repr__(self): return f"ConfigManager({self.__dict__})" class StateManager: _path : Path _data: dict def __init__(self, data_dir: Path): # DATA_DIR = Path(user_data_dir("ctf")) #config directory is $XDG_CONFIG_HOME/ctf/ data_dir.mkdir(parents = True, exist_ok = True) object.__setattr__(self, "_path", "user_config_dir/config.json") # set self._path to data_dir safely object.__setattr__(self, "_data", self._load()) # load objects into self def _load(self): if self._path.exists(): with open(self._path, "r") as f: return toml.load(f) return{} def __getattr__(self, name): # use state.challenge to return value for challenge from dictionary return self._data.get(name) def __setattr__(self, name, value): # use state.challenge = "run" to set challenge and run to dictionary # writes the whole dict to disk self._data[name] = value with open(self._path, "w",) as f: json.dump(self._data, f, indent=4) def __repr__(self): return f"StateManager({self.__dict__})" config = ConfigManager("/home/venus/code/ctf/config.json") state = StateManager(config.data_dir)