Files
HousemannandClaude Sonnet 4.6 3f253ffe81 Initial commit: Filebot Media Browser
Vue 3 + FastAPI Webapp zur Anzeige von Filebot/n8n-Medienmetadaten aus PostgreSQL.
Enthält Frontend, API, Nginx-Config, SQL-Migrationen und Docker-Compose-Setup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 05:38:37 +02:00

50 lines
1.4 KiB
Python

import re
from pathlib import Path
from typing import Any
import yaml
from pydantic import AliasChoices, BaseModel, Field, field_validator
IDENT_RE = re.compile(r"^[a-zA-Z_][a-zA-Z0-9_]*$")
class DatabaseConfig(BaseModel):
host: str = "192.168.30.186"
port: int = 5432
name: str = "postgres"
user: str = "postgres"
password: str = ""
table: str = "movie_files"
# "schema" ist in YAML erlaubt; intern db_schema (Pydantic-Konflikt mit BaseModel.schema)
db_schema: str = Field(
default="public",
validation_alias=AliasChoices("db_schema", "schema"),
)
ssl: bool = False
@field_validator("table", "db_schema")
@classmethod
def validate_identifiers(cls, v: str) -> str:
if not IDENT_RE.match(v):
raise ValueError(f"Ungültiger Datenbank-Identifier: {v}")
return v
@property
def qualified_table(self) -> str:
return f'"{self.db_schema}"."{self.table}"'
class AppConfig(BaseModel):
database: DatabaseConfig = Field(default_factory=DatabaseConfig)
def load_config(path: str | Path | None = None) -> tuple[AppConfig, Path]:
config_path = Path(path or "/app/config/config.yaml")
if not config_path.is_file():
return AppConfig(), config_path
with config_path.open(encoding="utf-8") as f:
raw: dict[str, Any] = yaml.safe_load(f) or {}
return AppConfig.model_validate(raw), config_path