Skip to content

Commit 94d7e43

Browse files
committed
fix: update shared recognize cache flow
1 parent 64b4de3 commit 94d7e43

6 files changed

Lines changed: 236 additions & 12 deletions

File tree

app/chain/__init__.py

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,48 @@ def _can_use_media_recognize_share(
415415
and not any([tmdbid, doubanid, bangumiid])
416416
)
417417

418+
@staticmethod
419+
def _snapshot_recognize_cache_meta(meta: Optional[MetaBase]) -> Optional[MetaBase]:
420+
"""
421+
保存共享识别前的本地缓存关键元数据,用于共享成功后回填正缓存覆盖负缓存。
422+
"""
423+
if not meta:
424+
return None
425+
return copy.deepcopy(meta)
426+
427+
@staticmethod
428+
def _update_local_recognize_cache(
429+
self,
430+
meta: Optional[MetaBase],
431+
mediainfo: Optional[MediaInfo],
432+
) -> None:
433+
"""
434+
共享识别成功后回填本地识别缓存,避免名称负缓存导致后续重复回查共享。
435+
"""
436+
if not meta or not mediainfo:
437+
return
438+
self.run_module(
439+
"update_recognize_cache",
440+
meta=meta,
441+
mediainfo=mediainfo,
442+
)
443+
444+
async def _async_update_local_recognize_cache(
445+
self,
446+
meta: Optional[MetaBase],
447+
mediainfo: Optional[MediaInfo],
448+
) -> None:
449+
"""
450+
异步回填本地识别缓存。
451+
"""
452+
if not meta or not mediainfo:
453+
return
454+
await self.async_run_module(
455+
"async_update_recognize_cache",
456+
meta=meta,
457+
mediainfo=mediainfo,
458+
)
459+
418460
def recognize_media(
419461
self,
420462
meta: MetaBase = None,
@@ -460,10 +502,12 @@ def recognize_media(
460502
cache=cache,
461503
)
462504
if mediainfo:
463-
share_helper.report(meta=meta, mediainfo=mediainfo)
505+
if not mediainfo.recognize_cache_hit:
506+
share_helper.report(meta=meta, mediainfo=mediainfo)
464507
return mediainfo
465508

466509
if self._can_use_media_recognize_share(meta, tmdbid, doubanid, bangumiid):
510+
shared_cache_meta = self._snapshot_recognize_cache_meta(meta)
467511
shared_item = share_helper.query(meta=meta, mtype=mtype)
468512
shared_params = share_helper.to_recognize_params(shared_item)
469513
if shared_params:
@@ -479,7 +523,9 @@ def recognize_media(
479523
cache=cache,
480524
)
481525
if mediainfo:
482-
share_helper.report(meta=meta, mediainfo=mediainfo)
526+
self._update_local_recognize_cache(shared_cache_meta, mediainfo)
527+
if not mediainfo.recognize_cache_hit:
528+
share_helper.report(meta=meta, mediainfo=mediainfo)
483529
return mediainfo
484530
return None
485531

@@ -528,10 +574,12 @@ async def async_recognize_media(
528574
cache=cache,
529575
)
530576
if mediainfo:
531-
await share_helper.async_report(meta=meta, mediainfo=mediainfo)
577+
if not mediainfo.recognize_cache_hit:
578+
await share_helper.async_report(meta=meta, mediainfo=mediainfo)
532579
return mediainfo
533580

534581
if self._can_use_media_recognize_share(meta, tmdbid, doubanid, bangumiid):
582+
shared_cache_meta = self._snapshot_recognize_cache_meta(meta)
535583
shared_item = await share_helper.async_query(meta=meta, mtype=mtype)
536584
shared_params = share_helper.to_recognize_params(shared_item)
537585
if shared_params:
@@ -547,7 +595,9 @@ async def async_recognize_media(
547595
cache=cache,
548596
)
549597
if mediainfo:
550-
await share_helper.async_report(meta=meta, mediainfo=mediainfo)
598+
await self._async_update_local_recognize_cache(shared_cache_meta, mediainfo)
599+
if not mediainfo.recognize_cache_hit:
600+
await share_helper.async_report(meta=meta, mediainfo=mediainfo)
551601
return mediainfo
552602
return None
553603

app/core/context.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ def to_dict(self):
152152

153153
@dataclass
154154
class MediaInfo:
155+
# 内部标记:是否命中本地识别缓存,不参与序列化
156+
recognize_cache_hit = False
155157
# 来源:themoviedb、douban、bangumi
156158
source: str = None
157159
# 类型 电影、电视剧

app/helper/recognize.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def _extract_keyword(meta: Optional[MetaBase]) -> Optional[str]:
3939
"""
4040
if not meta:
4141
return None
42-
keyword = getattr(meta, "original_name", None) or getattr(meta, "name", None)
42+
keyword = meta.original_name or meta.name
4343
if keyword:
4444
keyword = str(keyword).strip()
4545
return keyword or None
@@ -77,7 +77,7 @@ def _extract_season(
7777
"""
7878
if media_type != "tv":
7979
return None
80-
season = getattr(meta, "begin_season", None)
80+
season = meta.begin_season if meta else None
8181
if season is None and mediainfo:
8282
season = mediainfo.season
8383
try:
@@ -93,7 +93,7 @@ def _extract_year(
9393
"""
9494
提取年份
9595
"""
96-
year = getattr(meta, "year", None) or (mediainfo.year if mediainfo else None)
96+
year = (meta.year if meta else None) or (mediainfo.year if mediainfo else None)
9797
if year is None:
9898
return None
9999
year_text = str(year).strip()

app/modules/douban/__init__.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ def _recognize_media_core(self, meta: MetaBase = None,
108108
if doubanid:
109109
meta.doubanid = doubanid
110110
cache_info = self.cache.get(meta)
111+
cache_hit = False
111112

112113
# 识别豆瓣信息
113114
if not cache_info or not cache:
@@ -148,6 +149,7 @@ def _recognize_media_core(self, meta: MetaBase = None,
148149
self.cache.update(meta, info)
149150
else:
150151
# 使用缓存信息
152+
cache_hit = True
151153
if cache_info.get("title"):
152154
logger.info(f"{meta.name} 使用豆瓣识别缓存:{cache_info.get('title')}")
153155
info = douban_info_func(mtype=cache_info.get("type"),
@@ -159,6 +161,7 @@ def _recognize_media_core(self, meta: MetaBase = None,
159161
if info:
160162
# 赋值TMDB信息并返回
161163
mediainfo = MediaInfo(douban_info=info)
164+
mediainfo.recognize_cache_hit = cache_hit
162165
if meta:
163166
logger.info(f"{meta.name} 豆瓣识别结果:{mediainfo.type.value} "
164167
f"{mediainfo.title_year} "
@@ -209,6 +212,7 @@ async def _async_recognize_media_core(self, meta: MetaBase = None,
209212
if doubanid:
210213
meta.doubanid = doubanid
211214
cache_info = self.cache.get(meta)
215+
cache_hit = False
212216

213217
# 识别豆瓣信息
214218
if not cache_info or not cache:
@@ -249,6 +253,7 @@ async def _async_recognize_media_core(self, meta: MetaBase = None,
249253
self.cache.update(meta, info)
250254
else:
251255
# 使用缓存信息
256+
cache_hit = True
252257
if cache_info.get("title"):
253258
logger.info(f"{meta.name} 使用豆瓣识别缓存:{cache_info.get('title')}")
254259
info = await async_douban_info_func(mtype=cache_info.get("type"),
@@ -260,6 +265,7 @@ async def _async_recognize_media_core(self, meta: MetaBase = None,
260265
if info:
261266
# 赋值TMDB信息并返回
262267
mediainfo = MediaInfo(douban_info=info)
268+
mediainfo.recognize_cache_hit = cache_hit
263269
if meta:
264270
logger.info(f"{meta.name} 豆瓣识别结果:{mediainfo.type.value} "
265271
f"{mediainfo.title_year} "
@@ -319,6 +325,31 @@ async def async_recognize_media(self, meta: MetaBase = None,
319325
**kwargs
320326
)
321327

328+
def update_recognize_cache(
329+
self,
330+
meta: MetaBase,
331+
mediainfo: MediaInfo,
332+
) -> Optional[bool]:
333+
"""
334+
回填豆瓣本地识别缓存,覆盖名称负缓存,避免共享识别后重复回查。
335+
"""
336+
if not meta or not mediainfo:
337+
return None
338+
if mediainfo.source != "douban" or not mediainfo.douban_info:
339+
return None
340+
self.cache.update(meta, mediainfo.douban_info)
341+
return True
342+
343+
async def async_update_recognize_cache(
344+
self,
345+
meta: MetaBase,
346+
mediainfo: MediaInfo,
347+
) -> Optional[bool]:
348+
"""
349+
异步回填豆瓣本地识别缓存。
350+
"""
351+
return self.update_recognize_cache(meta=meta, mediainfo=mediainfo)
352+
322353
@rate_limit_exponential(source="douban_info")
323354
def douban_info(self, doubanid: str, mtype: MediaType = None, raise_exception: bool = True) -> Optional[dict]:
324355
"""

app/modules/themoviedb/__init__.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,7 @@ def recognize_media(self, meta: MetaBase = None,
490490
group_seasons = []
491491
if episode_group:
492492
group_seasons = self.tmdb.get_tv_group_seasons(episode_group)
493+
cache_hit = False
493494

494495
# 识别匹配
495496
if not cache_info or not cache:
@@ -525,6 +526,7 @@ def recognize_media(self, meta: MetaBase = None,
525526
self.cache.update(meta, info)
526527
else:
527528
# 使用缓存信息
529+
cache_hit = True
528530
if cache_info.get("title"):
529531
logger.info(f"{meta.name} 使用TMDB识别缓存:{cache_info.get('title')}")
530532
info = self.tmdb.get_info(mtype=cache_info.get("type"),
@@ -534,7 +536,10 @@ def recognize_media(self, meta: MetaBase = None,
534536
info = None
535537

536538
if info:
537-
return self._build_media_info_result(info, meta, tmdbid, episode_group, group_seasons)
539+
mediainfo = self._build_media_info_result(info, meta, tmdbid, episode_group, group_seasons)
540+
if mediainfo:
541+
mediainfo.recognize_cache_hit = cache_hit
542+
return mediainfo
538543
else:
539544
logger.info(f"{meta.name if meta else tmdbid} 未匹配到TMDB媒体信息")
540545

@@ -574,6 +579,7 @@ async def async_recognize_media(self, meta: MetaBase = None,
574579
group_seasons = []
575580
if episode_group:
576581
group_seasons = await self.tmdb.async_get_tv_group_seasons(episode_group)
582+
cache_hit = False
577583

578584
# 识别匹配
579585
if not cache_info or not cache:
@@ -609,6 +615,7 @@ async def async_recognize_media(self, meta: MetaBase = None,
609615
self.cache.update(meta, info)
610616
else:
611617
# 使用缓存信息
618+
cache_hit = True
612619
if cache_info.get("title"):
613620
logger.info(f"{meta.name} 使用TMDB识别缓存:{cache_info.get('title')}")
614621
info = await self.tmdb.async_get_info(mtype=cache_info.get("type"),
@@ -618,7 +625,10 @@ async def async_recognize_media(self, meta: MetaBase = None,
618625
info = None
619626

620627
if info:
621-
return await self._async_build_media_info_result(info, meta, tmdbid, episode_group, group_seasons)
628+
mediainfo = await self._async_build_media_info_result(info, meta, tmdbid, episode_group, group_seasons)
629+
if mediainfo:
630+
mediainfo.recognize_cache_hit = cache_hit
631+
return mediainfo
622632
else:
623633
logger.info(f"{meta.name if meta else tmdbid} 未匹配到TMDB媒体信息")
624634

@@ -692,6 +702,31 @@ async def async_tmdb_info(self, tmdbid: int, mtype: MediaType, season: Optional[
692702
else:
693703
return await self.tmdb.async_get_tv_season_detail(tmdbid=tmdbid, season=season)
694704

705+
def update_recognize_cache(
706+
self,
707+
meta: MetaBase,
708+
mediainfo: MediaInfo,
709+
) -> Optional[bool]:
710+
"""
711+
回填TMDB本地识别缓存,覆盖名称负缓存,避免共享识别后重复回查。
712+
"""
713+
if not meta or not mediainfo:
714+
return None
715+
if mediainfo.source != "themoviedb" or not mediainfo.tmdb_info:
716+
return None
717+
self.cache.update(meta, mediainfo.tmdb_info)
718+
return True
719+
720+
async def async_update_recognize_cache(
721+
self,
722+
meta: MetaBase,
723+
mediainfo: MediaInfo,
724+
) -> Optional[bool]:
725+
"""
726+
异步回填TMDB本地识别缓存。
727+
"""
728+
return self.update_recognize_cache(meta=meta, mediainfo=mediainfo)
729+
695730
def media_category(self) -> Optional[Dict[str, list]]:
696731
"""
697732
获取媒体分类

0 commit comments

Comments
 (0)