initial commit, functinal software
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
"""Resolve app, config, and output paths for editable and frozen runs."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def is_frozen() -> bool:
|
||||
return bool(getattr(sys, "frozen", False))
|
||||
|
||||
|
||||
def _customer_root_from_shared() -> Path:
|
||||
"""Repo layout: shared/src/orisys_app_shared -> apps/customer."""
|
||||
here = Path(__file__).resolve()
|
||||
# .../orisys-app/shared/src/orisys_app_shared/paths.py
|
||||
repo_root = here.parents[3]
|
||||
return repo_root / "apps" / "customer"
|
||||
|
||||
|
||||
def app_root() -> Path:
|
||||
"""Return the customer app root (editable) or EXE directory (frozen)."""
|
||||
if is_frozen():
|
||||
return Path(sys.executable).resolve().parent
|
||||
# Prefer cwd override when launched from apps/customer
|
||||
cwd = Path.cwd().resolve()
|
||||
if (cwd / "config").is_dir() and (cwd / "run.py").is_file():
|
||||
return cwd
|
||||
if (cwd / "apps" / "customer" / "config").is_dir():
|
||||
return cwd / "apps" / "customer"
|
||||
return _customer_root_from_shared()
|
||||
|
||||
|
||||
def config_dir() -> Path:
|
||||
if is_frozen():
|
||||
beside = app_root() / "config"
|
||||
if beside.is_dir():
|
||||
return beside
|
||||
internal = app_root() / "_internal" / "config"
|
||||
if internal.is_dir():
|
||||
return internal
|
||||
return app_root() / "config"
|
||||
|
||||
|
||||
def sensors_dir() -> Path:
|
||||
return config_dir() / "sensors"
|
||||
|
||||
|
||||
def locales_dir() -> Path:
|
||||
return config_dir() / "locales"
|
||||
|
||||
|
||||
def outputs_dir() -> Path:
|
||||
path = app_root() / "outputs"
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
return path
|
||||
|
||||
|
||||
def logs_dir() -> Path:
|
||||
path = outputs_dir() / "logs"
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
return path
|
||||
|
||||
|
||||
def calibration_export_dir() -> Path:
|
||||
path = outputs_dir() / "calibration"
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
return path
|
||||
|
||||
|
||||
def preference_path() -> Path:
|
||||
return app_root() / "preference.json"
|
||||
|
||||
|
||||
def preferences_default_path() -> Path:
|
||||
return config_dir() / "preferences.default.json"
|
||||
|
||||
|
||||
def branding_dir() -> Path:
|
||||
"""Branding assets shipped with the shared package."""
|
||||
# editable: shared/resources/branding
|
||||
# package: next to installed module via package resources fallback
|
||||
here = Path(__file__).resolve()
|
||||
candidates = [
|
||||
here.parents[2] / "resources" / "branding", # shared/resources/branding
|
||||
here.parent / "resources" / "branding",
|
||||
]
|
||||
if is_frozen():
|
||||
candidates.insert(0, app_root() / "branding")
|
||||
candidates.insert(0, app_root() / "_internal" / "branding")
|
||||
for path in candidates:
|
||||
if path.is_dir():
|
||||
return path
|
||||
return candidates[0]
|
||||
|
||||
|
||||
def logo_path() -> Path:
|
||||
return branding_dir() / "logo.png"
|
||||
|
||||
|
||||
def logo_topbar_path() -> Path:
|
||||
return branding_dir() / "logo_topbar.png"
|
||||
|
||||
|
||||
def sensor_json_path(sensor_type: str) -> Path | None:
|
||||
"""Return ``config/sensors/<type>/sensor.json`` when present."""
|
||||
path = sensors_dir() / str(sensor_type) / "sensor.json"
|
||||
return path if path.is_file() else None
|
||||
|
||||
|
||||
_PREFERRED_SENSOR_ROOT: Path | None = None
|
||||
|
||||
|
||||
def prefer_local_sensor_bundles(root: Path | None = None) -> Path | None:
|
||||
"""Prefer app ``config/sensors`` over packaged Orisys sensor bundles."""
|
||||
global _PREFERRED_SENSOR_ROOT
|
||||
|
||||
if root is not None:
|
||||
sensors = (Path(root) / "config" / "sensors").resolve()
|
||||
if not sensors.is_dir():
|
||||
sensors = Path(root).resolve()
|
||||
else:
|
||||
sensors = sensors_dir().resolve()
|
||||
if not sensors.is_dir():
|
||||
return None
|
||||
|
||||
if _PREFERRED_SENSOR_ROOT is not None and _PREFERRED_SENSOR_ROOT == sensors:
|
||||
return sensors
|
||||
|
||||
try:
|
||||
import orisys.configs as configs
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
original = configs._candidate_sensor_roots
|
||||
marker = str(sensors)
|
||||
if getattr(original, "_orisys_app_local_pref", None) == marker:
|
||||
_PREFERRED_SENSOR_ROOT = sensors
|
||||
return sensors
|
||||
|
||||
def _candidate_sensor_roots_prefer_local() -> list[Path]:
|
||||
roots = [sensors]
|
||||
for candidate in original():
|
||||
resolved = Path(candidate).resolve()
|
||||
if resolved != sensors and resolved not in roots:
|
||||
roots.append(resolved)
|
||||
return roots
|
||||
|
||||
_candidate_sensor_roots_prefer_local._orisys_app_local_pref = marker # type: ignore[attr-defined]
|
||||
configs._candidate_sensor_roots = _candidate_sensor_roots_prefer_local
|
||||
_PREFERRED_SENSOR_ROOT = sensors
|
||||
return sensors
|
||||
Reference in New Issue
Block a user