kl
This commit is contained in:
@@ -209,11 +209,8 @@ class Add_Note(Cmdlet):
|
||||
note_name = str(note_name or "").strip()
|
||||
note_text = str(note_text or "").strip()
|
||||
if not note_name or not note_text:
|
||||
log(
|
||||
"[add_note] Error: -query must include title:<title> and text:<text>",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 1
|
||||
pass # We now support implicit pipeline notes if -query is missing
|
||||
# But if explicit targeting (store+hash) is used, we still demand args below.
|
||||
|
||||
if hash_override and not store_override:
|
||||
log(
|
||||
@@ -224,6 +221,14 @@ class Add_Note(Cmdlet):
|
||||
|
||||
explicit_target = bool(hash_override and store_override)
|
||||
results = normalize_result_input(result)
|
||||
|
||||
if explicit_target and (not note_name or not note_text):
|
||||
log(
|
||||
"[add_note] Error: Explicit target (store+hash) requires -query with title/text",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 1
|
||||
|
||||
if results and explicit_target:
|
||||
# Direct targeting mode: apply note once to the explicit target and
|
||||
# pass through any piped items unchanged.
|
||||
@@ -287,7 +292,36 @@ class Add_Note(Cmdlet):
|
||||
ctx.emit(res)
|
||||
continue
|
||||
|
||||
item_note_text = note_text
|
||||
# Determine notes to write for this item
|
||||
notes_to_write: List[Tuple[str, str]] = []
|
||||
|
||||
# 1. Explicit arguments always take precedence
|
||||
if note_name and note_text:
|
||||
notes_to_write.append((note_name, note_text))
|
||||
|
||||
# 2. Pipeline notes auto-ingestion
|
||||
# Look for 'notes' dictionary in the item (propagated by pipeline/download-file)
|
||||
# Structure: {'notes': {'lyric': '...', 'sub': '...'}}
|
||||
# Check both root and nested 'extra'
|
||||
|
||||
# Check root 'notes' (dict or extra.notes)
|
||||
pipeline_notes = res.get("notes")
|
||||
if not isinstance(pipeline_notes, dict):
|
||||
extra = res.get("extra")
|
||||
if isinstance(extra, dict):
|
||||
pipeline_notes = extra.get("notes")
|
||||
|
||||
if isinstance(pipeline_notes, dict):
|
||||
for k, v in pipeline_notes.items():
|
||||
# If arg-provided note conflicts effectively with pipeline note?
|
||||
# We just append both.
|
||||
if v and str(v).strip():
|
||||
notes_to_write.append((str(k), str(v)))
|
||||
|
||||
if not notes_to_write:
|
||||
# Pass through items that have nothing to add
|
||||
ctx.emit(res)
|
||||
continue
|
||||
|
||||
store_name = str(store_override or res.get("store") or "").strip()
|
||||
raw_hash = res.get("hash")
|
||||
@@ -298,7 +332,7 @@ class Add_Note(Cmdlet):
|
||||
"[add_note] Error: Missing -store and item has no store field",
|
||||
file=sys.stderr
|
||||
)
|
||||
return 1
|
||||
continue
|
||||
|
||||
resolved_hash = self._resolve_hash(
|
||||
raw_hash=str(raw_hash) if raw_hash else None,
|
||||
@@ -312,80 +346,43 @@ class Add_Note(Cmdlet):
|
||||
)
|
||||
ctx.emit(res)
|
||||
continue
|
||||
|
||||
try:
|
||||
backend = store_registry[store_name]
|
||||
except Exception as exc:
|
||||
log(
|
||||
f"[add_note] Error: Unknown store '{store_name}': {exc}",
|
||||
file=sys.stderr
|
||||
)
|
||||
return 1
|
||||
|
||||
# Queue for bulk write per store. We still emit items immediately;
|
||||
# the pipeline only advances after this cmdlet returns.
|
||||
note_ops.setdefault(store_name,
|
||||
[]).append((resolved_hash,
|
||||
note_name,
|
||||
item_note_text))
|
||||
planned_ops += 1
|
||||
|
||||
|
||||
# Queue operations
|
||||
if store_name not in note_ops:
|
||||
note_ops[store_name] = []
|
||||
|
||||
for (n_name, n_text) in notes_to_write:
|
||||
note_ops[store_name].append((resolved_hash, n_name, n_text))
|
||||
planned_ops += 1
|
||||
|
||||
ctx.emit(res)
|
||||
|
||||
# Execute bulk writes per store.
|
||||
successful_writes = 0
|
||||
|
||||
# Execute batch operations
|
||||
success_count = 0
|
||||
for store_name, ops in note_ops.items():
|
||||
if not ops:
|
||||
continue
|
||||
try:
|
||||
backend = store_registry[store_name]
|
||||
except Exception:
|
||||
continue
|
||||
if not hasattr(backend, "set_note"):
|
||||
log(f"[add_note] Store '{store_name}' does not support notes", file=sys.stderr)
|
||||
continue
|
||||
|
||||
for (h, name, text) in ops:
|
||||
try:
|
||||
if backend.set_note(h, name, text, config=config):
|
||||
success_count += 1
|
||||
except Exception as e:
|
||||
log(f"[add_note] Write failed {store_name}:{h} ({name}): {e}", file=sys.stderr)
|
||||
|
||||
except Exception as e:
|
||||
log(f"[add_note] Store access failed '{store_name}': {e}", file=sys.stderr)
|
||||
|
||||
store_success = 0
|
||||
bulk_fn = getattr(backend, "set_note_bulk", None)
|
||||
if callable(bulk_fn):
|
||||
try:
|
||||
ok = bool(bulk_fn(list(ops), config=config))
|
||||
if ok:
|
||||
store_success += len(ops)
|
||||
ctx.print_if_visible(
|
||||
f"✓ add-note: {len(ops)} item(s) in '{store_name}'",
|
||||
file=sys.stderr
|
||||
)
|
||||
successful_writes += store_success
|
||||
continue
|
||||
log(
|
||||
f"[add_note] Warning: bulk set_note returned False for '{store_name}'",
|
||||
file=sys.stderr,
|
||||
)
|
||||
except Exception as exc:
|
||||
log(
|
||||
f"[add_note] Warning: bulk set_note failed for '{store_name}': {exc}; falling back",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
# Fallback: per-item writes
|
||||
for file_hash, name, text in ops:
|
||||
try:
|
||||
ok = bool(backend.set_note(file_hash, name, text, config=config))
|
||||
if ok:
|
||||
store_success += 1
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
if store_success:
|
||||
successful_writes += store_success
|
||||
ctx.print_if_visible(
|
||||
f"✓ add-note: {store_success} item(s) in '{store_name}'",
|
||||
file=sys.stderr
|
||||
)
|
||||
|
||||
log(
|
||||
f"[add_note] Updated {successful_writes}/{planned_ops} item(s)",
|
||||
file=sys.stderr
|
||||
)
|
||||
return 0 if successful_writes > 0 else 1
|
||||
if planned_ops > 0:
|
||||
msg = f"✓ add-note: Updated {success_count}/{planned_ops} notes across {len(note_ops)} stores"
|
||||
ctx.print_if_visible(msg, file=sys.stderr)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
CMDLET = Add_Note()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user