from __future__ import annotations from typing import Any, Dict, Sequence import json from . import register import models import pipeline as ctx from helper import hydrus as hydrus_wrapper from ._shared import Cmdlet, CmdletArg, normalize_hash from helper.logger import log CMDLET = Cmdlet( name="get-url", summary="List URLs associated with a Hydrus file.", usage="get-url [-hash ]", args=[ CmdletArg("-hash", description="Override the Hydrus file hash (SHA256) to target instead of the selected result."), ], details=[ "- Prints the known URLs for the selected Hydrus file.", ], ) def _parse_hash_and_rest(args: Sequence[str]) -> tuple[str | None, list[str]]: override_hash: str | None = None rest: list[str] = [] i = 0 while i < len(args): a = args[i] low = str(a).lower() if low in {"-hash", "--hash", "hash"} and i + 1 < len(args): override_hash = str(args[i + 1]).strip() i += 2 continue rest.append(a) i += 1 return override_hash, rest @register(["get-url", "get-urls", "get_url"]) # aliases def get_urls(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int: # Helper to get field from both dict and object def get_field(obj: Any, field: str, default: Any = None) -> Any: if isinstance(obj, dict): return obj.get(field, default) else: return getattr(obj, field, default) # Help try: if any(str(a).lower() in {"-?", "/?", "--help", "-h", "help", "--cmdlet"} for a in args): log(json.dumps(CMDLET, ensure_ascii=False, indent=2)) return 0 except Exception: pass override_hash, _ = _parse_hash_and_rest(args) hash_hex = normalize_hash(override_hash) if override_hash else normalize_hash(get_field(result, "hash_hex", None)) if not hash_hex: log("Selected result does not include a Hydrus hash") return 1 try: client = hydrus_wrapper.get_client(config) except Exception as exc: log(f"Hydrus client unavailable: {exc}") return 1 if client is None: log("Hydrus client unavailable") return 1 try: payload = client.fetch_file_metadata(hashes=[hash_hex], include_file_urls=True) except Exception as exc: log(f"Hydrus metadata fetch failed: {exc}") return 1 items = payload.get("metadata") if isinstance(payload, dict) else None meta = items[0] if (isinstance(items, list) and items and isinstance(items[0], dict)) else None urls = (meta.get("known_urls") if isinstance(meta, dict) else None) or [] if urls: ctx.emit("URLs:") for u in urls: text = str(u).strip() if text: ctx.emit(f"- {text}") else: ctx.emit("No URLs found.") return 0