From f5954d13877f649ccdae4854699c98d1c7b8d2fc Mon Sep 17 00:00:00 2001 From: pax Date: Thu, 9 Apr 2026 19:15:57 -0500 Subject: [PATCH] api: factory constructs CategoryFetcher for Gelbooru + Moebooru sites MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit client_for_type gains optional db + site_id kwargs. When both are passed and api_type is gelbooru or moebooru, a CategoryFetcher is constructed and assigned to client.category_fetcher. The fetcher owns the per-tag cache, the batch tag API fast path, and the per-post HTML scrape fallback. Danbooru and e621 never get a fetcher — their inline JSON categorization is already optimal. Test Connection dialog and scripts don't pass db/site_id, so they get fetcher-less clients with the existing search behavior. --- booru_viewer/core/api/detect.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/booru_viewer/core/api/detect.py b/booru_viewer/core/api/detect.py index a839238..80ba88e 100644 --- a/booru_viewer/core/api/detect.py +++ b/booru_viewer/core/api/detect.py @@ -118,8 +118,22 @@ def client_for_type( base_url: str, api_key: str | None = None, api_user: str | None = None, + db=None, + site_id: int | None = None, ) -> BooruClient: - """Return the appropriate client class for an API type string.""" + """Return the appropriate client class for an API type string. + + When ``db`` and ``site_id`` are passed, clients that need + post-hoc tag categorization (Gelbooru-shape, Moebooru) get a + ``CategoryFetcher`` attached. The fetcher handles the per-tag + cache, the batch tag API fast path (for Gelbooru proper), and + the per-post HTML scrape fallback. Danbooru and e621 categorize + inline and don't get a fetcher. + + Leave ``db``/``site_id`` as None for clients outside the main + app (Test Connection dialog, scripts) — category population + becomes a no-op. + """ clients = { "danbooru": DanbooruClient, "gelbooru": GelbooruClient, @@ -129,4 +143,8 @@ def client_for_type( cls = clients.get(api_type) if cls is None: raise ValueError(f"Unknown API type: {api_type}") - return cls(base_url, api_key=api_key, api_user=api_user) + client = cls(base_url, api_key=api_key, api_user=api_user) + if db is not None and site_id is not None and api_type in ("gelbooru", "moebooru"): + from .category_fetcher import CategoryFetcher + client.category_fetcher = CategoryFetcher(client, db, site_id) + return client