This commit is contained in:
2026-03-25 22:39:30 -07:00
parent c31402c8f1
commit 562acd809c
46 changed files with 2367 additions and 1868 deletions

View File

@@ -26,6 +26,10 @@ from typing import Any, Dict, List, Optional, Sequence, Tuple
from SYS import pipeline as ctx
from SYS.pipeline_progress import PipelineProgress
from SYS.detail_view_helpers import create_detail_view, prepare_detail_metadata
from SYS.payload_builders import extract_title_tag_value
from SYS.result_publication import publish_result_table
from SYS.result_table_helpers import add_row_columns
from . import _shared as sh
from SYS.field_access import get_field
@@ -259,36 +263,24 @@ def _emit_tags_as_table(
subject: Full context object (should preserve original metadata)
quiet: If True, don't display (emit-only mode)
"""
from SYS.result_table import ItemDetailView, extract_item_metadata
# Prepare metadata for the detail view, extracting all fields from subject first
metadata = extract_item_metadata(subject) or {}
# Preserve all additional fields from subject dict if it's a dict-like object
if isinstance(subject, dict):
for key, value in subject.items():
# Skip internal/control fields
if not key.startswith("_") and key not in {"selection_action", "selection_args"}:
# Convert keys to readable labels (snake_case -> Title Case)
label = str(key).replace("_", " ").title()
# Only add if not already present from extract_item_metadata
if label not in metadata and value is not None:
metadata[label] = value
# Apply explicit parameter overrides (these take priority)
if item_title:
metadata["Title"] = item_title
if file_hash:
metadata["Hash"] = file_hash
if store:
metadata["Store"] = service_name if service_name else store
if path:
metadata["Path"] = path
metadata = prepare_detail_metadata(
subject,
include_subject_fields=True,
title=item_title,
hash_value=file_hash,
store=(service_name if service_name else store),
path=path,
)
# Create ItemDetailView with exclude_tags=True so the panel shows file info
# but doesn't duplicate the tag list that we show as a table below.
table = ItemDetailView("Tags", item_metadata=metadata, max_columns=1, exclude_tags=True)
table.set_source_command("get-tag", [])
table = create_detail_view(
"Tags",
metadata,
max_columns=1,
exclude_tags=True,
source_command=("get-tag", []),
)
# Create TagItem for each tag and add to table
tag_items = []
@@ -383,12 +375,7 @@ def _extract_title_from(tags_list: List[str]) -> Optional[str]:
return extract_title(tags_list)
except Exception:
pass
for t in tags_list:
if isinstance(t, str) and t.lower().startswith("title:"):
val = t.split(":", 1)[1].strip()
if val:
return val
return None
return extract_title_tag_value(tags_list)
def _rename_file_if_title_tag(media: Optional[Path], tags_added: List[str]) -> bool:
@@ -1002,9 +989,12 @@ def _run_impl(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
# Extract values
query_raw = parsed_args.get("query")
hash_override = sh.parse_single_hash_query(query_raw)
if query_raw and not hash_override:
log("Invalid -query value (expected hash:<sha256>)", file=sys.stderr)
hash_override, query_valid = sh.require_single_hash_query(
query_raw,
"Invalid -query value (expected hash:<sha256>)",
log_file=sys.stderr,
)
if not query_valid:
return 1
store_key = parsed_args.get("store")
emit_requested = parsed_args.get("emit", False)
@@ -1023,25 +1013,16 @@ def _run_impl(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
except Exception:
display_subject = None
def _value_has_content(value: Any) -> bool:
if value is None:
return False
if isinstance(value, str):
return bool(value.strip())
if isinstance(value, (list, tuple, set)):
return len(value) > 0
return True
def _resolve_subject_value(*keys: str) -> Any:
for key in keys:
val = get_field(result, key, None)
if _value_has_content(val):
if sh.value_has_content(val):
return val
if display_subject is None:
return None
for key in keys:
val = get_field(display_subject, key, None)
if _value_has_content(val):
if sh.value_has_content(val):
return val
return None
@@ -1422,11 +1403,15 @@ def _run_impl(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
)
for idx, item in enumerate(items):
tags = _filter_scraped_tags(provider.to_tags(item))
row = table.add_row()
row.add_column("Title", item.get("title", ""))
row.add_column("Artist", item.get("artist", ""))
row.add_column("Album", item.get("album", ""))
row.add_column("Year", item.get("year", ""))
add_row_columns(
table,
[
("Title", item.get("title", "")),
("Artist", item.get("artist", "")),
("Album", item.get("album", "")),
("Year", item.get("year", "")),
],
)
payload = {
"tag": tags,
"provider": provider.name,
@@ -1447,7 +1432,7 @@ def _run_impl(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
# Store an overlay so that a subsequent `@N` selects from THIS metadata table,
# not from the previous searchable table.
ctx.set_last_result_table_overlay(table, selection_payload)
publish_result_table(ctx, table, selection_payload, overlay=True)
ctx.set_current_stage_table(table)
return 0