diff --git a/imagemonk/configuration.py b/imagemonk/configuration.py new file mode 100644 index 0000000..fb1debd --- /dev/null +++ b/imagemonk/configuration.py @@ -0,0 +1,125 @@ +import json +import os +from dataclasses import dataclass +from dataclasses import field +from pathlib import Path +from typing import Any +from typing import Dict +from typing import Optional +from typing import Tuple + +from imagemonk import constants + + +def _default_sqlite_pragmas() -> Dict[str, Any]: + """Default SQLite pragmas + + .. note:: This needs to be a separate callout function to avoid setting a mutable type in the + dataclass signature. + + .. note:: These settings are taken directly from + `the Peewee docs `_. + """ + return { + "journal_mode": "wal", + "cache_size": -1 * 64000, + "foreign_keys": 1, + "ignore_check_constraints": 0, + "synchronous": 0, + } + + +@dataclass +class _DBSqliteConfig: + path: Path = Path.cwd() / "imagemonk.db" + pragmas: Dict[str, Any] = field(default_factory=_default_sqlite_pragmas) + + @classmethod + def build(cls): + return cls( + path=Path(os.environ.get(constants.ENV_CONF_DB_SQLITE_PATH, cls.path)), + pragmas=json.loads(os.environ[constants.ENV_CONF_DB_SQLITE_PRAGMAS]) + if constants.ENV_CONF_DB_SQLITE_PRAGMAS in os.environ + else _default_sqlite_pragmas(), + ) + + +@dataclass +class _DBMariaConfig: + + hostname: str = "localhost" + username: str = "root" + password: Optional[str] = None + port: int = 3306 + schema: str = "imagemonk" + + @classmethod + def build(cls): + return cls( + hostname=os.getenv(constants.ENV_CONF_DB_MARIA_HOSTNAME, cls.hostname), + username=os.getenv(constants.ENV_CONF_DB_MARIA_USERNAME, cls.username), + password=os.environ.get(constants.ENV_CONF_DB_MARIA_PASSWORD, cls.password), + port=int(os.environ.get(constants.ENV_CONF_DB_MARIA_PORT, cls.port)), + schema=os.getenv(constants.ENV_CONF_DB_MARIA_SCHEMA, cls.schema), + ) + + +@dataclass +class _DBConfig: + + backend: constants.SupportedDatabaseBackend = ( + constants.SupportedDatabaseBackend.SQLITE + ) + sqlite: _DBSqliteConfig = field(default_factory=_DBSqliteConfig.build) + mariadb: _DBMariaConfig = field(default_factory=_DBMariaConfig.build) + + @classmethod + def build(cls): + return cls( + backend=constants.SupportedDatabaseBackend[ + os.environ[constants.ENV_CONF_DB_BACKEND] + ] + if constants.ENV_CONF_DB_BACKEND in os.environ + else cls.backend + ) + + +@dataclass +class _UploadConfig: + + size_limit: int = 1 * 1024 * 1024 + formats: Tuple[str] = ("jpg", "jpeg") + + @classmethod + def build(cls): + return cls( + size_limit=(int(os.environ[constants.ENV_CONF_FS_UPLOAD_MAX_SIZE]) * 1024) + if constants.ENV_CONF_FS_UPLOAD_MAX_SIZE in os.environ + else cls.size_limit, + formats=( + item.strip().lower() + for item in os.environ[constants.ENV_CONF_FS_UPLOAD_FORMATS].split(",") + ) + if constants.ENV_CONF_FS_UPLOAD_MAX_SIZE in os.environ + else cls.formats, + ) + + +@dataclass +class ImageMonkConfig: + database: _DBConfig = field(default_factory=_DBConfig.build) + upload: _UploadConfig = field(default_factory=_UploadConfig.build) + storage_path: Path = Path.cwd() + + @classmethod + def build(cls): + return cls( + storage_path=Path( + os.getenv(constants.ENV_CONF_FS_STORAGE_PATH, cls.storage_path) + ).resolve() + ) + + +def load() -> ImageMonkConfig: + + return ImageMonkConfig.build() diff --git a/imagemonk/constants.py b/imagemonk/constants.py new file mode 100644 index 0000000..7c6f3be --- /dev/null +++ b/imagemonk/constants.py @@ -0,0 +1,34 @@ +import enum + + +class SupportedDatabaseBackend(enum.Enum): + + MARIADB = enum.auto() + SQLITE = enum.auto() + + +HTTP_HEADER_RESPONSE_VERSION = "x-imagemonk-version" + +HTTP_HEADER_RESPONSE_DIGEST = "Digest" + +ENV_CONF_DB_BACKEND = "IMGMONK_DATABASE_BACKEND" + +ENV_CONF_DB_SQLITE_PATH = "IMGMONK_SQLITE_PATH" + +ENV_CONF_DB_SQLITE_PRAGMAS = "IMGMONK_SQLITE_PRAGMAS" + +ENV_CONF_DB_MARIA_HOSTNAME = "IMGMONK_MARIA_HOSTNAME" + +ENV_CONF_DB_MARIA_USERNAME = "IMGMONK_MARIA_USERNAME" + +ENV_CONF_DB_MARIA_PASSWORD = "IMGMONK_MARIA_PASSWORD" + +ENV_CONF_DB_MARIA_PORT = "IMGMONK_MARIA_PORT" + +ENV_CONF_DB_MARIA_SCHEMA = "IMGMONK_MARIA_SCHEMA" + +ENV_CONF_FS_STORAGE_PATH = "IMGMONK_STORAGE_PATH" + +ENV_CONF_FS_UPLOAD_MAX_SIZE = "IMGMONK_UPLOAD_LIMIT" + +ENV_CONF_FS_UPLOAD_FORMATS = "IMGMONK_UPLOAD_FORMATS"