Merge pull request #604 from WithdewHua/subscribe
This commit is contained in:
commit
c86a21d11d
@ -138,6 +138,53 @@ def subscribe_mediaid(
|
|||||||
return result if result else Subscribe()
|
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("/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,
|
||||||
|
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)
|
@router.get("/{subscribe_id}", summary="订阅详情", response_model=schemas.Subscribe)
|
||||||
def read_subscribe(
|
def read_subscribe(
|
||||||
subscribe_id: int,
|
subscribe_id: int,
|
||||||
@ -243,39 +290,3 @@ async def seerr_subscribe(request: Request, background_tasks: BackgroundTasks,
|
|||||||
username=user_name)
|
username=user_name)
|
||||||
|
|
||||||
return schemas.Response(success=True)
|
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)
|
|
||||||
|
@ -277,7 +277,7 @@ class SubscribeChain(ChainBase):
|
|||||||
logger.warn(f'订阅 {subscribe.keyword or subscribe.name} 未搜索到资源')
|
logger.warn(f'订阅 {subscribe.keyword or subscribe.name} 未搜索到资源')
|
||||||
if meta.type == MediaType.TV:
|
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
|
continue
|
||||||
# 过滤
|
# 过滤
|
||||||
matched_contexts = []
|
matched_contexts = []
|
||||||
@ -318,7 +318,7 @@ class SubscribeChain(ChainBase):
|
|||||||
logger.warn(f'订阅 {subscribe.name} 没有符合过滤条件的资源')
|
logger.warn(f'订阅 {subscribe.name} 没有符合过滤条件的资源')
|
||||||
# 非洗版未搜索到资源,但本地缺失可能有变化,更新订阅剩余集数
|
# 非洗版未搜索到资源,但本地缺失可能有变化,更新订阅剩余集数
|
||||||
if meta.type == MediaType.TV and not subscribe.best_version:
|
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
|
continue
|
||||||
# 自动下载
|
# 自动下载
|
||||||
downloads, lefts = self.downloadchain.batch_download(contexts=matched_contexts,
|
downloads, lefts = self.downloadchain.batch_download(contexts=matched_contexts,
|
||||||
@ -335,18 +335,18 @@ class SubscribeChain(ChainBase):
|
|||||||
mediainfo=mediainfo, downloads=downloads)
|
mediainfo=mediainfo, downloads=downloads)
|
||||||
else:
|
else:
|
||||||
# 未完成下载
|
# 未完成下载
|
||||||
logger.info(f'{mediainfo.title_year} 未下载未完整,继续订阅 ...')
|
logger.info(f'{mediainfo.title_year} 未下载完整,继续订阅 ...')
|
||||||
if meta.type == MediaType.TV and not subscribe.best_version:
|
if meta.type == MediaType.TV and not subscribe.best_version:
|
||||||
# 更新订阅剩余集数和时间
|
# 更新订阅剩余集数和时间
|
||||||
update_date = True if downloads else False
|
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)
|
mediainfo=mediainfo, update_date=update_date)
|
||||||
# 手动触发时发送系统消息
|
# 手动触发时发送系统消息
|
||||||
if manual:
|
if manual:
|
||||||
if sid:
|
if sid:
|
||||||
self.message.put(f'订阅 {subscribes[0].name} 搜索完成!')
|
self.message.put(f'订阅 {subscribes[0].name} 搜索完成!')
|
||||||
else:
|
else:
|
||||||
self.message.put(f'所有订阅搜索完成!')
|
self.message.put('所有订阅搜索完成!')
|
||||||
|
|
||||||
def finish_subscribe_or_not(self, subscribe: Subscribe, meta: MetaInfo,
|
def finish_subscribe_or_not(self, subscribe: Subscribe, meta: MetaInfo,
|
||||||
mediainfo: MediaInfo, downloads: List[Context]):
|
mediainfo: MediaInfo, downloads: List[Context]):
|
||||||
@ -509,11 +509,13 @@ class SubscribeChain(ChainBase):
|
|||||||
torrent_list=[torrent_info])
|
torrent_list=[torrent_info])
|
||||||
if result is not None and not result:
|
if result is not None and not result:
|
||||||
# 不符合过滤规则
|
# 不符合过滤规则
|
||||||
|
logger.info(f"{torrent_info.title} 不匹配当前过滤规则")
|
||||||
continue
|
continue
|
||||||
# 不在订阅站点范围的不处理
|
# 不在订阅站点范围的不处理
|
||||||
if subscribe.sites:
|
if subscribe.sites:
|
||||||
sub_sites = json.loads(subscribe.sites)
|
sub_sites = json.loads(subscribe.sites)
|
||||||
if sub_sites and torrent_info.site not in sub_sites:
|
if sub_sites and torrent_info.site not in sub_sites:
|
||||||
|
logger.info(f"{torrent_info.title} 不符合 {torrent_mediainfo.title_year} 订阅站点要求")
|
||||||
continue
|
continue
|
||||||
# 如果是电视剧
|
# 如果是电视剧
|
||||||
if torrent_mediainfo.type == MediaType.TV:
|
if torrent_mediainfo.type == MediaType.TV:
|
||||||
@ -585,12 +587,12 @@ class SubscribeChain(ChainBase):
|
|||||||
if meta.type == MediaType.TV and not subscribe.best_version:
|
if meta.type == MediaType.TV and not subscribe.best_version:
|
||||||
update_date = True if downloads else False
|
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)
|
mediainfo=mediainfo, update_date=update_date)
|
||||||
else:
|
else:
|
||||||
if meta.type == MediaType.TV:
|
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):
|
def check(self):
|
||||||
"""
|
"""
|
||||||
@ -614,18 +616,15 @@ class SubscribeChain(ChainBase):
|
|||||||
if not mediainfo:
|
if not mediainfo:
|
||||||
logger.warn(f'未识别到媒体信息,标题:{subscribe.name},tmdbid:{subscribe.tmdbid}')
|
logger.warn(f'未识别到媒体信息,标题:{subscribe.name},tmdbid:{subscribe.tmdbid}')
|
||||||
continue
|
continue
|
||||||
if not mediainfo.seasons:
|
# 对于电视剧,获取当前季的总集数
|
||||||
continue
|
|
||||||
# 获取当前季的总集数
|
|
||||||
episodes = mediainfo.seasons.get(subscribe.season) or []
|
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)
|
total_episode = len(episodes)
|
||||||
lack_episode = subscribe.lack_episode + (total_episode - subscribe.total_episode)
|
lack_episode = subscribe.lack_episode + (total_episode - subscribe.total_episode)
|
||||||
logger.info(f'订阅 {subscribe.name} 总集数变化,更新总集数为{total_episode},缺失集数为{lack_episode} ...')
|
logger.info(f'订阅 {subscribe.name} 总集数变化,更新总集数为{total_episode},缺失集数为{lack_episode} ...')
|
||||||
else:
|
else:
|
||||||
total_episode = subscribe.total_episode
|
total_episode = subscribe.total_episode
|
||||||
lack_episode = subscribe.lack_episode
|
lack_episode = subscribe.lack_episode
|
||||||
logger.info(f'订阅 {subscribe.name} 总集数未变化')
|
|
||||||
# 更新TMDB信息
|
# 更新TMDB信息
|
||||||
self.subscribeoper.update(subscribe.id, {
|
self.subscribeoper.update(subscribe.id, {
|
||||||
"name": mediainfo.title,
|
"name": mediainfo.title,
|
||||||
@ -682,7 +681,7 @@ class SubscribeChain(ChainBase):
|
|||||||
return True
|
return True
|
||||||
return False
|
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,
|
subscribe: Subscribe,
|
||||||
mediainfo: MediaInfo,
|
mediainfo: MediaInfo,
|
||||||
update_date: bool = False):
|
update_date: bool = False):
|
||||||
@ -770,7 +769,7 @@ class SubscribeChain(ChainBase):
|
|||||||
total_episode: int,
|
total_episode: int,
|
||||||
start_episode: int):
|
start_episode: int):
|
||||||
"""
|
"""
|
||||||
根据订阅开始集数和总结数,结合TMDB信息计算当前订阅的缺失集数
|
根据订阅开始集数和总集数,结合TMDB信息计算当前订阅的缺失集数
|
||||||
:param no_exists: 缺失季集列表
|
:param no_exists: 缺失季集列表
|
||||||
:param tmdb_id: TMDB ID
|
:param tmdb_id: TMDB ID
|
||||||
:param begin_season: 开始季
|
:param begin_season: 开始季
|
||||||
|
@ -54,7 +54,10 @@ class PlexModule(_ModuleBase):
|
|||||||
if movie:
|
if movie:
|
||||||
logger.info(f"媒体库中已存在:{movie}")
|
logger.info(f"媒体库中已存在:{movie}")
|
||||||
return ExistMediaInfo(type=MediaType.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:
|
if not movies:
|
||||||
logger.info(f"{mediainfo.title_year} 在媒体库中不存在")
|
logger.info(f"{mediainfo.title_year} 在媒体库中不存在")
|
||||||
return None
|
return None
|
||||||
@ -63,6 +66,7 @@ class PlexModule(_ModuleBase):
|
|||||||
return ExistMediaInfo(type=MediaType.MOVIE)
|
return ExistMediaInfo(type=MediaType.MOVIE)
|
||||||
else:
|
else:
|
||||||
tvs = self.plex.get_tv_episodes(title=mediainfo.title,
|
tvs = self.plex.get_tv_episodes(title=mediainfo.title,
|
||||||
|
original_title=mediainfo.original_title,
|
||||||
year=mediainfo.year,
|
year=mediainfo.year,
|
||||||
tmdb_id=mediainfo.tmdb_id,
|
tmdb_id=mediainfo.tmdb_id,
|
||||||
item_id=itemid)
|
item_id=itemid)
|
||||||
|
@ -130,11 +130,13 @@ class Plex(metaclass=Singleton):
|
|||||||
|
|
||||||
def get_movies(self,
|
def get_movies(self,
|
||||||
title: str,
|
title: str,
|
||||||
|
original_title: str = None,
|
||||||
year: str = None,
|
year: str = None,
|
||||||
tmdb_id: int = None) -> Optional[List[dict]]:
|
tmdb_id: int = None) -> Optional[List[dict]]:
|
||||||
"""
|
"""
|
||||||
根据标题和年份,检查电影是否在Plex中存在,存在则返回列表
|
根据标题和年份,检查电影是否在Plex中存在,存在则返回列表
|
||||||
:param title: 标题
|
:param title: 标题
|
||||||
|
:param original_title: 原产地标题
|
||||||
:param year: 年份,为空则不过滤
|
:param year: 年份,为空则不过滤
|
||||||
:param tmdb_id: TMDB ID
|
:param tmdb_id: TMDB ID
|
||||||
:return: 含title、year属性的字典列表
|
:return: 含title、year属性的字典列表
|
||||||
@ -144,9 +146,14 @@ class Plex(metaclass=Singleton):
|
|||||||
ret_movies = []
|
ret_movies = []
|
||||||
if year:
|
if year:
|
||||||
movies = self._plex.library.search(title=title, year=year, libtype="movie")
|
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:
|
else:
|
||||||
movies = self._plex.library.search(title=title, libtype="movie")
|
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")
|
movie_tmdbid = self.__get_ids(movie.guids).get("tmdb_id")
|
||||||
if tmdb_id and movie_tmdbid:
|
if tmdb_id and movie_tmdbid:
|
||||||
if str(movie_tmdbid) != str(tmdb_id):
|
if str(movie_tmdbid) != str(tmdb_id):
|
||||||
@ -157,6 +164,7 @@ class Plex(metaclass=Singleton):
|
|||||||
def get_tv_episodes(self,
|
def get_tv_episodes(self,
|
||||||
item_id: str = None,
|
item_id: str = None,
|
||||||
title: str = None,
|
title: str = None,
|
||||||
|
original_title: str = None,
|
||||||
year: str = None,
|
year: str = None,
|
||||||
tmdb_id: int = None,
|
tmdb_id: int = None,
|
||||||
season: int = None) -> Optional[Dict[int, list]]:
|
season: int = None) -> Optional[Dict[int, list]]:
|
||||||
@ -164,6 +172,7 @@ class Plex(metaclass=Singleton):
|
|||||||
根据标题、年份、季查询电视剧所有集信息
|
根据标题、年份、季查询电视剧所有集信息
|
||||||
:param item_id: 媒体ID
|
:param item_id: 媒体ID
|
||||||
:param title: 标题
|
:param title: 标题
|
||||||
|
:param original_title: 原产地标题
|
||||||
:param year: 年份,可以为空,为空时不按年份过滤
|
:param year: 年份,可以为空,为空时不按年份过滤
|
||||||
:param tmdb_id: TMDB ID
|
:param tmdb_id: TMDB ID
|
||||||
:param season: 季号,数字
|
:param season: 季号,数字
|
||||||
@ -176,6 +185,8 @@ class Plex(metaclass=Singleton):
|
|||||||
else:
|
else:
|
||||||
# 根据标题和年份模糊搜索,该结果不够准确
|
# 根据标题和年份模糊搜索,该结果不够准确
|
||||||
videos = self._plex.library.search(title=title, year=year, libtype="show")
|
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:
|
if not videos:
|
||||||
return {}
|
return {}
|
||||||
if isinstance(videos, list):
|
if isinstance(videos, list):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user