This commit is contained in:
2026-03-18 12:24:37 -07:00
parent b0e89ff950
commit 7c526784a8
6 changed files with 729 additions and 245 deletions

View File

@@ -112,10 +112,32 @@ def _start_ready_heartbeat(ipc_path: str, stop_event: threading.Event) -> thread
return thread
def _run_pipeline(pipeline_text: str, *, seeds: Any = None) -> Dict[str, Any]:
def _run_pipeline(
pipeline_text: str,
*,
seeds: Any = None,
json_output: bool = False,
) -> Dict[str, Any]:
# Import after sys.path fix.
from TUI.pipeline_runner import PipelineRunner # noqa: WPS433
def _json_safe(value: Any) -> Any:
if value is None or isinstance(value, (str, int, float, bool)):
return value
if isinstance(value, dict):
out: Dict[str, Any] = {}
for key, item in value.items():
out[str(key)] = _json_safe(item)
return out
if isinstance(value, (list, tuple, set)):
return [_json_safe(item) for item in value]
if hasattr(value, "to_dict") and callable(getattr(value, "to_dict")):
try:
return _json_safe(value.to_dict())
except Exception:
pass
return str(value)
def _table_to_payload(table: Any) -> Optional[Dict[str, Any]]:
if table is None:
return None
@@ -190,12 +212,20 @@ def _run_pipeline(pipeline_text: str, *, seeds: Any = None) -> Dict[str, Any]:
except Exception:
table_payload = None
data_payload = None
if json_output:
try:
data_payload = _json_safe(getattr(result, "emitted", None) or [])
except Exception:
data_payload = []
return {
"success": bool(result.success),
"stdout": result.stdout or "",
"stderr": result.stderr or "",
"error": result.error,
"table": table_payload,
"data": data_payload,
}
@@ -372,6 +402,112 @@ def _run_op(op: str, data: Any) -> Dict[str, Any]:
"choices": [],
}
if op_name in {"url-exists",
"url_exists",
"find-url",
"find_url"}:
try:
from Store import Store # noqa: WPS433
cfg = load_config() or {}
storage = Store(config=cfg, suppress_debug=True)
raw_needles: list[str] = []
if isinstance(data, dict):
maybe_needles = data.get("needles")
if isinstance(maybe_needles, (list, tuple, set)):
for item in maybe_needles:
text = str(item or "").strip()
if text and text not in raw_needles:
raw_needles.append(text)
elif isinstance(maybe_needles, str):
text = maybe_needles.strip()
if text:
raw_needles.append(text)
if not raw_needles:
text = str(data.get("url") or "").strip()
if text:
raw_needles.append(text)
if not raw_needles:
return {
"success": False,
"stdout": "",
"stderr": "",
"error": "Missing url",
"table": None,
"data": [],
}
matches: list[dict[str, Any]] = []
seen_keys: set[str] = set()
for backend_name in storage.list_backends() or []:
try:
backend = storage[backend_name]
except Exception:
continue
search_fn = getattr(backend, "search", None)
if not callable(search_fn):
continue
for needle in raw_needles:
query = f"url:{needle}"
try:
results = backend.search(
query,
limit=1,
minimal=True,
url_only=True,
) or []
except Exception:
continue
for item in results:
if hasattr(item, "to_dict") and callable(getattr(item, "to_dict")):
try:
item = item.to_dict()
except Exception:
item = {"title": str(item)}
elif not isinstance(item, dict):
item = {"title": str(item)}
payload = dict(item)
payload.setdefault("store", str(backend_name))
payload.setdefault("needle", str(needle))
key = str(payload.get("hash") or payload.get("url") or payload.get("title") or needle).strip().lower()
if key in seen_keys:
continue
seen_keys.add(key)
matches.append(payload)
if matches:
break
if matches:
break
return {
"success": True,
"stdout": "",
"stderr": "",
"error": None,
"table": None,
"data": matches,
}
except Exception as exc:
return {
"success": False,
"stdout": "",
"stderr": "",
"error": f"url-exists failed: {type(exc).__name__}: {exc}",
"table": None,
"data": [],
}
# Provide yt-dlp format list for a URL (for MPV "Change format" menu).
# Returns a ResultTable-like payload so the Lua UI can render without running cmdlets.
if op_name in {"ytdlp-formats",
@@ -1084,6 +1220,7 @@ def main(argv: Optional[list[str]] = None) -> int:
data = req.get("data")
pipeline_text = str(req.get("pipeline") or "").strip()
seeds = req.get("seeds")
json_output = bool(req.get("json") or req.get("output_json"))
if not req_id:
continue
@@ -1122,7 +1259,11 @@ def main(argv: Optional[list[str]] = None) -> int:
req_id=req_id,
)
else:
run = _run_pipeline(pipeline_text, seeds=seeds)
run = _run_pipeline(
pipeline_text,
seeds=seeds,
json_output=json_output,
)
resp = {
"id": req_id,
@@ -1133,6 +1274,7 @@ def main(argv: Optional[list[str]] = None) -> int:
""),
"error": run.get("error"),
"table": run.get("table"),
"data": run.get("data"),
}
if "choices" in run:
resp["choices"] = run.get("choices")