""" Configuration for Curator. Two stores, by responsibility: 1. Global config (``.Curator.!gtag`` next to Curator.py) — **application data only**: window state, MRU folders, and the pointers to where the pool and the Filmotéka output live (``pool_dir`` / ``filmoteka_dir``). Those pointers must stay here because the pool index is found *through* them. 2. Pool index (``/.Curator.!index``, see ``pool_index.py``) — everything describing a particular library: per-movie metadata **and** library-level settings (``tag_schema``, ``copyasis_folders``). It travels with the pool. """ import json from pathlib import Path # Global config file (next to the main script) GLOBAL_CONFIG_FILE = Path(__file__).parent.parent.parent / ".Curator.!gtag" # ============================================================================= # TAG SCHEMA - default library settings (stored per-pool in the index) # ============================================================================= # Tag schema: the single source of truth for which tag categories exist, how # they are derived from ČSFD, and how they map to the Filmotéka folder tree. # Each entry: # category — tag category name (e.g. "Žánr") # csfd_field — NFO source field feeding it (genres / year / countries / # rating), or None for a user-only category. (Key name kept for # index compatibility; the data now comes from the NFO.) # transform — named value transform: None (str) or "decade_band" (rating) # filmoteka_root — folder under the output: "" = at the root (e.g. genres), # "Dle X" = grouping folder, None = filterable but no folders # filename_template — optional per-category hardlink name used only inside this # category's folders (e.g. "{year} - {title}{ext}"); fields: # title / year / rating / ext / stem / filename. Absent/None = # keep the pool filename. Pool files are never renamed by this. # Grouping folders are prefixed with "- " so DLNA/TV browsers sort the special # folders (Dle …, Tipy dne, Nově přidané) before the genre folders at the root. # This lives in the code as the default; the effective schema is stored per-pool # in the index (``PoolIndex.settings["tag_schema"]``). DEFAULT_TAG_SCHEMA = [ {"category": "Žánr", "csfd_field": "genres", "transform": None, "filmoteka_root": ""}, {"category": "Rok", "csfd_field": "year", "transform": None, "filmoteka_root": "- Dle roku"}, {"category": "Země původu", "csfd_field": "countries", "transform": None, "filmoteka_root": "- Dle země původu"}, {"category": "Hodnocení", "csfd_field": "rating", "transform": "decade_band", "filmoteka_root": "- Dle hodnocení"}, ] # ============================================================================= # GLOBAL CONFIG - Application settings only # ============================================================================= DEFAULT_GLOBAL_CONFIG = { "window_geometry": "1200x800", "window_maximized": False, "last_folder": None, "sidebar_width": 250, "recent_folders": [], "pool_dir": None, # managed pool root (single source of truth) "filmoteka_dir": None, # generated Filmotéka output (hardlink tree) } def load_global_config() -> dict: """Load global application config""" if GLOBAL_CONFIG_FILE.exists(): try: with open(GLOBAL_CONFIG_FILE, "r", encoding="utf-8") as f: config = json.load(f) # Merge with defaults for any missing keys for key, value in DEFAULT_GLOBAL_CONFIG.items(): if key not in config: config[key] = value return config except Exception: return DEFAULT_GLOBAL_CONFIG.copy() return DEFAULT_GLOBAL_CONFIG.copy() def save_global_config(cfg: dict): """Save global application config""" with open(GLOBAL_CONFIG_FILE, "w", encoding="utf-8") as f: json.dump(cfg, f, indent=2, ensure_ascii=False) # ============================================================================= # BACKWARDS COMPATIBILITY # ============================================================================= def load_config(): """Legacy function - returns global config""" return load_global_config() def save_config(cfg: dict): """Legacy function - saves global config""" save_global_config(cfg)