Update configuration with new design requirements

This commit is contained in:
Ethan Paul 2021-10-28 23:06:37 -04:00
parent 0be8cb96b7
commit b61ef4624b
No known key found for this signature in database
GPG Key ID: D0E2CBF1245E92BF
2 changed files with 116 additions and 50 deletions

View File

@ -1,5 +1,3 @@
import datetime
import enum
import json
import os
from dataclasses import dataclass
@ -10,9 +8,7 @@ from typing import Dict
from typing import NamedTuple
from typing import Optional
from typing import Sequence
from typing import Tuple
import peewee
from typing import Union
from fresnel_lens import constants
@ -42,83 +38,141 @@ def _default_sqlite_pragmas() -> Dict[str, Any]:
@dataclass
class _DBSqliteConfig:
path: Path = Path.cwd() / "fresnel_lens.db"
class DatabaseSqliteConfig:
path: Path = Path.cwd() / "fresnel.db"
pragmas: Dict[str, Any] = field(default_factory=_default_sqlite_pragmas)
@classmethod
def build(cls):
def from_env(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(),
path=Path(os.environ.get("FRESNEL_DB_SQLITE_PATH", cls.path)),
pragmas=json.loads(os.environ["FRESNEL_DB_SQLITE_PRAGMAS"])
if "FRESNEL_DB_SQLITE_PRAGMAS" in os.environ
else constants.DEFAULT_SQLITE_PRAGMAS,
)
@dataclass
class _DBMariaConfig:
class DatabaseMariaConfig:
hostname: str = "localhost"
username: str = "root"
password: Optional[str] = None
port: int = 3306
schema: str = "fresnel_lens"
schema: str = "fresnel"
@classmethod
def build(cls):
def from_env(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),
hostname=os.getenv("FRESNEL_DB_MARIA_HOSTNAME", cls.hostname),
username=os.getenv("FRESNEL_DB_MARIA_USERNAME", cls.username),
password=os.environ.get("FRESNEL_DB_MARIA_PASSWORD", cls.password),
port=int(os.environ.get("FRESNEL_DB_MARIA_PORT", cls.port)),
schema=os.getenv("FRESNEL_DB_MARIA_SCHEMA", cls.schema),
)
@dataclass
class _DBConfig:
class DatabaseConfig:
backend: constants.DatabaseBackend = constants.DatabaseBackend.SQLITE
sqlite: _DBSqliteConfig = field(default_factory=_DBSqliteConfig.build)
mariadb: _DBMariaConfig = field(default_factory=_DBMariaConfig.build)
sqlite: DatabaseSqliteConfig = field(default_factory=DatabaseSqliteConfig.from_env)
mariadb: DatabaseMariaConfig = field(default_factory=DatabaseMariaConfig.from_env)
@classmethod
def build(cls):
def from_env(cls):
return cls(
backend=constants.DatabaseBackend[os.environ[constants.ENV_CONF_DB_BACKEND]]
if constants.ENV_CONF_DB_BACKEND in os.environ
backend=constants.DatabaseBackend[os.environ["FRESNEL_DB_BACKEND"].upper()]
if "FRESNEL_DB_BACKEND" in os.environ
else cls.backend
)
@dataclass
class ManipConfig:
alias: str
name: str
strategy: constants.DimensionStrategy = constants.DimensionStrategy.SCALE
anchor: constants.Anchor = constants.Anchor.C
formats: Sequence[constants.ImageFormat] = (
constants.ImageFormat.JPEG,
constants.ImageFormat.PNG,
)
horizontal: None
vertical: None
@dataclass
class ImageMuckConfig:
database: _DBConfig = field(default_factory=_DBConfig.build)
images: Path = Path.cwd() / "images"
cache_dir: Path = Path.cwd() / "cache"
expose_source: bool = False
manips: Sequence[ManipConfig] = ()
horizontal: Optional[Union[int, float]] = None
vertical: Optional[Union[int, float]] = None
@classmethod
def from_env(cls):
def from_env(cls, key: str):
strategy = (
constants.DimensionStrategy[
os.environ[f"FRESNEL_MANIP_{key}_STRATEGY"].upper()
]
if f"FRESNEL_MANIP_{key}_STRATEGY" in os.environ
else cls.strategy
)
dimension_conversion = (
float if strategy == constants.DimensionStrategy.RELATIVE else int
)
return cls(
storage_path=Path(
os.getenv(constants.ENV_CONF_FS_STORAGE_PATH, cls.storage_path)
).resolve()
name=os.getenv(f"FRESNEL_MANIP_{key}_NAME", key.lower()),
strategy=strategy,
anchor=constants.Anchor(os.environ[f"FRESNEL_MANIP_{key}_ANCHOR"].lower())
if f"FRESNEL_MANIP_{key}_ANCHOR" in os.environ
else cls.anchor,
formats=[
constants.ImageFormat[item.upper()]
for item in os.environ[f"FRESNEL_MANIP_{key}_FORMATS"].split(",")
]
if f"FRESNEL_MANIP_{key}_FORMATS" in os.environ
else cls.formats,
horizontal=dimension_conversion(
os.environ[f"FRESNEL_MANIP_{key}_HORIZONTAL"]
)
if f"FRESNEL_MANIP_{key}_HORIZONTAL" in os.environ
else cls.horizontal,
vertical=dimension_conversion(os.environ[f"FRESNEL_MANIP_{key}_VERTICAL"])
if f"FRESNEL_MANIP_{key}_VERTICAL" in os.environ
else cls.vertical,
)
def load() -> ImageMuckConfig:
return ImageMuckConfig.from_env()
@dataclass
class FresnelConfig:
database: DatabaseConfig = field(default_factory=DatabaseConfig.from_env)
sourcedir: Path = Path.cwd() / "images"
manipdir: Path = Path.cwd() / "images"
expose_source: bool = False
private: bool = False
manips: Dict[str, ManipConfig] = field(default_factory=dict)
@classmethod
def from_env(cls):
manip_names = set(
[
key.replace("FRESNEL_MANIP_", "").partition("_")[0]
for key in os.environ.keys()
if key.startswith("FRESNEL_MANIP_")
]
)
return cls(
sourcedir=Path(os.environ.get("FRESNEL_SOURCEDIR", cls.sourcedir))
.expanduser()
.resolve(),
manipdir=Path(os.environ.get("FRESNEL_MANIPDIR", cls.manipdir))
.expanduser()
.resolve(),
expose_source=os.getenv(
"FRESNEL_EXPOSE_SOURCE", str(cls.expose_source)
).lower()
== "true",
private=os.getenv("FRESNEL_PRIVATE", str(cls.private)).lower() == "true",
manips={name.lower(): ManipConfig.from_env(name) for name in manip_names},
)
def load() -> FresnelConfig:
try:
return FresnelConfig.from_env()
except (ValueError, TypeError, IndexError, KeyError) as err:
raise RuntimeError(err)

View File

@ -15,15 +15,27 @@ class DimensionStrategy(enum.Enum):
class ImageFormat(enum.Enum):
JPEG = ("jpg", "jpeg")
PNG = ("png",)
GIF = ("gif",)
JPEG = enum.auto()
PNG = enum.auto()
GIF = enum.auto()
class Anchor(enum.Enum):
TL = "top-left"
TC = "top-center"
TR = "top-center"
CL = "center-left"
C = "center"
CR = "center-right"
BL = "bottom-left"
BC = "bottom-center"
BR = "bottom-right"
HTTP_HEADER_RESPONSE_VERSION = "x-fresnel_lens-version"
HTTP_HEADER_RESPONSE_DIGEST = "Digest"
DEFAULT_SQLITE_PRAGMAS = {
"journal_mode": "wal",
"cache_size": -1 * 64000,
"foreign_keys": 1,
"ignore_check_constraints": 0,
"synchronous": 0,
}