diff --git a/src/weecfg/extension.py b/src/weecfg/extension.py index f2f048f7..228be5d1 100644 --- a/src/weecfg/extension.py +++ b/src/weecfg/extension.py @@ -15,6 +15,7 @@ import configobj import weecfg import weeutil.config +import weeutil.startup import weeutil.weeutil import weewx from weeutil.printer import Printer @@ -64,7 +65,7 @@ class ExtensionEngine(object): self.printer = printer or Printer() self.dry_run = dry_run - self.root_dict = weewx.extract_roots(self.config_dict) + self.root_dict = weeutil.startup.extract_roots(self.config_dict) self.printer.out("root dictionary: %s" % self.root_dict, 4) def enumerate_extensions(self): diff --git a/src/weectllib/__init__.py b/src/weectllib/__init__.py index f1a34e6b..314f4d75 100644 --- a/src/weectllib/__init__.py +++ b/src/weectllib/__init__.py @@ -8,6 +8,7 @@ import datetime import weecfg +import weeutil.startup import weewx from weeutil.weeutil import bcolors @@ -81,7 +82,7 @@ def dispatch(namespace): config_path, config_dict = weecfg.read_config(namespace.config) print(f"Using configuration file {bcolors.BOLD}{config_path}{bcolors.ENDC}") - weewx.initialize(config_dict, 'weectl') + weeutil.startup.initialize(config_dict, 'weectl') # Note a dry-run, if applicable: if hasattr(namespace, 'dry_run') and namespace.dry_run: diff --git a/src/weeutil/startup.py b/src/weeutil/startup.py new file mode 100644 index 00000000..9f56a5b3 --- /dev/null +++ b/src/weeutil/startup.py @@ -0,0 +1,72 @@ +# +# Copyright (c) 2009-2023 Tom Keffer +# +# See the file LICENSE.txt for your full rights. +# +"""Utilities used when starting up a WeeWX application""" +import importlib +import logging +import os.path +import sys + +import weeutil.logger +import weewx +from weeutil.weeutil import to_int + + +def add_user_path(config_dict): + """add the path to the parent of the user directory to PYTHONPATH.""" + root_dict = extract_roots(config_dict) + lib_dir = os.path.abspath(os.path.join(root_dict['USER_DIR'], '..')) + sys.path.append(lib_dir) + return lib_dir + + +def extract_roots(config_dict): + """Get the location of the various root directories used by weewx. + The extracted paths are *absolute* paths. That is, they are no longer relative to WEEWX_ROOT. + + Args: + config_dict(dict): The configuration dictionary + Returns: + dict[str, str]: Key is the type of root, value is its location. + """ + user_root = config_dict.get('USER_ROOT', 'bin/user') + root_dict = { + 'WEEWX_ROOT': config_dict['WEEWX_ROOT'], + 'USER_DIR': os.path.abspath(os.path.join(config_dict['WEEWX_ROOT'], user_root)), + 'BIN_DIR': os.path.abspath(os.path.join(os.path.dirname(__file__), '..')), + 'EXT_DIR': os.path.abspath(os.path.join(config_dict['WEEWX_ROOT'], user_root, 'installer')) + } + + # Add SKIN_ROOT if it can be found: + try: + root_dict['SKIN_DIR'] = os.path.abspath( + os.path.join(root_dict['WEEWX_ROOT'], config_dict['StdReport']['SKIN_ROOT']) + ) + except KeyError: + pass + + return root_dict + + +def initialize(config_dict, log_label): + """Set debug, set up the logger, and add the user path""" + + # Set weewx.debug as necessary: + weewx.debug = to_int(config_dict.get('debug', 0)) + + # Customize the logging with user settings. + weeutil.logger.setup(log_label, config_dict) + + # Add the 'user' package to PYTHONPATH + user_dir = add_user_path(config_dict) + + # Now we can import user.extensions + try: + importlib.import_module('user.extensions') + except ModuleNotFoundError as e: + log = logging.getLogger(__name__) + log.error("Cannot load user extensions: %s", e) + + return user_dir \ No newline at end of file diff --git a/src/weewx/__init__.py b/src/weewx/__init__.py index 6e0aab39..6a9f69ec 100644 --- a/src/weewx/__init__.py +++ b/src/weewx/__init__.py @@ -4,14 +4,8 @@ # See the file LICENSE.txt for your full rights. # """Package weewx, containing modules specific to the weewx runtime engine.""" -import importlib -import os.path -import sys import time -import weeutil.logger -from weeutil.weeutil import to_int - __version__ = "5.0.0rc1" # Holds the program launch time in unix epoch seconds: @@ -190,60 +184,3 @@ def require_weewx_version(module, required_version): % (module, required_version, __version__)) -def add_user_path(config_dict): - """add the path to the parent of the user directory to PYTHONPATH.""" - root_dict = extract_roots(config_dict) - lib_dir = os.path.abspath(os.path.join(root_dict['USER_DIR'], '..')) - import logging - log = logging.getLogger(__name__) - log.info("Adding to PYTHONPATH the 'user' directory '%s'" % lib_dir) - sys.path.append(lib_dir) - - -def extract_roots(config_dict): - """Get the location of the various root directories used by weewx. - The extracted paths are *absolute* paths. That is, they are no longer relative to WEEWX_ROOT. - - Args: - config_dict(dict): The configuration dictionary - Returns: - dict[str, str]: Key is the type of root, value is its location. - """ - user_root = config_dict.get('USER_ROOT', 'bin/user') - root_dict = { - 'WEEWX_ROOT': config_dict['WEEWX_ROOT'], - 'USER_DIR': os.path.abspath(os.path.join(config_dict['WEEWX_ROOT'], user_root)), - 'BIN_DIR': os.path.abspath(os.path.join(os.path.dirname(__file__), '..')), - 'EXT_DIR': os.path.abspath(os.path.join(config_dict['WEEWX_ROOT'], user_root, 'installer')) - } - - # Add SKIN_ROOT if it can be found: - try: - root_dict['SKIN_DIR'] = os.path.abspath( - os.path.join(root_dict['WEEWX_ROOT'], config_dict['StdReport']['SKIN_ROOT']) - ) - except KeyError: - pass - - return root_dict - - -def initialize(config_dict, log_label): - """Set debug, set up the logger, and add the user path""" - global debug - - # Set weewx.debug as necessary: - debug = to_int(config_dict.get('debug', 0)) - - # Customize the logging with user settings. - weeutil.logger.setup(log_label, config_dict) - - # Add the 'user' package to PYTHONPATH - add_user_path(config_dict) - # Now we can import user.extensions - try: - importlib.import_module('user.extensions') - except ModuleNotFoundError as e: - import logging - log = logging.getLogger(__name__) - log.error("Cannot load user extensions: %s" % e) diff --git a/src/weewxd.py b/src/weewxd.py index dfb528bc..ae1c4e92 100644 --- a/src/weewxd.py +++ b/src/weewxd.py @@ -20,6 +20,7 @@ import configobj import weecfg import weedb import weeutil.logger +import weeutil.startup import weewx.engine from weeutil.weeutil import to_bool, to_float from weewx import daemon @@ -82,8 +83,7 @@ def main(): config_path, config_dict = weecfg.read_config(namespace.config_arg, [namespace.config_option]) except (IOError, configobj.ConfigObjError) as e: - msg = "Error parsing config file: %s" % e - print(msg, file=sys.stderr) + print(f"Error parsing config file: {e}", file=sys.stderr) import traceback traceback.print_exc(file=sys.stderr) sys.exit(weewx.CONFIG_ERROR) @@ -92,10 +92,9 @@ def main(): # configured logging and debug, as well as perform other housekeeping # chores try: - weewx.initialize(config_dict, namespace.log_label) - except (ValueError, AttributeError) as e: - msg = "Failure during initialization: %s" % e - print(msg, file=sys.stderr) + user_dir = weeutil.startup.initialize(config_dict, namespace.log_label) + except Exception as e: + print(f"Failure during initialization: {e}", file=sys.stderr) import traceback traceback.print_exc(file=sys.stderr) sys.exit(weewx.CONFIG_ERROR) @@ -107,10 +106,11 @@ def main(): log.info("Using Python %s", sys.version) log.info("Located at %s", sys.executable) log.info("Platform %s", platform.platform()) - log.info("Locale is '%s'", locale.setlocale(locale.LC_ALL)) + log.info("Locale: '%s'", locale.setlocale(locale.LC_ALL)) log.info("Entry path: %s", __file__) - log.info("Using configuration file %s", config_path) - log.info("Debug is %s", weewx.debug) + log.info("Configuration file: %s", config_path) + log.info("User directory: %s", user_dir) + log.info("Debug: %s", weewx.debug) # If no command line --loop-on-init was specified, look in the config file. if namespace.loop_on_init is None: