diff options
author | Evgeny Zinoviev <me@ch1p.io> | 2023-06-08 02:26:28 +0300 |
---|---|---|
committer | Evgeny Zinoviev <me@ch1p.io> | 2023-06-08 02:26:28 +0300 |
commit | eb825f62ee876e5cf6c6ffc31a7e218d78c94993 (patch) | |
tree | 5d59f0d8ad9a171a714080a3ab75d7adc5d5dc2b /src/home | |
parent | 3ae1c3b5a7196cd7f556579658244868026b5e11 (diff) |
save
Diffstat (limited to 'src/home')
-rw-r--r-- | src/home/config/__init__.py | 12 | ||||
-rw-r--r-- | src/home/config/_configs.py | 5 | ||||
-rw-r--r-- | src/home/config/config.py | 175 | ||||
-rw-r--r-- | src/home/config/validators/__init__.py | 2 | ||||
-rw-r--r-- | src/home/config/validators/_util.py | 11 | ||||
-rw-r--r-- | src/home/config/validators/_validators.py (renamed from src/home/config/_validators.py) | 16 |
6 files changed, 126 insertions, 95 deletions
diff --git a/src/home/config/__init__.py b/src/home/config/__init__.py index cc9c091..10c5bd9 100644 --- a/src/home/config/__init__.py +++ b/src/home/config/__init__.py @@ -1 +1,11 @@ -from .config import ConfigStore, config, is_development_mode, setup_logging +from .config import ( + Config, + config, + is_development_mode, + setup_logging, + app_config +) +from .validators import validate +from ._configs import ( + LinuxBoardsConfig +)
\ No newline at end of file diff --git a/src/home/config/_configs.py b/src/home/config/_configs.py new file mode 100644 index 0000000..2f98d06 --- /dev/null +++ b/src/home/config/_configs.py @@ -0,0 +1,5 @@ +from .config import ConfigUnit + + +class LinuxBoardsConfig(ConfigUnit): + NAME = 'linux_boards' diff --git a/src/home/config/config.py b/src/home/config/config.py index b79fecb..8ed8483 100644 --- a/src/home/config/config.py +++ b/src/home/config/config.py @@ -3,110 +3,74 @@ import yaml import logging import os +from . import validators from os.path import join, isdir, isfile from typing import Optional, Any, MutableMapping from argparse import ArgumentParser from ..util import parse_addr -import _validators as validators -_validators = {} +my_validators = {} def _get_validator(name: str) -> Optional[callable]: if hasattr(validators, f'{name}_validator'): return getattr(validators, f'{name}_validator') - if name in _validators: - return _validators[name] + if name in my_validators: + return my_validators[name] return None def add_validator(name: str, f: callable): - _validators[name] = f + my_validators[name] = f -def _get_config_path(name: str) -> str: - formats = ['toml', 'yaml'] +class ConfigUnit: + NAME = 'dumb' - dirnames = [ - join(os.environ['HOME'], '.config', 'homekit'), - '/etc/homekit' - ] - - for dirname in dirnames: - if isdir(dirname): - for fmt in formats: - filename = join(dirname, f'{name}.{fmt}') - if isfile(filename): - return filename - - raise IOError(f'config \'{name}\' not found') - - -class SingleConfig: data: MutableMapping[str, Any] - def __init__(self): - self.data = {} + @classmethod + def get_config_path(cls, name=None) -> str: + if name is None: + name = cls.NAME + if name is None: + raise ValueError('get_config_path: name is none') - def load(self, - name: Optional[str] = None, - use_cli=True, - parser: ArgumentParser = None): - self.app_name = name + dirnames = ( + join(os.environ['HOME'], '.config', 'homekit'), + '/etc/homekit' + ) - if (name is None) and (not use_cli): - raise RuntimeError('either config name must be none or use_cli must be True') + for dirname in dirnames: + if isdir(dirname): + for fmt in ('toml', 'yaml'): + filename = join(dirname, f'{name}.{fmt}') + if isfile(filename): + return filename - log_default_fmt = False - log_file = None - log_verbose = False - no_config = name is False + raise IOError(f'config \'{name}\' not found') - path = None - if use_cli: - if parser is None: - parser = ArgumentParser() - if not no_config: - parser.add_argument('-c', '--config', type=str, required=name is None, - help='Path to the config in TOML or YAML format') - parser.add_argument('-V', '--verbose', action='store_true') - parser.add_argument('--log-file', type=str) - parser.add_argument('--log-default-fmt', action='store_true') - args = parser.parse_args() + def __init__(self, name=None): + self.data = {} - if not no_config and args.config: - path = args.config + if self.NAME != 'dumb': + self.load_from(self.get_config_path()) + self.validate() - if args.verbose: - log_verbose = True - if args.log_file: - log_file = args.log_file - if args.log_default_fmt: - log_default_fmt = args.log_default_fmt + elif name is not None: + self.NAME = name - if not no_config and path is None: - path = _get_config_path(name) - - if no_config: - self.data = {} - else: - if path.endswith('.toml'): - self.data = toml.load(path) - elif path.endswith('.yaml'): - with open(path, 'r') as fd: - self.data = yaml.safe_load(fd) - - if 'logging' in self: - if not log_file and 'file' in self['logging']: - log_file = self['logging']['file'] - if log_default_fmt and 'default_fmt' in self['logging']: - log_default_fmt = self['logging']['default_fmt'] + def load_from(self, path: str): + if path.endswith('.toml'): + self.data = toml.load(path) + elif path.endswith('.yaml'): + with open(path, 'r') as fd: + self.data = yaml.safe_load(fd) - setup_logging(log_verbose, log_file, log_default_fmt) - - if use_cli: - return args + def validate(self): + v = _get_validator(self.NAME) + v(self.data) def __getitem__(self, key): return self.data[key] @@ -139,22 +103,75 @@ class SingleConfig: class Config: app_name: Optional[str] + app_config: ConfigUnit def __init__(self): - self.app_name = None + self.app_config = ConfigUnit() + def load_app(self, + name: Optional[str] = None, + use_cli=True, + parser: ArgumentParser = None): + self.app_name = name + + if (name is None) and (not use_cli): + raise RuntimeError('either config name must be none or use_cli must be True') + + log_default_fmt = False + log_file = None + log_verbose = False + no_config = name is False + path = None + if use_cli: + if parser is None: + parser = ArgumentParser() + if not no_config: + parser.add_argument('-c', '--config', type=str, required=name is None, + help='Path to the config in TOML or YAML format') + parser.add_argument('-V', '--verbose', action='store_true') + parser.add_argument('--log-file', type=str) + parser.add_argument('--log-default-fmt', action='store_true') + args = parser.parse_args() + + if not no_config and args.config: + path = args.config + + if args.verbose: + log_verbose = True + if args.log_file: + log_file = args.log_file + if args.log_default_fmt: + log_default_fmt = args.log_default_fmt + + if not no_config and path is None: + path = ConfigUnit.get_config_path(name=name) + + if not no_config: + self.app_config.load_from(path) + + if 'logging' in self.app_config: + if not log_file and 'file' in self.app_config['logging']: + log_file = self.app_config['logging']['file'] + if log_default_fmt and 'default_fmt' in self.app_config['logging']: + log_default_fmt = self.app_config['logging']['default_fmt'] + + setup_logging(log_verbose, log_file, log_default_fmt) + + if use_cli: + return args -config = ConfigStore() +config = Config() +app_config = config.app_config def is_development_mode() -> bool: if 'HK_MODE' in os.environ and os.environ['HK_MODE'] == 'dev': return True - return ('logging' in config) and ('verbose' in config['logging']) and (config['logging']['verbose'] is True) + return ('logging' in config.app_config) and ('verbose' in config.app_config['logging']) and (config.app_config['logging']['verbose'] is True) def setup_logging(verbose=False, log_file=None, default_fmt=False): diff --git a/src/home/config/validators/__init__.py b/src/home/config/validators/__init__.py new file mode 100644 index 0000000..0e75132 --- /dev/null +++ b/src/home/config/validators/__init__.py @@ -0,0 +1,2 @@ +from ._validators import * +from ._util import validate diff --git a/src/home/config/validators/_util.py b/src/home/config/validators/_util.py new file mode 100644 index 0000000..5227c40 --- /dev/null +++ b/src/home/config/validators/_util.py @@ -0,0 +1,11 @@ +import inspect + +from cerberus import Validator, DocumentError + + +def validate(schema, data): + v = Validator(schema) + if not v.validate(data): + frame = inspect.currentframe().f_back + caller_name = frame.f_code.co_name + raise DocumentError(f'{caller_name}: failed to validate data: ' + v.errors) diff --git a/src/home/config/_validators.py b/src/home/config/validators/_validators.py index 963a25f..cddc1b0 100644 --- a/src/home/config/_validators.py +++ b/src/home/config/validators/_validators.py @@ -1,23 +1,9 @@ -import logging -import inspect - -from cerberus import Validator, DocumentError - +from ._util import validate __all__ = [ 'linux_boards_validator' ] -_logger = logging.getLogger(__name__) - - -def validate(schema, data): - v = Validator(schema) - if not v.validate(data): - frame = inspect.currentframe().f_back - caller_name = frame.f_code.co_name - raise DocumentError(f'{caller_name}: failed to validate data: ' + v.errors) - def linux_boards_validator(data) -> None: validate({ |