fix subscribe api

This commit is contained in:
jxxghp
2023-07-03 10:42:01 +08:00
parent 4a91a43c30
commit 8adab8d645
5 changed files with 73 additions and 41 deletions

View File

@ -1,4 +1,4 @@
from typing import List, Any, Union from typing import List, Any
from fastapi import APIRouter, Request, BackgroundTasks, Depends, HTTPException, Header from fastapi import APIRouter, Request, BackgroundTasks, Depends, HTTPException, Header
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
@ -35,8 +35,8 @@ async def read_subscribes(
return Subscribe.list(db) return Subscribe.list(db)
@router.get("/{mediaid}", summary="查询订阅", response_model=schemas.Subscribe) @router.get("/media/{mediaid}", summary="查询订阅", response_model=schemas.Subscribe)
async def subscribe_info_by_id( async def subscribe_mediaid(
mediaid: str, mediaid: str,
season: int = None, season: int = None,
db: Session = Depends(get_db), db: Session = Depends(get_db),
@ -54,6 +54,17 @@ async def subscribe_info_by_id(
return result if result else Subscribe() return result if result else Subscribe()
@router.get("/{subscribe_id}", summary="订阅详情", response_model=schemas.Subscribe)
async def read_subscribe(
subscribe_id: int,
db: Session = Depends(get_db),
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
"""
根据订阅编号查询订阅信息
"""
return Subscribe.get(db, subscribe_id)
@router.post("/", summary="新增订阅", response_model=schemas.Response) @router.post("/", summary="新增订阅", response_model=schemas.Response)
async def create_subscribe( async def create_subscribe(
*, *,
@ -73,15 +84,17 @@ async def create_subscribe(
title = subscribe_in.name title = subscribe_in.name
else: else:
title = None title = None
result = SubscribeChain().add(mtype=mtype, sid, message = SubscribeChain().add(mtype=mtype,
title=title, title=title,
year=subscribe_in.year, year=subscribe_in.year,
tmdbid=subscribe_in.tmdbid, tmdbid=subscribe_in.tmdbid,
season=subscribe_in.season, season=subscribe_in.season,
doubanid=subscribe_in.doubanid, doubanid=subscribe_in.doubanid,
username=current_user.name, username=current_user.name,
exist_ok=True) exist_ok=True)
return schemas.Response(success=True if result else False, message=result) return schemas.Response(success=True if sid else False, message=message, data={
"id": sid
})
@router.put("/", summary="更新订阅", response_model=schemas.Subscribe) @router.put("/", summary="更新订阅", response_model=schemas.Subscribe)

View File

@ -311,11 +311,11 @@ async def arr_add_movie(apikey: str, movie: RadarrMovie) -> Any:
status_code=403, status_code=403,
detail="认证失败!", detail="认证失败!",
) )
sid = SubscribeChain().add(title=movie.title, sid, message = SubscribeChain().add(title=movie.title,
year=movie.year, year=movie.year,
mtype=MediaType.MOVIE, mtype=MediaType.MOVIE,
tmdbid=movie.tmdbId, tmdbid=movie.tmdbId,
userid="Seerr") userid="Seerr")
if sid: if sid:
return { return {
"id": sid "id": sid
@ -323,7 +323,7 @@ async def arr_add_movie(apikey: str, movie: RadarrMovie) -> Any:
else: else:
raise HTTPException( raise HTTPException(
status_code=500, status_code=500,
detail="添加订阅失败" detail=f"添加订阅失败{message}"
) )
@ -626,15 +626,16 @@ async def arr_add_series(apikey: str, tv: schemas.SonarrSeries) -> Any:
detail="认证失败!", detail="认证失败!",
) )
sid = 0 sid = 0
message = ""
for season in tv.seasons: for season in tv.seasons:
if not season.get("monitored"): if not season.get("monitored"):
continue continue
sid = SubscribeChain().add(title=tv.title, sid, message = SubscribeChain().add(title=tv.title,
year=tv.year, year=tv.year,
season=season.get("seasonNumber"), season=season.get("seasonNumber"),
tmdbid=tv.tmdbId, tmdbid=tv.tmdbId,
mtype=MediaType.TV, mtype=MediaType.TV,
userid="Seerr") userid="Seerr")
if sid: if sid:
return { return {
@ -643,7 +644,7 @@ async def arr_add_series(apikey: str, tv: schemas.SonarrSeries) -> Any:
else: else:
raise HTTPException( raise HTTPException(
status_code=500, status_code=500,
detail="添加订阅失败" detail=f"添加订阅失败{message}"
) )

View File

@ -1,5 +1,6 @@
import re import re
from typing import Dict, List, Optional, Union from datetime import datetime
from typing import Dict, List, Optional, Union, Tuple
from app.chain import ChainBase from app.chain import ChainBase
from app.chain.download import DownloadChain from app.chain.download import DownloadChain
@ -38,8 +39,9 @@ class SubscribeChain(ChainBase):
season: int = None, season: int = None,
userid: str = None, userid: str = None,
username: str = None, username: str = None,
message: bool = True,
exist_ok: bool = False, exist_ok: bool = False,
**kwargs) -> Optional[int]: **kwargs) -> Tuple[Optional[int], str]:
""" """
识别媒体信息并添加订阅 识别媒体信息并添加订阅
""" """
@ -61,7 +63,7 @@ class SubscribeChain(ChainBase):
mediainfo: MediaInfo = self.recognize_media(meta=metainfo, mtype=mtype, tmdbid=tmdbid) mediainfo: MediaInfo = self.recognize_media(meta=metainfo, mtype=mtype, tmdbid=tmdbid)
if not mediainfo: if not mediainfo:
logger.warn(f'未识别到媒体信息,标题:{title}tmdbid{tmdbid}') logger.warn(f'未识别到媒体信息,标题:{title}tmdbid{tmdbid}')
return 0 return None, "未识别到媒体信息"
# 更新媒体图片 # 更新媒体图片
self.obtain_images(mediainfo=mediainfo) self.obtain_images(mediainfo=mediainfo)
# 总集数 # 总集数
@ -76,14 +78,14 @@ class SubscribeChain(ChainBase):
tmdbid=mediainfo.tmdb_id) tmdbid=mediainfo.tmdb_id)
if not mediainfo: if not mediainfo:
logger.error(f"媒体信息识别失败!") logger.error(f"媒体信息识别失败!")
return 0 return None, "媒体信息识别失败"
if not mediainfo.seasons: if not mediainfo.seasons:
logger.error(f"媒体信息中没有季集信息,标题:{title}tmdbid{tmdbid}") logger.error(f"媒体信息中没有季集信息,标题:{title}tmdbid{tmdbid}")
return 0 return None, "媒体信息中没有季集信息"
total_episode = len(mediainfo.seasons.get(season) or []) total_episode = len(mediainfo.seasons.get(season) or [])
if not total_episode: if not total_episode:
logger.error(f'未获取到总集数,标题:{title}tmdbid{tmdbid}') logger.error(f'未获取到总集数,标题:{title}tmdbid{tmdbid}')
return 0 return None, "未获取到总集数"
kwargs.update({ kwargs.update({
'total_episode': total_episode 'total_episode': total_episode
}) })
@ -96,21 +98,21 @@ class SubscribeChain(ChainBase):
sid, err_msg = self.subscribehelper.add(mediainfo, doubanid=doubanid, season=season, **kwargs) sid, err_msg = self.subscribehelper.add(mediainfo, doubanid=doubanid, season=season, **kwargs)
if not sid: if not sid:
logger.error(f'{mediainfo.title_year} {err_msg}') logger.error(f'{mediainfo.title_year} {err_msg}')
if not exist_ok: if not exist_ok and message:
# 发回原用户 # 发回原用户
self.post_message(title=f"{mediainfo.title_year}{metainfo.season} " self.post_message(title=f"{mediainfo.title_year}{metainfo.season} "
f"添加订阅失败!", f"添加订阅失败!",
text=f"{err_msg}", text=f"{err_msg}",
image=mediainfo.get_message_image(), image=mediainfo.get_message_image(),
userid=userid) userid=userid)
else: elif message:
logger.info(f'{mediainfo.title_year}{metainfo.season} 添加订阅成功') logger.info(f'{mediainfo.title_year}{metainfo.season} 添加订阅成功')
# 广而告之 # 广而告之
self.post_message(title=f"{mediainfo.title_year}{metainfo.season} 已添加订阅", self.post_message(title=f"{mediainfo.title_year}{metainfo.season} 已添加订阅",
text=f"评分:{mediainfo.vote_average},来自用户:{username or userid}", text=f"评分:{mediainfo.vote_average},来自用户:{username or userid}",
image=mediainfo.get_message_image()) image=mediainfo.get_message_image())
# 返回结果 # 返回结果
return sid return sid, ""
def remote_refresh(self, userid: Union[str, int] = None): def remote_refresh(self, userid: Union[str, int] = None):
""" """
@ -228,8 +230,10 @@ class SubscribeChain(ChainBase):
else: else:
# 未完成下载 # 未完成下载
logger.info(f'{mediainfo.title_year} 未下载未完整,继续订阅 ...') logger.info(f'{mediainfo.title_year} 未下载未完整,继续订阅 ...')
# 更新订阅剩余集数 # 更新订阅剩余集数和时间
self.__upate_lack_episodes(lefts=lefts, subscribe=subscribe, mediainfo=mediainfo) update_date = True if downloads else False
self.__upate_lack_episodes(lefts=lefts, subscribe=subscribe,
mediainfo=mediainfo, update_date=update_date)
def refresh(self): def refresh(self):
""" """
@ -352,15 +356,18 @@ class SubscribeChain(ChainBase):
self.post_message(title=f'{mediainfo.title_year}{meta.season} 已完成订阅', self.post_message(title=f'{mediainfo.title_year}{meta.season} 已完成订阅',
image=mediainfo.get_message_image()) image=mediainfo.get_message_image())
else: else:
update_date = True if downloads else False
# 未完成下载,计算剩余集数 # 未完成下载,计算剩余集数
self.__upate_lack_episodes(lefts=lefts, subscribe=subscribe, mediainfo=mediainfo) self.__upate_lack_episodes(lefts=lefts, subscribe=subscribe,
mediainfo=mediainfo, update_date=update_date)
else: else:
# 未搜索到资源,但本地缺失可能有变化,更新订阅剩余集数 # 未搜索到资源,但本地缺失可能有变化,更新订阅剩余集数
self.__upate_lack_episodes(lefts=no_exists, subscribe=subscribe, mediainfo=mediainfo) self.__upate_lack_episodes(lefts=no_exists, subscribe=subscribe, mediainfo=mediainfo)
def __upate_lack_episodes(self, lefts: Dict[int, Dict[int, NotExistMediaInfo]], def __upate_lack_episodes(self, lefts: Dict[int, Dict[int, NotExistMediaInfo]],
subscribe: Subscribe, subscribe: Subscribe,
mediainfo: MediaInfo): mediainfo: MediaInfo,
update_date: bool = False):
""" """
更新订阅剩余集数 更新订阅剩余集数
""" """
@ -371,9 +378,16 @@ class SubscribeChain(ChainBase):
left_episodes = season_info.episodes left_episodes = season_info.episodes
logger.info(f'{mediainfo.title_year}{season} 未搜索到资源,' logger.info(f'{mediainfo.title_year}{season} 未搜索到资源,'
f'更新缺失集数为{len(left_episodes)} ...') f'更新缺失集数为{len(left_episodes)} ...')
self.subscribehelper.update(subscribe.id, { if update_date:
"lack_episode": len(left_episodes) # 同时更新最后时间
}) self.subscribehelper.update(subscribe.id, {
"lack_episode": len(left_episodes),
"last_update": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
})
else:
self.subscribehelper.update(subscribe.id, {
"lack_episode": len(left_episodes)
})
def remote_list(self, userid: Union[str, int] = None): def remote_list(self, userid: Union[str, int] = None):
""" """

View File

@ -48,6 +48,8 @@ class Subscribe(Base):
note = Column(String) note = Column(String)
# 状态N-新建, R-订阅中 # 状态N-新建, R-订阅中
state = Column(String, nullable=False, index=True, default='N') state = Column(String, nullable=False, index=True, default='N')
# 最后更新时间
last_update = Column(String)
@staticmethod @staticmethod
def exists(db: Session, tmdbid: int, season: int = None): def exists(db: Session, tmdbid: int, season: int = None):

View File

@ -41,6 +41,8 @@ class Subscribe(BaseModel):
note: Optional[str] = None note: Optional[str] = None
# 状态N-新建, R-订阅中 # 状态N-新建, R-订阅中
state: Optional[str] = None state: Optional[str] = None
# 最后更新时间
last_update: Optional[str] = None
class Config: class Config:
orm_mode = True orm_mode = True