cmdlet refactor
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Dict, List, Sequence
|
||||
import sys
|
||||
|
||||
from SYS.logger import log
|
||||
from SYS.detail_view_helpers import create_detail_view, prepare_detail_metadata
|
||||
from SYS.payload_builders import build_table_result_payload
|
||||
from SYS.result_publication import publish_result_table
|
||||
from SYS.result_table_helpers import add_row_columns
|
||||
|
||||
from SYS import pipeline as ctx
|
||||
from .. import _shared as sh
|
||||
|
||||
Cmdlet = sh.Cmdlet
|
||||
CmdletArg = sh.CmdletArg
|
||||
SharedArgs = sh.SharedArgs
|
||||
normalize_hash = sh.normalize_hash
|
||||
parse_cmdlet_args = sh.parse_cmdlet_args
|
||||
normalize_result_input = sh.normalize_result_input
|
||||
should_show_help = sh.should_show_help
|
||||
|
||||
|
||||
class Get_Note(Cmdlet):
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__(
|
||||
name="get-note",
|
||||
summary="List notes on a file in a store.",
|
||||
usage='get-note -instance <store> [-query "hash:<sha256>"]',
|
||||
alias=["get-notes",
|
||||
"get_note"],
|
||||
arg=[
|
||||
SharedArgs.INSTANCE,
|
||||
SharedArgs.QUERY,
|
||||
],
|
||||
detail=[
|
||||
"- Notes are retrieved via the selected store backend.",
|
||||
"- Lyrics are stored in a note named 'lyric'.",
|
||||
],
|
||||
exec=self.run,
|
||||
)
|
||||
try:
|
||||
SharedArgs.INSTANCE.choices = SharedArgs.get_store_choices(None)
|
||||
except Exception:
|
||||
pass
|
||||
self.register()
|
||||
|
||||
def run(self, result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
if should_show_help(args):
|
||||
log(f"Cmdlet: {self.name}\nSummary: {self.summary}\nUsage: {self.usage}")
|
||||
return 0
|
||||
|
||||
parsed = parse_cmdlet_args(args, self)
|
||||
store_override = parsed.get("instance")
|
||||
query_hash, query_valid = sh.require_single_hash_query(
|
||||
parsed.get("query"),
|
||||
"[get_note] Error: -query must be of the form hash:<sha256>",
|
||||
log_file=sys.stderr,
|
||||
)
|
||||
if not query_valid:
|
||||
return 1
|
||||
|
||||
results = normalize_result_input(result)
|
||||
if not results:
|
||||
if store_override and query_hash:
|
||||
results = [{
|
||||
"store": str(store_override),
|
||||
"hash": query_hash
|
||||
}]
|
||||
else:
|
||||
log(
|
||||
'[get_note] Error: Requires piped item(s) or -instance and -query "hash:<sha256>"',
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 1
|
||||
|
||||
store_registry = None
|
||||
any_notes = False
|
||||
display_items: List[Dict[str, Any]] = []
|
||||
|
||||
# We assume single subject for get-note detail view
|
||||
main_res = results[0]
|
||||
|
||||
metadata = prepare_detail_metadata(main_res)
|
||||
|
||||
note_table = create_detail_view(
|
||||
"Notes",
|
||||
metadata,
|
||||
table_name="note",
|
||||
source_command=("get-note", []),
|
||||
)
|
||||
|
||||
for res in results:
|
||||
if not isinstance(res, dict):
|
||||
continue
|
||||
|
||||
store_name, resolved_hash = sh.resolve_item_store_hash(
|
||||
res,
|
||||
override_store=str(store_override) if store_override else None,
|
||||
override_hash=str(query_hash) if query_hash else None,
|
||||
path_fields=("path",),
|
||||
)
|
||||
|
||||
if not store_name:
|
||||
log(
|
||||
"[get_note] Error: Missing -instance and item has no store field",
|
||||
file=sys.stderr
|
||||
)
|
||||
return 1
|
||||
|
||||
if not resolved_hash:
|
||||
continue
|
||||
|
||||
# Update metadata if we resolved a hash that wasn't in source
|
||||
if resolved_hash and not metadata.get("Hash"):
|
||||
metadata["Hash"] = resolved_hash
|
||||
if store_name and not metadata.get("Store"):
|
||||
metadata["Store"] = store_name
|
||||
|
||||
backend, store_registry, exc = sh.get_store_backend(
|
||||
config,
|
||||
store_name,
|
||||
store_registry=store_registry,
|
||||
)
|
||||
if backend is None:
|
||||
log(
|
||||
f"[get_note] Error: Unknown store '{store_name}': {exc}",
|
||||
file=sys.stderr
|
||||
)
|
||||
return 1
|
||||
|
||||
notes = {}
|
||||
try:
|
||||
notes = backend.get_note(
|
||||
resolved_hash,
|
||||
config=config
|
||||
) or {}
|
||||
except Exception:
|
||||
notes = {}
|
||||
|
||||
if not notes:
|
||||
continue
|
||||
|
||||
any_notes = True
|
||||
# Emit each note as its own row so CLI renders a proper note table
|
||||
for k in sorted(notes.keys(), key=lambda x: str(x).lower()):
|
||||
v = notes.get(k)
|
||||
raw_text = str(v or "")
|
||||
# Keep payload small for IPC/pipes.
|
||||
raw_text = raw_text[:999]
|
||||
preview = " ".join(raw_text.replace("\r", "").split("\n"))
|
||||
payload = build_table_result_payload(
|
||||
columns=[
|
||||
("Name", str(k)),
|
||||
("Text", preview.strip()),
|
||||
],
|
||||
store=store_name,
|
||||
hash=resolved_hash,
|
||||
note_name=str(k),
|
||||
note_text=raw_text,
|
||||
)
|
||||
display_items.append(payload)
|
||||
if note_table is not None:
|
||||
add_row_columns(
|
||||
note_table,
|
||||
[("Name", str(k)), ("Text", preview.strip())],
|
||||
)
|
||||
|
||||
ctx.emit(payload)
|
||||
|
||||
# Always set the table overlay even if empty to show item details
|
||||
publish_result_table(ctx, note_table, display_items, subject=result, overlay=True)
|
||||
|
||||
if not any_notes:
|
||||
log("No notes found.")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
CMDLET = Get_Note()
|
||||
Reference in New Issue
Block a user