config: changes in how the config is validated
now it validates in steps 1 defaults 2 user settings 3 user includes 4 auto-generated section unknown keys will be removed from the auto-generated section if no other errors are found detect and warn about missing newlines in headers
This commit is contained in:
parent
432305bec9
commit
d0ab325744
@ -47,6 +47,8 @@ class KlipperScreenConfig:
|
||||
|
||||
try:
|
||||
self.config.read(self.default_config_path)
|
||||
# In case a user altered defaults.conf
|
||||
self.validate_config(self.config)
|
||||
if self.config_path != self.default_config_path:
|
||||
user_def, saved_def = self.separate_saved_config(self.config_path)
|
||||
self.defined_config = configparser.ConfigParser()
|
||||
@ -59,19 +61,16 @@ class KlipperScreenConfig:
|
||||
self.exclude_from_config(self.defined_config)
|
||||
|
||||
self.log_config(self.defined_config)
|
||||
self.config.read_string(user_def)
|
||||
if self.validate_config(self.defined_config, string=user_def):
|
||||
self.config.read_string(user_def)
|
||||
if saved_def is not None:
|
||||
self.config.read_string(saved_def)
|
||||
logging.info(f"====== Saved Def ======\n{saved_def}\n=======================")
|
||||
auto_gen = configparser.ConfigParser()
|
||||
auto_gen.read_string(saved_def)
|
||||
if self.validate_config(auto_gen, string=saved_def, remove=True):
|
||||
self.config.read_string(saved_def)
|
||||
logging.info(f"====== Saved Def ======\n{saved_def}\n=======================")
|
||||
# This is the final config
|
||||
# self.log_config(self.config)
|
||||
if self.validate_config():
|
||||
logging.info('Configuration validated succesfuly')
|
||||
else:
|
||||
logging.error('Invalid configuration detected !!!')
|
||||
logging.info('Loading default config')
|
||||
self.config = configparser.ConfigParser()
|
||||
self.config.read(self.default_config_path)
|
||||
except KeyError as Kerror:
|
||||
msg = f"Error reading config: {self.config_path}\n{Kerror}"
|
||||
logging.exception(msg)
|
||||
@ -139,9 +138,16 @@ class KlipperScreenConfig:
|
||||
self.lang = self.langs[lang]
|
||||
self.lang.install(names=['gettext', 'ngettext'])
|
||||
|
||||
def validate_config(self):
|
||||
def validate_config(self, config, string="", remove=False):
|
||||
valid = True
|
||||
for section in self.config:
|
||||
if string:
|
||||
msg = "Section headers have extra information after brackets possible newline issue:"
|
||||
for line in string.split('\n'):
|
||||
if re.match(r".+\].", line):
|
||||
logging.error(line)
|
||||
self.errors.append(f'{msg}\n\n{line}')
|
||||
return False
|
||||
for section in config:
|
||||
if section == 'DEFAULT' or section.startswith('include '):
|
||||
# Do not validate 'DEFAULT' or 'include*' sections
|
||||
continue
|
||||
@ -175,7 +181,7 @@ class KlipperScreenConfig:
|
||||
)
|
||||
elif section.startswith('preheat '):
|
||||
strs = ('gcode', '')
|
||||
numbers = [f'{option}' for option in self.config[section] if option != 'gcode']
|
||||
numbers = [f'{option}' for option in config[section] if option != 'gcode']
|
||||
elif section.startswith('menu '):
|
||||
strs = ('name', 'icon', 'panel', 'method', 'params', 'enable', 'confirm', 'style')
|
||||
elif section == 'bed_screws':
|
||||
@ -183,25 +189,29 @@ class KlipperScreenConfig:
|
||||
numbers = ('rotation', '')
|
||||
strs = ('screw_positions', '')
|
||||
elif section.startswith('graph') or section.startswith('displayed_macros'):
|
||||
bools = [f'{option}' for option in self.config[section]]
|
||||
bools = [f'{option}' for option in config[section]]
|
||||
elif section.startswith('z_calibrate_position'):
|
||||
# This section may be deprecated in favor of moving this options under the printer section
|
||||
numbers = ('calibrate_x_position', 'calibrate_y_position')
|
||||
else:
|
||||
self.errors.append(f'Section [{section}] not recognized')
|
||||
|
||||
for key in self.config[section]:
|
||||
for key in config[section]:
|
||||
if key not in bools and key not in strs and key not in numbers:
|
||||
msg = f'Option "{key}" not recognized for section "[{section}]"'
|
||||
self.errors.append(msg)
|
||||
# This most probably is not a big issue, continue to load the config
|
||||
elif key in numbers and not self.is_float(self.config[section][key]) \
|
||||
or key in bools and self.config[section][key] not in ["False", "false", "True", "true"]:
|
||||
if remove:
|
||||
# This should only be called for the auto-generated section
|
||||
self.config.remove_option(section, key)
|
||||
else:
|
||||
self.errors.append(msg)
|
||||
elif key in numbers and not self.is_float(config[section][key]) \
|
||||
or key in bools and not self.is_bool(config[section][key]):
|
||||
msg = (
|
||||
f'Unable to parse "{key}" from [{section}]\n'
|
||||
f'Expected a {"number" if key in numbers else "boolean"} but got: {self.config[section][key]}'
|
||||
f'Expected a {"number" if key in numbers else "boolean"} but got: {config[section][key]}'
|
||||
)
|
||||
self.errors.append(msg)
|
||||
logging.error('Invalid configuration detected !!!')
|
||||
valid = False
|
||||
return valid
|
||||
|
||||
@ -213,6 +223,10 @@ class KlipperScreenConfig:
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def is_bool(element):
|
||||
return element in ["False", "false", "True", "true"]
|
||||
|
||||
def get_errors(self):
|
||||
return "".join(f'{error}\n\n' for error in self.errors)
|
||||
|
||||
@ -347,7 +361,10 @@ class KlipperScreenConfig:
|
||||
self._include_config("/".join(full_path.split("/")[:-1]), include)
|
||||
self.exclude_from_config(config)
|
||||
self.log_config(config)
|
||||
self.config.read(file)
|
||||
with open(file, 'r') as f:
|
||||
string = f.read()
|
||||
if self.validate_config(config, string=string):
|
||||
self.config.read(file)
|
||||
|
||||
def separate_saved_config(self, config_path):
|
||||
user_def = []
|
||||
|
Loading…
x
Reference in New Issue
Block a user