diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2024-09-26 11:40:51 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2024-10-30 14:42:53 -0400 |
commit | a91d8a66f3e1b11e2391f5d95983e8c8e1439aac (patch) | |
tree | caa621e1785b8aac55f09279fb33222c478034ce /klippy/configfile.py | |
parent | 9d4ab862b9eb06d48bbb274a6dcc12bc93d801ed (diff) | |
download | kutter-a91d8a66f3e1b11e2391f5d95983e8c8e1439aac.tar.gz kutter-a91d8a66f3e1b11e2391f5d95983e8c8e1439aac.tar.xz kutter-a91d8a66f3e1b11e2391f5d95983e8c8e1439aac.zip |
configfile: Separate access tracking to new ConfigValidate class
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'klippy/configfile.py')
-rw-r--r-- | klippy/configfile.py | 111 |
1 files changed, 73 insertions, 38 deletions
diff --git a/klippy/configfile.py b/klippy/configfile.py index 7801bfa5..5d497c3d 100644 --- a/klippy/configfile.py +++ b/klippy/configfile.py @@ -306,7 +306,7 @@ class ConfigAutoSave: self.fileconfig = cfgrdr.build_fileconfig(autosave_data, filename) cfgrdr.append_fileconfig(regular_fileconfig, autosave_data, '*AUTOSAVE*') - return regular_fileconfig + return regular_fileconfig, self.fileconfig def get_status(self, eventtime): return {'save_config_pending': self.save_config_pending, 'save_config_pending_items': self.status_save_pending} @@ -406,6 +406,55 @@ class ConfigAutoSave: ###################################################################### +# Config validation (check for undefined options) +###################################################################### + +class ConfigValidate: + def __init__(self, printer): + self.printer = printer + self.status_settings = {} + self.access_tracking = {} + self.autosave_options = {} + def start_access_tracking(self, autosave_fileconfig): + # Note autosave options for use during undefined options check + self.autosave_options = {} + for section in autosave_fileconfig.sections(): + for option in autosave_fileconfig.options(section): + self.autosave_options[(section.lower(), option.lower())] = 1 + self.access_tracking = {} + return self.access_tracking + def check_unused(self, fileconfig): + # Don't warn on fields set in autosave segment + access_tracking = dict(self.access_tracking) + access_tracking.update(self.autosave_options) + # Note locally used sections + valid_sections = { s: 1 for s, o in self.printer.lookup_objects() } + valid_sections.update({ s: 1 for s, o in access_tracking }) + # Validate that there are no undefined parameters in the config file + for section_name in fileconfig.sections(): + section = section_name.lower() + if section not in valid_sections: + raise error("Section '%s' is not a valid config section" + % (section,)) + for option in fileconfig.options(section_name): + option = option.lower() + if (section, option) not in access_tracking: + raise error("Option '%s' is not valid in section '%s'" + % (option, section)) + # Setup get_status() + self._build_status_settings() + # Clear tracking state + self.access_tracking.clear() + self.autosave_options.clear() + def _build_status_settings(self): + self.status_settings = {} + for (section, option), value in self.access_tracking.items(): + self.status_settings.setdefault(section, {})[option] = value + def get_status(self, eventtime): + return {'settings': self.status_settings} + + +###################################################################### # Main printer config tracking ###################################################################### @@ -413,11 +462,11 @@ class PrinterConfig: def __init__(self, printer): self.printer = printer self.autosave = ConfigAutoSave(printer) + self.validate = ConfigValidate(printer) self.deprecated = {} self.runtime_warnings = [] self.deprecate_warnings = [] self.status_raw_config = {} - self.status_settings = {} self.status_warnings = [] def get_printer(self): return self.printer @@ -427,53 +476,32 @@ class PrinterConfig: fileconfig = cfgrdr.build_fileconfig(data, filename) return ConfigWrapper(self.printer, fileconfig, {}, 'printer') def read_main_config(self): - fileconfig = self.autosave.load_main_config() - return ConfigWrapper(self.printer, fileconfig, {}, 'printer') - def check_unused_options(self, config): - fileconfig = config.fileconfig - objects = dict(self.printer.lookup_objects()) - # Determine all the fields that have been accessed - access_tracking = dict(config.access_tracking) - for section in self.autosave.fileconfig.sections(): - for option in self.autosave.fileconfig.options(section): - access_tracking[(section.lower(), option.lower())] = 1 - # Validate that there are no undefined parameters in the config file - valid_sections = { s: 1 for s, o in access_tracking } - for section_name in fileconfig.sections(): - section = section_name.lower() - if section not in valid_sections and section not in objects: - raise error("Section '%s' is not a valid config section" - % (section,)) - for option in fileconfig.options(section_name): - option = option.lower() - if (section, option) not in access_tracking: - raise error("Option '%s' is not valid in section '%s'" - % (option, section)) - # Setup get_status() - self._build_status(config) + fileconfig, autosave_fileconfig = self.autosave.load_main_config() + access_tracking = self.validate.start_access_tracking( + autosave_fileconfig) + config = ConfigWrapper(self.printer, fileconfig, + access_tracking, 'printer') + self._build_status_config(config) + return config def log_config(self, config): cfgrdr = ConfigFileReader() lines = ["===== Config file =====", cfgrdr.build_config_string(config.fileconfig), "======================="] self.printer.set_rollover_info("config", "\n".join(lines)) - # Status reporting + def check_unused_options(self, config): + self.validate.check_unused(config.fileconfig) + # Deprecation warnings def runtime_warning(self, msg): logging.warning(msg) res = {'type': 'runtime_warning', 'message': msg} self.runtime_warnings.append(res) self.status_warnings = self.runtime_warnings + self.deprecate_warnings def deprecate(self, section, option, value=None, msg=None): - self.deprecated[(section, option, value)] = msg - def _build_status(self, config): - self.status_raw_config.clear() - for section in config.get_prefix_sections(''): - self.status_raw_config[section.get_name()] = section_status = {} - for option in section.get_prefix_options(''): - section_status[option] = section.get(option, note_valid=False) - self.status_settings = {} - for (section, option), value in config.access_tracking.items(): - self.status_settings.setdefault(section, {})[option] = value + key = (section, option, value) + if key in self.deprecated and self.deprecated[key] == msg: + return + self.deprecated[key] = msg self.deprecate_warnings = [] for (section, option, value), msg in self.deprecated.items(): if value is None: @@ -485,11 +513,18 @@ class PrinterConfig: res['option'] = option self.deprecate_warnings.append(res) self.status_warnings = self.runtime_warnings + self.deprecate_warnings + # Status reporting + def _build_status_config(self, config): + self.status_raw_config = {} + for section in config.get_prefix_sections(''): + self.status_raw_config[section.get_name()] = section_status = {} + for option in section.get_prefix_options(''): + section_status[option] = section.get(option, note_valid=False) def get_status(self, eventtime): status = {'config': self.status_raw_config, - 'settings': self.status_settings, 'warnings': self.status_warnings} status.update(self.autosave.get_status(eventtime)) + status.update(self.validate.get_status(eventtime)) return status # Autosave functions def set(self, section, option, value): |