f
This commit is contained in:
16
CLI.py
16
CLI.py
@@ -1194,17 +1194,26 @@ class CmdletExecutor:
|
||||
"get_relationship",
|
||||
"get-file",
|
||||
"get_file",
|
||||
"get-metadata",
|
||||
"get_metadata",
|
||||
}
|
||||
self_managing_commands = {
|
||||
"get-tag",
|
||||
"get_tag",
|
||||
"tags",
|
||||
"get-metadata",
|
||||
"get_metadata",
|
||||
"search-file",
|
||||
"search_file",
|
||||
}
|
||||
|
||||
if cmd_name in self_managing_commands:
|
||||
table = ctx.get_last_result_table()
|
||||
table = (
|
||||
ctx.get_display_table()
|
||||
if hasattr(ctx, "get_display_table") else None
|
||||
)
|
||||
if table is None:
|
||||
table = ctx.get_last_result_table()
|
||||
if table is None:
|
||||
table = Table(table_title)
|
||||
for emitted in emits:
|
||||
@@ -1249,8 +1258,9 @@ class CmdletExecutor:
|
||||
progress_ui = None
|
||||
pipe_idx = None
|
||||
|
||||
stdout_console().print()
|
||||
stdout_console().print(table)
|
||||
if not getattr(table, "_rendered_by_cmdlet", False):
|
||||
stdout_console().print()
|
||||
stdout_console().print(table)
|
||||
|
||||
# If the cmdlet produced a current-stage table without emits (e.g. format selection),
|
||||
# render it here for parity with REPL pipeline runner.
|
||||
|
||||
@@ -3520,32 +3520,6 @@ def check_url_exists_in_storage(
|
||||
continue
|
||||
|
||||
if not backend_hits:
|
||||
fallback_hits: List[Dict[str, Any]] = []
|
||||
try:
|
||||
fallback_hits = backend.search("url:*", limit=200) or []
|
||||
except Exception:
|
||||
fallback_hits = []
|
||||
|
||||
for hit in fallback_hits:
|
||||
url_values = _extract_urls_from_hit(hit, backend, allow_backend_lookup=True)
|
||||
|
||||
if not url_values:
|
||||
continue
|
||||
|
||||
matched = False
|
||||
for url_value in url_values:
|
||||
for needle in (needles or []):
|
||||
if _match_normalized_url(str(needle or ""), str(url_value or "")):
|
||||
matched = True
|
||||
break
|
||||
if matched:
|
||||
break
|
||||
|
||||
if not matched:
|
||||
continue
|
||||
|
||||
return _build_display_row_for_hit(hit, backend_name, original_url)
|
||||
|
||||
return None
|
||||
|
||||
hit = backend_hits[0]
|
||||
|
||||
@@ -1019,7 +1019,8 @@ class Download_File(Cmdlet):
|
||||
return None
|
||||
|
||||
try:
|
||||
idx = int(str(query_format).lstrip("#").strip())
|
||||
s_val = str(query_format).strip()
|
||||
idx = int(s_val.lstrip("#"))
|
||||
except Exception:
|
||||
raise ValueError(f"Invalid format index: {query_format}")
|
||||
|
||||
@@ -1032,6 +1033,12 @@ class Download_File(Cmdlet):
|
||||
if not fmts:
|
||||
raise ValueError("Unable to list formats for the URL; cannot resolve numeric format index")
|
||||
|
||||
# Prioritize exact format_id match if it's a numeric string that happens to be an ID
|
||||
# (e.g. YouTube's 251 for opus).
|
||||
if s_val and not s_val.startswith("#"):
|
||||
if any(str(f.get("format_id", "")) == s_val for f in fmts):
|
||||
return s_val
|
||||
|
||||
candidate_formats = [f for f in fmts if self._is_browseable_format(f)]
|
||||
filtered_formats = candidate_formats if candidate_formats else list(fmts)
|
||||
|
||||
@@ -1461,13 +1468,15 @@ class Download_File(Cmdlet):
|
||||
|
||||
for url in supported_url:
|
||||
try:
|
||||
debug(f"[download-file] Processing URL in loop (1/3 stage 1): {url}")
|
||||
debug(f"[download-file] Processing URL in loop: {url}")
|
||||
|
||||
canonical_url = self._canonicalize_url_for_storage(
|
||||
requested_url=url,
|
||||
ytdlp_tool=ytdlp_tool,
|
||||
playlist_items=playlist_items,
|
||||
)
|
||||
canonical_url = url
|
||||
if not skip_per_url_preflight or clip_ranges:
|
||||
canonical_url = self._canonicalize_url_for_storage(
|
||||
requested_url=url,
|
||||
ytdlp_tool=ytdlp_tool,
|
||||
playlist_items=playlist_items,
|
||||
)
|
||||
|
||||
if not skip_per_url_preflight:
|
||||
debug(f"[download-file] Running duplicate preflight for: {canonical_url}")
|
||||
@@ -1963,52 +1972,27 @@ class Download_File(Cmdlet):
|
||||
ytdl_format = query_format
|
||||
playlist_selection_handled = False
|
||||
|
||||
if len(supported_url) == 1 and not playlist_items and not ytdl_format:
|
||||
if len(supported_url) == 1 and not playlist_items:
|
||||
candidate_url = supported_url[0]
|
||||
|
||||
if query_format and not query_wants_audio:
|
||||
# If query_format is provided and numeric, resolve it now.
|
||||
if query_format and not query_wants_audio and not ytdl_format:
|
||||
try:
|
||||
debug(f"[download-file] Resolving numeric format for {candidate_url}...")
|
||||
debug(f"[download-file] Resolving format for {candidate_url} (query='{query_format}')...")
|
||||
idx_fmt = self._format_id_for_query_index(query_format, candidate_url, formats_cache, ytdlp_tool)
|
||||
if idx_fmt:
|
||||
debug(f"Resolved format selection '{query_format}' -> {idx_fmt}")
|
||||
ytdl_format = idx_fmt
|
||||
except ValueError as e:
|
||||
log(f"Error parsing format selection: {e}", file=sys.stderr)
|
||||
return 1
|
||||
if idx_fmt:
|
||||
debug(f"Resolved numeric format selection '{query_format}' -> {idx_fmt}")
|
||||
ytdl_format = idx_fmt
|
||||
# Fallback: Treat as literal format if resolution fails or it's not a valid row index.
|
||||
debug(f"Format resolution for '{query_format}' failed ({e}); treating as literal.")
|
||||
ytdl_format = query_format
|
||||
|
||||
if not ytdl_format:
|
||||
debug(f"[download-file] Checking for playlist at {candidate_url}...")
|
||||
if self._maybe_show_playlist_table(url=candidate_url, ytdlp_tool=ytdlp_tool):
|
||||
playlist_selection_handled = True
|
||||
try:
|
||||
last_table = pipeline_context.get_last_result_table() if hasattr(pipeline_context, "get_last_result_table") else None
|
||||
if hasattr(last_table, "rows") and getattr(last_table, "rows", None):
|
||||
sample_index = 1
|
||||
sample_fmt_id = None
|
||||
try:
|
||||
sample_row = last_table.rows[0]
|
||||
sample_fmt_id = sample_row._full_metadata.get("item_selector") if getattr(sample_row, "_full_metadata", None) else None
|
||||
except Exception:
|
||||
sample_fmt_id = None
|
||||
|
||||
try:
|
||||
sample_pipeline = f'download-file "{candidate_url}"'
|
||||
hint = (
|
||||
"To select non-interactively, re-run with an explicit format: "
|
||||
"e.g. mm \"{pipeline} -query 'format:{fmt}' | add-file -store <store>\" or "
|
||||
"mm \"{pipeline} -query 'format:{index}' | add-file -store <store>\""
|
||||
).format(
|
||||
pipeline=sample_pipeline,
|
||||
fmt=sample_fmt_id or "<format_id>",
|
||||
index=sample_index,
|
||||
)
|
||||
log(hint, file=sys.stderr)
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# ... (existing logging code) ...
|
||||
return 0
|
||||
|
||||
skip_per_url_preflight = False
|
||||
|
||||
@@ -1829,9 +1829,7 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
payload["service_name"] = service_name_override
|
||||
return payload
|
||||
|
||||
raw_result_tags = get_field(result, "tag", None)
|
||||
if not isinstance(raw_result_tags, list):
|
||||
raw_result_tags = get_field(result, "tags", None)
|
||||
raw_result_tags = _resolve_subject_value("tag", "tags")
|
||||
display_tags: List[str] = []
|
||||
if isinstance(raw_result_tags, list):
|
||||
display_tags = [str(t) for t in raw_result_tags if t is not None]
|
||||
|
||||
Reference in New Issue
Block a user