You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

40 lines
2.9 KiB

"""Validation and override conversion for GUI experiment fields."""
from __future__ import annotations
from pathlib import Path
from typing import Any
from .gui_models import GuiExperimentRequest, GuiValidationResult
def validate_experiment_request(request: GuiExperimentRequest) -> GuiValidationResult:
errors: list[str] = []; warnings: list[str] = []
if request.input_type not in {"camera", "video"}: errors.append("Input type must be camera or video")
if request.camera_index < 0: errors.append("Camera index must be zero or greater")
if request.input_type == "video" and (not request.video_path or not Path(request.video_path).is_file()): errors.append("Select an existing video file")
if request.voice_mode not in {"prompt", "control", "disabled"}: errors.append("Voice mode is invalid")
if not 0.0 <= request.voice_volume <= 1.0: errors.append("Volume must be between 0.0 and 1.0")
if request.face_every is not None and request.face_every < 1: errors.append("Face interval must be at least 1")
if request.max_face_persons is not None and request.max_face_persons < 1: errors.append("Maximum face persons must be at least 1")
if request.signage_yaw_direction not in {None, "positive", "negative"}: errors.append("Signage yaw direction is invalid")
if request.voice_mode == "prompt" and (not request.audio_file or not Path(request.audio_file).is_file()): warnings.append("Prompt mode has no existing audio file")
if not Path(request.config_path).is_file(): errors.append("Configuration file does not exist")
return GuiValidationResult(tuple(errors), tuple(warnings))
def experiment_overrides(request: GuiExperimentRequest) -> dict[str, Any]:
values: dict[str, Any] = {
"input": {"type": request.input_type, "camera_id": request.camera_index,
"video_path": request.video_path if request.input_type == "video" else None},
"display": {"enabled": request.show_opencv_window},
"voice_prompt": {"enabled": request.voice_mode != "disabled", "mode": request.voice_mode},
"audio": {"volume": request.voice_volume},
"unified_logging": {"enabled": request.enable_unified_logging,
"camera_position_note": request.camera_position_note},
}
if request.audio_file: values["audio"]["file_path"] = request.audio_file
if request.face_every is not None: values.setdefault("face", {})["process_every_n_frames"] = request.face_every
if request.max_face_persons is not None: values.setdefault("face", {})["max_persons_per_frame"] = request.max_face_persons
if request.signage_yaw_direction: values.setdefault("turn_detection", {})["signage_yaw_direction"] = request.signage_yaw_direction
return values
class ConfigPanelLogic:
"""Compatibility facade used by tests and a future richer config editor."""
validate = staticmethod(validate_experiment_request)
to_overrides = staticmethod(experiment_overrides)