Files
AI_Printer/tools/esptool-factory/factory_gui/path_utils.py

75 lines
2.1 KiB
Python

from __future__ import annotations
import os
import sys
from pathlib import Path
from typing import Optional
def is_frozen() -> bool:
return getattr(sys, "frozen", False)
def _find_app_bundle_root(exe_path: Path) -> Optional[Path]:
for parent in exe_path.parents:
if parent.suffix.lower() == ".app":
return parent
return None
def _pick_runtime_root(exe_path: Path) -> Path:
candidates: list[Path] = []
app_root = _find_app_bundle_root(exe_path)
if app_root is not None:
candidates.append(app_root.parent)
candidates.append(exe_path.parent)
for candidate in candidates:
if (candidate / "conf" / "factory_private.json.enc").exists():
return candidate
if (candidate / "conf").exists() or (candidate / "bin").exists() or (candidate / "keys").exists():
return candidate
return exe_path.parent
def venv_python(base_dir: Path) -> Path:
scripts = "Scripts" if os.name == "nt" else "bin"
exe = "python.exe" if os.name == "nt" else "python3"
return base_dir / ".venv" / scripts / exe
def resolve_python(base_dir: Path) -> Path:
venv_py = venv_python(base_dir)
if venv_py.exists():
return venv_py
raise FileNotFoundError(
"未找到当前目录的虚拟环境:\n"
f"{venv_py}\n"
"请先创建并安装依赖:\n"
f" python3 -m venv {base_dir / '.venv'}\n"
f" {venv_py} -m pip install -r {base_dir / 'requirements.txt'}"
)
def get_base_dir() -> Path:
if is_frozen():
return _pick_runtime_root(Path(sys.executable).resolve())
return Path(__file__).resolve().parent.parent
def resolve_bin_dir(base_dir: Path, configured: Path) -> Path:
if configured.is_absolute():
return configured
return base_dir / configured
def select_bin_dir(base_dir: Path, configured: Path) -> Path:
return resolve_bin_dir(base_dir, configured)
def _display_path(base_dir: Path, path: Path) -> str:
try:
rel = path.relative_to(base_dir)
return str(rel)
except ValueError:
return path.name