From adeb5361ab3df39dc98c2159434e4a5741eef52d Mon Sep 17 00:00:00 2001 From: jxxghp Date: Thu, 16 Jan 2025 17:51:47 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E6=94=AF=E6=8C=81=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E7=B3=BB=E5=88=97=E5=90=88=E9=9B=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/endpoints/media.py | 4 +++- app/api/endpoints/tmdb.py | 14 ++++++++++++++ app/chain/__init__.py | 7 +++++++ app/chain/tmdb.py | 7 +++++++ app/core/context.py | 4 ++++ app/modules/themoviedb/__init__.py | 21 +++++++++++++++++++++ app/modules/themoviedb/tmdbapi.py | 29 ++++++++++++++++++++++++++++- app/schemas/context.py | 4 +++- app/schemas/types.py | 1 + 9 files changed, 88 insertions(+), 3 deletions(-) diff --git a/app/api/endpoints/media.py b/app/api/endpoints/media.py index 792726f5..6903fb0c 100644 --- a/app/api/endpoints/media.py +++ b/app/api/endpoints/media.py @@ -72,7 +72,7 @@ def search(title: str, """ 模糊搜索媒体/人物信息列表 media:媒体信息,person:人物信息 """ - def __get_source(obj: Union[dict, schemas.MediaPerson]): + def __get_source(obj: Union[schemas.MediaInfo, schemas.MediaPerson, dict]): """ 获取对象属性 """ @@ -85,6 +85,8 @@ def search(title: str, _, medias = MediaChain().search(title=title) if medias: result = [media.to_dict() for media in medias] + elif type == "collection": + result = MediaChain().search_collections(name=title) else: result = MediaChain().search_persons(name=title) if result: diff --git a/app/api/endpoints/tmdb.py b/app/api/endpoints/tmdb.py index 18cb2d94..dc0bab4f 100644 --- a/app/api/endpoints/tmdb.py +++ b/app/api/endpoints/tmdb.py @@ -60,6 +60,20 @@ def tmdb_recommend(tmdbid: int, return [] +@router.get("/collection/{collection_id}", summary="系列合集详情", response_model=List[schemas.MediaInfo]) +def tmdb_collection(collection_id: int, + page: int = 1, + count: int = 20, + _: schemas.TokenPayload = Depends(verify_token)) -> Any: + """ + 根据合集ID查询合集详情 + """ + medias = TmdbChain().tmdb_collection(collection_id=collection_id) + if medias: + return [media.to_dict() for media in medias][(page - 1) * count:page * count] + return [] + + @router.get("/credits/{tmdbid}/{type_name}", summary="演员阵容", response_model=List[schemas.MediaPerson]) def tmdb_credits(tmdbid: int, type_name: str, diff --git a/app/chain/__init__.py b/app/chain/__init__.py index fa3da2e5..b041b755 100644 --- a/app/chain/__init__.py +++ b/app/chain/__init__.py @@ -301,6 +301,13 @@ class ChainBase(metaclass=ABCMeta): """ return self.run_module("search_persons", name=name) + def search_collections(self, name: str) -> Optional[List[MediaInfo]]: + """ + 搜索集合信息 + :param name: 集合名称 + """ + return self.run_module("search_collections", name=name) + def search_torrents(self, site: CommentedMap, keywords: List[str], mtype: MediaType = None, diff --git a/app/chain/tmdb.py b/app/chain/tmdb.py index d57c7cf3..6699b5b4 100644 --- a/app/chain/tmdb.py +++ b/app/chain/tmdb.py @@ -38,6 +38,13 @@ class TmdbChain(ChainBase, metaclass=Singleton): """ return self.run_module("tmdb_trending", page=page) + def tmdb_collection(self, collection_id: int) -> Optional[List[MediaInfo]]: + """ + 根据合集ID查询集合 + :param collection_id: 合集ID + """ + return self.run_module("tmdb_collection", collection_id=collection_id) + def tmdb_seasons(self, tmdbid: int) -> List[schemas.TmdbSeason]: """ 根据TMDBID查询themoviedb所有季信息 diff --git a/app/core/context.py b/app/core/context.py index 00958e04..6fd42f67 100644 --- a/app/core/context.py +++ b/app/core/context.py @@ -178,6 +178,8 @@ class MediaInfo: douban_id: str = None # Bangumi ID bangumi_id: int = None + # 合集ID + collection_id: int = None # 媒体原语种 original_language: str = None # 媒体原发行标题 @@ -397,6 +399,8 @@ class MediaInfo: if info.get("external_ids"): self.tvdb_id = info.get("external_ids", {}).get("tvdb_id") self.imdb_id = info.get("external_ids", {}).get("imdb_id") + # 合集ID + self.collection_id = info.get('collection_id') # 评分 self.vote_average = round(float(info.get('vote_average')), 1) if info.get('vote_average') else 0 # 描述 diff --git a/app/modules/themoviedb/__init__.py b/app/modules/themoviedb/__init__.py index 35339cb6..130b4f37 100644 --- a/app/modules/themoviedb/__init__.py +++ b/app/modules/themoviedb/__init__.py @@ -311,6 +311,27 @@ class TheMovieDbModule(_ModuleBase): return [MediaPerson(source='themoviedb', **person) for person in results] return [] + def search_collections(self, name: str) -> Optional[List[MediaInfo]]: + """ + 搜索集合信息 + """ + if not name: + return [] + results = self.tmdb.search_collections(name) + if results: + return [MediaInfo(tmdb_info=info) for info in results] + return [] + + def tmdb_collection(self, collection_id: int) -> Optional[List[MediaInfo]]: + """ + 根据合集ID查询集合 + :param collection_id: 合集ID + """ + results = self.tmdb.get_collection(collection_id) + if results: + return [MediaInfo(tmdb_info=info) for info in results] + return [] + def metadata_nfo(self, meta: MetaBase, mediainfo: MediaInfo, season: int = None, episode: int = None) -> Optional[str]: """ diff --git a/app/modules/themoviedb/tmdbapi.py b/app/modules/themoviedb/tmdbapi.py index 132a9af7..b27ca808 100644 --- a/app/modules/themoviedb/tmdbapi.py +++ b/app/modules/themoviedb/tmdbapi.py @@ -11,7 +11,7 @@ from app.log import logger from app.schemas.types import MediaType from app.utils.http import RequestUtils from app.utils.string import StringUtils -from .tmdbv3api import TMDb, Search, Movie, TV, Season, Episode, Discover, Trending, Person +from .tmdbv3api import TMDb, Search, Movie, TV, Season, Episode, Discover, Trending, Person, Collection from .tmdbv3api.exceptions import TMDbException @@ -44,6 +44,7 @@ class TmdbApi: self.discover = Discover() self.trending = Trending() self.person = Person() + self.collection = Collection() def search_multiis(self, title: str) -> List[dict]: """ @@ -101,6 +102,32 @@ class TmdbApi: return [] return self.search.people(term=name) or [] + def search_collections(self, name: str) -> List[dict]: + """ + 查询模糊匹配的所有合集TMDB信息 + """ + if not name: + return [] + collections = self.search.collections(term=name) or [] + for collection in collections: + collection['media_type'] = MediaType.COLLECTION + collection['collection_id'] = collection.get("id") + return collections + + def get_collection(self, collection_id: int) -> List[dict]: + """ + 根据合集ID查询合集详情 + """ + if not collection_id: + return [] + try: + return self.collection.details(collection_id=collection_id) + except TMDbException as err: + logger.error(f"连接TMDB出错:{str(err)}") + except Exception as e: + logger.error(f"连接TMDB出错:{str(e)}") + return [] + @staticmethod def __compare_names(file_name: str, tmdb_names: list) -> bool: """ diff --git a/app/schemas/context.py b/app/schemas/context.py index 7ba78a7a..cef29256 100644 --- a/app/schemas/context.py +++ b/app/schemas/context.py @@ -67,7 +67,7 @@ class MediaInfo(BaseModel): """ # 来源:themoviedb、douban、bangumi source: Optional[str] = None - # 类型 电影、电视剧 + # 类型 电影、电视剧、合集 type: Optional[str] = None # 媒体标题 title: Optional[str] = None @@ -79,6 +79,8 @@ class MediaInfo(BaseModel): title_year: Optional[str] = None # 当前指定季,如有 season: Optional[int] = None + # 合集等id + collection_id: Optional[int] = None # TMDB ID tmdb_id: Optional[int] = None # IMDB ID diff --git a/app/schemas/types.py b/app/schemas/types.py index 4415f532..257b0c33 100644 --- a/app/schemas/types.py +++ b/app/schemas/types.py @@ -5,6 +5,7 @@ from enum import Enum class MediaType(Enum): MOVIE = '电影' TV = '电视剧' + COLLECTION = '合集' UNKNOWN = '未知'