63 lines
2.0 KiB
Python
63 lines
2.0 KiB
Python
import os
|
|
from dataclasses import dataclass, field
|
|
from pathlib import Path
|
|
|
|
|
|
def secret(name: str) -> str:
|
|
path = os.getenv(name + "_FILE")
|
|
return Path(path).read_text().strip() if path else os.getenv(name, "")
|
|
|
|
|
|
@dataclass
|
|
class Settings:
|
|
data_dir: Path = field(default_factory=lambda: Path(os.getenv("DATA_DIR", "/data")))
|
|
config_dir: Path = field(
|
|
default_factory=lambda: Path(os.getenv("CONFIG_DIR", "/config"))
|
|
)
|
|
mock: bool = field(
|
|
default_factory=lambda: os.getenv("KOKONNA_MOCK", "true").lower() == "true"
|
|
)
|
|
write_enabled: bool = field(
|
|
default_factory=lambda: (
|
|
os.getenv("KOKONNA_WRITE_ENABLED", "false").lower() == "true"
|
|
)
|
|
)
|
|
api_key: str = field(default_factory=lambda: secret("KOKONNA_API_KEY"), repr=False)
|
|
api_token: str = field(
|
|
default_factory=lambda: secret("FRAME_FLOW_TOKEN"), repr=False
|
|
)
|
|
additional_secrets: list[str] = field(default_factory=list, repr=False)
|
|
device_id: str = "living-room"
|
|
timezone: str = "Asia/Shanghai"
|
|
cors_origins: list[str] = field(
|
|
default_factory=lambda: [
|
|
x.strip()
|
|
for x in os.getenv("CORS_ALLOWED_ORIGINS", "").split(",")
|
|
if x.strip()
|
|
]
|
|
)
|
|
image_url_hosts: list[str] = field(
|
|
default_factory=lambda: [
|
|
x.strip().lower()
|
|
for x in os.getenv("IMAGE_URL_ALLOWED_HOSTS", "").split(",")
|
|
if x.strip()
|
|
]
|
|
)
|
|
font_path: str = field(
|
|
default_factory=lambda: os.getenv(
|
|
"FONT_PATH", "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc"
|
|
)
|
|
)
|
|
max_bytes: int = 20 * 1024 * 1024
|
|
idempotency_hours: int = 168
|
|
sync_timeout: int = 600
|
|
|
|
def sanitize(self, value):
|
|
import json
|
|
|
|
encoded = json.dumps(value, ensure_ascii=False)
|
|
for key in (self.api_key, self.api_token, *self.additional_secrets):
|
|
if key:
|
|
encoded = encoded.replace(key, "[REDACTED]")
|
|
return json.loads(encoded)
|