"""Filesystem locations: bundled resources and per-user data/config/cache folders. Works from a source checkout and from a PyInstaller bundle (sys._MEIPASS). Override all user folders with ACKIT_HOME (used by tests). """ import os import sys APP_NAME = "UnheardCity" def resource_root(): """Folder that contains `data/` (repo root, or the PyInstaller bundle root).""" if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"): return sys._MEIPASS return os.path.dirname(os.path.dirname(os.path.abspath(__file__))) def package_data(*parts): """Files shipped inside the package (codebooks, known setups, hash list).""" return os.path.join(os.path.dirname(os.path.abspath(__file__)), "data", *parts) def catalog_dir(): return os.path.join(resource_root(), "data", "catalog") def _base(kind): home = os.environ.get("ACKIT_HOME") if home: return os.path.join(home, kind) if sys.platform == "win32": root = os.environ.get("LOCALAPPDATA" if kind == "cache" else "APPDATA") or os.path.expanduser("~") return os.path.join(root, APP_NAME, kind if kind == "cache" else "") xdg = {"data": ("XDG_DATA_HOME", "~/.local/share"), "config": ("XDG_CONFIG_HOME", "~/.config"), "cache": ("XDG_CACHE_HOME", "~/.cache")}[kind] return os.path.join(os.environ.get(xdg[0]) or os.path.expanduser(xdg[1]), APP_NAME.lower()) def user_dir(kind): """kind: 'data' (originals store, notes), 'config' (settings), 'cache' (indexes).""" p = os.path.normpath(_base(kind)) os.makedirs(p, exist_ok=True) return p