"""Tunetti configuration — stored at ~/.config/tunetti/config.json .""" import json from pathlib import Path # ── Config file location (XDG compliant) ────────────────────────────────── CONFIG_DIR = Path.home() / ".config" / "tunetti" CONFIG_FILE = CONFIG_DIR / "config.json" # Legacy config in the project directory (for migration). _LEGACY_FILE = Path(__file__).parent / "tunetti_config.json" DEFAULT_CONFIG: dict = { # Playback "volume": 50, "max_history": 5000, "ffplay_args": ["-nodisp", "-autoexit", "-loglevel", "quiet"], # Database "db_path": str(CONFIG_DIR / "music_history.db"), # Discord "discord_client_id": "1510266468388835328", "discord_rpc_enabled": True, # Visualizer "visualizer_enabled": True, } def _migrate_legacy() -> None: """Copy old project-level config and database to the new XDG location.""" if CONFIG_FILE.exists(): return # new config already exists — nothing to do if not _LEGACY_FILE.exists(): return # nothing to migrate CONFIG_DIR.mkdir(parents=True, exist_ok=True) try: with open(_LEGACY_FILE) as f: old = json.load(f) # Migrate the database file if it lived in the old project dir. old_db_path = Path(old.get("db_path", "")) if old_db_path.parent == Path(__file__).parent and old_db_path.exists(): new_db_path = CONFIG_DIR / "music_history.db" if not new_db_path.exists(): import shutil shutil.copy2(str(old_db_path), str(new_db_path)) old["db_path"] = str(new_db_path) save_config({**DEFAULT_CONFIG, **old}) # Rename legacy config so we don't re-migrate every launch. _LEGACY_FILE.rename(_LEGACY_FILE.with_suffix(".json.migrated")) except (json.JSONDecodeError, OSError): pass def load_config() -> dict: _migrate_legacy() if CONFIG_FILE.exists(): try: with open(CONFIG_FILE) as f: return {**DEFAULT_CONFIG, **json.load(f)} except (json.JSONDecodeError, OSError): pass # First launch — create the directory and write defaults. CONFIG_DIR.mkdir(parents=True, exist_ok=True) save_config(dict(DEFAULT_CONFIG)) return dict(DEFAULT_CONFIG) def save_config(config: dict) -> None: """Merge *config* over defaults and persist to disk.""" CONFIG_DIR.mkdir(parents=True, exist_ok=True) merged = {**DEFAULT_CONFIG, **config} with open(CONFIG_FILE, "w") as f: json.dump(merged, f, indent=2) def save_volume(volume: int) -> None: """Persist current volume to disk and update in-memory SETTINGS.""" volume = max(0, min(100, volume)) SETTINGS["volume"] = volume save_config(dict(SETTINGS)) def save_setting(key: str, value) -> None: """Persist a single setting and update the in-memory SETTINGS dict.""" SETTINGS[key] = value save_config(dict(SETTINGS)) def get_setting(key: str): """Return a setting value from the in-memory dict.""" return SETTINGS.get(key, DEFAULT_CONFIG.get(key)) SETTINGS = load_config()