64 lines
1.9 KiB
Python
64 lines
1.9 KiB
Python
"""Runtime settings store.
|
|||
|
|
|
||
|
|
Configuration can come from two places: environment variables (the deploy-time
|
||
|
|
defaults) and a JSON file written by the in-app Settings page. The file, when
|
||
|
|
present, wins. ``load`` returns the effective settings; ``save`` persists the
|
||
|
|
editable subset and returns the new effective settings.
|
||
|
|
"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import json
|
||
|
|
import os
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
SETTINGS_FILE = Path(os.environ.get("SETTINGS_FILE", "cache/settings.json"))
|
||
|
|
|
||
|
|
FIELDS = (
|
||
|
|
"emby_url",
|
||
|
|
"emby_api_key",
|
||
|
|
"navidrome_url",
|
||
|
|
"navidrome_user",
|
||
|
|
"navidrome_password",
|
||
|
|
"music_root",
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def env_defaults() -> dict:
|
||
|
|
return {
|
||
|
|
"emby_url": os.environ.get("EMBY_URL", "http://10.0.0.2:8096"),
|
||
|
|
"emby_api_key": os.environ.get("EMBY_API_KEY", ""),
|
||
|
|
"navidrome_url": os.environ.get("NAVIDROME_URL", "http://10.0.0.2:4533"),
|
||
|
|
"navidrome_user": os.environ.get("NAVIDROME_USER", ""),
|
||
|
|
"navidrome_password": os.environ.get("NAVIDROME_PASSWORD", ""),
|
||
|
|
"music_root": os.environ.get("MUSIC_ROOT", r"\\Matt-htpc\d\Music"),
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
def _read_file() -> dict:
|
||
|
|
if not SETTINGS_FILE.exists():
|
||
|
|
return {}
|
||
|
|
try:
|
||
|
|
data = json.loads(SETTINGS_FILE.read_text(encoding="utf-8"))
|
||
|
|
except (OSError, ValueError):
|
||
|
|
return {}
|
||
|
|
return {k: str(v) for k, v in data.items() if k in FIELDS and v is not None}
|
||
|
|
|
||
|
|
|
||
|
|
def load() -> dict:
|
||
|
|
"""Effective settings: env defaults overlaid with the saved file."""
|
||
|
|
values = env_defaults()
|
||
|
|
values.update(_read_file())
|
||
|
|
return values
|
||
|
|
|
||
|
|
|
||
|
|
def save(updates: dict) -> dict:
|
||
|
|
"""Persist the editable subset of ``updates`` and return effective settings."""
|
||
|
|
current = _read_file()
|
||
|
|
for key in FIELDS:
|
||
|
|
if key in updates and updates[key] is not None:
|
||
|
|
current[key] = str(updates[key]).strip()
|
||
|
|
SETTINGS_FILE.parent.mkdir(parents=True, exist_ok=True)
|
||
|
|
SETTINGS_FILE.write_text(json.dumps(current, indent=2), encoding="utf-8")
|
||
|
|
return load()
|