This commit is contained in:
2026-05-16 15:03:33 -07:00
parent 717cb13dda
commit 5048729b0c
10 changed files with 1646 additions and 241 deletions
+76 -18
View File
@@ -544,6 +544,81 @@ class ytdlp(TableProviderMixin, Provider):
}
AUTO_STAGE_USE_SELECTION_ARGS = True
@staticmethod
def _playlist_entry_to_url(entry: Any, *, extractor_name: str) -> Optional[str]:
if not isinstance(entry, dict):
return None
for key in ("webpage_url", "original_url", "url"):
value = entry.get(key)
if isinstance(value, str) and value.strip():
cleaned = value.strip()
try:
if urlparse(cleaned).scheme in {"http", "https"}:
return cleaned
except Exception:
return cleaned
entry_id = entry.get("id")
if isinstance(entry_id, str) and entry_id.strip() and "youtube" in extractor_name:
return f"https://www.youtube.com/watch?v={entry_id.strip()}"
return None
def resolve_preflight_items(self, url: str, **kwargs: Any) -> Optional[List[Dict[str, Any]]]:
url_str = str(url or "").strip()
if not url_str or not is_url_supported_by_ytdlp(url_str):
return None
parsed = kwargs.get("parsed") if isinstance(kwargs.get("parsed"), dict) else {}
query_spec = parsed.get("query")
query_keyed = _parse_query_keyed_spec(str(query_spec) if query_spec is not None else None)
playlist_items = str(parsed.get("item")) if parsed.get("item") else None
item_values: List[str] = []
if isinstance(query_keyed, dict):
item_values.extend(query_keyed.get("item", []) or [])
if item_values and not playlist_items:
playlist_items = ",".join([value for value in item_values if value])
ytdlp_tool = YtDlpTool(self.config)
try:
probe = probe_url(
url_str,
no_playlist=False,
playlist_items=playlist_items,
timeout_seconds=15,
cookiefile=_cookiefile_str(ytdlp_tool),
)
except Exception:
probe = None
if not isinstance(probe, dict):
return None
entries = probe.get("entries")
if not isinstance(entries, list) or not entries:
return None
extractor_name = str(probe.get("extractor") or probe.get("extractor_key") or "").strip().lower()
items: List[Dict[str, Any]] = []
for idx, entry in enumerate(entries, 1):
entry_url = self._playlist_entry_to_url(entry, extractor_name=extractor_name)
if not entry_url:
continue
playlist_index = None
if isinstance(entry, dict):
playlist_index = entry.get("playlist_index")
try:
playlist_index_value = int(playlist_index)
except Exception:
playlist_index_value = idx
items.append(
{
"url": entry_url,
"playlist_index": playlist_index_value,
}
)
return items or None
def extract_query_arguments(self, query: str) -> Tuple[str, Dict[str, Any]]:
normalized_query, inline_args = parse_inline_query_arguments(query)
search_parts: List[str] = []
@@ -745,23 +820,6 @@ class ytdlp(TableProviderMixin, Provider):
elif "youtube" in extractor_name:
table_type = "youtube"
def _entry_to_url(entry: Any) -> Optional[str]:
if not isinstance(entry, dict):
return None
for key in ("webpage_url", "original_url", "url"):
value = entry.get(key)
if isinstance(value, str) and value.strip():
cleaned = value.strip()
try:
if urlparse(cleaned).scheme in {"http", "https"}:
return cleaned
except Exception:
return cleaned
entry_id = entry.get("id")
if isinstance(entry_id, str) and entry_id.strip() and "youtube" in extractor_name:
return f"https://www.youtube.com/watch?v={entry_id.strip()}"
return None
table = Table(preserve_order=True)
safe_url = str(url or "").strip()
table.title = f'download-file -url "{safe_url}"' if safe_url else "download-file"
@@ -781,7 +839,7 @@ class ytdlp(TableProviderMixin, Provider):
title = entry.get("title") if isinstance(entry, dict) else None
uploader = entry.get("uploader") if isinstance(entry, dict) else None
duration = entry.get("duration") if isinstance(entry, dict) else None
entry_url = _entry_to_url(entry)
entry_url = self._playlist_entry_to_url(entry, extractor_name=extractor_name)
row = build_table_result_payload(
table="download-file",
title=str(title or f"Item {idx}"),