From 7f897df4b2947b2d308bb44405903f225350a0fc Mon Sep 17 00:00:00 2001 From: pax Date: Thu, 9 Apr 2026 19:15:02 -0500 Subject: [PATCH] gelbooru: implement _post_view_url + _tag_api_url + prefetch wiring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Overrides both URL methods from the base class: _post_view_url(post) -> /index.php?page=post&s=view&id={id} Universal HTML scrape path — works on Gelbooru proper, Rule34, Safebooru.org without auth. _tag_api_url() -> {base_url}/index.php Batch tag DAPI fast path. The CategoryFetcher's probe-and-cache determines at runtime whether the endpoint actually honors names=. Gelbooru proper: probe succeeds. Rule34: probe fails (garbage response), falls back to HTML. Safebooru.org: no auth, dispatch skips batch entirely. search() and get_post() now call await self.category_fetcher.prefetch_batch(posts) after building the post list, when a fetcher is attached. The prefetch is fire-and-forget — search returns immediately and the background tasks fill categories as the user reads. When no fetcher is attached (Test Connection dialog, scripts), this is a no-op and behavior is unchanged. --- booru_viewer/core/api/gelbooru.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/booru_viewer/core/api/gelbooru.py b/booru_viewer/core/api/gelbooru.py index a65e1b6..f47e850 100644 --- a/booru_viewer/core/api/gelbooru.py +++ b/booru_viewer/core/api/gelbooru.py @@ -13,6 +13,12 @@ log = logging.getLogger("booru") class GelbooruClient(BooruClient): api_type = "gelbooru" + def _post_view_url(self, post: Post) -> str: + return f"{self.base_url}/index.php?page=post&s=view&id={post.id}" + + def _tag_api_url(self) -> str: + return f"{self.base_url}/index.php" + async def search( self, tags: str = "", page: int = 1, limit: int = DEFAULT_PAGE_SIZE ) -> list[Post]: @@ -75,6 +81,8 @@ class GelbooruClient(BooruClient): created_at=_parse_date(item.get("created_at")), ) ) + if self.category_fetcher is not None: + await self.category_fetcher.prefetch_batch(posts) return posts @staticmethod @@ -107,7 +115,7 @@ class GelbooruClient(BooruClient): file_url = item.get("file_url", "") if not file_url: return None - return Post( + post = Post( id=item["id"], file_url=file_url, preview_url=item.get("preview_url"), @@ -119,6 +127,9 @@ class GelbooruClient(BooruClient): height=item.get("height", 0), created_at=_parse_date(item.get("created_at")), ) + if self.category_fetcher is not None: + await self.category_fetcher.prefetch_batch([post]) + return post async def autocomplete(self, query: str, limit: int = 10) -> list[str]: try: