You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
2.1 KiB
69 lines
2.1 KiB
import os
|
|
import typing
|
|
from logging import NullHandler, getLogger
|
|
|
|
import yaml
|
|
|
|
try:
|
|
from importlib.resources import files
|
|
except ImportError:
|
|
from importlib_resources import files # type: ignore[assignment,no-redef,import-not-found]
|
|
|
|
from knowit.serializer import get_yaml_loader
|
|
|
|
logger = getLogger(__name__)
|
|
logger.addHandler(NullHandler())
|
|
|
|
|
|
class _Value(typing.NamedTuple):
|
|
code: str
|
|
default: str
|
|
human: str
|
|
technical: str
|
|
|
|
|
|
_valid_aliases = _Value._fields
|
|
|
|
|
|
class Config:
|
|
"""Application config class."""
|
|
|
|
@classmethod
|
|
def build(cls, path: typing.Optional[typing.Union[str, os.PathLike]] = None) -> 'Config':
|
|
"""Build config instance."""
|
|
loader = get_yaml_loader()
|
|
config_file = files(__package__).joinpath('defaults.yml')
|
|
with config_file.open('rb') as stream:
|
|
cfgs = [yaml.load(stream, Loader=loader)]
|
|
|
|
if path:
|
|
with open(path, 'rb') as stream:
|
|
cfgs.append(yaml.load(stream, Loader=loader))
|
|
|
|
profiles_data = {}
|
|
for cfg in cfgs:
|
|
if 'profiles' in cfg:
|
|
profiles_data.update(cfg['profiles'])
|
|
|
|
knowledge_data = {}
|
|
for cfg in cfgs:
|
|
if 'knowledge' in cfg:
|
|
knowledge_data.update(cfg['knowledge'])
|
|
|
|
data: typing.Dict[str, typing.MutableMapping] = {'general': {}}
|
|
for class_name, data_map in knowledge_data.items():
|
|
data.setdefault(class_name, {})
|
|
for code, detection_values in data_map.items():
|
|
alias_map = (profiles_data.get(class_name) or {}).get(code) or {}
|
|
alias_map.setdefault('code', code)
|
|
alias_map.setdefault('default', alias_map['code'])
|
|
alias_map.setdefault('human', alias_map['default'])
|
|
alias_map.setdefault('technical', alias_map['human'])
|
|
value = _Value(**{k: v for k, v in alias_map.items() if k in _valid_aliases})
|
|
for detection_value in detection_values:
|
|
data[class_name][str(detection_value)] = value
|
|
|
|
config = Config()
|
|
config.__dict__ = data
|
|
return config
|