from pathlib import Path from dataclasses import dataclass from argparse import ArgumentParser from typing import List from os import getenv from sys import argv from xdg.BaseDirectory import xdg_cache_home from json import loads @dataclass class Config: cache_file: Path = Path(xdg_cache_home) / Path("spotify-shortcuts.json") client_id: str | None = None client_secret: str | None = None notifications: bool = True @staticmethod def from_file(path: Path): if not path.exists(): raise FileNotFoundError(f"Configuration file {path} does not exist.") with open(path, "r") as f: data = loads(f.read()) return Config( cache_file=Path(data.get("cacheFile", Config.cache_file)), client_id=data.get("clientId", Config.client_id), client_secret=data.get("clientSecret", Config.client_secret), ) def load_config(args: List[str] = argv[1:]) -> Config: parser = ArgumentParser(description="Spotify CLI Tool") parser.add_argument( "--cache-file", type=Path, default=Config.cache_file, help="Path to the cache file for Spotify authentication", ) parser.add_argument( "--client-id", type=str, default=Config.client_id, help="Spotify API Client ID", ) parser.add_argument( "--client-secret", type=str, default=Config.client_secret, help="Spotify API Client Secret", ) parser.add_argument( "--config-file", type=str, help="Path to a json configuration file with keys clientId and clientSecret", ) parser.add_argument( "--no-notifications", action="store_true", help="Disable desktop notifications", ) ns = parser.parse_args(args) cfg = Config() if (cfg_file := ns.config_file or getenv("SPOTIFY_SHORTCUTS_CONFIG", None)) != None: cfg = Config.from_file(Path(cfg_file)) return Config( cache_file=ns.cache_file or cfg.cache_file, client_id=ns.client_id or cfg.client_id, client_secret=ns.client_secret or cfg.client_secret, notifications=not ns.no_notifications or cfg.notifications, )