Get config loading and parsing into usable state

This commit is contained in:
hygienic-books 2022-03-13 17:17:44 +01:00
parent d1130baa10
commit 720493d0de

78
main.py
View File

@ -32,18 +32,55 @@ log = logging.getLogger("rich")
log.setLevel(logging.DEBUG)
config = configparser.ConfigParser()
class ConfigParser(configparser.ConfigParser):
"""Can get options() without defaults
Taken from https://stackoverflow.com/a/12600066.
"""
def options(self, section, no_defaults=False, **kwargs):
if no_defaults:
try:
return list(self._sections[section].keys())
except KeyError:
raise configparser.NoSectionError(section)
else:
return super().options(section)
ini_defaults = []
internal_defaults = {
"self_name": "mvw-dl",
"tmp_base_dir": "/tmp/%(self_name)s",
"state_base_dir": "/var/lib/%(self_name)s",
"state_files_dir": "%(state_base_dir)s/state",
"state_file_retention": "50",
"state_file_name_prefix": "state-",
"state_file_name_suffix": ".log"
}
config = ConfigParser(defaults=internal_defaults)
config.read(CONST.CFG_DEFAULT_FILENAME)
def validate_config_defaults(config_obj: configparser.ConfigParser()) -> None:
def print_section_header(header: str) -> str:
return f"Loading config section '[{header}]' ..."
def validate_default_section(config_obj: configparser.ConfigParser()) -> None:
log.debug(f"Loading config from file '{CONST.CFG_DEFAULT_ABS_PATH}' ...")
if not config_obj.sections():
log.error(f"No config sections found in '{CONST.CFG_DEFAULT_ABS_PATH}'. Exiting 1 ...")
sys.exit(1)
if config.defaults():
log.debug(f"Symbol legend:\n"
f"* Global default from section '[{config_obj.default_section}]'\n"
f"~ Local option, doesn't exist in '[{config_obj.default_section}]'\n"
f"+ Local override of a value from '[{config_obj.default_section}]'\n"
f"= Local override, same value as in '[{config_obj.default_section}]'")
log.debug(print_section_header(config_obj.default_section))
for default in config_obj.defaults():
log.debug(f" {default} = {config_obj[config_obj.default_section][default]}")
ini_defaults.append({default: config_obj[config_obj.default_section][default]})
log.debug(f"* {default} = {config_obj[config_obj.default_section][default]}")
else:
log.debug(f"No defaults defined")
@ -57,22 +94,32 @@ def config_has_valid_section(config_obj: configparser.ConfigParser()) -> bool:
return has_valid_section
#def option_has_default_value(config_option: configparser.ConfigParser(), section: str) -> bool:
#
#~ local option that doesn't exist in defaults section
#+ local option that overrides a default
#* global option
def is_default(config_key: str) -> bool:
return any(config_key in ini_default for ini_default in ini_defaults)
def is_same_as_default(config_kv_pair: dict) -> bool:
return config_kv_pair in ini_defaults
def validate_config_sections(config_obj: configparser.ConfigParser()) -> None:
for section in config_obj.sections():
log.debug(f"Loading config '[{section}]' ...")
for key in config_obj[section]:
# log.debug(config_obj.has_option(section, key))
is_local_option = True if config_obj.has_option(section, key) else False
log.debug(f""" {key}{"/" if is_local_option else ".."} = {config_obj[section][key]}""")
log.debug(print_section_header(section))
if CONST.CFG_MANDATORY not in config_obj.options(section, no_defaults=True):
log.warning(f"Config section '[{section}]' does not have mandatory option '{CONST.CFG_MANDATORY}' set, "
f"skipping section ...")
config_obj.remove_section(section)
else:
for key in config_obj.options(section, no_defaults=True):
kv_prefix = "~"
if is_default(key):
kv_prefix = "+"
if is_same_as_default({key: config_obj[section][key]}):
kv_prefix = "="
log.debug(f"{kv_prefix} {key} = {config_obj[section][key]}")
validate_config_defaults(config)
validate_default_section(config)
if config_has_valid_section(config):
validate_config_sections(config)
else:
@ -80,10 +127,9 @@ else:
f"option set. Exiting 2 ...")
sys.exit(2)
# https://stackoverflow.com/a/2451872
quit()
# This is a sample Python script.
# Press Umschalt+F10 to execute it or replace it with your code.