import os from dataclasses import dataclass import hashlib from pathlib import Path def _env_bool(name: str, default: bool) -> bool: raw = os.getenv(name) if raw is None: return default normalized = raw.strip().lower() if normalized in {"1", "true", "yes", "on"}: return True if normalized in {"0", "false", "no", "off"}: return False return default @dataclass(frozen=True) class Settings: access_token: str catalog_db_path: str player_db_path: str local_library_root: str | None disable_auth: bool cache_relay_enabled: bool admin_username: str admin_password_hash: str secret_encryption_key: str cache_reconcile_interval_seconds: int stream_token_ttl_seconds: int musicfree_version_json_path: str musicfree_apk_path: str def _default_admin_password_hash() -> str: return f"sha256${hashlib.sha256('admin'.encode('utf-8')).hexdigest()}" def _env_int(name: str, default: int) -> int: raw = os.getenv(name) if raw is None: return default try: return int(raw.strip()) except ValueError: return default def _default_musicfree_release_dir() -> Path: project_root = Path(__file__).resolve().parents[2] sibling_release_dir = project_root.parent / "MusicFree" / "release" if sibling_release_dir.is_dir(): return sibling_release_dir return project_root / "release" def get_settings() -> Settings: musicfree_release_dir = Path( os.getenv("MUSICFREE_RELEASE_DIR", str(_default_musicfree_release_dir())) ) return Settings( access_token=os.getenv("PUBLIC_MUSIC_ACCESS_TOKEN", "dev-token"), catalog_db_path=os.getenv("CATALOG_DB_PATH", "./data/catalog_read.db"), player_db_path=os.getenv("PLAYER_DB_PATH", "./data/player.db"), local_library_root=os.getenv("LOCAL_LIBRARY_ROOT"), disable_auth=_env_bool("MUSIC_SERVER_DISABLE_AUTH", default=False), cache_relay_enabled=_env_bool("MUSIC_SERVER_CACHE_RELAY_ENABLED", default=True), admin_username=os.getenv("MUSIC_SERVER_ADMIN_USERNAME", "admin"), admin_password_hash=os.getenv( "MUSIC_SERVER_ADMIN_PASSWORD_HASH", _default_admin_password_hash(), ), secret_encryption_key=os.getenv( "MUSIC_SERVER_SECRET_ENCRYPTION_KEY", "dev-secret-encryption-key", ), cache_reconcile_interval_seconds=_env_int( "MUSIC_SERVER_CACHE_RECONCILE_INTERVAL_SECONDS", 600, ), stream_token_ttl_seconds=_env_int( "MUSIC_SERVER_STREAM_TOKEN_TTL_SECONDS", 3600, ), musicfree_version_json_path=os.getenv( "MUSICFREE_VERSION_JSON", str(musicfree_release_dir / "version.json"), ), musicfree_apk_path=os.getenv( "MUSICFREE_APK_PATH", str(musicfree_release_dir / "MusicFree_latest_release_universal.apk"), ), )