hkh
This commit is contained in:
136
CLI.py
136
CLI.py
@@ -115,7 +115,13 @@ from SYS.cli_parsing import SelectionSyntax, SelectionFilterSyntax, MedeiaLexer
|
||||
|
||||
|
||||
|
||||
def _send_mpv_ipc_command(command: List[Any], *, ipc_path: Optional[str] = None, timeout: float = 0.75) -> bool:
|
||||
def _send_mpv_ipc_command(
|
||||
command: List[Any],
|
||||
*,
|
||||
ipc_path: Optional[str] = None,
|
||||
timeout: float = 0.75,
|
||||
wait_for_response: bool = True,
|
||||
) -> bool:
|
||||
if not isinstance(command, list) or not command:
|
||||
return False
|
||||
|
||||
@@ -130,13 +136,16 @@ def _send_mpv_ipc_command(command: List[Any], *, ipc_path: Optional[str] = None,
|
||||
try:
|
||||
response = client.send_command({
|
||||
"command": command,
|
||||
})
|
||||
}, wait=bool(wait_for_response))
|
||||
finally:
|
||||
try:
|
||||
client.disconnect()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if not wait_for_response:
|
||||
return bool(response and (response.get("async") or response.get("request_id") is not None))
|
||||
|
||||
return bool(response and response.get("error") == "success")
|
||||
except Exception as exc:
|
||||
debug(f"mpv ipc command failed: {exc}")
|
||||
@@ -155,10 +164,11 @@ def _notify_mpv_osd(text: str, *, duration_ms: int = 3500, ipc_path: Optional[st
|
||||
max(0, int(duration_ms)),
|
||||
],
|
||||
ipc_path=ipc_path,
|
||||
wait_for_response=False,
|
||||
)
|
||||
|
||||
|
||||
def _notify_mpv_callback(metadata: Dict[str, Any], execution_result: Dict[str, Any]) -> bool:
|
||||
def _send_mpv_callback_event(metadata: Dict[str, Any], payload: Dict[str, Any]) -> bool:
|
||||
callback = metadata.get("mpv_callback") if isinstance(metadata, dict) else None
|
||||
if not isinstance(callback, dict):
|
||||
return False
|
||||
@@ -169,26 +179,102 @@ def _notify_mpv_callback(metadata: Dict[str, Any], execution_result: Dict[str, A
|
||||
if not script_name or not message_name:
|
||||
return False
|
||||
|
||||
payload = {
|
||||
"phase": "completed",
|
||||
"success": bool(execution_result.get("success")),
|
||||
"status": str(execution_result.get("status") or "completed"),
|
||||
"error": str(execution_result.get("error") or "").strip(),
|
||||
"command_text": str(execution_result.get("command_text") or "").strip(),
|
||||
event_payload = {
|
||||
"kind": str(metadata.get("kind") or "").strip(),
|
||||
}
|
||||
if isinstance(payload, dict):
|
||||
event_payload.update(payload)
|
||||
|
||||
return _send_mpv_ipc_command(
|
||||
[
|
||||
"script-message-to",
|
||||
script_name,
|
||||
message_name,
|
||||
json.dumps(payload, ensure_ascii=False),
|
||||
json.dumps(event_payload, ensure_ascii=False),
|
||||
],
|
||||
ipc_path=ipc_path,
|
||||
wait_for_response=False,
|
||||
)
|
||||
|
||||
|
||||
def _notify_mpv_callback(metadata: Dict[str, Any], execution_result: Dict[str, Any]) -> bool:
|
||||
return _send_mpv_callback_event(
|
||||
metadata,
|
||||
{
|
||||
"phase": "completed",
|
||||
"success": bool(execution_result.get("success")),
|
||||
"status": str(execution_result.get("status") or "completed"),
|
||||
"error": str(execution_result.get("error") or "").strip(),
|
||||
"command_text": str(execution_result.get("command_text") or "").strip(),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def _build_mpv_progress_callback(metadata: Dict[str, Any]) -> Optional[Any]:
|
||||
callback = metadata.get("mpv_callback") if isinstance(metadata, dict) else None
|
||||
if not isinstance(callback, dict):
|
||||
return None
|
||||
|
||||
last_sent_at: Dict[str, float] = {}
|
||||
last_percent: Dict[str, int] = {}
|
||||
last_text: Dict[str, str] = {}
|
||||
|
||||
def emit(payload: Dict[str, Any]) -> bool:
|
||||
if not isinstance(payload, dict):
|
||||
return False
|
||||
|
||||
event_name = str(payload.get("event") or "").strip().lower()
|
||||
now = time.monotonic()
|
||||
throttle_key = event_name or "progress"
|
||||
|
||||
if event_name == "pipe-percent":
|
||||
pipe_index = int(payload.get("pipe_index") or 0)
|
||||
percent = max(0, min(100, int(payload.get("percent") or 0)))
|
||||
throttle_key = f"pipe-percent:{pipe_index}"
|
||||
prev = last_percent.get(throttle_key)
|
||||
if prev == percent:
|
||||
return False
|
||||
if prev is not None and percent < 100 and (percent - prev) < 5 and (now - last_sent_at.get(throttle_key, 0.0)) < 0.35:
|
||||
return False
|
||||
last_percent[throttle_key] = percent
|
||||
payload = dict(payload)
|
||||
payload["percent"] = percent
|
||||
elif event_name == "transfer":
|
||||
label = str(payload.get("label") or "transfer").strip() or "transfer"
|
||||
throttle_key = f"transfer:{label}"
|
||||
completed = payload.get("completed")
|
||||
total = payload.get("total")
|
||||
percent = None
|
||||
try:
|
||||
if total is not None and int(total) > 0 and completed is not None:
|
||||
percent = max(0, min(100, int(round((int(completed) / max(1, int(total))) * 100.0))))
|
||||
except Exception:
|
||||
percent = None
|
||||
if percent is not None:
|
||||
prev = last_percent.get(throttle_key)
|
||||
if prev == percent:
|
||||
return False
|
||||
if prev is not None and percent < 100 and (percent - prev) < 3 and (now - last_sent_at.get(throttle_key, 0.0)) < 0.35:
|
||||
return False
|
||||
last_percent[throttle_key] = percent
|
||||
payload = dict(payload)
|
||||
payload["percent"] = percent
|
||||
elif event_name == "status":
|
||||
pipe_index = int(payload.get("pipe_index") or 0)
|
||||
throttle_key = f"status:{pipe_index}"
|
||||
text = str(payload.get("text") or "").strip()
|
||||
if last_text.get(throttle_key) == text and (now - last_sent_at.get(throttle_key, 0.0)) < 0.5:
|
||||
return False
|
||||
last_text[throttle_key] = text
|
||||
|
||||
last_sent_at[throttle_key] = now
|
||||
event_payload = dict(payload)
|
||||
event_payload.setdefault("phase", "progress")
|
||||
return _send_mpv_callback_event(metadata, event_payload)
|
||||
|
||||
return emit
|
||||
|
||||
|
||||
def _notify_mpv_completion(metadata: Dict[str, Any], execution_result: Dict[str, Any]) -> bool:
|
||||
callback_sent = _notify_mpv_callback(metadata, execution_result)
|
||||
|
||||
@@ -1024,6 +1110,15 @@ class CmdletExecutor:
|
||||
ctx.set_live_progress(progress_ui)
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
progress_cb = (
|
||||
ctx.get_progress_event_callback()
|
||||
if hasattr(ctx, "get_progress_event_callback") else None
|
||||
)
|
||||
if callable(progress_cb) and hasattr(progress_ui, "set_event_callback"):
|
||||
progress_ui.set_event_callback(progress_cb)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
pipe_idx = 0
|
||||
|
||||
@@ -2418,14 +2513,30 @@ Come to love it when others take what you share, as there is no greater joy
|
||||
if isinstance(queued_payload, dict) and isinstance(queued_payload.get("metadata"), dict)
|
||||
else None
|
||||
)
|
||||
progress_event_callback = _build_mpv_progress_callback(queued_metadata) if queued_metadata else None
|
||||
try:
|
||||
from SYS import pipeline as ctx
|
||||
|
||||
ctx.set_current_command_text(user_input)
|
||||
if hasattr(ctx, "set_progress_event_callback"):
|
||||
ctx.set_progress_event_callback(progress_event_callback)
|
||||
pipeline_ctx_ref = ctx
|
||||
except Exception:
|
||||
pipeline_ctx_ref = None
|
||||
|
||||
if queued_metadata:
|
||||
try:
|
||||
_send_mpv_callback_event(
|
||||
queued_metadata,
|
||||
{
|
||||
"phase": "started",
|
||||
"event": "command-started",
|
||||
"command_text": user_input,
|
||||
},
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
execution_result: Dict[str, Any] = {
|
||||
"status": "completed",
|
||||
"success": True,
|
||||
@@ -2627,6 +2738,11 @@ Come to love it when others take what you share, as there is no greater joy
|
||||
pass
|
||||
if pipeline_ctx_ref:
|
||||
pipeline_ctx_ref.clear_current_command_text()
|
||||
if hasattr(pipeline_ctx_ref, "set_progress_event_callback"):
|
||||
try:
|
||||
pipeline_ctx_ref.set_progress_event_callback(None)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
repl_queue_stop.set()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user