huy
This commit is contained in:
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user