This commit is contained in:
2025-12-31 05:17:37 -08:00
parent 3bbaa28fb4
commit e8842ceded
10 changed files with 1255 additions and 29 deletions

101
CLI.py
View File

@@ -2556,8 +2556,11 @@ class PipelineExecutor:
# Auto-insert downloader stages for provider tables.
try:
current_table = ctx.get_current_stage_table(
) or ctx.get_last_result_table()
current_table = ctx.get_current_stage_table()
if current_table is None and hasattr(ctx, "get_display_table"):
current_table = ctx.get_display_table()
if current_table is None:
current_table = ctx.get_last_result_table()
except Exception:
current_table = None
table_type = (
@@ -2584,6 +2587,9 @@ class PipelineExecutor:
"libgen"}:
print("Auto-piping selection to download-file")
stages.append(["download-file"])
elif isinstance(table_type, str) and table_type.startswith("metadata."):
print("Auto-applying metadata selection via get-tag")
stages.append(["get-tag"])
else:
first_cmd = stages[0][0] if stages and stages[0] else None
if table_type == "soulseek" and first_cmd not in (
@@ -2636,6 +2642,13 @@ class PipelineExecutor:
):
print("Auto-inserting download-file after Libgen selection")
stages.insert(0, ["download-file"])
if isinstance(table_type, str) and table_type.startswith("metadata.") and first_cmd not in (
"get-tag",
"get_tag",
".pipe",
):
print("Auto-inserting get-tag after metadata selection")
stages.insert(0, ["get-tag"])
return True, piped_result
else:
@@ -3691,6 +3704,90 @@ class PipelineExecutor:
pass
if not stages and piped_result is not None:
# Special-case: selecting metadata rows (e.g., get-tag -scrape) should
# immediately apply tags to the target item instead of just echoing a
# selection table.
try:
items = piped_result if isinstance(piped_result, list) else [piped_result]
applied_any = False
from cmdlet._shared import normalize_hash # type: ignore
from cmdlet.get_tag import _filter_scraped_tags, _emit_tags_as_table # type: ignore
from Store import Store # type: ignore
cfg_loader = ConfigLoader(root=Path.cwd())
config = cfg_loader.load()
for item in items:
if not isinstance(item, dict):
continue
provider = item.get("provider")
tags = item.get("tag")
if not provider or not isinstance(tags, list) or not tags:
continue
file_hash = normalize_hash(
item.get("hash")
or item.get("hash_hex")
or item.get("file_hash")
or item.get("sha256")
)
store_name = item.get("store") or item.get("storage")
subject_path = (
item.get("path")
or item.get("target")
or item.get("filename")
)
if str(provider).strip().lower() == "ytdlp":
apply_tags = [str(t) for t in tags if t is not None]
else:
apply_tags = _filter_scraped_tags([str(t) for t in tags if t is not None])
if not apply_tags:
continue
if store_name and file_hash:
try:
backend = Store(config)[str(store_name)]
backend.add_tag(file_hash, apply_tags, config=config)
try:
updated_tags, _src = backend.get_tag(file_hash, config=config)
except Exception:
updated_tags = apply_tags
_emit_tags_as_table(
tags_list=list(updated_tags or apply_tags),
file_hash=file_hash,
store=str(store_name),
service_name=None,
config=config,
item_title=str(item.get("title") or provider),
path=str(subject_path) if subject_path else None,
subject=item,
)
applied_any = True
continue
except Exception:
pass
# No store/hash: just emit the tags to the pipeline/view.
_emit_tags_as_table(
tags_list=list(apply_tags),
file_hash=file_hash,
store=str(store_name or "local"),
service_name=None,
config=config,
item_title=str(item.get("title") or provider),
path=str(subject_path) if subject_path else None,
subject=item,
)
applied_any = True
if applied_any:
# Selection handled; skip default selection echo.
return
except Exception:
# Fall back to default selection rendering on any failure.
pass
table = ResultTable("Selection Result")
items = piped_result if isinstance(piped_result,
list) else [piped_result]