mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-07-21 04:31:59 +08:00
perf: optimize media recognition internals
This commit is contained in:
@@ -71,6 +71,42 @@ class DoubanModule(_ModuleBase):
|
||||
"""
|
||||
return 2
|
||||
|
||||
@staticmethod
|
||||
def _prepare_search_names(meta: MetaBase) -> List[str]:
|
||||
"""
|
||||
准备搜索名称列表,保留中英文名称分别识别且按顺序去重的历史行为。
|
||||
"""
|
||||
# 简体名称
|
||||
zh_name = zhconv.convert(meta.cn_name, "zh-hans") if meta.cn_name else None
|
||||
# 使用中英文名分别识别,去重去空,但要保持顺序
|
||||
return list(dict.fromkeys([k for k in [meta.cn_name, zh_name, meta.en_name] if k]))
|
||||
|
||||
@staticmethod
|
||||
def _build_search_medias_result(meta: MetaBase, items: Optional[List[dict]]) -> List[MediaInfo]:
|
||||
"""
|
||||
构建豆瓣搜索结果,并沿用原有的类型、标题包含和季信息处理规则。
|
||||
"""
|
||||
if not items:
|
||||
return []
|
||||
ret_medias = []
|
||||
for item_obj in items:
|
||||
if meta.type and meta.type != MediaType.UNKNOWN and meta.type.value != item_obj.get("type_name"):
|
||||
continue
|
||||
if item_obj.get("type_name") not in (MediaType.TV.value, MediaType.MOVIE.value):
|
||||
continue
|
||||
if meta.name not in item_obj.get("target", {}).get("title"):
|
||||
continue
|
||||
ret_medias.append(MediaInfo(douban_info=item_obj.get("target")))
|
||||
# 将搜索词中的季写入标题中
|
||||
if ret_medias and meta.begin_season:
|
||||
# 小写数据转大写
|
||||
season_str = cn2an.an2cn(meta.begin_season, "low")
|
||||
for media in ret_medias:
|
||||
if media.type == MediaType.TV:
|
||||
media.title = f"{media.title} 第{season_str}季"
|
||||
media.season = meta.begin_season
|
||||
return ret_medias
|
||||
|
||||
def _recognize_media_core(self, meta: MetaBase = None,
|
||||
mtype: MediaType = None,
|
||||
doubanid: Optional[str] = None,
|
||||
@@ -107,7 +143,7 @@ class DoubanModule(_ModuleBase):
|
||||
meta.type = mtype
|
||||
if doubanid:
|
||||
meta.doubanid = doubanid
|
||||
cache_info = self.cache.get(meta)
|
||||
cache_info = self.cache.get(meta) if cache else {}
|
||||
cache_hit = False
|
||||
|
||||
# 识别豆瓣信息
|
||||
@@ -118,11 +154,7 @@ class DoubanModule(_ModuleBase):
|
||||
info = douban_info_func(doubanid=doubanid, mtype=mtype or meta.type)
|
||||
elif meta:
|
||||
info = {}
|
||||
# 简体名称
|
||||
zh_name = zhconv.convert(meta.cn_name, "zh-hans") if meta.cn_name else None
|
||||
# 使用中英文名分别识别,去重去空,但要保持顺序
|
||||
names = list(dict.fromkeys([k for k in [meta.cn_name, zh_name, meta.en_name] if k]))
|
||||
for name in names:
|
||||
for name in self._prepare_search_names(meta):
|
||||
if meta.begin_season:
|
||||
logger.info(f"正在识别 {name} 第{meta.begin_season}季 ...")
|
||||
else:
|
||||
@@ -211,7 +243,7 @@ class DoubanModule(_ModuleBase):
|
||||
meta.type = mtype
|
||||
if doubanid:
|
||||
meta.doubanid = doubanid
|
||||
cache_info = self.cache.get(meta)
|
||||
cache_info = self.cache.get(meta) if cache else {}
|
||||
cache_hit = False
|
||||
|
||||
# 识别豆瓣信息
|
||||
@@ -222,11 +254,7 @@ class DoubanModule(_ModuleBase):
|
||||
info = await async_douban_info_func(doubanid=doubanid, mtype=mtype or meta.type)
|
||||
elif meta:
|
||||
info = {}
|
||||
# 简体名称
|
||||
zh_name = zhconv.convert(meta.cn_name, "zh-hans") if meta.cn_name else None
|
||||
# 使用中英文名分别识别,去重去空,但要保持顺序
|
||||
names = list(dict.fromkeys([k for k in [meta.cn_name, zh_name, meta.en_name] if k]))
|
||||
for name in names:
|
||||
for name in self._prepare_search_names(meta):
|
||||
if meta.begin_season:
|
||||
logger.info(f"正在识别 {name} 第{meta.begin_season}季 ...")
|
||||
else:
|
||||
@@ -913,24 +941,7 @@ class DoubanModule(_ModuleBase):
|
||||
if not result or not result.get("items"):
|
||||
return []
|
||||
# 返回数据
|
||||
ret_medias = []
|
||||
for item_obj in result.get("items"):
|
||||
if meta.type and meta.type != MediaType.UNKNOWN and meta.type.value != item_obj.get("type_name"):
|
||||
continue
|
||||
if item_obj.get("type_name") not in (MediaType.TV.value, MediaType.MOVIE.value):
|
||||
continue
|
||||
if meta.name not in item_obj.get("target", {}).get("title"):
|
||||
continue
|
||||
ret_medias.append(MediaInfo(douban_info=item_obj.get("target")))
|
||||
# 将搜索词中的季写入标题中
|
||||
if ret_medias and meta.begin_season:
|
||||
# 小写数据转大写
|
||||
season_str = cn2an.an2cn(meta.begin_season, "low")
|
||||
for media in ret_medias:
|
||||
if media.type == MediaType.TV:
|
||||
media.title = f"{media.title} 第{season_str}季"
|
||||
media.season = meta.begin_season
|
||||
return ret_medias
|
||||
return self._build_search_medias_result(meta, result.get("items"))
|
||||
|
||||
async def async_search_medias(self, meta: MetaBase) -> Optional[List[MediaInfo]]:
|
||||
"""
|
||||
@@ -946,24 +957,7 @@ class DoubanModule(_ModuleBase):
|
||||
if not result or not result.get("items"):
|
||||
return []
|
||||
# 返回数据
|
||||
ret_medias = []
|
||||
for item_obj in result.get("items"):
|
||||
if meta.type and meta.type != MediaType.UNKNOWN and meta.type.value != item_obj.get("type_name"):
|
||||
continue
|
||||
if item_obj.get("type_name") not in (MediaType.TV.value, MediaType.MOVIE.value):
|
||||
continue
|
||||
if meta.name not in item_obj.get("target", {}).get("title"):
|
||||
continue
|
||||
ret_medias.append(MediaInfo(douban_info=item_obj.get("target")))
|
||||
# 将搜索词中的季写入标题中
|
||||
if ret_medias and meta.begin_season:
|
||||
# 小写数据转大写
|
||||
season_str = cn2an.an2cn(meta.begin_season, "low")
|
||||
for media in ret_medias:
|
||||
if media.type == MediaType.TV:
|
||||
media.title = f"{media.title} 第{season_str}季"
|
||||
media.season = meta.begin_season
|
||||
return ret_medias
|
||||
return self._build_search_medias_result(meta, result.get("items"))
|
||||
|
||||
def search_persons(self, name: str) -> Optional[List[MediaPerson]]:
|
||||
"""
|
||||
|
||||
@@ -19,6 +19,8 @@ from app.schemas.types import MediaType, MediaImageType, ModuleType, MediaRecogn
|
||||
from app.utils.http import RequestUtils
|
||||
|
||||
|
||||
_DATE_RE = re.compile(r"^\d{4}-\d{2}-\d{2}$")
|
||||
|
||||
|
||||
class TheMovieDbModule(_ModuleBase):
|
||||
"""
|
||||
@@ -118,6 +120,59 @@ class TheMovieDbModule(_ModuleBase):
|
||||
# 使用中英文名分别识别,去重去空,但要保持顺序
|
||||
return list(dict.fromkeys([k for k in [meta.cn_name, zh_name, meta.en_name] if k]))
|
||||
|
||||
@staticmethod
|
||||
def _fill_group_season_info(mediainfo: MediaInfo, episode_group: Optional[str],
|
||||
group_seasons: List[dict]) -> None:
|
||||
"""
|
||||
将指定剧集组的季、集、年份信息写入 MediaInfo。
|
||||
"""
|
||||
seasons = {}
|
||||
season_info = []
|
||||
season_years = {}
|
||||
for group_season in group_seasons:
|
||||
# 季
|
||||
season = group_season.get("order")
|
||||
# 集列表
|
||||
episodes = group_season.get("episodes")
|
||||
if not episodes:
|
||||
continue
|
||||
seasons[season] = [ep.get("episode_number") for ep in episodes]
|
||||
season_info.append(group_season)
|
||||
# 当前季第一集时间
|
||||
first_date = episodes[0].get("air_date")
|
||||
if first_date and _DATE_RE.match(first_date):
|
||||
season_years[season] = str(first_date).split("-")[0]
|
||||
# 每季集清单
|
||||
if seasons:
|
||||
mediainfo.seasons = seasons
|
||||
mediainfo.number_of_seasons = len(seasons)
|
||||
# 每季集详情
|
||||
if season_info:
|
||||
mediainfo.season_info = season_info
|
||||
# 每季年份
|
||||
if season_years:
|
||||
mediainfo.season_years = season_years
|
||||
# 所有剧集组
|
||||
mediainfo.episode_group = episode_group
|
||||
mediainfo.episode_groups = group_seasons
|
||||
|
||||
@staticmethod
|
||||
def _build_search_medias_result(meta: MetaBase, results: Optional[List[dict]]) -> List[MediaInfo]:
|
||||
"""
|
||||
构建搜索结果,并沿用原有逻辑把搜索词中的季写入电视剧标题中。
|
||||
"""
|
||||
if not results:
|
||||
return []
|
||||
medias = [MediaInfo(tmdb_info=info) for info in results]
|
||||
if meta.begin_season:
|
||||
# 小写数据转大写
|
||||
season_str = cn2an.an2cn(meta.begin_season, "low")
|
||||
for media in medias:
|
||||
if media.type == MediaType.TV:
|
||||
media.title = f"{media.title} 第{season_str}季"
|
||||
media.season = meta.begin_season
|
||||
return medias
|
||||
|
||||
def _get_info_by_tmdbid(self, tmdbid: int, mtype: Optional[MediaType],
|
||||
meta: Optional[MetaBase]) -> Optional[dict]:
|
||||
"""
|
||||
@@ -289,36 +344,7 @@ class TheMovieDbModule(_ModuleBase):
|
||||
"""
|
||||
if mediainfo.type == MediaType.TV and mediainfo.episode_groups:
|
||||
if group_seasons:
|
||||
# 指定剧集组时
|
||||
seasons = {}
|
||||
season_info = []
|
||||
season_years = {}
|
||||
for group_season in group_seasons:
|
||||
# 季
|
||||
season = group_season.get("order")
|
||||
# 集列表
|
||||
episodes = group_season.get("episodes")
|
||||
if not episodes:
|
||||
continue
|
||||
seasons[season] = [ep.get("episode_number") for ep in episodes]
|
||||
season_info.append(group_season)
|
||||
# 当前季第一季时间
|
||||
first_date = episodes[0].get("air_date")
|
||||
if re.match(r"^\d{4}-\d{2}-\d{2}$", first_date):
|
||||
season_years[season] = str(first_date).split("-")[0]
|
||||
# 每季集清单
|
||||
if seasons:
|
||||
mediainfo.seasons = seasons
|
||||
mediainfo.number_of_seasons = len(seasons)
|
||||
# 每季集详情
|
||||
if season_info:
|
||||
mediainfo.season_info = season_info
|
||||
# 每季年份
|
||||
if season_years:
|
||||
mediainfo.season_years = season_years
|
||||
# 所有剧集组
|
||||
mediainfo.episode_group = episode_group
|
||||
mediainfo.episode_groups = group_seasons
|
||||
self._fill_group_season_info(mediainfo, episode_group, group_seasons)
|
||||
else:
|
||||
# 每季年份
|
||||
season_years = {}
|
||||
@@ -337,7 +363,7 @@ class TheMovieDbModule(_ModuleBase):
|
||||
# 当前季第一季时间
|
||||
first_date = episodes[0].get("air_date")
|
||||
# 判断是不是日期格式
|
||||
if first_date and re.match(r"^\d{4}-\d{2}-\d{2}$", first_date):
|
||||
if first_date and _DATE_RE.match(first_date):
|
||||
season_years[season] = str(first_date).split("-")[0]
|
||||
if season_years:
|
||||
mediainfo.season_years = season_years
|
||||
@@ -350,36 +376,7 @@ class TheMovieDbModule(_ModuleBase):
|
||||
"""
|
||||
if mediainfo.type == MediaType.TV and mediainfo.episode_groups:
|
||||
if group_seasons:
|
||||
# 指定剧集组时
|
||||
seasons = {}
|
||||
season_info = []
|
||||
season_years = {}
|
||||
for group_season in group_seasons:
|
||||
# 季
|
||||
season = group_season.get("order")
|
||||
# 集列表
|
||||
episodes = group_season.get("episodes")
|
||||
if not episodes:
|
||||
continue
|
||||
seasons[season] = [ep.get("episode_number") for ep in episodes]
|
||||
season_info.append(group_season)
|
||||
# 当前季第一季时间
|
||||
first_date = episodes[0].get("air_date")
|
||||
if re.match(r"^\d{4}-\d{2}-\d{2}$", first_date):
|
||||
season_years[season] = str(first_date).split("-")[0]
|
||||
# 每季集清单
|
||||
if seasons:
|
||||
mediainfo.seasons = seasons
|
||||
mediainfo.number_of_seasons = len(seasons)
|
||||
# 每季集详情
|
||||
if season_info:
|
||||
mediainfo.season_info = season_info
|
||||
# 每季年份
|
||||
if season_years:
|
||||
mediainfo.season_years = season_years
|
||||
# 所有剧集组
|
||||
mediainfo.episode_group = episode_group
|
||||
mediainfo.episode_groups = group_seasons
|
||||
self._fill_group_season_info(mediainfo, episode_group, group_seasons)
|
||||
else:
|
||||
# 每季年份
|
||||
season_years = {}
|
||||
@@ -398,7 +395,7 @@ class TheMovieDbModule(_ModuleBase):
|
||||
# 当前季第一季时间
|
||||
first_date = episodes[0].get("air_date")
|
||||
# 判断是不是日期格式
|
||||
if first_date and re.match(r"^\d{4}-\d{2}-\d{2}$", first_date):
|
||||
if first_date and _DATE_RE.match(first_date):
|
||||
season_years[season] = str(first_date).split("-")[0]
|
||||
if season_years:
|
||||
mediainfo.season_years = season_years
|
||||
@@ -484,7 +481,7 @@ class TheMovieDbModule(_ModuleBase):
|
||||
meta.type = mtype
|
||||
if tmdbid:
|
||||
meta.tmdbid = tmdbid
|
||||
cache_info = self.cache.get(meta)
|
||||
cache_info = self.cache.get(meta) if cache else {}
|
||||
|
||||
# 查询剧集组
|
||||
group_seasons = []
|
||||
@@ -573,7 +570,7 @@ class TheMovieDbModule(_ModuleBase):
|
||||
meta.type = mtype
|
||||
if tmdbid:
|
||||
meta.tmdbid = tmdbid
|
||||
cache_info = self.cache.get(meta)
|
||||
cache_info = self.cache.get(meta) if cache else {}
|
||||
|
||||
# 查询剧集组
|
||||
group_seasons = []
|
||||
@@ -764,17 +761,7 @@ class TheMovieDbModule(_ModuleBase):
|
||||
else:
|
||||
results = self.tmdb.search_tvs(meta.name, meta.year)
|
||||
# 将搜索词中的季写入标题中
|
||||
if results:
|
||||
medias = [MediaInfo(tmdb_info=info) for info in results]
|
||||
if meta.begin_season:
|
||||
# 小写数据转大写
|
||||
season_str = cn2an.an2cn(meta.begin_season, "low")
|
||||
for media in medias:
|
||||
if media.type == MediaType.TV:
|
||||
media.title = f"{media.title} 第{season_str}季"
|
||||
media.season = meta.begin_season
|
||||
return medias
|
||||
return []
|
||||
return self._build_search_medias_result(meta, results)
|
||||
|
||||
def search_persons(self, name: str) -> Optional[List[schemas.MediaPerson]]:
|
||||
"""
|
||||
@@ -1206,17 +1193,7 @@ class TheMovieDbModule(_ModuleBase):
|
||||
else:
|
||||
results = await self.tmdb.async_search_tvs(meta.name, meta.year)
|
||||
# 将搜索词中的季写入标题中
|
||||
if results:
|
||||
medias = [MediaInfo(tmdb_info=info) for info in results]
|
||||
if meta.begin_season:
|
||||
# 小写数据转大写
|
||||
season_str = cn2an.an2cn(meta.begin_season, "low")
|
||||
for media in medias:
|
||||
if media.type == MediaType.TV:
|
||||
media.title = f"{media.title} 第{season_str}季"
|
||||
media.season = meta.begin_season
|
||||
return medias
|
||||
return []
|
||||
return self._build_search_medias_result(meta, results)
|
||||
|
||||
async def async_tmdb_discover(self, mtype: MediaType, sort_by: str,
|
||||
with_genres: str,
|
||||
|
||||
Reference in New Issue
Block a user