"""Archive search plugin runner.""" import json import db from errors import BookNotFoundError from models import ArchiveSearcherPlugin, BookRow, CandidateRecord from logic.identification import build_query def run_archive_searcher(plugin: ArchiveSearcherPlugin, book_id: str) -> BookRow: """Run an archive search for a book and merge results into the candidates list. Args: plugin: The archive searcher plugin to execute. book_id: ID of the book to search for. Returns: Updated BookRow after merging search results. Raises: BookNotFoundError: If book_id does not exist. """ with db.transaction() as c: book = db.get_book(c, book_id) if not book: raise BookNotFoundError(book_id) query = build_query(book) if not query: return book results: list[CandidateRecord] = plugin.search(query) existing: list[CandidateRecord] = json.loads(book.candidates or "[]") existing = [cd for cd in existing if cd.get("source") != plugin.plugin_id] existing.extend(results) db.set_book_candidates(c, book_id, json.dumps(existing)) updated = db.get_book(c, book_id) if not updated: raise BookNotFoundError(book_id) return updated def run_archive_searcher_bg(plugin: ArchiveSearcherPlugin, book_id: str) -> None: """Run an archive search in fire-and-forget mode; all exceptions are suppressed. Args: plugin: The archive searcher plugin to execute. book_id: ID of the book to search for. """ try: run_archive_searcher(plugin, book_id) except Exception: pass