feat(factory): add local flashing toolkit and secure OTA defaults
This commit is contained in:
74
tools/esptool-factory/factory_gui/path_utils.py
Normal file
74
tools/esptool-factory/factory_gui/path_utils.py
Normal file
@@ -0,0 +1,74 @@
|
||||
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
|
||||
Reference in New Issue
Block a user