"""API credentials for the optional cover sources (IGDB, ScreenScraper, TheMovieDB). Credentials live in a small JSON file next to the database so both the GUI and the HTTP API (running on the NAS) can share them. Environment variables take precedence over the file. """ import json import os from pathlib import Path from . import config CREDENTIALS_PATH = Path( os.environ.get("PSP_CREDENTIALS", str(config.USER_DATA_DIR / "credentials.json")) ) FIELDS = [ "igdb_client_id", "igdb_client_secret", "tmdb_api_key", "google_api_key", "google_cx", "screenscraper_devid", "screenscraper_devpassword", "screenscraper_ssid", "screenscraper_sspassword", "screenscraper_softname", ] _ENV_MAP = { "igdb_client_id": "IGDB_CLIENT_ID", "igdb_client_secret": "IGDB_CLIENT_SECRET", "tmdb_api_key": "TMDB_API_KEY", "google_api_key": "GOOGLE_API_KEY", "google_cx": "GOOGLE_CX", "screenscraper_devid": "SCREENSCRAPER_DEVID", "screenscraper_devpassword": "SCREENSCRAPER_DEVPASSWORD", "screenscraper_ssid": "SCREENSCRAPER_SSID", "screenscraper_sspassword": "SCREENSCRAPER_SSPASSWORD", "screenscraper_softname": "SCREENSCRAPER_SOFTNAME", } _cache = None def load(): """Return the credentials dict (cached; env vars win over the file).""" global _cache if _cache is None: creds = {} if CREDENTIALS_PATH.exists(): try: creds = json.loads(CREDENTIALS_PATH.read_text(encoding="utf-8")) except (OSError, ValueError): creds = {} if not isinstance(creds, dict): creds = {} for key, env in _ENV_MAP.items(): value = os.environ.get(env) if value: creds[key] = value _cache = creds return _cache def save(values): """Merge `values` into the credential file and refresh the cache.""" global _cache creds = dict(load()) for key in FIELDS: if key in values: value = (values[key] or "").strip() if value: creds[key] = value else: creds.pop(key, None) try: CREDENTIALS_PATH.parent.mkdir(parents=True, exist_ok=True) tmp = CREDENTIALS_PATH.with_name(CREDENTIALS_PATH.name + ".tmp") tmp.write_text(json.dumps(creds, indent=2), encoding="utf-8") os.replace(tmp, CREDENTIALS_PATH) except OSError: pass _cache = creds return creds