From 4ab60423c12b6acb1e968ebee89a2d79a9521837 Mon Sep 17 00:00:00 2001 From: WithdewHua Date: Fri, 15 Sep 2023 00:08:15 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=E6=A0=B9=E6=8D=AE=E5=8E=9F?= =?UTF-8?q?=E6=A0=87=E9=A2=98=E6=9F=A5=E8=AF=A2=E5=AA=92=E4=BD=93=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8(plex)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/modules/plex/__init__.py | 6 +++++- app/modules/plex/plex.py | 13 ++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app/modules/plex/__init__.py b/app/modules/plex/__init__.py index fe785e58..35c7e16d 100644 --- a/app/modules/plex/__init__.py +++ b/app/modules/plex/__init__.py @@ -54,7 +54,10 @@ class PlexModule(_ModuleBase): if movie: logger.info(f"媒体库中已存在:{movie}") return ExistMediaInfo(type=MediaType.MOVIE) - movies = self.plex.get_movies(title=mediainfo.title, year=mediainfo.year, tmdb_id=mediainfo.tmdb_id) + movies = self.plex.get_movies(title=mediainfo.title, + original_title=mediainfo.original_title, + year=mediainfo.year, + tmdb_id=mediainfo.tmdb_id) if not movies: logger.info(f"{mediainfo.title_year} 在媒体库中不存在") return None @@ -63,6 +66,7 @@ class PlexModule(_ModuleBase): return ExistMediaInfo(type=MediaType.MOVIE) else: tvs = self.plex.get_tv_episodes(title=mediainfo.title, + original_title=mediainfo.original_title, year=mediainfo.year, tmdb_id=mediainfo.tmdb_id, item_id=itemid) diff --git a/app/modules/plex/plex.py b/app/modules/plex/plex.py index 726fb7a5..e656040c 100644 --- a/app/modules/plex/plex.py +++ b/app/modules/plex/plex.py @@ -130,11 +130,13 @@ class Plex(metaclass=Singleton): def get_movies(self, title: str, + original_title: str = None, year: str = None, tmdb_id: int = None) -> Optional[List[dict]]: """ 根据标题和年份,检查电影是否在Plex中存在,存在则返回列表 :param title: 标题 + :param original_title: 原产地标题 :param year: 年份,为空则不过滤 :param tmdb_id: TMDB ID :return: 含title、year属性的字典列表 @@ -144,9 +146,14 @@ class Plex(metaclass=Singleton): ret_movies = [] if year: movies = self._plex.library.search(title=title, year=year, libtype="movie") + # 根据原标题再查一遍 + if original_title and str(original_title) != str(title): + movies.extend(self._plex.library.search(title=original_title, year=year, libtype="movie")) else: movies = self._plex.library.search(title=title, libtype="movie") - for movie in movies: + if original_title and str(original_title) != str(title): + movies.extend(self._plex.library.search(title=original_title, year=year, libtype="movie")) + for movie in set(movies): movie_tmdbid = self.__get_ids(movie.guids).get("tmdb_id") if tmdb_id and movie_tmdbid: if str(movie_tmdbid) != str(tmdb_id): @@ -157,6 +164,7 @@ class Plex(metaclass=Singleton): def get_tv_episodes(self, item_id: str = None, title: str = None, + original_title: str = None, year: str = None, tmdb_id: int = None, season: int = None) -> Optional[Dict[int, list]]: @@ -164,6 +172,7 @@ class Plex(metaclass=Singleton): 根据标题、年份、季查询电视剧所有集信息 :param item_id: 媒体ID :param title: 标题 + :param original_title: 原产地标题 :param year: 年份,可以为空,为空时不按年份过滤 :param tmdb_id: TMDB ID :param season: 季号,数字 @@ -176,6 +185,8 @@ class Plex(metaclass=Singleton): else: # 根据标题和年份模糊搜索,该结果不够准确 videos = self._plex.library.search(title=title, year=year, libtype="show") + if not videos and original_title and str(original_title) != str(title): + videos = self._plex.library.search(title=original_title, year=year, libtype="show") if not videos: return {} if isinstance(videos, list): From b8663ee735dfbb7042a2a85f6141c10ba07ad594 Mon Sep 17 00:00:00 2001 From: WithdewHua Date: Thu, 14 Sep 2023 22:51:39 +0800 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=E5=90=8C=E6=97=B6=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=94=B5=E5=BD=B1=E8=AE=A2=E9=98=85=E4=BF=A1=E6=81=AF=EF=BC=9B?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/chain/subscribe.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/app/chain/subscribe.py b/app/chain/subscribe.py index cc196698..a305f363 100644 --- a/app/chain/subscribe.py +++ b/app/chain/subscribe.py @@ -277,7 +277,7 @@ class SubscribeChain(ChainBase): logger.warn(f'订阅 {subscribe.keyword or subscribe.name} 未搜索到资源') if meta.type == MediaType.TV: # 未搜索到资源,但本地缺失可能有变化,更新订阅剩余集数 - self.__upate_lack_episodes(lefts=no_exists, subscribe=subscribe, mediainfo=mediainfo) + self.__update_lack_episodes(lefts=no_exists, subscribe=subscribe, mediainfo=mediainfo) continue # 过滤 matched_contexts = [] @@ -318,7 +318,7 @@ class SubscribeChain(ChainBase): logger.warn(f'订阅 {subscribe.name} 没有符合过滤条件的资源') # 非洗版未搜索到资源,但本地缺失可能有变化,更新订阅剩余集数 if meta.type == MediaType.TV and not subscribe.best_version: - self.__upate_lack_episodes(lefts=no_exists, subscribe=subscribe, mediainfo=mediainfo) + self.__update_lack_episodes(lefts=no_exists, subscribe=subscribe, mediainfo=mediainfo) continue # 自动下载 downloads, lefts = self.downloadchain.batch_download(contexts=matched_contexts, @@ -335,18 +335,18 @@ class SubscribeChain(ChainBase): mediainfo=mediainfo, downloads=downloads) else: # 未完成下载 - logger.info(f'{mediainfo.title_year} 未下载未完整,继续订阅 ...') + logger.info(f'{mediainfo.title_year} 未下载完整,继续订阅 ...') if meta.type == MediaType.TV and not subscribe.best_version: # 更新订阅剩余集数和时间 update_date = True if downloads else False - self.__upate_lack_episodes(lefts=lefts, subscribe=subscribe, + self.__update_lack_episodes(lefts=lefts, subscribe=subscribe, mediainfo=mediainfo, update_date=update_date) # 手动触发时发送系统消息 if manual: if sid: self.message.put(f'订阅 {subscribes[0].name} 搜索完成!') else: - self.message.put(f'所有订阅搜索完成!') + self.message.put('所有订阅搜索完成!') def finish_subscribe_or_not(self, subscribe: Subscribe, meta: MetaInfo, mediainfo: MediaInfo, downloads: List[Context]): @@ -509,11 +509,13 @@ class SubscribeChain(ChainBase): torrent_list=[torrent_info]) if result is not None and not result: # 不符合过滤规则 + logger.info(f"{torrent_info.title} 不匹配当前过滤规则") continue # 不在订阅站点范围的不处理 if subscribe.sites: sub_sites = json.loads(subscribe.sites) if sub_sites and torrent_info.site not in sub_sites: + logger.info(f"{torrent_info.title} 不符合 {torrent_mediainfo.title_year} 订阅站点要求") continue # 如果是电视剧 if torrent_mediainfo.type == MediaType.TV: @@ -585,12 +587,12 @@ class SubscribeChain(ChainBase): if meta.type == MediaType.TV and not subscribe.best_version: update_date = True if downloads else False # 未完成下载,计算剩余集数 - self.__upate_lack_episodes(lefts=lefts, subscribe=subscribe, + self.__update_lack_episodes(lefts=lefts, subscribe=subscribe, mediainfo=mediainfo, update_date=update_date) else: if meta.type == MediaType.TV: # 未搜索到资源,但本地缺失可能有变化,更新订阅剩余集数 - self.__upate_lack_episodes(lefts=no_exists, subscribe=subscribe, mediainfo=mediainfo) + self.__update_lack_episodes(lefts=no_exists, subscribe=subscribe, mediainfo=mediainfo) def check(self): """ @@ -614,18 +616,15 @@ class SubscribeChain(ChainBase): if not mediainfo: logger.warn(f'未识别到媒体信息,标题:{subscribe.name},tmdbid:{subscribe.tmdbid}') continue - if not mediainfo.seasons: - continue - # 获取当前季的总集数 + # 对于电视剧,获取当前季的总集数 episodes = mediainfo.seasons.get(subscribe.season) or [] - if len(episodes) > subscribe.total_episode or 0: + if len(episodes) > (subscribe.total_episode or 0): total_episode = len(episodes) lack_episode = subscribe.lack_episode + (total_episode - subscribe.total_episode) logger.info(f'订阅 {subscribe.name} 总集数变化,更新总集数为{total_episode},缺失集数为{lack_episode} ...') else: total_episode = subscribe.total_episode lack_episode = subscribe.lack_episode - logger.info(f'订阅 {subscribe.name} 总集数未变化') # 更新TMDB信息 self.subscribeoper.update(subscribe.id, { "name": mediainfo.title, @@ -682,7 +681,7 @@ class SubscribeChain(ChainBase): return True return False - def __upate_lack_episodes(self, lefts: Dict[int, Dict[int, NotExistMediaInfo]], + def __update_lack_episodes(self, lefts: Dict[int, Dict[int, NotExistMediaInfo]], subscribe: Subscribe, mediainfo: MediaInfo, update_date: bool = False): @@ -770,7 +769,7 @@ class SubscribeChain(ChainBase): total_episode: int, start_episode: int): """ - 根据订阅开始集数和总结数,结合TMDB信息计算当前订阅的缺失集数 + 根据订阅开始集数和总集数,结合TMDB信息计算当前订阅的缺失集数 :param no_exists: 缺失季集列表 :param tmdb_id: TMDB ID :param begin_season: 开始季 From ca2c0392bbca56a7092919dfe51ce317d01f0b55 Mon Sep 17 00:00:00 2001 From: WithdewHua Date: Sat, 16 Sep 2023 18:42:47 +0800 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20=E8=B0=83=E6=95=B4=20API=20=E9=A1=BA?= =?UTF-8?q?=E5=BA=8F,=E9=81=BF=E5=85=8D=E9=94=99=E8=AF=AF=E5=8C=B9?= =?UTF-8?q?=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/endpoints/subscribe.py | 72 +++++++++++++++++----------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/app/api/endpoints/subscribe.py b/app/api/endpoints/subscribe.py index c4bf53d7..052bf107 100644 --- a/app/api/endpoints/subscribe.py +++ b/app/api/endpoints/subscribe.py @@ -138,6 +138,42 @@ def subscribe_mediaid( return result if result else Subscribe() +@router.get("/refresh", summary="刷新订阅", response_model=schemas.Response) +def refresh_subscribes( + db: Session = Depends(get_db), + _: schemas.TokenPayload = Depends(verify_token)) -> Any: + """ + 刷新所有订阅 + """ + SubscribeChain(db).refresh() + return schemas.Response(success=True) + + +@router.get("/search", summary="搜索所有订阅", response_model=schemas.Response) +def search_subscribes( + background_tasks: BackgroundTasks, + db: Session = Depends(get_db), + _: schemas.TokenPayload = Depends(verify_token)) -> Any: + """ + 搜索所有订阅 + """ + background_tasks.add_task(start_subscribe_search, db=db, sid=None, state='R') + return schemas.Response(success=True) + + +@router.get("/search/{subscribe_id}", summary="搜索订阅", response_model=schemas.Response) +def search_subscribe( + subscribe_id: int, + background_tasks: BackgroundTasks, + db: Session = Depends(get_db), + _: schemas.TokenPayload = Depends(verify_token)) -> Any: + """ + 根据订阅编号搜索订阅 + """ + background_tasks.add_task(start_subscribe_search, db=db, sid=subscribe_id, state=None) + return schemas.Response(success=True) + + @router.get("/{subscribe_id}", summary="订阅详情", response_model=schemas.Subscribe) def read_subscribe( subscribe_id: int, @@ -243,39 +279,3 @@ async def seerr_subscribe(request: Request, background_tasks: BackgroundTasks, username=user_name) return schemas.Response(success=True) - - -@router.get("/refresh", summary="刷新订阅", response_model=schemas.Response) -def refresh_subscribes( - db: Session = Depends(get_db), - _: schemas.TokenPayload = Depends(verify_token)) -> Any: - """ - 刷新所有订阅 - """ - SubscribeChain(db).refresh() - return schemas.Response(success=True) - - -@router.get("/search/{subscribe_id}", summary="搜索订阅", response_model=schemas.Response) -def search_subscribe( - subscribe_id: int, - background_tasks: BackgroundTasks, - db: Session = Depends(get_db), - _: schemas.TokenPayload = Depends(verify_token)) -> Any: - """ - 搜索所有订阅 - """ - background_tasks.add_task(start_subscribe_search, db=db, sid=subscribe_id, state=None) - return schemas.Response(success=True) - - -@router.get("/search", summary="搜索所有订阅", response_model=schemas.Response) -def search_subscribes( - background_tasks: BackgroundTasks, - db: Session = Depends(get_db), - _: schemas.TokenPayload = Depends(verify_token)) -> Any: - """ - 搜索所有订阅 - """ - background_tasks.add_task(start_subscribe_search, db=db, sid=None, state='R') - return schemas.Response(success=True) From 3fb02f64909b3e14a6a137c5a875c76dfbc44d62 Mon Sep 17 00:00:00 2001 From: WithdewHua Date: Sat, 16 Sep 2023 18:45:34 +0800 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E8=AE=A2=E9=98=85=20tmdb=20=E4=BF=A1=E6=81=AF=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/endpoints/subscribe.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/api/endpoints/subscribe.py b/app/api/endpoints/subscribe.py index 052bf107..8cb05512 100644 --- a/app/api/endpoints/subscribe.py +++ b/app/api/endpoints/subscribe.py @@ -149,6 +149,17 @@ def refresh_subscribes( return schemas.Response(success=True) +@router.get("/check", summary="刷新订阅 TMDB 信息", response_model=schemas.Response) +def check_subscribes( + db: Session = Depends(get_db), + _: schemas.TokenPayload = Depends(verify_token)) -> Any: + """ + 刷新所有订阅 + """ + SubscribeChain(db).check() + return schemas.Response(success=True) + + @router.get("/search", summary="搜索所有订阅", response_model=schemas.Response) def search_subscribes( background_tasks: BackgroundTasks,