104 lines
3.1 KiB
Python
104 lines
3.1 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from typing import Any, Iterable, Optional, Sequence
|
||
|
|
|
||
|
|
|
||
|
|
def _labelize_key(key: str) -> str:
|
||
|
|
return str(key or "").replace("_", " ").title()
|
||
|
|
|
||
|
|
|
||
|
|
def _normalize_tags_value(tags: Any) -> Optional[str]:
|
||
|
|
if tags is None:
|
||
|
|
return None
|
||
|
|
if isinstance(tags, str):
|
||
|
|
text = tags.strip()
|
||
|
|
return text or None
|
||
|
|
if isinstance(tags, Sequence):
|
||
|
|
seen: list[str] = []
|
||
|
|
for tag in tags:
|
||
|
|
text = str(tag or "").strip()
|
||
|
|
if text and text not in seen:
|
||
|
|
seen.append(text)
|
||
|
|
return ", ".join(seen) if seen else None
|
||
|
|
text = str(tags).strip()
|
||
|
|
return text or None
|
||
|
|
|
||
|
|
|
||
|
|
def prepare_detail_metadata(
|
||
|
|
subject: Any,
|
||
|
|
*,
|
||
|
|
include_subject_fields: bool = False,
|
||
|
|
title: Optional[str] = None,
|
||
|
|
hash_value: Optional[str] = None,
|
||
|
|
store: Optional[str] = None,
|
||
|
|
path: Optional[str] = None,
|
||
|
|
tags: Any = None,
|
||
|
|
prefer_existing_tags: bool = True,
|
||
|
|
extra_fields: Optional[dict[str, Any]] = None,
|
||
|
|
) -> dict[str, Any]:
|
||
|
|
from SYS.result_table import extract_item_metadata
|
||
|
|
|
||
|
|
metadata = extract_item_metadata(subject) or {}
|
||
|
|
|
||
|
|
if include_subject_fields and isinstance(subject, dict):
|
||
|
|
for key, value in subject.items():
|
||
|
|
if str(key).startswith("_") or key in {"selection_action", "selection_args"}:
|
||
|
|
continue
|
||
|
|
label = _labelize_key(str(key))
|
||
|
|
if label not in metadata and value is not None:
|
||
|
|
metadata[label] = value
|
||
|
|
|
||
|
|
if title:
|
||
|
|
metadata["Title"] = title
|
||
|
|
if hash_value:
|
||
|
|
metadata["Hash"] = hash_value
|
||
|
|
if store:
|
||
|
|
metadata["Store"] = store
|
||
|
|
if path:
|
||
|
|
metadata["Path"] = path
|
||
|
|
|
||
|
|
tags_text = _normalize_tags_value(tags)
|
||
|
|
if tags_text and (not prefer_existing_tags or not metadata.get("Tags")):
|
||
|
|
metadata["Tags"] = tags_text
|
||
|
|
|
||
|
|
for key, value in (extra_fields or {}).items():
|
||
|
|
if value is not None:
|
||
|
|
metadata[str(key)] = value
|
||
|
|
|
||
|
|
return metadata
|
||
|
|
|
||
|
|
|
||
|
|
def create_detail_view(
|
||
|
|
title: str,
|
||
|
|
metadata: dict[str, Any],
|
||
|
|
*,
|
||
|
|
table_name: Optional[str] = None,
|
||
|
|
source_command: Optional[tuple[str, Sequence[str]]] = None,
|
||
|
|
init_command: Optional[tuple[str, Sequence[str]]] = None,
|
||
|
|
max_columns: Optional[int] = None,
|
||
|
|
exclude_tags: bool = False,
|
||
|
|
value_case: Optional[str] = "preserve",
|
||
|
|
perseverance: bool = True,
|
||
|
|
) -> Any:
|
||
|
|
from SYS.result_table import ItemDetailView
|
||
|
|
|
||
|
|
kwargs: dict[str, Any] = {"item_metadata": metadata}
|
||
|
|
if max_columns is not None:
|
||
|
|
kwargs["max_columns"] = max_columns
|
||
|
|
if exclude_tags:
|
||
|
|
kwargs["exclude_tags"] = True
|
||
|
|
|
||
|
|
table = ItemDetailView(title, **kwargs)
|
||
|
|
if table_name:
|
||
|
|
table = table.set_table(table_name)
|
||
|
|
if value_case:
|
||
|
|
table = table.set_value_case(value_case)
|
||
|
|
if perseverance:
|
||
|
|
table = table._perseverance(True)
|
||
|
|
if source_command:
|
||
|
|
name, args = source_command
|
||
|
|
table.set_source_command(name, list(args))
|
||
|
|
if init_command:
|
||
|
|
name, args = init_command
|
||
|
|
table = table.init_command(name, list(args))
|
||
|
|
return table
|