From f631733bf501293018a4db6525c92d1b6892e275 Mon Sep 17 00:00:00 2001 From: Ace Date: Thu, 21 May 2020 19:52:39 +0200 Subject: [PATCH] minor improvements to settings parser Code cleanup, better validation logic, better naming of functions --- inkycal/config/__init__.py | 2 +- inkycal/config/parser.py | 137 ------------------------------ inkycal/config/settings_parser.py | 124 +++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 138 deletions(-) delete mode 100644 inkycal/config/parser.py create mode 100644 inkycal/config/settings_parser.py diff --git a/inkycal/config/__init__.py b/inkycal/config/__init__.py index b3de81b..bea450e 100644 --- a/inkycal/config/__init__.py +++ b/inkycal/config/__init__.py @@ -1,4 +1,4 @@ -from .parser import settings +from .settings_parser import settings print('loaded settings') from .layout import layout print('loaded layout') diff --git a/inkycal/config/parser.py b/inkycal/config/parser.py deleted file mode 100644 index f0a097d..0000000 --- a/inkycal/config/parser.py +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: utf-8 -*- -""" -Json settings parser. Currently in alpha! -Copyright by aceisace -""" - -import json -from os import chdir #Ad-hoc - -# TODO: -# Check of jsmin can/should be used to parse jsonc settings file -# Remove check of fixed settings file location. Ask user to specify path -# to settings file - -from os import path - -class settings: - """Load and validate settings from the settings file""" - - __supported_languages = ['en', 'de', 'ru', 'it', 'es', 'fr', 'el', 'sv', 'nl', - 'pl', 'ua', 'nb', 'vi', 'zh_tw', 'zh-cn', 'ja', 'ko'] - __supported_units = ['metric', 'imperial'] - __supported_hours = [12, 24] - __supported_display_orientation = ['normal', 'upside_down'] - __supported_models = [ - 'epd_7_in_5_v2_colour', 'epd_7_in_5_v2', - 'epd_7_in_5_colour', 'epd_7_in_5', - 'epd_5_in_83_colour','epd_5_in_83', - 'epd_4_in_2_colour', 'epd_4_in_2' - ] - - def __init__(self, settings_file_path): - """Load settings from path (folder or settings.json file)""" - try: - if settings_file_path.endswith('settings.json'): - folder = settings_file_path.split('/settings.json')[0] - else: - folder = settings_file_path - - chdir(folder) - with open("settings.json") as file: - self.raw_settings = json.load(file) - - except FileNotFoundError: - print('No settings file found in specified location') - - try: - self.language = self.raw_settings['language'] - if self.language not in self.__supported_languages or type(self.language) != str: - print('Unsupported language: {}!. Switching to english'.format(language)) - self.language = 'en' - - - self.units = self.raw_settings['units'] - if self.units not in self.__supported_units or type(self.units) != str: - print('Units ({}) not supported, using metric units.'.format(units)) - self.units = 'metric' - - - self.hours = self.raw_settings['hours'] - if self.hours not in self.__supported_hours or type(self.hours) != int: - print('Selected hours: {} not supported, using 24-hours'.format(hours)) - self.hours = '24' - - - self.model = self.raw_settings['model'] - if self.model not in self.__supported_models or type(self.model) != str: - print('Model: {} not supported. Please select a valid option'.format(model)) - print('Switching to 7.5" ePaper black-white (v1) (fallback)') - self.model = 'epd_7_in_5' - - - self.calibration_hours = self.raw_settings['calibration_hours'] - if not self.calibration_hours or type(self.calibration_hours) != list: - print('Invalid calibration hours: {}'.format(calibration_hours)) - print('Using default option, 0am,12am,6pm') - self.calibration_hours = [0,12,18] - - - self.display_orientation = self.raw_settings['display_orientation'] - if self.display_orientation not in self.__supported_display_orientation or type( - self.display_orientation) != str: - print('Invalid ({}) display orientation.'.format(display_orientation)) - print('Switching to default orientation, normal-mode') - self.display_orientation = 'normal' - - ### Check if empty, If empty, set to none - for sections in self.raw_settings['panels']: - - if sections['location'] == 'top': - self.top_section = sections['type'] - self.top_section_config = sections['config'] - - elif sections['location'] == 'middle': - self.middle_section = sections['type'] - self.middle_section_config = sections['config'] - - elif sections['location'] == 'bottom': - self.bottom_section = sections['type'] - self.bottom_section_config = sections['config'] - - - print('settings loaded') - except Exception as e: - print(e.reason) - - def module_init(self, module_name): - """Get all data from settings file by providing the module name""" - if module_name == self.top_section: - config = self.top_section_config - elif module_name == self.middle_section: - config = self.middle_section_config - elif module_name == self.bottom_section: - config = self.bottom_section_config - else: - print('Invalid module name!') - config = None - - for module in self.raw_settings['panels']: - if module_name == module['type']: - location = module['location'] - - return config, location - - def which_modules(self): - """Returns a list of modules (from settings file) which should be loaded - on start""" - lst = [self.top_section, self.middle_section, self.bottom_section] - return lst - - -def main(): - print('running settings parser as standalone...') - -if __name__ == '__main__': - main() diff --git a/inkycal/config/settings_parser.py b/inkycal/config/settings_parser.py new file mode 100644 index 0000000..f5ea74f --- /dev/null +++ b/inkycal/config/settings_parser.py @@ -0,0 +1,124 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +""" +Json settings parser. Currently in BETA. +Copyright by aceisace +""" +import json +import os + +class settings: + """Load and validate settings from the settings file""" + + _supported_languages = ['en', 'de', 'ru', 'it', 'es', 'fr', 'el', 'sv', 'nl', + 'pl', 'ua', 'nb', 'vi', 'zh_tw', 'zh-cn', 'ja', 'ko'] + _supported_units = ['metric', 'imperial'] + _supported_hours = [12, 24] + _supported_display_orientation = ['normal', 'upside_down'] + _supported_models = [ + 'epd_7_in_5_v2_colour', 'epd_7_in_5_v2', + 'epd_7_in_5_colour', 'epd_7_in_5', + 'epd_5_in_83_colour','epd_5_in_83', + 'epd_4_in_2_colour', 'epd_4_in_2' + ] + + def __init__(self, settings_file_path): + """Load settings from path (folder or settings.json file)""" + try: + # If + if settings_file_path.endswith('settings.json'): + folder = settings_file_path.split('/settings.json')[0] + else: + folder = settings_file_path + + os.chdir(folder) + with open("settings.json") as file: + settings = json.load(file) + self._settings = settings + + except FileNotFoundError: + print('No settings file found in specified location') + + self._validate() + + def _validate(self): + """Validate the basic config""" + settings = self._settings + + required = ['language', 'units', 'hours', 'model', 'calibration_hours', + 'display_orientation'] + + # Check if all required settings exist + for param in required: + if not param in settings: + raise Exception ( + 'required parameter: {} not found in settings file!'.format(param)) + + # Attempt to parse the parameters + self.language = settings['language'] + self.units = settings['units'] + self.hours = settings['hours'] + self.model = settings['model'] + self.calibration_hours = settings['calibration_hours'] + self.display_orientation = settings['display_orientation'] + + # Validate the parameters + if (not isinstance(self.language, str) or self.language not in + self._supported_languages): + print('Language not supported, switching to fallback, en') + self.language = 'en' + + if (not isinstance(self.units, str) or self.units not in + self._supported_units): + print('units not supported, switching to fallback, metric') + self.units = 'metric' + + if (not isinstance(self.hours, int) or self.hours not in + self._supported_hours): + print('hour-format not supported, switching to fallback, 24') + self.hours = 24 + + if (not isinstance(self.model, str) or self.model not in + self._supported_models): + print('model not supported, switching to fallback, epd_7_in_5') + self.model = 'epd_7_in_5' + + if (not isinstance(self.calibration_hours, list)): + print('calibration_hours not supported, switching to fallback, [0,12,18]') + self.calibration_hours = [0,12,18] + + if (not isinstance(self.display_orientation, str) or self.display_orientation not in + self._supported_display_orientation): + print('display orientation not supported, switching to fallback, normal') + self.display_orientation = 'normal' + + print('Settings file loaded') + + def _active_modules(self): + modules = [section['type'] for section in self._settings['panels']] + return modules + + def get_config(self, module_name): + """Ge the config of this module""" + if module_name not in self._active_modules(): + print('No config is available for this module') + else: + for section in self._settings['panels']: + if section['type'] == module_name: + config = section['config'] + return config + + def get_position(self, module_name): + """Get the position of this module's image on the display""" + if module_name not in self._active_modules(): + print('No position is available for this module') + else: + for section in self._settings['panels']: + if section['type'] == module_name: + position = section['location'] + return position + +if __name__ == '__main__': + print('running {0} in standalone/debug mode'.format( + os.path.basename(__file__).split('.py')[0])) +