Refactor configuration to use a file exclusively
This commit is contained in:
parent
9e31bd74b1
commit
16188a3f3a
|
@ -1,24 +0,0 @@
|
||||||
import os
|
|
||||||
import logging
|
|
||||||
|
|
||||||
DUNGEON_PATH = os.path.abspath(os.environ.get("INQUISITOR_DUNGEON") or "./dungeon")
|
|
||||||
SOURCES_PATH = os.path.abspath(os.environ.get("INQUISITOR_SOURCES") or "./sources")
|
|
||||||
CACHE_PATH = os.path.abspath(os.environ.get("INQUISITOR_CACHE") or "./cache")
|
|
||||||
|
|
||||||
logger = logging.getLogger("inquisitor")
|
|
||||||
handler = logging.StreamHandler()
|
|
||||||
logger.addHandler(handler)
|
|
||||||
|
|
||||||
def log_normal():
|
|
||||||
logger.setLevel(logging.INFO)
|
|
||||||
handler.setLevel(logging.INFO)
|
|
||||||
formatter = logging.Formatter('[{levelname}] {message}', style="{")
|
|
||||||
handler.setFormatter(formatter)
|
|
||||||
|
|
||||||
def log_verbose():
|
|
||||||
logger.setLevel(logging.DEBUG)
|
|
||||||
handler.setLevel(logging.DEBUG)
|
|
||||||
formatter = logging.Formatter('[{asctime}] [{levelname}:{filename}:{lineno}] {message}', style="{")
|
|
||||||
handler.setFormatter(formatter)
|
|
||||||
|
|
||||||
log_normal()
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
from .resolver import data_path as DUNGEON_PATH
|
||||||
|
from .resolver import source_path as SOURCES_PATH
|
||||||
|
from .resolver import cache_path as CACHE_PATH
|
||||||
|
from .resolver import logger, add_logging_handler, init_default_logging
|
|
@ -0,0 +1,125 @@
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
# Constants governing config resolution:
|
||||||
|
# Path to the config file, containing key-value pairs of the other settings
|
||||||
|
CONFIG_ENVVAR = 'INQUISITOR_CONFIG'
|
||||||
|
DEFAULT_CONFIG_PATH = '/etc/inquisitor.conf'
|
||||||
|
|
||||||
|
# Path to the folder where items are stored
|
||||||
|
CONFIG_DATA = 'DataPath'
|
||||||
|
DEFAULT_DATA_PATH = '/var/inquisitor/data/'
|
||||||
|
|
||||||
|
# Path to the folder where source modules are stored
|
||||||
|
CONFIG_SOURCES = 'SourcePath'
|
||||||
|
DEFAULT_SOURCES_PATH = '/var/inquisitor/sources/'
|
||||||
|
|
||||||
|
# Path to the folder where cached files are stored
|
||||||
|
CONFIG_CACHE = 'CachePath'
|
||||||
|
DEFAULT_CACHE_PATH = '/var/inquisitor/cache/'
|
||||||
|
|
||||||
|
# Path to a log file where logging will be redirected
|
||||||
|
CONFIG_LOGFILE = 'LogFile'
|
||||||
|
DEFAULT_LOG_FILE = None
|
||||||
|
|
||||||
|
# Whether logging is verbose
|
||||||
|
CONFIG_VERBOSE = 'Verbose'
|
||||||
|
DEFAULT_VERBOSITY = False
|
||||||
|
|
||||||
|
|
||||||
|
def read_config_file(config_path):
|
||||||
|
"""
|
||||||
|
Reads a config file of key-value pairs, where non-blank lines are
|
||||||
|
either comments beginning with the character '#' or keys and values
|
||||||
|
separated by the character '='.
|
||||||
|
"""
|
||||||
|
# Parse the config file into key-value pairs
|
||||||
|
if not os.path.isfile(config_path):
|
||||||
|
raise FileNotFoundError(f'No config file found at {config_path}')
|
||||||
|
accumulated_configs = {}
|
||||||
|
with open(config_path, 'r', encoding='utf8') as cfg:
|
||||||
|
line_no = 0
|
||||||
|
for line in cfg:
|
||||||
|
line_no += 1
|
||||||
|
# Skip blank lines
|
||||||
|
if not line.strip():
|
||||||
|
continue
|
||||||
|
# Skip comments
|
||||||
|
if line.lstrip().startswith('#'):
|
||||||
|
continue
|
||||||
|
# Accumulate config keyvalue pairs
|
||||||
|
if '=' not in line:
|
||||||
|
raise ValueError(f'Invalid config format on line {line_no}')
|
||||||
|
key, value = line.split('=', maxsplit=1)
|
||||||
|
accumulated_configs[key.strip()] = value.strip()
|
||||||
|
|
||||||
|
return accumulated_configs
|
||||||
|
|
||||||
|
|
||||||
|
# Read envvar for config file location, with fallback to default
|
||||||
|
config_path = os.path.abspath(
|
||||||
|
os.environ.get(CONFIG_ENVVAR) or
|
||||||
|
DEFAULT_CONFIG_PATH
|
||||||
|
)
|
||||||
|
|
||||||
|
configs = read_config_file(config_path)
|
||||||
|
|
||||||
|
# Extract and validate config values
|
||||||
|
data_path = configs.get(CONFIG_DATA) or DEFAULT_DATA_PATH
|
||||||
|
if not os.path.isabs(data_path):
|
||||||
|
raise ValueError(f'Non-absolute data path: {data_path}')
|
||||||
|
if not os.path.isdir(data_path):
|
||||||
|
raise FileNotFoundError(f'Cannot find directory {data_path}')
|
||||||
|
|
||||||
|
source_path = configs.get(CONFIG_SOURCES) or DEFAULT_SOURCES_PATH
|
||||||
|
if not os.path.isabs(source_path):
|
||||||
|
raise ValueError(f'Non-absolute source path: {source_path}')
|
||||||
|
if not os.path.isdir(source_path):
|
||||||
|
raise FileNotFoundError(f'Cannot find directory {source_path}')
|
||||||
|
|
||||||
|
cache_path = configs.get(CONFIG_CACHE) or DEFAULT_CACHE_PATH
|
||||||
|
if not os.path.isabs(cache_path):
|
||||||
|
raise ValueError(f'Non-absolute cache path: {cache_path}')
|
||||||
|
if not os.path.isdir(cache_path):
|
||||||
|
raise FileNotFoundError(f'Cannot find directory {cache_path}')
|
||||||
|
|
||||||
|
log_file = configs.get(CONFIG_LOGFILE) or DEFAULT_LOG_FILE
|
||||||
|
if log_file and not os.path.isabs(log_file):
|
||||||
|
raise ValueError(f'Non-absolute log file path: {log_file}')
|
||||||
|
|
||||||
|
is_verbose = (configs.get(CONFIG_VERBOSE) == 'true') or DEFAULT_VERBOSITY
|
||||||
|
|
||||||
|
|
||||||
|
# Set up logging
|
||||||
|
logger = logging.getLogger("inquisitor")
|
||||||
|
logger.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
def add_logging_handler(verbose, log_filename):
|
||||||
|
"""
|
||||||
|
Adds a logging handler according to the given settings
|
||||||
|
"""
|
||||||
|
log_format = (
|
||||||
|
'[{asctime}] [{levelname}:{filename}:{lineno}] {message}'
|
||||||
|
if verbose else
|
||||||
|
'[{levelname}] {message}'
|
||||||
|
)
|
||||||
|
formatter = logging.Formatter(log_format, style='{')
|
||||||
|
|
||||||
|
log_level = (
|
||||||
|
logging.DEBUG
|
||||||
|
if verbose else
|
||||||
|
logging.INFO
|
||||||
|
)
|
||||||
|
handler = (
|
||||||
|
logging.FileHandler(log_filename, encoding='utf8')
|
||||||
|
if log_filename else
|
||||||
|
logging.StreamHandler()
|
||||||
|
)
|
||||||
|
handler.setFormatter(formatter)
|
||||||
|
handler.setLevel(log_level)
|
||||||
|
|
||||||
|
logger.addHandler(handler)
|
||||||
|
|
||||||
|
def init_default_logging():
|
||||||
|
add_logging_handler(is_verbose, log_file)
|
Loading…
Reference in New Issue