65 lines
2.5 KiB
Python
65 lines
2.5 KiB
Python
"""Paths and settings. Everything is environment-driven so the same image runs
|
|
locally and in Docker without code changes (REQ-072)."""
|
|
|
|
import os
|
|
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
|
|
# huggingface_hub reads HF_TOKEN / HUGGING_FACE_HUB_TOKEN; accept either name in
|
|
# .env so pasting a token under the obvious name just works.
|
|
if os.environ.get("HF_TOKEN") and not os.environ.get("HUGGING_FACE_HUB_TOKEN"):
|
|
os.environ["HUGGING_FACE_HUB_TOKEN"] = os.environ["HF_TOKEN"]
|
|
|
|
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
DATA_DIR = os.path.abspath(os.environ.get("APP_DATA_DIR", os.path.join(REPO_ROOT, "data")))
|
|
PROJECTS_DIR = os.path.join(DATA_DIR, "projects")
|
|
DB_PATH = os.path.join(DATA_DIR, "app.db")
|
|
|
|
# Where the video archive is mounted. Projects store a path relative to nothing —
|
|
# they store an absolute one — but this is the default the UI starts browsing from.
|
|
VIDEO_ROOT = os.path.abspath(os.environ.get("VIDEO_ARCHIVE", os.path.join(DATA_DIR, "archive")))
|
|
|
|
|
|
def archive_host_paths() -> dict:
|
|
"""Where the archive sits on the host — for the copy-path buttons (REQ-179).
|
|
|
|
VIDEO_ARCHIVE_HOST may stay relative (portable across machines): compose
|
|
injects the host cwd as ARCHIVE_HOST_PWD (compose always has PWD — a
|
|
Windows-side run yields a drive-letter path, handled below), bare-metal
|
|
resolves against the process cwd (start.sh cds to the repo root)."""
|
|
import re
|
|
host = os.environ.get("VIDEO_ARCHIVE_HOST", "")
|
|
if host and not os.path.isabs(host):
|
|
base = os.environ.get("ARCHIVE_HOST_PWD") or os.getcwd()
|
|
host = os.path.abspath(os.path.join(base, host))
|
|
if not host and VIDEO_ROOT != "/videos":
|
|
host = VIDEO_ROOT # bare-metal with no VIDEO_ARCHIVE_HOST at all
|
|
if not host:
|
|
return {"linux": None, "windows": None}
|
|
linux = host.rstrip("/")
|
|
if re.match(r"^[A-Za-z]:[\\/]", linux):
|
|
return {"linux": None, "windows": linux.replace("/", "\\")}
|
|
distro = os.environ.get("WSL_DISTRO_NAME", "")
|
|
windows = f"\\\\wsl.localhost\\{distro}\\" + linux.lstrip("/").replace("/", "\\") if distro else None
|
|
return {"linux": linux, "windows": windows}
|
|
|
|
|
|
# Vite dev server needs cross-origin access; in Docker nginx proxies /api and
|
|
# this is irrelevant.
|
|
CORS_ORIGINS = [
|
|
origin.strip()
|
|
for origin in os.environ.get("CORS_ORIGINS", "http://localhost:5173").split(",")
|
|
if origin.strip()
|
|
]
|
|
|
|
|
|
def ensure_dirs() -> None:
|
|
os.makedirs(PROJECTS_DIR, exist_ok=True)
|
|
|
|
|
|
def project_dir(slug: str) -> str:
|
|
return os.path.join(PROJECTS_DIR, slug)
|