from os import path, chmod, makedirs, pardir from pathlib import Path from shutil import copy from yaml import safe_load, dump from jinja2 import Environment, FileSystemLoader from copy import deepcopy class Configuration(object): # TODO: Figure out how to handle windows config CONFIG_DIR = path.expanduser('~/.config/grocy') USER_TEMPLATE_DIR = path.expanduser('~/.config/grocy/templates') CONFIG_FILE = CONFIG_DIR + '/config.yml' TEMPLATE_EXT = 'yml' PROJ_DIR = Path(__file__).resolve().parent.parent PROJ_TEMPLATE_DIR = '{}/templates'.format(PROJ_DIR) API_KEY_HEADER = 'GROCY-API-KEY' DEFAULT_CFG = { 'logger': { 'level': 'DEBUG', 'file_location': None }, 'domain': 'https://demo-en.grocy.info', 'token': None, 'formats': { 'col': 'center', 'table': 'simple' } } def update(self, props): # Set nested fields (e.g. logger, formats) if props['logger']: for prop in props['logger']: prop_attr = 'logger_{prop}'.format(prop=prop) prop_value = props['logger'][prop] setattr(self, prop_attr, prop_value) if props['formats']: for prop in props['formats']: prop_attr = '{prop}_format'.format(prop=prop) prop_value = props['formats'][prop] setattr(self, prop_attr, prop_value) for prop, value in props.items(): if not prop == 'logger' and prop in props: setattr(self, prop, value) def create(self, user_cfg_options={}): cfg_json = deepcopy(self.DEFAULT_CFG) if user_cfg_options['logger_level']: self.logger_level = user_cfg_options['logger_level'] cfg_json['logger']['level'] = self.logger_level if user_cfg_options['logger_file_location']: self.logger_file_location = user_cfg_options['logger_file_location'] cfg_json['logger']['file_location'] = self.logger_file_location if user_cfg_options['domain']: self.domain = user_cfg_options['domain'] cfg_json['domain'] = self.domain if user_cfg_options['token']: self.token = user_cfg_options['token'] cfg_json['token'] = self.token if user_cfg_options['col_format']: self.col_format = user_cfg_options['col_format'] cfg_json['formats']['col'] = self.col_format if user_cfg_options['table_format']: self.table_format = user_cfg_options['table_format'] cfg_json['formats']['table'] = self.table_format # Create new configuration makedirs(self.CONFIG_DIR) with open(self.CONFIG_FILE, 'x') as fd: dump_cfg = dump(cfg_json, default_flow_style=False, allow_unicode=True, encoding=None) fd.write(dump_cfg) chmod(self.CONFIG_DIR, 0o755) # Create template directory makedirs(self.USER_TEMPLATE_DIR) copy(self.PROJ_TEMPLATE_DIR, self.USER_TEMPLATE_DIR) @property def exists(self): return path.exists(self.CONFIG_FILE) def load(self): if self.exists: with open(self.CONFIG_FILE) as fd: data = safe_load(fd) self.update(data) else: self.create() def templates(self, name): try: TEMPLATE_LOADER = Environment(loader=FileSystemLoader([self.USER_TEMPLATE_DIR, self.PROJ_TEMPLATE_DIR]), trim_blocks=False, lstrip_blocks=True, keep_trailing_newline=False) return TEMPLATE_LOADER.get_template('{}.{}'.format(name, self.TEMPLATE_EXT)) except Exception as e: raise e