refactored and updated tags cmdlet and hydrusnetwork interaction plugin features
This commit is contained in:
+99
-24
@@ -13,6 +13,7 @@ from SYS.result_publication import publish_result_table
|
||||
from SYS import models
|
||||
from SYS import pipeline as ctx
|
||||
from . import _shared as sh
|
||||
from Store import Store # retained for test monkeypatch compatibility
|
||||
|
||||
normalize_result_input = sh.normalize_result_input
|
||||
filter_results_by_temp = sh.filter_results_by_temp
|
||||
@@ -28,7 +29,6 @@ parse_cmdlet_args = sh.parse_cmdlet_args
|
||||
collapse_namespace_tag = sh.collapse_namespace_tag
|
||||
should_show_help = sh.should_show_help
|
||||
get_field = sh.get_field
|
||||
from Store import Store
|
||||
|
||||
_FIELD_NAME_RE = re.compile(r"^[A-Za-z0-9_]+$")
|
||||
|
||||
@@ -663,8 +663,40 @@ class Add_Tag(Cmdlet):
|
||||
total_added = 0
|
||||
total_modified = 0
|
||||
unresolved_template_count = 0
|
||||
store_registry: Any = None
|
||||
|
||||
store_registry = Store(config, suppress_debug=True)
|
||||
def _resolve_backend(name: Optional[str]) -> tuple[Any | None, Any, Exception | None]:
|
||||
nonlocal store_registry
|
||||
backend_name = str(name or "").strip()
|
||||
if not backend_name:
|
||||
return None, store_registry, KeyError("Missing store name")
|
||||
if backend_name in _backend_instance_cache:
|
||||
return _backend_instance_cache[backend_name], store_registry, None
|
||||
try:
|
||||
backend, registry, exc = sh.get_preferred_store_backend(
|
||||
config,
|
||||
backend_name,
|
||||
store_registry=store_registry,
|
||||
suppress_debug=True,
|
||||
)
|
||||
except TypeError as exc2:
|
||||
# Tests may monkeypatch get_store_backend with a reduced signature.
|
||||
if "store_registry" in str(exc2):
|
||||
backend, registry, exc = sh.get_store_backend(
|
||||
config,
|
||||
backend_name,
|
||||
suppress_debug=True,
|
||||
)
|
||||
else:
|
||||
raise
|
||||
if registry is not None:
|
||||
store_registry = registry
|
||||
if backend is not None:
|
||||
_backend_instance_cache[backend_name] = backend
|
||||
return backend, store_registry, exc
|
||||
|
||||
pending_bulk_add: Dict[tuple[int, tuple[str, ...], tuple[str, ...]], Dict[str, Any]] = {}
|
||||
_backend_instance_cache: Dict[str, Any] = {}
|
||||
|
||||
extract_matched_items = 0
|
||||
extract_no_match_items = 0
|
||||
@@ -697,9 +729,8 @@ class Add_Tag(Cmdlet):
|
||||
|
||||
is_known_backend = False
|
||||
try:
|
||||
is_known_backend = bool(store_name_str) and store_registry.is_available(
|
||||
store_name_str
|
||||
)
|
||||
backend_probe, store_registry, _probe_exc = _resolve_backend(store_name_str)
|
||||
is_known_backend = backend_probe is not None
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -864,7 +895,7 @@ class Add_Tag(Cmdlet):
|
||||
# If it's not a known backend and we didn't handle it above as a local/pipeline
|
||||
# metadata edit, then it's an error.
|
||||
log(
|
||||
f"[add_tag] Error: Unknown store '{store_name_str}'. Available: {store_registry.list_backends()}",
|
||||
f"[add_tag] Error: Unknown store '{store_name_str}'",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 1
|
||||
@@ -883,12 +914,7 @@ class Add_Tag(Cmdlet):
|
||||
ctx.emit(res)
|
||||
continue
|
||||
|
||||
backend, store_registry, exc = sh.get_store_backend(
|
||||
config,
|
||||
str(store_name),
|
||||
store_registry=store_registry,
|
||||
suppress_debug=True,
|
||||
)
|
||||
backend, store_registry, exc = _resolve_backend(str(store_name))
|
||||
if backend is None:
|
||||
log(
|
||||
f"[add_tag] Error: Unknown store '{store_name}': {exc}",
|
||||
@@ -1027,18 +1053,40 @@ class Add_Tag(Cmdlet):
|
||||
tags_to_add = []
|
||||
merged_tags = list(existing_tag_list)
|
||||
|
||||
try:
|
||||
ok_add = backend.add_tag(
|
||||
resolved_hash,
|
||||
item_tag_to_add,
|
||||
config=config,
|
||||
existing_tags=existing_tag_list,
|
||||
)
|
||||
if not ok_add:
|
||||
log("[add_tag] Warning: Store rejected tag update", file=sys.stderr)
|
||||
except Exception as exc:
|
||||
log(f"[add_tag] Warning: Failed adding tag: {exc}", file=sys.stderr)
|
||||
ok_add = False
|
||||
queued_bulk = False
|
||||
ok_add = False
|
||||
add_tags_bulk_fn = getattr(backend, "add_tags_bulk", None)
|
||||
if tags_to_add and callable(add_tags_bulk_fn):
|
||||
add_key = tuple(sorted({str(t).strip().lower() for t in tags_to_add if str(t).strip()}))
|
||||
remove_key = tuple(sorted({str(t).strip().lower() for t in tags_to_remove if str(t).strip()}))
|
||||
if add_key:
|
||||
batch_key = (id(backend), add_key, remove_key)
|
||||
bucket = pending_bulk_add.get(batch_key)
|
||||
if bucket is None:
|
||||
bucket = {
|
||||
"backend": backend,
|
||||
"add_tags": list(add_key),
|
||||
"remove_tags": list(remove_key),
|
||||
"hashes": [],
|
||||
}
|
||||
pending_bulk_add[batch_key] = bucket
|
||||
bucket["hashes"].append(resolved_hash)
|
||||
queued_bulk = True
|
||||
ok_add = True
|
||||
|
||||
if not queued_bulk:
|
||||
try:
|
||||
ok_add = backend.add_tag(
|
||||
resolved_hash,
|
||||
item_tag_to_add,
|
||||
config=config,
|
||||
existing_tags=existing_tag_list,
|
||||
)
|
||||
if not ok_add:
|
||||
log("[add_tag] Warning: Store rejected tag update", file=sys.stderr)
|
||||
except Exception as exc:
|
||||
log(f"[add_tag] Warning: Failed adding tag: {exc}", file=sys.stderr)
|
||||
ok_add = False
|
||||
|
||||
if ok_add and merged_tags:
|
||||
refreshed_list = list(merged_tags)
|
||||
@@ -1075,6 +1123,33 @@ class Add_Tag(Cmdlet):
|
||||
|
||||
ctx.emit(res)
|
||||
|
||||
for bucket in pending_bulk_add.values():
|
||||
backend = bucket.get("backend")
|
||||
add_tags_for_batch = list(bucket.get("add_tags") or [])
|
||||
remove_tags_for_batch = list(bucket.get("remove_tags") or [])
|
||||
hashes_for_batch = [str(h).strip().lower() for h in (bucket.get("hashes") or []) if str(h).strip()]
|
||||
if backend is None or not hashes_for_batch:
|
||||
continue
|
||||
|
||||
batch_items = [(h, list(add_tags_for_batch), list(remove_tags_for_batch)) for h in hashes_for_batch]
|
||||
add_tags_bulk_fn = getattr(backend, "add_tags_bulk", None)
|
||||
applied = False
|
||||
if callable(add_tags_bulk_fn):
|
||||
try:
|
||||
applied = bool(add_tags_bulk_fn(batch_items))
|
||||
except Exception:
|
||||
applied = False
|
||||
|
||||
if applied:
|
||||
continue
|
||||
|
||||
# Fallback path: retain correctness if backend bulk call fails.
|
||||
for h in hashes_for_batch:
|
||||
try:
|
||||
backend.add_tag(h, list(add_tags_for_batch), config=config)
|
||||
except Exception as exc:
|
||||
log(f"[add_tag] Warning: Failed fallback add_tag for {h}: {exc}", file=sys.stderr)
|
||||
|
||||
log(
|
||||
f"[add_tag] Added {total_added} new tag(s) across {len(results)} item(s); modified {total_modified} item(s)",
|
||||
file=sys.stderr,
|
||||
|
||||
Reference in New Issue
Block a user