from pathlib import Path import json import sys from typing import Dict, Optional # Get the directory where the application is running from # If frozen (PyInstaller), use the executable's directory # Otherwise use the directory of this module if getattr(sys, 'frozen', False): # Running as compiled executable _APP_DIR = Path(sys.executable).parent else: # Running as script - go up from config/ to pyucc/ to root _APP_DIR = Path(__file__).parent.parent.parent _DEFAULT_PATH = _APP_DIR / "settings.json" def _read_file(path: Path) -> Dict: if not path.exists(): return {} try: with path.open("r", encoding="utf-8") as fh: data = json.load(fh) if isinstance(data, dict): return data except Exception: return {} return {} def _write_file(path: Path, data: Dict) -> None: path.parent.mkdir(parents=True, exist_ok=True) with path.open("w", encoding="utf-8") as fh: json.dump(data, fh, indent=2, ensure_ascii=False) def load_settings(path: Optional[Path] = None) -> Dict: p = path or _DEFAULT_PATH return _read_file(p) def save_settings(data: Dict, path: Optional[Path] = None) -> None: p = path or _DEFAULT_PATH _write_file(p, data) def get_baseline_dir() -> Optional[str]: s = load_settings() return s.get("baseline_dir") def get_max_keep() -> int: s = load_settings() try: v = int(s.get("max_keep", 5)) except Exception: v = 5 return v def get_zip_baselines() -> bool: """Get whether to create zip archives for baselines (default: False).""" s = load_settings() return s.get("zip_baselines", False) def set_baseline_settings( baseline_dir: Optional[str], max_keep: int, zip_baselines: bool = False ) -> None: s = load_settings() if baseline_dir is not None: s["baseline_dir"] = baseline_dir s["max_keep"] = int(max_keep) s["zip_baselines"] = bool(zip_baselines) save_settings(s) def get_duplicates_settings() -> Dict: """Return stored duplicates dialog settings or empty dict if none.""" s = load_settings() return s.get("duplicates", {}) def set_duplicates_settings( threshold: float = 5.0, extensions: Optional[list] = None, k: int = 25, window: int = 4, ) -> None: """Persist duplicates dialog settings. Args: threshold: percent threshold for fuzzy duplicates extensions: list of extensions (strings) or None k: k-gram size for fingerprinting window: winnowing window size """ s = load_settings() s.setdefault("duplicates", {}) s["duplicates"]["threshold"] = float(threshold) s["duplicates"]["extensions"] = list(extensions) if extensions is not None else None s["duplicates"]["k"] = int(k) s["duplicates"]["window"] = int(window) save_settings(s)