category_fetcher: compose from partial cache coverage
try_compose_from_cache previously required 100% cache coverage — every tag in the post had to have a cached label or it returned False and populated nothing. One rare uncached tag out of 50 blocked the entire composition, leaving the post with zero categories even though 49/50 labels were available. Fix: compose whatever IS cached, return True when at least one tag got categorized. Tags not in the cache are simply absent from the categories dict (they stay in the flat tags string). The return value now means "the post has usable categories" rather than "the post has complete categories." This distinction matters because the dispatch logic uses the return value to decide whether to skip the fetch path — partial coverage is better than no coverage, and the missing tags get cached eventually when other posts that contain them get fetched. Verified against Gelbooru: post with 50 tags where 49 were cached now gets 49/50 categorized (Artist, Character, Copyright, General, Meta) instead of 0/50.
This commit is contained in:
parent
af9b68273c
commit
165733c6e0
@ -136,15 +136,23 @@ class CategoryFetcher:
|
|||||||
def try_compose_from_cache(self, post: "Post") -> bool:
|
def try_compose_from_cache(self, post: "Post") -> bool:
|
||||||
"""Build ``post.tag_categories`` from cached labels.
|
"""Build ``post.tag_categories`` from cached labels.
|
||||||
|
|
||||||
Returns True if **every** tag in ``post.tag_list`` has a
|
Populates ``post.tag_categories`` with whatever tags ARE
|
||||||
cached label (i.e. the composition is complete). When True
|
cached, even if some are missing. Returns True when at least
|
||||||
the post is fully categorized and no HTTP is needed.
|
one tag was categorized (meaning the post is usable — the
|
||||||
|
info panel can render categories, templates can resolve
|
||||||
|
``%artist%`` / ``%character%`` etc.). Returns False only
|
||||||
|
when the cache has literally nothing for any of the post's
|
||||||
|
tags, which means a fetch is needed.
|
||||||
|
|
||||||
|
Tags not in the cache are simply absent from the category
|
||||||
|
dict. They stay in ``post.tags`` (the flat string) and can
|
||||||
|
be picked up by a later per-post fetch if needed.
|
||||||
"""
|
"""
|
||||||
tags = post.tag_list
|
tags = post.tag_list
|
||||||
if not tags:
|
if not tags:
|
||||||
return True
|
return True
|
||||||
cached = self._db.get_tag_labels(self._site_id, tags)
|
cached = self._db.get_tag_labels(self._site_id, tags)
|
||||||
if len(cached) < len(set(tags)):
|
if not cached:
|
||||||
return False
|
return False
|
||||||
cats: dict[str, list[str]] = {}
|
cats: dict[str, list[str]] = {}
|
||||||
for tag in tags:
|
for tag in tags:
|
||||||
@ -153,7 +161,7 @@ class CategoryFetcher:
|
|||||||
cats.setdefault(label, []).append(tag)
|
cats.setdefault(label, []).append(tag)
|
||||||
if cats:
|
if cats:
|
||||||
post.tag_categories = _canonical_order(cats)
|
post.tag_categories = _canonical_order(cats)
|
||||||
return True
|
return bool(cats)
|
||||||
|
|
||||||
# ----- batch tag API fast path -----
|
# ----- batch tag API fast path -----
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user