Pour toi : recommandations diverses et déjà-possédé réellement exclu
Deux défauts enchaînés : la requête Kitsu cumulait les genres en ET (quatre catégories → 1 seul titre, précisément le téléchargement à l'origine des genres), et l'exclusion échouait car « Titre - Saison 1 - E3 » ne normalisait jamais vers « Titre » canonique. - Une requête Kitsu par genre, fusion entrelacée (chaque genre contribue) - normalize_title retire saison/épisode en boucle avec frontières de mots (« - Saison 1 - E3 », « S1 E1 » → titre canonique ; « Série 9 » intact) - test de non-régession : le possédé avec marqueurs n'est plus recommandé
This commit is contained in:
@@ -303,15 +303,34 @@ class DiscoverService:
|
||||
return result
|
||||
|
||||
top_genres = sorted(genre_counts, key=genre_counts.get, reverse=True)[:_MAX_GENRES]
|
||||
slugs = [category_slug(genre) for genre in top_genres]
|
||||
items = await self._kitsu_anime(
|
||||
{
|
||||
"filter[categories]": ",".join(slugs),
|
||||
"sort": "-userCount",
|
||||
"page[limit]": limit, # le déjà-possédé est filtré après
|
||||
}
|
||||
)
|
||||
kept = [item for item in items if item["title"] and item["title"].casefold() not in owned]
|
||||
# Une requête par genre (Kitsu cumule les catégories en ET : quatre genres
|
||||
# ensemble ne laissent que quelques titres — parfois le déjà-possédé !).
|
||||
# Fusion entrelacée : chaque genre contribue, doublons retirés.
|
||||
pools = [
|
||||
list(pool)
|
||||
for pool in await asyncio.gather(*(
|
||||
self._kitsu_anime(
|
||||
{"filter[categories]": category_slug(g), "sort": "-userCount", "page[limit]": limit}
|
||||
)
|
||||
for g in top_genres
|
||||
))
|
||||
if pool
|
||||
]
|
||||
candidates: list[dict] = []
|
||||
seen: set[str] = set()
|
||||
while pools:
|
||||
for pool in pools[:]:
|
||||
item = pool.pop(0)
|
||||
key = str(item.get("kitsu_id") or item.get("title", "").casefold())
|
||||
if key not in seen:
|
||||
seen.add(key)
|
||||
candidates.append(item)
|
||||
if not pool:
|
||||
pools.remove(pool)
|
||||
kept = [
|
||||
item for item in candidates
|
||||
if item["title"] and normalize_title(item["title"]).casefold() not in owned
|
||||
][:limit]
|
||||
result = {"based_on": top_genres, "items": kept}
|
||||
self._cache.set(cache_key, result, _FOR_YOU_TTL_SECONDS)
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user