diff --git a/app/modules/themoviedb/tmdbapi.py b/app/modules/themoviedb/tmdbapi.py index fa1da865..34f3743f 100644 --- a/app/modules/themoviedb/tmdbapi.py +++ b/app/modules/themoviedb/tmdbapi.py @@ -200,55 +200,45 @@ class TmdbApi: ret_info['media_type'] = MediaType.MOVIE if ret_info.get("media_type") == "movie" else MediaType.TV return ret_info - def _match_multi_item(self, name: str, multi: dict, get_info_func) -> Optional[dict]: + @staticmethod + def _match_multi_title(name_compare_func, name: str, multi: dict) -> bool: """ - 匹配单个多媒体搜索结果项 - :param name: 查询名称 - :param multi: 搜索结果项 - :param get_info_func: 获取详细信息的函数(同步或异步) - :return: 匹配的结果或None + 匹配单个多媒体搜索结果项的标题/原标题 + """ + if multi.get("media_type") == "movie": + return (name_compare_func(name, multi.get('title')) + or name_compare_func(name, multi.get('original_title'))) + elif multi.get("media_type") == "tv": + return (name_compare_func(name, multi.get('name')) + or name_compare_func(name, multi.get('original_name'))) + return False + + def _match_multi_names(self, name: str, multi: dict, get_info_func) -> Optional[dict]: + """ + 匹配单个多媒体搜索结果项的别名、译名 """ if multi.get("media_type") == "movie": - if self.__compare_names(name, multi.get('title')) \ - or self.__compare_names(name, multi.get('original_title')): - return multi - # 匹配别名、译名 if not multi.get("names"): multi = get_info_func(mtype=MediaType.MOVIE, tmdbid=multi.get("id")) if multi and self.__compare_names(name, multi.get("names")): return multi elif multi.get("media_type") == "tv": - if self.__compare_names(name, multi.get('name')) \ - or self.__compare_names(name, multi.get('original_name')): - return multi - # 匹配别名、译名 if not multi.get("names"): multi = get_info_func(mtype=MediaType.TV, tmdbid=multi.get("id")) if multi and self.__compare_names(name, multi.get("names")): return multi return None - async def _async_match_multi_item(self, name: str, multi: dict) -> Optional[dict]: + async def _async_match_multi_names(self, name: str, multi: dict) -> Optional[dict]: """ - 匹配单个多媒体搜索结果项(异步版本) - :param name: 查询名称 - :param multi: 搜索结果项 - :return: 匹配的结果或None + 匹配单个多媒体搜索结果项的别名、译名(异步版本) """ if multi.get("media_type") == "movie": - if self.__compare_names(name, multi.get('title')) \ - or self.__compare_names(name, multi.get('original_title')): - return multi - # 匹配别名、译名 if not multi.get("names"): multi = await self.async_get_info(mtype=MediaType.MOVIE, tmdbid=multi.get("id")) if multi and self.__compare_names(name, multi.get("names")): return multi elif multi.get("media_type") == "tv": - if self.__compare_names(name, multi.get('name')) \ - or self.__compare_names(name, multi.get('original_name')): - return multi - # 匹配别名、译名 if not multi.get("names"): multi = await self.async_get_info(mtype=MediaType.TV, tmdbid=multi.get("id")) if multi and self.__compare_names(name, multi.get("names")): @@ -366,18 +356,18 @@ class TmdbApi: key=lambda x: x.get('release_date') or '0000-00-00', reverse=True ) + # 过滤年份 + if year: + movies = [m for m in movies + if (m.get('release_date') or '')[0:4] == year] + # 第一轮:优先匹配标题、原标题 for movie in movies: - # 年份 - movie_year = movie.get('release_date')[0:4] if movie.get('release_date') else None - if year and movie_year != year: - # 年份不匹配 - continue - # 匹配标题、原标题 if self.__compare_names(name, movie.get('title')): return movie if self.__compare_names(name, movie.get('original_title')): return movie - # 匹配别名、译名 + # 第二轮:匹配别名、译名 + for movie in movies: if not movie.get("names"): movie = self.get_info(mtype=MediaType.MOVIE, tmdbid=movie.get("id")) if movie and self.__compare_names(name, movie.get("names")): @@ -413,17 +403,18 @@ class TmdbApi: key=lambda x: x.get('first_air_date') or '0000-00-00', reverse=True ) + # 过滤年份 + if year: + tvs = [t for t in tvs + if (t.get('first_air_date') or '')[0:4] == year] + # 第一轮:优先匹配标题、原标题 for tv in tvs: - tv_year = tv.get('first_air_date')[0:4] if tv.get('first_air_date') else None - if year and tv_year != year: - # 年份不匹配 - continue - # 匹配标题、原标题 if self.__compare_names(name, tv.get('name')): return tv if self.__compare_names(name, tv.get('original_name')): return tv - # 匹配别名、译名 + # 第二轮:匹配别名、译名 + for tv in tvs: if not tv.get("names"): tv = self.get_info(mtype=MediaType.TV, tmdbid=tv.get("id")) if tv and self.__compare_names(name, tv.get("names")): @@ -575,12 +566,19 @@ class TmdbApi: # 按年份降序排列,电影在前面 multis = self._sort_multi_results(multis) + # 第一轮:优先匹配标题、原标题 ret_info = {} for multi in multis: - matched = self._match_multi_item(name, multi, self.get_info) - if matched: - ret_info = matched + if self._match_multi_title(self.__compare_names, name, multi): + ret_info = multi break + # 第二轮:匹配别名、译名 + if not ret_info: + for multi in multis: + matched = self._match_multi_names(name, multi, self.get_info) + if matched: + ret_info = matched + break # 类型变更 return self._convert_media_type(ret_info) @@ -1521,18 +1519,18 @@ class TmdbApi: key=lambda x: x.get('release_date') or '0000-00-00', reverse=True ) + # 过滤年份 + if year: + movies = [m for m in movies + if (m.get('release_date') or '')[0:4] == year] + # 第一轮:优先匹配标题、原标题 for movie in movies: - # 年份 - movie_year = movie.get('release_date')[0:4] if movie.get('release_date') else None - if year and movie_year != year: - # 年份不匹配 - continue - # 匹配标题、原标题 if self.__compare_names(name, movie.get('title')): return movie if self.__compare_names(name, movie.get('original_title')): return movie - # 匹配别名、译名 + # 第二轮:匹配别名、译名 + for movie in movies: if not movie.get("names"): movie = await self.async_get_info(mtype=MediaType.MOVIE, tmdbid=movie.get("id")) if movie and self.__compare_names(name, movie.get("names")): @@ -1568,17 +1566,18 @@ class TmdbApi: key=lambda x: x.get('first_air_date') or '0000-00-00', reverse=True ) + # 过滤年份 + if year: + tvs = [t for t in tvs + if (t.get('first_air_date') or '')[0:4] == year] + # 第一轮:优先匹配标题、原标题 for tv in tvs: - tv_year = tv.get('first_air_date')[0:4] if tv.get('first_air_date') else None - if year and tv_year != year: - # 年份不匹配 - continue - # 匹配标题、原标题 if self.__compare_names(name, tv.get('name')): return tv if self.__compare_names(name, tv.get('original_name')): return tv - # 匹配别名、译名 + # 第二轮:匹配别名、译名 + for tv in tvs: if not tv.get("names"): tv = await self.async_get_info(mtype=MediaType.TV, tmdbid=tv.get("id")) if tv and self.__compare_names(name, tv.get("names")): @@ -1897,12 +1896,19 @@ class TmdbApi: # 按年份降序排列,电影在前面 multis = self._sort_multi_results(multis) + # 第一轮:优先匹配标题、原标题 ret_info = {} for multi in multis: - matched = await self._async_match_multi_item(name, multi) - if matched: - ret_info = matched + if self._match_multi_title(self.__compare_names, name, multi): + ret_info = multi break + # 第二轮:匹配别名、译名 + if not ret_info: + for multi in multis: + matched = await self._async_match_multi_names(name, multi) + if matched: + ret_info = matched + break # 类型变更 return self._convert_media_type(ret_info)