30 lines
1.2 KiB
Python
30 lines
1.2 KiB
Python
|
|
"""Helpers for resolving runtime paths in source and frozen builds."""
|
||
|
|
|
||
|
|
import os
|
||
|
|
import sys
|
||
|
|
|
||
|
|
|
||
|
|
def get_app_root() -> str:
|
||
|
|
"""Return the app root directory.
|
||
|
|
|
||
|
|
In normal source runs, this is the repository root. In a frozen Windows
|
||
|
|
build, it is the bundle content root (PyInstaller's internal directory)
|
||
|
|
so bundled runtime folders like `static/`, `scripts/`, and `data/` stay
|
||
|
|
together with the executable payload.
|
||
|
|
"""
|
||
|
|
if getattr(sys, "frozen", False):
|
||
|
|
return getattr(sys, "_MEIPASS", os.path.dirname(os.path.abspath(sys.executable)))
|
||
|
|
return os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||
|
|
|
||
|
|
|
||
|
|
def get_default_data_dir() -> str:
|
||
|
|
"""Return the default path to the data directory.
|
||
|
|
|
||
|
|
In normal runs, this is a 'data' subdirectory under the app root.
|
||
|
|
In frozen builds, it is a persistent user directory (~/.odysseus/data)
|
||
|
|
to prevent SQLite databases and other persistent files from being
|
||
|
|
written to the ephemeral, temporary extraction bundle directory.
|
||
|
|
"""
|
||
|
|
if getattr(sys, "frozen", False):
|
||
|
|
return os.path.join(os.path.expanduser("~"), ".odysseus", "data")
|
||
|
|
return os.path.join(get_app_root(), "data")
|