diff --git a/izzylib/config.py b/izzylib/config.py new file mode 100644 index 0000000..2826b2a --- /dev/null +++ b/izzylib/config.py @@ -0,0 +1,107 @@ +from . import izzylog +from .dotdict import DotDict +from .path import Path + +try: + import yaml +except ImportError: + izzylog.verbose('Failed to import pyyaml. YamlConfig disabled') + yaml = None + + +class BaseConfig(DotDict): + def __init__(self, config_file=None, value_parser=None, **defaults): + self._defaults = defaults + self._config_file = Path(config_file) + self._parser = value_parser or self.parse_value + + super().__init__(defaults) + + + def __setitem__(self, key, value): + if not key in self._defaults: + raise KeyError(f'Not a valid config option: {key}') + + value = self._parser(key, value) + super().__setitem__(key, value) + + + def _load_config(self): + pass + + + def _save_config(self): + pass + + + def parse_value(self, key, value): + return value + + + def set_data(self, _data={}, **kwargs): + if _data == None: + return + + data = {**_data, **kwargs} + + for k, v in data.items(): + self[k] = v + + + def reset(self, key=None): + if not key: + self.set_data(self._defaults) + + else: + self[key] = self._defaults[key] + + + def load(self): + try: + self.set_data(self._load_config() or {}) + + return True + + except FileNotFoundError: + izzylog.warning('Cannot find path to config file:', self._config_file) + return False + + + def save(self, indent='\t'): + self._config_file.parent().mkdir() + self._save_config() + + +class JsonConfig(BaseConfig): + def _load_config(self): + self.load_json(self._config_file) + + + def _save_config(self): + self.save_json(self._config_file, indent='\t') + + +class YamlConfig(BaseConfig): + def __init__(self, *args, **kwargs): + if not yaml: + raise ImportError('PyYaml not found') + + super().__init__(*args, **kwargs) + + + def _load_config(self): + with self._config_file.open('r') as fd: + data = yaml.safe_load(fd) + + return data + + + def _save_config(self): + data = dict(self) + + for k,v in data.items(): + if isinstance(v, dict): + data[k] = dict(v) + + with self._config_file.open('w') as fd: + yaml.safe_dump(data, fd, sort_keys=False)