From d8d22e5f38c0451d68b36177a0dda19cbedb30e4 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 6 Jan 2022 14:20:26 +1100 Subject: [PATCH] Refactor code (so that it actually runs)... - Invoke does not have access to the local virtual environment - Some functions need to be split out from settings.py --- InvenTree/InvenTree/config.py | 90 +++++++++++++++++++++++++++++++++ InvenTree/InvenTree/settings.py | 64 +++-------------------- requirements.txt | 1 - tasks.py | 17 ++----- 4 files changed, 102 insertions(+), 70 deletions(-) create mode 100644 InvenTree/InvenTree/config.py diff --git a/InvenTree/InvenTree/config.py b/InvenTree/InvenTree/config.py new file mode 100644 index 0000000000..35671c1b26 --- /dev/null +++ b/InvenTree/InvenTree/config.py @@ -0,0 +1,90 @@ +""" +Helper functions for loading InvenTree configuration options +""" + +import os +import shutil +import logging + + +logger = logging.getLogger('inventree') + + +def get_base_dir(): + """ Returns the base (top-level) InvenTree directory """ + return os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +def get_config_file(): + """ + Returns the path of the InvenTree configuration file. + + Note: It will be created it if does not already exist! + """ + + base_dir = get_base_dir() + + cfg_filename = os.getenv('INVENTREE_CONFIG_FILE') + + if cfg_filename: + cfg_filename = cfg_filename.strip() + cfg_filename = os.path.abspath(cfg_filename) + else: + # Config file is *not* specified - use the default + cfg_filename = os.path.join(base_dir, 'config.yaml') + + if not os.path.exists(cfg_filename): + print("InvenTree configuration file 'config.yaml' not found - creating default file") + + cfg_template = os.path.join(base_dir, "config_template.yaml") + shutil.copyfile(cfg_template, cfg_filename) + print(f"Created config file {cfg_filename}") + + return cfg_filename + + +def get_plugin_file(): + """ + Returns the path of the InvenTree plugins specification file. + + Note: It will be created if it does not already exist! + """ + # Check if the plugin.txt file (specifying required plugins) is specified + PLUGIN_FILE = os.getenv('INVENTREE_PLUGIN_FILE') + + if not PLUGIN_FILE: + # If not specified, look in the same directory as the configuration file + + config_dir = os.path.dirname(get_config_file()) + + PLUGIN_FILE = os.path.join(config_dir, 'plugins.txt') + + if not os.path.exists(PLUGIN_FILE): + logger.warning("Plugin configuration file does not exist") + logger.info(f"Creating plugin file at '{PLUGIN_FILE}'") + + # If opening the file fails (no write permission, for example), then this will throw an error + with open(PLUGIN_FILE, 'w') as plugin_file: + plugin_file.write("# InvenTree Plugins (uses PIP framework to install)\n\n") + + return PLUGIN_FILE + + +def get_setting(environment_var, backup_val, default_value=None): + """ + Helper function for retrieving a configuration setting value + + - First preference is to look for the environment variable + - Second preference is to look for the value of the settings file + - Third preference is the default value + """ + + val = os.getenv(environment_var) + + if val is not None: + return val + + if backup_val is not None: + return backup_val + + return default_value diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index d738a640b9..89e60a597e 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -17,7 +17,6 @@ import os import random import socket import string -import shutil import sys from datetime import datetime @@ -28,30 +27,12 @@ from django.utils.translation import gettext_lazy as _ from django.contrib.messages import constants as messages import django.conf.locale +from .config import get_base_dir, get_config_file, get_plugin_file, get_setting + def _is_true(x): # Shortcut function to determine if a value "looks" like a boolean - return str(x).lower() in ['1', 'y', 'yes', 't', 'true'] - - -def get_setting(environment_var, backup_val, default_value=None): - """ - Helper function for retrieving a configuration setting value - - - First preference is to look for the environment variable - - Second preference is to look for the value of the settings file - - Third preference is the default value - """ - - val = os.getenv(environment_var) - - if val is not None: - return val - - if backup_val is not None: - return backup_val - - return default_value + return str(x).strip().lower() in ['1', 'y', 'yes', 't', 'true'] # Determine if we are running in "test" mode e.g. "manage.py test" @@ -61,27 +42,9 @@ TESTING = 'test' in sys.argv DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' # Build paths inside the project like this: os.path.join(BASE_DIR, ...) -BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +BASE_DIR = get_base_dir() -# Specify where the "config file" is located. -# By default, this is 'config.yaml' - -cfg_filename = os.getenv('INVENTREE_CONFIG_FILE') - -if cfg_filename: - cfg_filename = cfg_filename.strip() - cfg_filename = os.path.abspath(cfg_filename) - -else: - # Config file is *not* specified - use the default - cfg_filename = os.path.join(BASE_DIR, 'config.yaml') - -if not os.path.exists(cfg_filename): - print("InvenTree configuration file 'config.yaml' not found - creating default file") - - cfg_template = os.path.join(BASE_DIR, "config_template.yaml") - shutil.copyfile(cfg_template, cfg_filename) - print(f"Created config file {cfg_filename}") +cfg_filename = get_config_file() with open(cfg_filename, 'r') as cfg: CONFIG = yaml.safe_load(cfg) @@ -89,6 +52,8 @@ with open(cfg_filename, 'r') as cfg: # We will place any config files in the same directory as the config file config_dir = os.path.dirname(cfg_filename) +PLUGIN_FILE = get_plugin_file() + # Default action is to run the system in Debug mode # SECURITY WARNING: don't run with debug turned on in production! DEBUG = _is_true(get_setting( @@ -143,21 +108,6 @@ LOGGING = { # Get a logger instance for this setup file logger = logging.getLogger("inventree") -# Check if the plugin.txt file (specifying required plugins) is specified -PLUGIN_FILE = os.getenv('INVENTREE_PLUGIN_FILE') - -if not PLUGIN_FILE: - # If not specified, look in the same directory as the configuration file - PLUGIN_FILE = os.path.join(config_dir, 'plugins.txt') - -if not os.path.exists(PLUGIN_FILE): - logger.warning("Plugin configuration file does not exist") - logger.info(f"Creating plugin file at '{PLUGIN_FILE}'") - - # If opening the file fails (no write permission, for example), then this will throw an error - with open(PLUGIN_FILE, 'w') as plugin_file: - plugin_file.write("# InvenTree Plugins (uses PIP framework to install)\n\n") - """ Specify a secret key to be used by django. diff --git a/requirements.txt b/requirements.txt index a150ae503a..d6405bb7bc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,7 +33,6 @@ flake8==3.8.3 # PEP checking gunicorn>=20.1.0 # Gunicorn web server importlib_metadata # Backport for importlib.metadata inventree # Install the latest version of the InvenTree API python library -invoke>=1.6.0 # Invoke management tool (must be installed in venv) markdown==3.3.4 # Force particular version of markdown pep8-naming==0.11.1 # PEP naming convention extension pillow==8.3.2 # Image manipulation diff --git a/tasks.py b/tasks.py index 89a579ac9e..34528e2609 100644 --- a/tasks.py +++ b/tasks.py @@ -77,21 +77,14 @@ def plugins(c): Installs all plugins as specified in 'plugins.txt' """ - try: - from InvenTree.InvenTree.settings import PLUGIN_FILE - except: - print("Error: Could not import PLUGIN_FILE from settings.py") - return - - if not os.path.exists(PLUGIN_FILE): - # Create an empty plugin - print(f"Plugins file '{PLUGIN_FILE}' does not exist") - return + from InvenTree.InvenTree.config import get_plugin_file - print(f"Installing plugin packages from '{PLUGIN_FILE}'") + plugin_file = get_plugin_file() + + print(f"Installing plugin packages from '{plugin_file}'") # Install the plugins - c.run(f"pip3 install -U -r '{PLUGIN_FILE}'") + c.run(f"pip3 install -U -r '{plugin_file}'") @task(post=[plugins]) def install(c):