diff --git a/app/api/endpoints/search.py b/app/api/endpoints/search.py index 67970e9d..53f4e6c4 100644 --- a/app/api/endpoints/search.py +++ b/app/api/endpoints/search.py @@ -25,11 +25,11 @@ async def search_latest(_: schemas.TokenPayload = Depends(verify_token)) -> Any: def search_by_id(mediaid: str, mtype: str = None, area: str = "title", + season: int = None, _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ - 根据TMDBID/豆瓣ID精确搜索站点资源 tmdb:/douban:/ + 根据TMDBID/豆瓣ID精确搜索站点资源 tmdb:/douban:/bangumi: """ - torrents = [] if mtype: mtype = MediaType(mtype) if mediaid.startswith("tmdb:"): @@ -39,11 +39,11 @@ def search_by_id(mediaid: str, doubaninfo = MediaChain().get_doubaninfo_by_tmdbid(tmdbid=tmdbid, mtype=mtype) if doubaninfo: torrents = SearchChain().search_by_id(doubanid=doubaninfo.get("id"), - mtype=mtype, area=area) + mtype=mtype, area=area, season=season) else: return schemas.Response(success=False, message="未识别到豆瓣媒体信息") else: - torrents = SearchChain().search_by_id(tmdbid=tmdbid, mtype=mtype, area=area) + torrents = SearchChain().search_by_id(tmdbid=tmdbid, mtype=mtype, area=area, season=season) elif mediaid.startswith("douban:"): doubanid = mediaid.replace("douban:", "") if settings.RECOGNIZE_SOURCE == "themoviedb": @@ -51,11 +51,11 @@ def search_by_id(mediaid: str, tmdbinfo = MediaChain().get_tmdbinfo_by_doubanid(doubanid=doubanid, mtype=mtype) if tmdbinfo: torrents = SearchChain().search_by_id(tmdbid=tmdbinfo.get("id"), - mtype=mtype, area=area) + mtype=mtype, area=area, season=season) else: return schemas.Response(success=False, message="未识别到TMDB媒体信息") else: - torrents = SearchChain().search_by_id(doubanid=doubanid, mtype=mtype, area=area) + torrents = SearchChain().search_by_id(doubanid=doubanid, mtype=mtype, area=area, season=season) elif mediaid.startswith("bangumi:"): bangumiid = int(mediaid.replace("bangumi:", "")) if settings.RECOGNIZE_SOURCE == "themoviedb": @@ -63,7 +63,7 @@ def search_by_id(mediaid: str, tmdbinfo = MediaChain().get_tmdbinfo_by_bangumiid(bangumiid=bangumiid) if tmdbinfo: torrents = SearchChain().search_by_id(tmdbid=tmdbinfo.get("id"), - mtype=mtype, area=area) + mtype=mtype, area=area, season=season) else: return schemas.Response(success=False, message="未识别到TMDB媒体信息") else: @@ -71,7 +71,7 @@ def search_by_id(mediaid: str, doubaninfo = MediaChain().get_doubaninfo_by_bangumiid(bangumiid=bangumiid) if doubaninfo: torrents = SearchChain().search_by_id(doubanid=doubaninfo.get("id"), - mtype=mtype, area=area) + mtype=mtype, area=area, season=season) else: return schemas.Response(success=False, message="未识别到豆瓣媒体信息") else: diff --git a/app/chain/search.py b/app/chain/search.py index 7564c277..da403e67 100644 --- a/app/chain/search.py +++ b/app/chain/search.py @@ -34,19 +34,27 @@ class SearchChain(ChainBase): self.torrenthelper = TorrentHelper() def search_by_id(self, tmdbid: int = None, doubanid: str = None, - mtype: MediaType = None, area: str = "title") -> List[Context]: + mtype: MediaType = None, area: str = "title", season: int = None) -> List[Context]: """ 根据TMDBID/豆瓣ID搜索资源,精确匹配,但不不过滤本地存在的资源 :param tmdbid: TMDB ID :param doubanid: 豆瓣 ID :param mtype: 媒体,电影 or 电视剧 :param area: 搜索范围,title or imdbid + :param season: 季数 """ mediainfo = self.recognize_media(tmdbid=tmdbid, doubanid=doubanid, mtype=mtype) if not mediainfo: logger.error(f'{tmdbid} 媒体信息识别失败!') return [] - results = self.process(mediainfo=mediainfo, area=area) + no_exists = None + if season: + no_exists = { + tmdbid or doubanid: { + season: NotExistMediaInfo(episodes=[]) + } + } + results = self.process(mediainfo=mediainfo, area=area, no_exists=no_exists) # 保存眲结果 bytes_results = pickle.dumps(results) self.systemconfig.set(SystemConfigKey.SearchResults, bytes_results) diff --git a/app/modules/douban/__init__.py b/app/modules/douban/__init__.py index 44c998b5..cd5f3a77 100644 --- a/app/modules/douban/__init__.py +++ b/app/modules/douban/__init__.py @@ -2,6 +2,8 @@ import re from pathlib import Path from typing import List, Optional, Tuple, Union +import cn2an + from app.core.config import settings from app.core.context import MediaInfo from app.core.meta import MetaBase @@ -551,7 +553,14 @@ class DoubanModule(_ModuleBase): if item_obj.get("type_name") not in (MediaType.TV.value, MediaType.MOVIE.value): 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 @retry(Exception, 5, 3, 3, logger=logger) diff --git a/app/modules/themoviedb/__init__.py b/app/modules/themoviedb/__init__.py index 3993c967..e7ac5eba 100644 --- a/app/modules/themoviedb/__init__.py +++ b/app/modules/themoviedb/__init__.py @@ -1,6 +1,8 @@ from pathlib import Path from typing import Optional, List, Tuple, Union +import cn2an + from app import schemas from app.core.config import settings from app.core.context import MediaInfo @@ -245,8 +247,18 @@ class TheMovieDbModule(_ModuleBase): results = self.tmdb.search_movies(meta.name, meta.year) else: results = self.tmdb.search_tvs(meta.name, meta.year) - - return [MediaInfo(tmdb_info=info) for info in results] + # 将搜索词中的季写入标题中 + 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 [] def scrape_metadata(self, path: Path, mediainfo: MediaInfo, transfer_type: str, force_nfo: bool = False, force_img: bool = False) -> None: diff --git a/app/schemas/context.py b/app/schemas/context.py index 12e86700..7aa10ac1 100644 --- a/app/schemas/context.py +++ b/app/schemas/context.py @@ -73,7 +73,7 @@ class MediaInfo(BaseModel): year: Optional[str] = None # 标题(年份) title_year: Optional[str] = None - # 季 + # 当前指定季,如有 season: Optional[int] = None # TMDB ID tmdb_id: Optional[int] = None