Source code for dbs_annotator.utils.user_data

"""Per-user data locations for config and presets.

All user-owned runtime files (config JSON, preset overrides, cached state) MUST
resolve under :func:`user_data_dir` so they survive reinstalls and in-place
upgrades on every platform. The install directory (Windows ``Program Files`` /
``%LOCALAPPDATA%\\Programs\\...``, the macOS ``.app`` bundle, the Linux
``/opt`` or ``/usr`` prefix) is wiped or replaced by every MSI / DMG / dpkg
upgrade and must never hold user data.

The path is derived from Qt's :class:`QStandardPaths` so it follows platform
conventions. Organization and application directory names are set in
``dbs_annotator.config`` as ``FS_ORG_NAME`` / ``FS_APP_NAME`` (ASCII, no spaces)
and applied in ``__main__`` via ``QApplication``:

* Windows: ``%LOCALAPPDATA%\\WyssGeneva\\DBSAnnotator``
* macOS:   ``~/Library/Application Support/WyssGeneva/DBSAnnotator``
* Linux:   ``~/.local/share/WyssGeneva/DBSAnnotator``
"""

from __future__ import annotations

from pathlib import Path

from PySide6.QtCore import QStandardPaths


[docs] def user_data_dir() -> Path: """Return the platform-appropriate per-user data directory for the app. The directory is created if it does not yet exist. If Qt cannot determine a writable location (e.g. headless CI without a home directory), the caller gets a sensible fallback under ``~/.dbs-annotator``. """ location = QStandardPaths.writableLocation( QStandardPaths.StandardLocation.AppLocalDataLocation ) base = Path(location) if location else Path.home() / ".dbs-annotator" base.mkdir(parents=True, exist_ok=True) return base
[docs] def user_config_file(name: str) -> Path: """Return a path under :func:`user_data_dir` for a named config file. Parent directories are created on demand so callers can immediately write to the returned path. """ path = user_data_dir() / name path.parent.mkdir(parents=True, exist_ok=True) return path