fix path errors

This commit is contained in:
ykcheungab
2026-08-26 19:22:37 +08:00
parent 2cb152b76e
commit d59e1cb7fb
35 changed files with 546 additions and 69 deletions
+30 -9
View File
@@ -646,22 +646,42 @@ class FingerDashboardWindow(QMainWindow):
self._update_play_enabled_for_source()
def _select_config(self) -> None:
from .preferences import (
default_finger_config,
normalize_config_preference,
packaged_finger_bundle_root,
)
start = packaged_finger_bundle_root()
start_dir = str(start) if start is not None else "sensors/finger"
path, _ = QFileDialog.getOpenFileName(
self,
"选择配置文件",
"config",
start_dir,
"JSON (*.json);;所有文件 (*)",
)
if path:
self.settings_panel.set_config_path(path)
self.config.config = path
config = normalize_config_preference(path) or default_finger_config()
self.settings_panel.set_config_path(config)
self.config.config = config
self._save_preferences()
def _select_finger_assets(self) -> None:
from .preferences import (
default_finger_assets_dir,
default_finger_config,
normalize_assets_preference,
normalize_config_preference,
packaged_finger_bundle_root,
)
start = packaged_finger_bundle_root()
path = QFileDialog.getExistingDirectory(
self,
"选择传感器 bundle 目录",
self.settings_panel.sensor_bundle_dir() or "sensors/finger",
str(start) if start is not None else (
self.settings_panel.sensor_bundle_dir() or "sensors/finger"
),
)
if path:
bundle_dir = Path(path)
@@ -677,12 +697,13 @@ class FingerDashboardWindow(QMainWindow):
if isinstance(rel_assets, str) and rel_assets.strip():
assets_dir = bundle_dir / rel_assets
if config_path.is_file():
self.settings_panel.set_config_path(str(config_path))
self.config.config = str(config_path)
self.settings_panel.set_finger_export_dir(str(assets_dir))
self.config.export_dir = str(assets_dir)
config = normalize_config_preference(str(config_path)) or default_finger_config()
self.settings_panel.set_config_path(config)
self.config.config = config
assets = normalize_assets_preference(str(assets_dir)) or default_finger_assets_dir()
self.settings_panel.set_finger_export_dir(assets)
self.config.export_dir = assets
self._save_preferences()
def _select_csv_dir(self) -> None:
path = QFileDialog.getExistingDirectory(
self,
+101 -3
View File
@@ -13,6 +13,17 @@ LEGACY_CAMERA_SELECTION_FILE = "camera_selection.json"
# Keep preference.json at examples/gui/ for backward compatibility.
_GUI_DIR = Path(__file__).resolve().parents[1]
# Old lab / repo-relative paths that predate packaged sensors/<name>/.
_LEGACY_CONFIG_PATHS = {
"dd02",
"dd02-ov",
"config/dd02-ov.json",
"./config/dd02-ov.json",
"config/finger.json",
"./config/finger.json",
"sensors/finger/sensor.json",
}
def preference_path() -> Path:
# Keep preference file at examples/gui/preference.json
@@ -23,6 +34,92 @@ def legacy_camera_selection_path() -> Path:
return resource_path(LEGACY_CAMERA_SELECTION_FILE)
def default_finger_config() -> str:
"""Public product config stem resolved via packaged ``sensors/finger``."""
return "finger"
def default_finger_assets_dir() -> str:
try:
from orisys.finger import DEFAULT_FINGER_EXPORT_DIR
return DEFAULT_FINGER_EXPORT_DIR
except ImportError:
return "sensors/finger/assets/30fps-0703"
def packaged_finger_bundle_root() -> Path | None:
"""Filesystem root of the installed ``sensors/finger`` bundle when present."""
try:
from orisys.configs import resolve_sensor_bundle
except ImportError:
return None
bundle = resolve_sensor_bundle("finger")
return bundle.root if bundle is not None else None
def packaged_finger_assets_root() -> Path | None:
try:
from orisys.configs import resolve_sensor_asset_dir
except ImportError:
return None
return resolve_sensor_asset_dir("finger")
def normalize_config_preference(value: str | None) -> str:
"""Map legacy config paths to the packaged ``finger`` sensor name."""
if value is None or not str(value).strip():
return default_finger_config()
text = str(value).strip().replace("\\", "/")
if text in _LEGACY_CONFIG_PATHS or text.endswith("/dd02-ov.json"):
return default_finger_config()
root = packaged_finger_bundle_root()
if root is not None:
try:
if Path(value).resolve() == (root / "sensor.json").resolve():
return default_finger_config()
except OSError:
pass
return text
def normalize_assets_preference(value: str | None) -> str:
"""Prefer packaged ``sensors/finger/assets/...`` when saved paths are stale."""
default = default_finger_assets_dir()
if value is None or not str(value).strip():
return default
text = str(value).strip()
posix = text.replace("\\", "/")
if posix == default or posix.endswith("/sensors/finger/assets/30fps-0703"):
return default
path = Path(text)
if path.is_dir():
packaged = packaged_finger_assets_root()
if packaged is not None:
try:
if path.resolve() == packaged.resolve():
return default
except OSError:
pass
if "sensors/finger" in posix or path.name == "30fps-0703":
return text if path.is_absolute() else default
return text
return default
def _normalize_preferences(prefs: dict[str, Any]) -> dict[str, Any]:
prefs = dict(prefs)
if "config_path" in prefs or prefs:
prefs["config_path"] = normalize_config_preference(prefs.get("config_path"))
if "finger_assets_dir" in prefs or prefs:
prefs["finger_assets_dir"] = normalize_assets_preference(prefs.get("finger_assets_dir"))
prefs.setdefault("sensor_bundle_dir", "sensors/finger")
return prefs
def _read_json(path: Path) -> dict[str, Any]:
if not path.is_file():
return {}
@@ -34,14 +131,14 @@ def _read_json(path: Path) -> dict[str, Any]:
def load_preferences() -> dict[str, Any]:
"""Load preferences, migrating camera_id from legacy file when needed."""
"""Load preferences, migrating camera_id / legacy config paths when needed."""
prefs = _read_json(preference_path())
if "video_source" not in prefs:
legacy = _read_json(legacy_camera_selection_path())
camera_id = legacy.get("camera_id")
if camera_id is not None and str(camera_id).strip():
prefs["video_source"] = str(camera_id).strip()
return prefs
return _normalize_preferences(prefs)
def save_preferences(prefs: dict[str, Any]) -> None:
@@ -49,9 +146,10 @@ def save_preferences(prefs: dict[str, Any]) -> None:
if not isinstance(prefs, dict):
return
path = preference_path()
normalized = _normalize_preferences(prefs)
try:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(prefs, indent=2) + "\n", encoding="utf-8")
path.write_text(json.dumps(normalized, indent=2) + "\n", encoding="utf-8")
except OSError:
pass
+31 -1
View File
@@ -25,6 +25,23 @@ class SensorBundlePreset:
export_dir: str
def _packaged_finger_preset() -> SensorBundlePreset | None:
"""Use logical names that resolve through the installed wheel sensors/ layout."""
try:
from orisys.configs import resolve_sensor_bundle
except ImportError:
return None
bundle = resolve_sensor_bundle("finger")
if bundle is None:
return None
return SensorBundlePreset(
label="ORY-FINGER",
bundle_dir="sensors/finger",
config="finger",
export_dir=DEFAULT_FINGER_EXPORT_DIR,
)
def _load_manifest(bundle_root: Path) -> dict:
path = bundle_root / "manifest.json"
if not path.is_file():
@@ -50,6 +67,14 @@ def _bundle_from_root(bundle_root: Path, *, label: str | None = None) -> SensorB
break
except ValueError:
continue
# Packaged / checkout sensors/finger: keep resolvable product names, not absolute paths.
if rel_bundle.replace("\\", "/").endswith("sensors/finger") or bundle_root.name == "finger":
return SensorBundlePreset(
label=label or "ORY-FINGER",
bundle_dir="sensors/finger",
config="finger",
export_dir=DEFAULT_FINGER_EXPORT_DIR,
)
return SensorBundlePreset(
label=label or "ORY-FINGER",
bundle_dir=rel_bundle,
@@ -59,6 +84,9 @@ def _bundle_from_root(bundle_root: Path, *, label: str | None = None) -> SensorB
def default_finger_bundle() -> SensorBundlePreset:
packaged = _packaged_finger_preset()
if packaged is not None:
return packaged
for root in _repo_root_candidates():
preset = _bundle_from_root(root / "sensors" / "finger", label="ORY-FINGER")
if preset is not None:
@@ -66,7 +94,7 @@ def default_finger_bundle() -> SensorBundlePreset:
return SensorBundlePreset(
label="ORY-FINGER",
bundle_dir="sensors/finger",
config="sensors/finger/sensor.json",
config="finger",
export_dir=DEFAULT_FINGER_EXPORT_DIR,
)
@@ -108,6 +136,8 @@ def sensor_bundle_preset_index(
for idx, preset in enumerate(presets):
if config == preset.config and export_dir == preset.export_dir:
return idx
if config in ("finger", "dd02", "dd02-ov") and preset.config == "finger":
return idx
if config.endswith("/sensor.json") and export_dir.endswith("/" + Path(preset.export_dir).name):
return idx
return -1
@@ -16,6 +16,7 @@ from PyQt5.QtWidgets import (
)
from viz.render_2d import ArrowBackground
from orisys.finger import DEFAULT_FINGER_EXPORT_DIR
from ..layout import DashboardLayout, LAYOUT
from ..mesh_view_state import MeshViewState
@@ -157,7 +158,7 @@ class SettingsPanelWidget(QWidget):
bundle_row.addWidget(self.btn_browse_finger_assets)
root.addLayout(bundle_row)
self.config_edit = QLineEdit("sensors/finger/sensor.json")
self.config_edit = QLineEdit("finger")
self.config_edit.hide()
self.btn_browse_config = QPushButton("…")
self.btn_browse_config.hide()
@@ -167,10 +168,9 @@ class SettingsPanelWidget(QWidget):
self.cal_edit.setPlaceholderText("Optional calibration path")
self.cal_edit.hide()
self.finger_assets_edit = QLineEdit("sensors/finger/assets/30fps-0703")
self.finger_assets_edit = QLineEdit(DEFAULT_FINGER_EXPORT_DIR)
self.finger_assets_edit.hide()
self._apply_bundle_preset(self._bundle_presets[0])
root.addWidget(self._caption("CSV save directory"))
csv_dir_row = QHBoxLayout()
csv_dir_row.setSpacing(6)