h
This commit is contained in:
@@ -1033,6 +1033,7 @@ class Add_File(Cmdlet):
|
||||
except Exception as exc:
|
||||
debug(f"[add-file] Failed to retrieve via hash+store: {exc}")
|
||||
|
||||
|
||||
# PRIORITY 2: Try explicit path argument
|
||||
if path_arg:
|
||||
media_path = Path(path_arg)
|
||||
|
||||
@@ -40,6 +40,8 @@ from tool.ytdlp import (
|
||||
_format_chapters_note,
|
||||
_read_text_file,
|
||||
is_url_supported_by_ytdlp,
|
||||
is_browseable_format,
|
||||
format_for_table_selection,
|
||||
list_formats,
|
||||
probe_url,
|
||||
)
|
||||
@@ -1553,22 +1555,8 @@ class Download_File(Cmdlet):
|
||||
return fmts
|
||||
|
||||
def _is_browseable_format(self, fmt: Any) -> bool:
|
||||
if not isinstance(fmt, dict):
|
||||
return False
|
||||
format_id = str(fmt.get("format_id") or "").strip()
|
||||
if not format_id:
|
||||
return False
|
||||
ext = str(fmt.get("ext") or "").strip().lower()
|
||||
if ext in {"mhtml", "json"}:
|
||||
return False
|
||||
note = str(fmt.get("format_note") or "").lower()
|
||||
if "storyboard" in note:
|
||||
return False
|
||||
if format_id.lower().startswith("sb"):
|
||||
return False
|
||||
vcodec = str(fmt.get("vcodec", "none"))
|
||||
acodec = str(fmt.get("acodec", "none"))
|
||||
return not (vcodec == "none" and acodec == "none")
|
||||
"""Check if format is user-browseable. Delegates to ytdlp helper."""
|
||||
return is_browseable_format(fmt)
|
||||
|
||||
def _format_id_for_query_index(
|
||||
self,
|
||||
@@ -2374,6 +2362,9 @@ class Download_File(Cmdlet):
|
||||
table = ResultTable(title=f"Available formats for {url}", max_columns=10, preserve_order=True)
|
||||
table.set_table("ytdlp.formatlist")
|
||||
table.set_source_command("download-file", [url])
|
||||
|
||||
debug(f"[ytdlp.formatlist] Displaying format selection table for {url}")
|
||||
debug(f"[ytdlp.formatlist] Provider: ytdlp (routing to download-file via TABLE_AUTO_STAGES)")
|
||||
|
||||
results_list: List[Dict[str, Any]] = []
|
||||
for idx, fmt in enumerate(filtered_formats, 1):
|
||||
@@ -2392,65 +2383,28 @@ class Download_File(Cmdlet):
|
||||
except Exception:
|
||||
selection_format_id = format_id
|
||||
|
||||
size_str = ""
|
||||
size_prefix = ""
|
||||
size_bytes = filesize
|
||||
if not size_bytes:
|
||||
size_bytes = filesize_approx
|
||||
if size_bytes:
|
||||
size_prefix = "~"
|
||||
try:
|
||||
if isinstance(size_bytes, (int, float)) and size_bytes > 0:
|
||||
size_mb = float(size_bytes) / (1024 * 1024)
|
||||
size_str = f"{size_prefix}{size_mb:.1f}MB"
|
||||
except Exception:
|
||||
size_str = ""
|
||||
|
||||
desc_parts: List[str] = []
|
||||
if resolution and resolution != "audio only":
|
||||
desc_parts.append(resolution)
|
||||
if ext:
|
||||
desc_parts.append(str(ext).upper())
|
||||
if vcodec != "none":
|
||||
desc_parts.append(f"v:{vcodec}")
|
||||
if acodec != "none":
|
||||
desc_parts.append(f"a:{acodec}")
|
||||
if size_str:
|
||||
desc_parts.append(size_str)
|
||||
format_desc = " | ".join(desc_parts)
|
||||
|
||||
format_dict = {
|
||||
"table": "download-file",
|
||||
"title": f"Format {format_id}",
|
||||
"url": url,
|
||||
"target": url,
|
||||
"detail": format_desc,
|
||||
"annotations": [ext, resolution] if resolution else [ext],
|
||||
"media_kind": "format",
|
||||
"cmd": base_cmd,
|
||||
"columns": [
|
||||
("ID", format_id),
|
||||
("Resolution", resolution or "N/A"),
|
||||
("Ext", ext),
|
||||
("Size", size_str or ""),
|
||||
("Video", vcodec),
|
||||
("Audio", acodec),
|
||||
],
|
||||
"full_metadata": {
|
||||
"format_id": format_id,
|
||||
"url": url,
|
||||
"item_selector": selection_format_id,
|
||||
},
|
||||
"_selection_args": None,
|
||||
}
|
||||
|
||||
selection_args: List[str] = ["-format", selection_format_id]
|
||||
# Use ytdlp helper to format for table
|
||||
format_dict = format_for_table_selection(
|
||||
fmt,
|
||||
url,
|
||||
idx,
|
||||
selection_format_id=selection_format_id,
|
||||
)
|
||||
|
||||
# Add base command for display
|
||||
format_dict["cmd"] = base_cmd
|
||||
|
||||
# Append clip values to selection args if needed
|
||||
selection_args: List[str] = format_dict["_selection_args"].copy()
|
||||
try:
|
||||
if (not clip_spec) and clip_values:
|
||||
selection_args.extend(["-query", f"clip:{','.join([v for v in clip_values if v])}"])
|
||||
except Exception:
|
||||
pass
|
||||
format_dict["_selection_args"] = selection_args
|
||||
|
||||
# Also update in full_metadata for provider registration
|
||||
format_dict["full_metadata"]["_selection_args"] = selection_args
|
||||
|
||||
results_list.append(format_dict)
|
||||
table.add_result(format_dict)
|
||||
@@ -2470,6 +2424,9 @@ class Download_File(Cmdlet):
|
||||
setattr(table, "_rendered_by_cmdlet", True)
|
||||
pipeline_context.set_current_stage_table(table)
|
||||
pipeline_context.set_last_result_table(table, results_list)
|
||||
|
||||
debug(f"[ytdlp.formatlist] Format table registered with {len(results_list)} formats")
|
||||
debug(f"[ytdlp.formatlist] When user selects @N, will invoke: download-file {url} -format <format_id>")
|
||||
|
||||
log(f"", file=sys.stderr)
|
||||
return 0
|
||||
@@ -3675,6 +3632,27 @@ class Download_File(Cmdlet):
|
||||
raw_url = self._normalize_urls(parsed)
|
||||
piped_items = self._collect_piped_items_if_no_urls(result, raw_url)
|
||||
|
||||
# Handle TABLE_AUTO_STAGES routing: if a piped PipeObject has _selection_args,
|
||||
# re-invoke download-file with those args instead of processing the PipeObject itself
|
||||
if piped_items and not raw_url:
|
||||
for item in piped_items:
|
||||
try:
|
||||
if hasattr(item, 'metadata') and isinstance(item.metadata, dict):
|
||||
selection_args = item.metadata.get('_selection_args')
|
||||
if selection_args and isinstance(selection_args, (list, tuple)):
|
||||
# Found selection args - extract URL and re-invoke with format args
|
||||
item_url = getattr(item, 'url', None) or item.metadata.get('url')
|
||||
if item_url:
|
||||
debug(f"[ytdlp] Detected selection args from table selection: {selection_args}")
|
||||
# Reconstruct args: URL + selection args
|
||||
new_args = [str(item_url)] + [str(arg) for arg in selection_args]
|
||||
debug(f"[ytdlp] Re-invoking download-file with: {new_args}")
|
||||
# Recursively call _run_impl with the new args
|
||||
return self._run_impl(None, new_args, config)
|
||||
except Exception as e:
|
||||
debug(f"[ytdlp] Error handling selection args: {e}")
|
||||
pass
|
||||
|
||||
had_piped_input = False
|
||||
try:
|
||||
if isinstance(result, list):
|
||||
@@ -3962,13 +3940,21 @@ class Download_File(Cmdlet):
|
||||
log(f"Invalid storage location: {e}", file=sys.stderr)
|
||||
return None
|
||||
|
||||
# Priority 2: Config default output/temp directory
|
||||
# Priority 2: Config default output/temp directory, then OS temp
|
||||
try:
|
||||
from SYS.config import resolve_output_dir
|
||||
|
||||
final_output_dir = resolve_output_dir(config)
|
||||
except Exception:
|
||||
final_output_dir = Path.home() / "Downloads"
|
||||
final_output_dir = None
|
||||
|
||||
# If config resolution failed, use OS temp directory
|
||||
if not final_output_dir:
|
||||
try:
|
||||
import tempfile
|
||||
final_output_dir = Path(tempfile.gettempdir()) / "Medios-Macina"
|
||||
except Exception:
|
||||
final_output_dir = Path.home() / ".Medios-Macina-temp"
|
||||
|
||||
debug(f"Using default directory: {final_output_dir}")
|
||||
|
||||
|
||||
@@ -556,6 +556,33 @@ class search_file(Cmdlet):
|
||||
library_root = get_local_storage_path(config or {})
|
||||
if not library_root:
|
||||
log("No library root configured", file=sys.stderr)
|
||||
log("", file=sys.stderr)
|
||||
|
||||
# Show config panel for FolderStore
|
||||
try:
|
||||
from SYS.rich_display import show_store_config_panel
|
||||
show_store_config_panel("folder", ["NAME", "PATH"])
|
||||
log("", file=sys.stderr)
|
||||
except Exception:
|
||||
log("Example config for FolderStore:", file=sys.stderr)
|
||||
log("[store=folder]", file=sys.stderr)
|
||||
log('NAME="default"', file=sys.stderr)
|
||||
log('PATH="/path/to/library"', file=sys.stderr)
|
||||
log("", file=sys.stderr)
|
||||
|
||||
# Show config panel for HydrusNetworkStore
|
||||
try:
|
||||
from SYS.rich_display import show_store_config_panel
|
||||
show_store_config_panel("hydrusnetwork", ["NAME", "API", "URL"])
|
||||
log("", file=sys.stderr)
|
||||
except Exception:
|
||||
log("Example config for HydrusNetworkStore:", file=sys.stderr)
|
||||
log("[store=hydrusnetwork]", file=sys.stderr)
|
||||
log('NAME="default"', file=sys.stderr)
|
||||
log('API="your-api-key"', file=sys.stderr)
|
||||
log('URL="http://localhost:45869"', file=sys.stderr)
|
||||
log("", file=sys.stderr)
|
||||
|
||||
return 1
|
||||
|
||||
# Use context manager to ensure database is always closed
|
||||
|
||||
Reference in New Issue
Block a user