fix subscribe api
This commit is contained in:
parent
09c84d021d
commit
2590721b97
@ -1,4 +1,4 @@
|
||||
from typing import List, Any
|
||||
from typing import List, Any, Union
|
||||
|
||||
from fastapi import APIRouter, Request, BackgroundTasks, Depends, HTTPException, Header
|
||||
from sqlalchemy.orm import Session
|
||||
@ -33,6 +33,25 @@ async def read_subscribes(
|
||||
return Subscribe.list(db)
|
||||
|
||||
|
||||
@router.get("/{mediaid}", summary="查询订阅", response_model=schemas.Subscribe)
|
||||
async def subscribe_info_by_id(
|
||||
mediaid: str,
|
||||
season: int,
|
||||
db: Session = Depends(get_db),
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
根据TMDBID或豆瓣ID查询订阅 tmdb:/douban:
|
||||
"""
|
||||
if mediaid.startswith("tmdb:"):
|
||||
result = Subscribe.exists(db, int(mediaid[5:]), season)
|
||||
elif mediaid.startswith("douban:"):
|
||||
result = Subscribe.get_by_doubanid(db, mediaid[7:])
|
||||
else:
|
||||
result = None
|
||||
|
||||
return result if result else Subscribe()
|
||||
|
||||
|
||||
@router.post("/", summary="新增订阅", response_model=schemas.Response)
|
||||
async def create_subscribe(
|
||||
*,
|
||||
@ -42,8 +61,24 @@ async def create_subscribe(
|
||||
"""
|
||||
新增订阅
|
||||
"""
|
||||
result = SubscribeChain().add(**subscribe_in.dict())
|
||||
return schemas.Response(success=result)
|
||||
# 类型转换
|
||||
if subscribe_in.type:
|
||||
mtype = MediaType.TV if subscribe_in.type == "电视剧" else MediaType.MOVIE
|
||||
else:
|
||||
mtype = None
|
||||
# 标题转换
|
||||
if subscribe_in.name:
|
||||
title = subscribe_in.name
|
||||
else:
|
||||
title = None
|
||||
result = SubscribeChain().add(mtype=mtype,
|
||||
title=title,
|
||||
year=subscribe_in.year,
|
||||
tmdbid=subscribe_in.tmdbid,
|
||||
season=subscribe_in.season,
|
||||
doubanid=subscribe_in.doubanid,
|
||||
exist_ok=True)
|
||||
return schemas.Response(success=True if result else False, message=result)
|
||||
|
||||
|
||||
@router.put("/", summary="更新订阅", response_model=schemas.Subscribe)
|
||||
@ -79,6 +114,24 @@ async def delete_subscribe(
|
||||
return schemas.Response(success=True)
|
||||
|
||||
|
||||
@router.delete("/{mediaid}", summary="删除订阅", response_model=schemas.Response)
|
||||
async def delete_subscribe_by_id(
|
||||
mediaid: str,
|
||||
season: int,
|
||||
db: Session = Depends(get_db),
|
||||
_: schemas.TokenPayload = Depends(verify_token)
|
||||
) -> Any:
|
||||
"""
|
||||
根据TMDBID或豆瓣ID删除订阅 tmdb:/douban:
|
||||
"""
|
||||
if mediaid.startswith("tmdb:"):
|
||||
Subscribe().delete_by_tmdbid(db, int(mediaid[5:]), season)
|
||||
elif mediaid.startswith("douban:"):
|
||||
Subscribe().delete_by_doubanid(db, mediaid[7:])
|
||||
|
||||
return schemas.Response(success=True)
|
||||
|
||||
|
||||
@router.post("/seerr", summary="OverSeerr/JellySeerr通知订阅", response_model=schemas.Response)
|
||||
async def seerr_subscribe(request: Request, background_tasks: BackgroundTasks,
|
||||
authorization: str = Header(None)) -> Any:
|
||||
|
@ -34,6 +34,7 @@ class SubscribeChain(ChainBase):
|
||||
def add(self, title: str, year: str,
|
||||
mtype: MediaType = None,
|
||||
tmdbid: int = None,
|
||||
doubanid: str = None,
|
||||
season: int = None,
|
||||
userid: str = None,
|
||||
username: str = None,
|
||||
@ -60,7 +61,7 @@ class SubscribeChain(ChainBase):
|
||||
mediainfo: MediaInfo = self.recognize_media(meta=metainfo, mtype=mtype, tmdbid=tmdbid)
|
||||
if not mediainfo:
|
||||
logger.warn(f'未识别到媒体信息,标题:{title},tmdbid:{tmdbid}')
|
||||
return False
|
||||
return 0
|
||||
# 更新媒体图片
|
||||
self.obtain_images(mediainfo=mediainfo)
|
||||
# 总集数
|
||||
@ -75,14 +76,14 @@ class SubscribeChain(ChainBase):
|
||||
tmdbid=mediainfo.tmdb_id)
|
||||
if not mediainfo:
|
||||
logger.error(f"媒体信息识别失败!")
|
||||
return False
|
||||
return 0
|
||||
if not mediainfo.seasons:
|
||||
logger.error(f"媒体信息中没有季集信息,标题:{title},tmdbid:{tmdbid}")
|
||||
return False
|
||||
return 0
|
||||
total_episode = len(mediainfo.seasons.get(season) or [])
|
||||
if not total_episode:
|
||||
logger.error(f'未获取到总集数,标题:{title},tmdbid:{tmdbid}')
|
||||
return False
|
||||
return 0
|
||||
kwargs.update({
|
||||
'total_episode': total_episode
|
||||
})
|
||||
@ -92,7 +93,7 @@ class SubscribeChain(ChainBase):
|
||||
'lack_episode': kwargs.get('total_episode')
|
||||
})
|
||||
# 添加订阅
|
||||
sid, err_msg = self.subscribehelper.add(mediainfo, season=season, **kwargs)
|
||||
sid, err_msg = self.subscribehelper.add(mediainfo, doubanid=doubanid, season=season, **kwargs)
|
||||
if not sid:
|
||||
logger.error(f'{mediainfo.title_year} {err_msg}')
|
||||
if not exist_ok:
|
||||
|
@ -109,6 +109,8 @@ class MediaInfo:
|
||||
title: Optional[str] = None
|
||||
# 年份
|
||||
year: Optional[str] = None
|
||||
# 季
|
||||
season: Optional[int] = None
|
||||
# TMDB ID
|
||||
tmdb_id: Optional[int] = None
|
||||
# IMDB ID
|
||||
@ -334,7 +336,10 @@ class MediaInfo:
|
||||
self.type = MediaType.MOVIE if info.get("type") == "movie" else MediaType.TV
|
||||
# 标题
|
||||
if not self.title:
|
||||
self.title = MetaInfo(info.get("title")).name
|
||||
self.title = info.get("title")
|
||||
# 识别标题中的季
|
||||
meta = MetaInfo(self.title)
|
||||
self.season = meta.begin_season
|
||||
# 原语种标题
|
||||
if not self.original_title:
|
||||
self.original_title = info.get("original_title")
|
||||
|
@ -2,6 +2,7 @@ from sqlalchemy import Column, Integer, String, Sequence
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.db.models import Base
|
||||
from app.schemas import MediaType
|
||||
|
||||
|
||||
class Subscribe(Base):
|
||||
@ -19,8 +20,8 @@ class Subscribe(Base):
|
||||
keyword = Column(String)
|
||||
tmdbid = Column(Integer, index=True)
|
||||
imdbid = Column(String)
|
||||
tvdbid = Column(Integer, index=True)
|
||||
doubanid = Column(String)
|
||||
tvdbid = Column(Integer)
|
||||
doubanid = Column(String, index=True)
|
||||
# 季号
|
||||
season = Column(Integer)
|
||||
# 海报
|
||||
@ -60,7 +61,10 @@ class Subscribe(Base):
|
||||
return db.query(Subscribe).filter(Subscribe.state == state).all()
|
||||
|
||||
@staticmethod
|
||||
def get_by_tmdbid(db: Session, tmdbid: int):
|
||||
def get_by_tmdbid(db: Session, tmdbid: int, season: int = None):
|
||||
if season:
|
||||
return db.query(Subscribe).filter(Subscribe.tmdbid == tmdbid,
|
||||
Subscribe.season == season).all()
|
||||
return db.query(Subscribe).filter(Subscribe.tmdbid == tmdbid).all()
|
||||
|
||||
@staticmethod
|
||||
@ -68,5 +72,17 @@ class Subscribe(Base):
|
||||
return db.query(Subscribe).filter(Subscribe.name == title).first()
|
||||
|
||||
@staticmethod
|
||||
def get_by_tvdbid(db: Session, tvdbid: int):
|
||||
return db.query(Subscribe).filter(Subscribe.tvdbid == tvdbid).first()
|
||||
def get_by_doubanid(db: Session, doubanid: str):
|
||||
return db.query(Subscribe).filter(Subscribe.doubanid == doubanid).first()
|
||||
|
||||
def delete_by_tmdbid(self, db: Session, tmdbid: int, season: int):
|
||||
subscrbies = self.get_by_tmdbid(db, tmdbid, season)
|
||||
for subscrbie in subscrbies:
|
||||
subscrbie.delete(db, subscrbie.id)
|
||||
return True
|
||||
|
||||
def delete_by_doubanid(self, db: Session, doubanid: str):
|
||||
subscribe = self.get_by_doubanid(db, doubanid)
|
||||
if subscribe:
|
||||
subscribe.delete(db, subscribe.id)
|
||||
return True
|
||||
|
@ -18,7 +18,8 @@ class SystemConfig(Base):
|
||||
def get_by_key(db: Session, key: str):
|
||||
return db.query(SystemConfig).filter(SystemConfig.key == key).first()
|
||||
|
||||
@staticmethod
|
||||
def delete_by_key(db: Session, key: str):
|
||||
db.query(SystemConfig).filter(SystemConfig.key == key).delete()
|
||||
db.commit()
|
||||
def delete_by_key(self, db: Session, key: str):
|
||||
systemconfig = self.get_by_key(db, key)
|
||||
if systemconfig:
|
||||
systemconfig.delete(db, systemconfig.id)
|
||||
return True
|
||||
|
@ -37,6 +37,8 @@ class User(Base):
|
||||
def get_by_name(db: Session, name: str):
|
||||
return db.query(User).filter(User.name == name).first()
|
||||
|
||||
@staticmethod
|
||||
def delete_by_name(db: Session, name: str):
|
||||
return db.query(User).filter(User.name == name).delete()
|
||||
def delete_by_name(self, db: Session, name: str):
|
||||
user = self.get_by_name(db, name)
|
||||
if user:
|
||||
user.delete(db, user.id)
|
||||
return True
|
||||
|
@ -14,22 +14,23 @@ class SubscribeOper(DbOper):
|
||||
"""
|
||||
新增订阅
|
||||
"""
|
||||
subscribe = Subscribe(name=mediainfo.title,
|
||||
year=mediainfo.year,
|
||||
type=mediainfo.type.value,
|
||||
tmdbid=mediainfo.tmdb_id,
|
||||
imdbid=mediainfo.imdb_id,
|
||||
tvdbid=mediainfo.tvdb_id,
|
||||
poster=mediainfo.get_poster_image(),
|
||||
backdrop=mediainfo.get_backdrop_image(),
|
||||
vote=mediainfo.vote_average,
|
||||
description=mediainfo.overview,
|
||||
**kwargs)
|
||||
if not subscribe.exists(self._db, tmdbid=mediainfo.tmdb_id, season=kwargs.get('season')):
|
||||
subscribe = Subscribe.exists(self._db, tmdbid=mediainfo.tmdb_id, season=kwargs.get('season'))
|
||||
if not subscribe:
|
||||
subscribe = Subscribe(name=mediainfo.title,
|
||||
year=mediainfo.year,
|
||||
type=mediainfo.type.value,
|
||||
tmdbid=mediainfo.tmdb_id,
|
||||
imdbid=mediainfo.imdb_id,
|
||||
tvdbid=mediainfo.tvdb_id,
|
||||
poster=mediainfo.get_poster_image(),
|
||||
backdrop=mediainfo.get_backdrop_image(),
|
||||
vote=mediainfo.vote_average,
|
||||
description=mediainfo.overview,
|
||||
**kwargs)
|
||||
subscribe.create(self._db)
|
||||
return subscribe.id, "新增订阅成功"
|
||||
else:
|
||||
return 0, "订阅已存在"
|
||||
return subscribe.id, "订阅已存在"
|
||||
|
||||
def get(self, sid: int) -> Subscribe:
|
||||
"""
|
||||
|
@ -583,6 +583,8 @@ class TheMovieDbModule(_ModuleBase):
|
||||
images = self.tmdb.get_tv_images(mediainfo.tmdb_id, season=1)
|
||||
if not images:
|
||||
return mediainfo
|
||||
if isinstance(images, list):
|
||||
images = images[0]
|
||||
# 背景图
|
||||
if not mediainfo.backdrop_path:
|
||||
backdrops = images.get("backdrops")
|
||||
|
@ -37,7 +37,6 @@ class Scheduler(metaclass=Singleton):
|
||||
})
|
||||
|
||||
def __init__(self):
|
||||
return
|
||||
# CookieCloud定时同步
|
||||
if settings.COOKIECLOUD_INTERVAL:
|
||||
self._scheduler.add_job(CookieCloudChain().process,
|
||||
|
@ -56,6 +56,8 @@ class MediaInfo(BaseModel):
|
||||
title: Optional[str] = None
|
||||
# 年份
|
||||
year: Optional[str] = None
|
||||
# 季
|
||||
season: Optional[int] = None
|
||||
# TMDB ID
|
||||
tmdb_id: Optional[int] = None
|
||||
# IMDB ID
|
||||
|
@ -4,43 +4,43 @@ from pydantic import BaseModel
|
||||
|
||||
|
||||
class Subscribe(BaseModel):
|
||||
id: Optional[int]
|
||||
id: Optional[int] = None
|
||||
# 订阅名称
|
||||
name: Optional[str]
|
||||
name: Optional[str] = None
|
||||
# 订阅年份
|
||||
year: Optional[str]
|
||||
year: Optional[str] = None
|
||||
# 订阅类型 电影/电视剧
|
||||
type: Optional[str]
|
||||
type: Optional[str] = None
|
||||
# 搜索关键字
|
||||
keyword: Optional[str]
|
||||
tmdbid: Optional[int]
|
||||
doubanid: Optional[str]
|
||||
keyword: Optional[str] = None
|
||||
tmdbid: Optional[int] = None
|
||||
doubanid: Optional[str] = None
|
||||
# 季号
|
||||
season: Optional[int]
|
||||
season: Optional[int] = None
|
||||
# 海报
|
||||
poster: Optional[str]
|
||||
poster: Optional[str] = None
|
||||
# 背景图
|
||||
backdrop: Optional[str]
|
||||
backdrop: Optional[str] = None
|
||||
# 评分
|
||||
vote: Optional[int]
|
||||
vote: Optional[int] = 0
|
||||
# 描述
|
||||
description: Optional[str]
|
||||
description: Optional[str] = None
|
||||
# 过滤规则
|
||||
filter: Optional[str]
|
||||
filter: Optional[str] = None
|
||||
# 包含
|
||||
include: Optional[str]
|
||||
include: Optional[str] = None
|
||||
# 排除
|
||||
exclude: Optional[str]
|
||||
exclude: Optional[str] = None
|
||||
# 总集数
|
||||
total_episode: Optional[int]
|
||||
total_episode: Optional[int] = 0
|
||||
# 开始集数
|
||||
start_episode: Optional[int]
|
||||
start_episode: Optional[int] = 0
|
||||
# 缺失集数
|
||||
lack_episode: Optional[int]
|
||||
lack_episode: Optional[int] = 0
|
||||
# 附加信息
|
||||
note: Optional[str]
|
||||
note: Optional[str] = None
|
||||
# 状态:N-新建, R-订阅中
|
||||
state: Optional[str]
|
||||
state: Optional[str] = None
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
Loading…
x
Reference in New Issue
Block a user