2020-08-23 21:58:26 +00:00
|
|
|
import os
|
2020-10-28 13:21:20 +00:00
|
|
|
import toml
|
2020-10-30 22:59:07 +00:00
|
|
|
import logging.config
|
|
|
|
import collections.abc
|
|
|
|
|
2020-08-23 21:58:26 +00:00
|
|
|
from pathlib import Path
|
2020-09-03 15:56:12 +00:00
|
|
|
from werkzeug.middleware.proxy_fix import ProxyFix
|
2020-10-30 02:30:46 +00:00
|
|
|
from flaschengeist import _module_path, logger
|
2020-08-23 21:58:26 +00:00
|
|
|
|
2020-10-30 22:59:07 +00:00
|
|
|
|
2021-01-23 01:12:42 +00:00
|
|
|
# Default config:
|
2021-05-26 23:27:53 +00:00
|
|
|
config = {"DATABASE": {"engine": "mysql", "port": 3306}}
|
2021-01-23 01:12:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
def update_dict(d, u):
|
2020-10-30 22:59:07 +00:00
|
|
|
for k, v in u.items():
|
|
|
|
if isinstance(v, collections.abc.Mapping):
|
2021-01-23 01:12:42 +00:00
|
|
|
d[k] = update_dict(d.get(k, {}), v)
|
2020-10-30 22:59:07 +00:00
|
|
|
else:
|
|
|
|
d[k] = v
|
|
|
|
return d
|
|
|
|
|
|
|
|
|
2021-01-25 12:09:20 +00:00
|
|
|
def read_configuration(test_config):
|
2021-01-23 01:12:42 +00:00
|
|
|
global config
|
2021-01-25 12:09:20 +00:00
|
|
|
paths = [_module_path]
|
2021-01-23 01:12:42 +00:00
|
|
|
|
2021-01-25 12:09:20 +00:00
|
|
|
if not test_config:
|
|
|
|
paths.append(Path.home() / ".config")
|
|
|
|
if "FLASCHENGEIST_CONF" in os.environ:
|
|
|
|
paths.append(Path(os.environ.get("FLASCHENGEIST_CONF")))
|
2020-10-30 22:59:07 +00:00
|
|
|
|
2021-01-23 01:12:42 +00:00
|
|
|
for loc in paths:
|
|
|
|
try:
|
|
|
|
with (loc / "flaschengeist.toml").open() as source:
|
|
|
|
print("Reading config file from >{}<".format(loc))
|
|
|
|
update_dict(config, toml.load(source))
|
|
|
|
except IOError:
|
|
|
|
pass
|
2021-01-25 12:09:20 +00:00
|
|
|
if test_config:
|
|
|
|
update_dict(config, test_config)
|
2020-08-23 21:58:26 +00:00
|
|
|
|
|
|
|
|
2021-11-16 13:07:05 +00:00
|
|
|
def configure_logger():
|
2021-01-23 01:12:42 +00:00
|
|
|
global config
|
2021-11-16 13:07:05 +00:00
|
|
|
# Read default config
|
2020-10-28 13:21:20 +00:00
|
|
|
logger_config = toml.load(_module_path / "logging.toml")
|
2021-11-16 13:07:05 +00:00
|
|
|
|
2020-10-28 13:21:20 +00:00
|
|
|
if "LOGGING" in config:
|
2021-11-16 13:07:05 +00:00
|
|
|
# Override with user config
|
|
|
|
update_dict(logger_config, config.get("LOGGING"))
|
|
|
|
# Check for shortcuts
|
2020-10-28 13:21:20 +00:00
|
|
|
if "level" in config["LOGGING"]:
|
|
|
|
logger_config["loggers"]["flaschengeist"] = {"level": config["LOGGING"]["level"]}
|
2021-11-16 13:07:05 +00:00
|
|
|
logger_config["handlers"]["console"]["level"] = config["LOGGING"]["level"]
|
|
|
|
logger_config["handlers"]["file"]["level"] = config["LOGGING"]["level"]
|
|
|
|
if not config["LOGGING"].get("console", True):
|
|
|
|
logger_config["handlers"]["console"]["level"] = "CRITICAL"
|
2020-10-28 13:21:20 +00:00
|
|
|
if "file" in config["LOGGING"]:
|
|
|
|
logger_config["root"]["handlers"].append("file")
|
|
|
|
logger_config["handlers"]["file"]["filename"] = config["LOGGING"]["file"]
|
|
|
|
path = Path(config["LOGGING"]["file"])
|
|
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
logging.config.dictConfig(logger_config)
|
|
|
|
|
2021-11-16 13:07:05 +00:00
|
|
|
|
|
|
|
def configure_app(app, test_config=None):
|
|
|
|
global config
|
|
|
|
read_configuration(test_config)
|
|
|
|
|
|
|
|
# Always enable this builtin plugins!
|
|
|
|
update_dict(config, {"auth": {"enabled": True}, "roles": {"enabled": True}, "users": {"enabled": True}})
|
|
|
|
|
2020-10-28 13:21:20 +00:00
|
|
|
if "secret_key" not in config["FLASCHENGEIST"]:
|
2020-11-18 00:56:33 +00:00
|
|
|
logger.warning("No secret key was configured, please configure one for production systems!")
|
2020-10-28 13:21:20 +00:00
|
|
|
app.config["SECRET_KEY"] = "0a657b97ef546da90b2db91862ad4e29"
|
|
|
|
else:
|
|
|
|
app.config["SECRET_KEY"] = config["FLASCHENGEIST"]["secret_key"]
|
2020-08-23 21:58:26 +00:00
|
|
|
|
2021-05-26 23:27:53 +00:00
|
|
|
if test_config is not None:
|
|
|
|
config["DATABASE"]["engine"] = "sqlite"
|
|
|
|
|
|
|
|
if config["DATABASE"]["engine"] == "mysql":
|
2021-05-26 23:52:30 +00:00
|
|
|
engine = "mysql"
|
|
|
|
try:
|
|
|
|
# Try mysqlclient first
|
|
|
|
from MySQLdb import _mysql
|
|
|
|
except ModuleNotFoundError:
|
|
|
|
engine += "+pymysql"
|
2021-05-26 23:27:53 +00:00
|
|
|
options = "?charset=utf8mb4"
|
|
|
|
elif config["DATABASE"]["engine"] == "postgres":
|
|
|
|
engine = "postgresql+psycopg2"
|
|
|
|
options = "?client_encoding=utf8"
|
|
|
|
elif config["DATABASE"]["engine"] == "sqlite":
|
|
|
|
engine = "sqlite"
|
|
|
|
options = ""
|
|
|
|
host = ""
|
|
|
|
else:
|
|
|
|
logger.error(f"Invalid database engine configured. >{config['DATABASE']['engine']}< is unknown")
|
|
|
|
raise Exception
|
|
|
|
if config["DATABASE"]["engine"] in ["mysql", "postgresql"]:
|
|
|
|
host = "{user}:{password}@{host}:{port}".format(
|
2021-01-23 01:12:42 +00:00
|
|
|
user=config["DATABASE"]["user"],
|
2021-05-26 23:27:53 +00:00
|
|
|
password=config["DATABASE"]["password"],
|
2021-01-23 01:12:42 +00:00
|
|
|
host=config["DATABASE"]["host"],
|
2021-02-10 20:21:53 +00:00
|
|
|
port=config["DATABASE"]["port"],
|
2021-01-23 01:12:42 +00:00
|
|
|
)
|
2021-05-26 23:27:53 +00:00
|
|
|
app.config["SQLALCHEMY_DATABASE_URI"] = f"{engine}://{host}/{config['DATABASE']['database']}{options}"
|
2020-08-23 21:58:26 +00:00
|
|
|
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
|
2020-09-03 15:56:12 +00:00
|
|
|
|
2020-10-28 13:21:20 +00:00
|
|
|
if "root" in config["FLASCHENGEIST"]:
|
|
|
|
logger.debug("Setting application root to >{}<".format(config["FLASCHENGEIST"]["root"]))
|
|
|
|
app.config["APPLICATION_ROOT"] = config["FLASCHENGEIST"]["root"]
|
|
|
|
if config["FLASCHENGEIST"].get("proxy", False):
|
2020-09-07 16:11:38 +00:00
|
|
|
logger.debug("Fixing wsgi_app for using behind a proxy server")
|
2020-09-03 15:56:12 +00:00
|
|
|
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)
|