From f024d6dec6afa3e75cb849fc758556c9fd8ec4ef Mon Sep 17 00:00:00 2001 From: Sebastian Lenzlinger Date: Thu, 27 Jun 2024 13:40:20 +0200 Subject: [PATCH] Add config loading in main and a project test folder. --- iottb/main.py | 67 ++++++++++++++++++++++++++++++++-------------- tests/__init__.py | 0 tests/test_main.py | 0 3 files changed, 47 insertions(+), 20 deletions(-) create mode 100644 tests/__init__.py create mode 100644 tests/test_main.py diff --git a/iottb/main.py b/iottb/main.py index c9ee405..9422bf3 100644 --- a/iottb/main.py +++ b/iottb/main.py @@ -1,13 +1,15 @@ +import json import subprocess import click -from pathlib import PurePath +from pathlib import PurePath, Path import configparser import logging from logging.handlers import RotatingFileHandler import sys APP_NAME = 'iottb' +DB_NAME = 'iottb.db' CONSOLE_LOG_FORMATS = { 0: '%(levelname)s - %(message)s', @@ -23,11 +25,13 @@ LOGFILE_LOG_FORMAT = { MAX_VERBOSITY = len(CONSOLE_LOG_FORMATS) - 1 assert len(LOGFILE_LOG_FORMAT) == len(CONSOLE_LOG_FORMATS), 'Log formats must be same size' +logger = logging.getLogger(__name__) + def setup_logging(verbosity, debug): """ Setup root logger for iottb """ log_level = logging.ERROR - logger = logging.getLogger() + handlers = [] date_format = '%Y-%m-%d %H:%M:%S' if verbosity > 0: log_level = logging.WARNING @@ -38,7 +42,7 @@ def setup_logging(verbosity, debug): console_handler = logging.StreamHandler(sys.stdout) console_handler.setFormatter(logging.Formatter(CONSOLE_LOG_FORMATS[verbosity], datefmt=date_format)) console_handler.setLevel(logging.DEBUG) # can keep at debug since it depends on global level? - logger.addHandler(console_handler) + handlers.append(console_handler) if debug: log_level = logging.DEBUG @@ -49,31 +53,54 @@ def setup_logging(verbosity, debug): file_handler.setLevel(logging.INFO) # finnish root logger setup - logger.addHandler(file_handler) - logger.setLevel(log_level) - return logger + handlers.append(file_handler) + # Force this config to be applied to root logger + logging.basicConfig(level=log_level, handlers=handlers, force=True) -class Environment: - def __init__(self, cfg=None, db=None, device=None): - self.cfg = cfg - self.db = db - self.device = device - pass +def create_default_config(cfg_file): + """Create default iottb config file.""" + assert logger is not None, 'Logger must be initialized' + logger.info(f'Creating default config file at {cfg_file}') + # By default, create iottb.db in user home + defaults = { + 'DefaultDatabase': DB_NAME, + 'DatabaseLocations': { + DB_NAME: str(Path.home() / DB_NAME) + } + } + with open(cfg_file, 'w') as config_file: + json.dump(defaults, config_file) + return defaults -def load_config(cfg_file_path): - cfg_file = PurePath(click.get_app_dir(APP_NAME)).joinpath('iottb.cfg') +def load_config(ctx, param, value): + """ Try to load iottb config file. + If the file does not exist, it will be created with default values.` + Try to load the iottb config file from the given path. + If the file does not exist, it will be created with default values. + The only value set is the path to the iottb.db file. + """ + logger.info(f'Loading config from {value}') + cfg_file = value + if not cfg_file.is_file(): + defaults = create_default_config(cfg_file) + else: + defaults = json.load(cfg_file) + + ctx.obj['path']['cfg'] = cfg_file + ctx.obj['path']['db'] = defaults['DatabaseLocations'][defaults['DefaultDatabase']] @click.group() @click.option('-v', '--verbosity', type=click.IntRange(0, MAX_VERBOSITY), default=0, - help='Verbosity level') -@click.option('-d', '--debug', is_flag=True, default=False, help='Debug mode') -@click.option('--cfg-file', type=click.Path(), default=PurePath(click.get_app_dir(APP_NAME)).joinpath('iottb.cfg'), - envvar='IOTTB_CONF_HOME',) -def main(debug, verbose): - setup_logging(verbose, debug) + help='Set verbosity') +@click.option('-d', '--debug', is_flag=True, default=False, help='Enable debug mode') +@click.option('--cfg-file', type=click.Path(), default=Path(click.get_app_dir(APP_NAME)).joinpath('iottb.cfg'), + envvar='IOTTB_CONF_HOME', is_eager=True, callback=load_config, help='Path to iottb config file') +@click.pass_context +def main(verbosity, debug): + setup_logging(verbosity, debug) if __name__ == '__main__': diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_main.py b/tests/test_main.py new file mode 100644 index 0000000..e69de29