This commit is contained in:
2026-01-18 10:50:42 -08:00
parent 66132811e0
commit 66e6c6eb72
34 changed files with 718 additions and 516 deletions

View File

@@ -19,7 +19,7 @@ from typing import Any, Callable, Dict, Iterable, List, Optional, Sequence, Set
from dataclasses import dataclass, field
from SYS import models
from SYS import pipeline as pipeline_context
from SYS.result_table import ResultTable
from SYS.result_table import Table
from SYS.rich_display import stderr_console as get_stderr_console
from rich.prompt import Confirm
from contextlib import AbstractContextManager, nullcontext
@@ -1722,28 +1722,34 @@ def _print_live_safe_stderr(message: str) -> None:
except Exception:
return
cm = None
cm: AbstractContextManager[Any] | None = None
try:
from SYS import pipeline as _pipeline_ctx # type: ignore
suspend = getattr(_pipeline_ctx, "suspend_live_progress", None)
cm = suspend() if callable(suspend) else None
candidate = suspend() if callable(suspend) else None
if isinstance(candidate, AbstractContextManager):
cm = candidate
elif candidate is not None and hasattr(candidate, "__enter__") and hasattr(candidate, "__exit__"):
cm = candidate # type: ignore[arg-type]
except Exception:
cm = None
try:
from contextlib import nullcontext
except Exception:
nullcontext = None # type: ignore
if cm is None:
cm = nullcontext() if callable(nullcontext) else None
cm = nullcontext()
try:
if cm is not None:
with cm:
stderr_console.print(str(message))
else:
stderr_console.print(str(message))
console = stderr_console()
print_func = getattr(console, "print", None)
except Exception:
return
if not callable(print_func):
return
try:
with cm:
print_func(str(message))
except Exception:
return
@@ -1919,21 +1925,21 @@ def _print_saved_output_panel(item: Any, final_path: Path) -> None:
# If Rich Live progress is active, pause it while printing so the panel
# doesn't get overwritten/truncated by Live's cursor control.
cm: AbstractContextManager[Any] | None = None
try:
from SYS import pipeline as _pipeline_ctx # type: ignore
suspend = getattr(_pipeline_ctx, "suspend_live_progress", None)
cm = suspend() if callable(suspend) else None
cm_candidate = suspend() if callable(suspend) else None
if isinstance(cm_candidate, AbstractContextManager):
cm = cm_candidate
elif cm_candidate is not None and hasattr(cm_candidate, "__enter__") and hasattr(cm_candidate, "__exit__"):
cm = cm_candidate # type: ignore[arg-type]
except Exception:
cm = None
try:
from contextlib import nullcontext
except Exception:
nullcontext = None # type: ignore
if cm is None:
cm = nullcontext() if callable(nullcontext) else None
cm = nullcontext()
try:
location = str(final_path)
@@ -1974,11 +1980,17 @@ def _print_saved_output_panel(item: Any, final_path: Path) -> None:
grid.add_row("Hash", file_hash or "(unknown)")
try:
if cm is not None:
with cm:
stderr_console.print(Panel(grid, title="Saved", expand=False))
else:
stderr_console.print(Panel(grid, title="Saved", expand=False))
console = stderr_console()
print_func = getattr(console, "print", None)
except Exception:
return
if not callable(print_func):
return
try:
with cm:
print_func(Panel(grid, title="Saved", expand=False))
except Exception:
return
@@ -2635,7 +2647,7 @@ def propagate_metadata(
if p_obj.hash and p_obj.hash != "unknown":
prev_by_hash[p_obj.hash] = p_obj
normalized: List[models.PipeObject] = []
normalized: List[Any] = []
# Pre-calculate length matching for heuristic
is_same_length = len(new_items) == len(prev_normalized)
@@ -3688,11 +3700,12 @@ def check_url_exists_in_storage(
if isinstance(response, dict):
raw_hashes = response.get("hashes") or response.get("file_hashes")
raw_ids = response.get("file_ids")
hash_list = raw_hashes if isinstance(raw_hashes, list) else []
has_ids = isinstance(raw_ids, list) and len(raw_ids) > 0
has_hashes = isinstance(raw_hashes, list) and len(raw_hashes) > 0
has_hashes = len(hash_list) > 0
if has_hashes:
try:
found_hash = str(raw_hashes[0]).strip()
found_hash = str(hash_list[0]).strip()
except Exception:
found_hash = None
if has_ids or has_hashes:
@@ -3816,10 +3829,10 @@ def check_url_exists_in_storage(
_mark_preflight_checked()
return True
table = ResultTable(f"URL already exists ({len(matched_urls)} url(s))", max_columns=10)
table.set_no_choice(True)
table = Table(f"URL already exists ({len(matched_urls)} url(s))", max_columns=10)
table._interactive(True)
try:
table.set_preserve_order(True)
table._perseverance(True)
except Exception:
pass

View File

@@ -419,7 +419,7 @@ class Add_File(Cmdlet):
# The user then runs @N (optionally piped), which replays add-file with selected paths.
if dir_scan_mode:
try:
from SYS.result_table import ResultTable
from SYS.result_table import Table
from pathlib import Path as _Path
# Build base args to replay: keep everything except the directory -path.
@@ -437,7 +437,7 @@ class Add_File(Cmdlet):
continue
base_args.append(t)
table = ResultTable(title="Files in Directory", preserve_order=True)
table = Table(title="Files in Directory", preserve_order=True)
table.set_table("add-file.directory")
table.set_source_command("add-file", base_args)
@@ -668,7 +668,7 @@ class Add_File(Cmdlet):
# Legacy search-file refresh is no longer used for final display.
if want_final_search_file and collected_payloads:
try:
from SYS.result_table import ResultTable
from SYS.result_table import Table
from SYS.rich_display import render_item_details_panel
# Stop the live pipeline progress UI before rendering the details panels.
@@ -701,7 +701,7 @@ class Add_File(Cmdlet):
for idx, payload in enumerate(collected_payloads, 1):
render_item_details_panel(payload, title=f"#{idx} Item Details")
table = ResultTable("Result")
table = Table("Result")
for payload in collected_payloads:
table.add_result(payload)
setattr(table, "_rendered_by_cmdlet", True)
@@ -1442,9 +1442,9 @@ class Add_File(Cmdlet):
return
try:
from SYS.result_table import ResultTable
from SYS.result_table import Table
table = ResultTable("Result")
table = Table("Result")
table.add_result(payload)
# Overlay so @1 refers to this add-file result without overwriting search history
ctx.set_last_result_table_overlay(table, [payload], subject=payload)

View File

@@ -1020,12 +1020,12 @@ class Add_Tag(Cmdlet):
if is_last_stage and display_items:
try:
from SYS.rich_display import render_item_details_panel
from SYS.result_table import ResultTable
from SYS.result_table import Table
for idx, item in enumerate(display_items, 1):
render_item_details_panel(item, title=f"#{idx} Item Details")
table = ResultTable("Result")
table = Table("Result")
for item in display_items:
table.add_result(item)
setattr(table, "_rendered_by_cmdlet", True)

View File

@@ -13,7 +13,7 @@ from Store import Store
from . import _shared as sh
from API import HydrusNetwork as hydrus_wrapper
from SYS import pipeline as ctx
from SYS.result_table import ResultTable, _format_size
from SYS.result_table import Table, _format_size
from SYS.rich_display import stdout_console
@@ -581,8 +581,8 @@ class Delete_File(sh.Cmdlet):
deleted_rows.extend(rows)
if deleted_rows:
table = ResultTable("Deleted")
table.set_no_choice(True).set_preserve_order(True)
table = Table("Deleted")
table._interactive(True)._perseverance(True)
for row in deleted_rows:
result_row = table.add_row()
result_row.add_column("Title", row.get("title", ""))

View File

@@ -21,7 +21,7 @@ from API.HTTP import _download_direct_file
from SYS.models import DownloadError, DownloadOptions, DownloadMediaResult
from SYS.logger import log, debug
from SYS.pipeline_progress import PipelineProgress
from SYS.result_table import ResultTable
from SYS.result_table import Table
from SYS.rich_display import stderr_console as get_stderr_console
from SYS import pipeline as pipeline_context
from SYS.utils import sha256_file
@@ -746,12 +746,12 @@ class Download_File(Cmdlet):
try:
from SYS.rich_display import render_item_details_panel
from SYS.result_table import ResultTable
from SYS.result_table import Table
for idx, item in enumerate(emitted_items, 1):
render_item_details_panel(item, title=f"#{idx} Item Details")
table = ResultTable("Result")
table = Table("Result")
for item in emitted_items:
table.add_result(item)
setattr(table, "_rendered_by_cmdlet", True)
@@ -1184,7 +1184,7 @@ class Download_File(Cmdlet):
return f"https://www.youtube.com/watch?v={entry_id.strip()}"
return None
table = ResultTable()
table = Table()
safe_url = str(url or "").strip()
table.title = f'download-file -url "{safe_url}"' if safe_url else "download-file"
if table_type:
@@ -1194,7 +1194,7 @@ class Download_File(Cmdlet):
table.table = table_type
table.set_source_command("download-file", [])
try:
table.set_preserve_order(True)
table._perseverance(True)
except Exception:
pass
@@ -1318,7 +1318,7 @@ class Download_File(Cmdlet):
if remaining_args:
base_cmd += " " + " ".join(remaining_args)
table = ResultTable(title=f"Available formats for {url}", max_columns=10, preserve_order=True)
table = Table(title=f"Available formats for {url}", max_columns=10, preserve_order=True)
table.set_table("ytdlp.formatlist")
table.set_source_command("download-file", [url])
@@ -1601,7 +1601,7 @@ class Download_File(Cmdlet):
if formats:
formats_to_show = formats
table = ResultTable(title=f"Available formats for {url}", max_columns=10, preserve_order=True)
table = Table(title=f"Available formats for {url}", max_columns=10, preserve_order=True)
table.set_table("ytdlp.formatlist")
table.set_source_command("download-file", [url])

View File

@@ -15,7 +15,7 @@ SharedArgs = sh.SharedArgs
parse_cmdlet_args = sh.parse_cmdlet_args
get_field = sh.get_field
from SYS import pipeline as ctx
from SYS.result_table import ResultTable
from SYS.result_table import Table
class Get_Metadata(Cmdlet):
@@ -147,7 +147,7 @@ class Get_Metadata(Cmdlet):
}
@staticmethod
def _add_table_body_row(table: ResultTable, row: Dict[str, Any]) -> None:
def _add_table_body_row(table: Table, row: Dict[str, Any]) -> None:
"""Add a single row to the ResultTable using the prepared columns."""
columns = row.get("columns") if isinstance(row, dict) else None
lookup: Dict[str,
@@ -285,7 +285,7 @@ class Get_Metadata(Cmdlet):
)
table_title = f"get-metadata: {title}" if title else "get-metadata"
table = ResultTable(table_title
table = Table(table_title
).init_command(table_title,
"get-metadata",
list(args))

View File

@@ -7,7 +7,7 @@ import sys
from SYS.logger import log
from SYS import pipeline as ctx
from SYS.result_table import ResultTable
from SYS.result_table import Table
from . import _shared as sh
Cmdlet = sh.Cmdlet
@@ -112,7 +112,7 @@ class Get_Note(Cmdlet):
ItemDetailView("Notes", item_metadata=metadata)
.set_table("note")
.set_value_case("preserve")
.set_preserve_order(True)
._perseverance(True)
)
note_table.set_source_command("get-note", [])

View File

@@ -23,7 +23,7 @@ should_show_help = sh.should_show_help
get_field = sh.get_field
from API.folder import API_folder_store
from SYS.config import get_local_storage_path
from SYS.result_table import ResultTable
from SYS.result_table import Table
from Store import Store
CMDLET = Cmdlet(

View File

@@ -1552,9 +1552,9 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
)
return 0
from SYS.result_table import ResultTable
from SYS.result_table import Table
table = ResultTable(f"Metadata: {provider.name}")
table = Table(f"Metadata: {provider.name}")
table.set_table(f"metadata.{provider.name}")
table.set_source_command("get-tag", [])
selection_payload = []

View File

@@ -18,7 +18,7 @@ Cmdlet, SharedArgs, parse_cmdlet_args, get_field, normalize_hash = (
sh.normalize_hash,
)
from SYS.logger import log
from SYS.result_table import ResultTable
from SYS.result_table import Table
from Store import Store
from SYS import pipeline as ctx
@@ -575,10 +575,10 @@ class Get_Url(Cmdlet):
display_items: List[Dict[str, Any]] = []
table = (
ResultTable(
Table(
"url",
max_columns=5
).set_preserve_order(True).set_table("url").set_value_case("preserve")
)._perseverance(True).set_table("url").set_value_case("preserve")
)
table.set_source_command("get-url", ["-url", search_pattern])
@@ -660,7 +660,7 @@ class Get_Url(Cmdlet):
"Urls",
item_metadata=metadata,
max_columns=1
).set_preserve_order(True).set_table("url").set_value_case("preserve")
)._perseverance(True).set_table("url").set_value_case("preserve")
)
table.set_source_command("get-url", [])

View File

@@ -260,7 +260,7 @@ class search_file(Cmdlet):
try:
results_list: List[Dict[str, Any]] = []
from SYS.result_table import ResultTable
from SYS.result_table import Table
provider_text = str(provider_name or "").strip()
provider_lower = provider_text.lower()
@@ -311,7 +311,7 @@ class search_file(Cmdlet):
# Internet Archive search results are effectively folders (items); selecting @N
# should open a list of downloadable files for the chosen item.
table_type = "internetarchive.folder"
table = ResultTable(table_title).set_preserve_order(preserve_order)
table = Table(table_title)._perseverance(preserve_order)
table.set_table(table_type)
if provider_lower == "alldebrid":
table_meta["view"] = "files" if effective_open_id is not None else "folders"
@@ -654,16 +654,16 @@ class search_file(Cmdlet):
)
results_list = []
from SYS.result_table import ResultTable
from SYS.result_table import Table
table = ResultTable(command_title)
table = Table(command_title)
try:
table.set_source_command("search-file", list(args_list))
except Exception:
pass
if hash_query:
try:
table.set_preserve_order(True)
table._perseverance(True)
except Exception:
pass