fix: restore tmdb trending recommendations

This commit is contained in:
jxxghp
2026-05-20 10:55:01 +08:00
parent c3e4e1a764
commit a5745af484
6 changed files with 112 additions and 20 deletions

View File

@@ -157,7 +157,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
return [tv.to_dict() for tv in tvs] if tvs else []
@log_execution_time(logger=logger)
@cached(ttl=recommend_ttl, region=recommend_cache_region)
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
def tmdb_trending(self, page: Optional[int] = 1) -> List[dict]:
"""
TMDB流行趋势
@@ -312,7 +312,7 @@ class RecommendChain(ChainBase, metaclass=Singleton):
return [tv.to_dict() for tv in tvs] if tvs else []
@log_execution_time(logger=logger)
@cached(ttl=recommend_ttl, region=recommend_cache_region)
@cached(ttl=recommend_ttl, region=recommend_cache_region, skip_empty=True)
async def async_tmdb_trending(self, page: Optional[int] = 1) -> List[dict]:
"""
异步TMDB流行趋势

View File

@@ -1220,6 +1220,26 @@ class TmdbApi:
logger.error(str(e))
return []
@staticmethod
def _normalize_trending_infos(infos: Optional[List[dict]]) -> List[dict]:
"""
过滤流行趋势中的人物等非媒体项,并统一电影、电视剧的媒体类型。
"""
if not infos:
return []
ret_infos = []
for info in infos:
media_type = info.get("media_type")
if media_type == "movie":
info["media_type"] = MediaType.MOVIE
elif media_type == "tv":
info["media_type"] = MediaType.TV
elif media_type not in [MediaType.MOVIE, MediaType.TV]:
continue
ret_infos.append(info)
return ret_infos
def discover_trending(self, page: Optional[int] = 1) -> List[dict]:
"""
流行趋势
@@ -1228,7 +1248,8 @@ class TmdbApi:
return []
try:
logger.debug(f"正在获取流行趋势page={page} ...")
return self.trending.all_week(page=page)
tmdbinfo = self.trending.all_week(page=page)
return self._normalize_trending_infos(tmdbinfo)
except Exception as e:
logger.error(str(e))
return []
@@ -1988,7 +2009,8 @@ class TmdbApi:
return []
try:
logger.debug(f"正在获取流行趋势page={page} ...")
return await self.trending.async_all_week(page=page)
tmdbinfo = await self.trending.async_all_week(page=page)
return self._normalize_trending_infos(tmdbinfo)
except Exception as e:
logger.error(str(e))
return []

View File

@@ -171,7 +171,7 @@ class TMDb(object):
json_data = cls._decode_compressed_response_json(response)
if json_data is not cls._JSON_DECODE_FAILED:
return json_data
raise TMDbException(cls._build_invalid_json_message(response)) from err
raise TMDbException(cls._build_invalid_json_message(response, err)) from err
@classmethod
def _decode_compressed_response_json(cls, response):
@@ -224,23 +224,27 @@ class TMDb(object):
return None
@staticmethod
def _build_invalid_json_message(response):
def _build_invalid_json_message(response, parse_error: Exception = None):
"""
生成非JSON响应的诊断信息避免日志只保留JSONDecodeError文本。
"""
status_code = getattr(response, "status_code", None)
headers = getattr(response, "headers", {}) or {}
content_type = TMDb._get_header_value(headers, "Content-Type")
is_encoding_error = isinstance(parse_error, UnicodeDecodeError)
try:
response_text = getattr(response, "text", "") or ""
except Exception as err: # pragma: no cover - 防御异常响应对象
response_text = f"<读取响应内容失败:{err!r}>"
if not isinstance(response_text, str):
response_text = repr(response_text)
response_text = response_text.strip()
if len(response_text) > 200:
response_text = f"{response_text[:200]}..."
# 编码错误时响应体通常是压缩字节或乱码,打印内容只会污染日志。
response_text = ""
if not is_encoding_error:
try:
response_text = getattr(response, "text", "") or ""
except Exception as err: # pragma: no cover - 防御异常响应对象
response_text = f"<读取响应内容失败:{err!r}>"
if not isinstance(response_text, str):
response_text = repr(response_text)
response_text = response_text.strip()
if len(response_text) > 200:
response_text = f"{response_text[:200]}..."
message_parts = ["TheMovieDb 返回数据不是有效JSON"]
if status_code is not None:
@@ -250,7 +254,9 @@ class TMDb(object):
content_encoding = TMDb._get_header_value(headers, "Content-Encoding")
if content_encoding:
message_parts.append(f"Content-Encoding{content_encoding}")
if response_text:
if is_encoding_error:
message_parts.append("响应内容因编码错误已省略")
elif response_text:
message_parts.append(f"响应内容:{response_text!r}")
else:
message_parts.append("响应内容为空")