fix subscribe api

This commit is contained in:
jxxghp 2023-07-02 00:16:43 +08:00
parent 09c84d021d
commit 2590721b97
11 changed files with 137 additions and 55 deletions

View File

@ -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:

View File

@ -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:

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:
"""

View File

@ -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")

View File

@ -37,7 +37,6 @@ class Scheduler(metaclass=Singleton):
})
def __init__(self):
return
# CookieCloud定时同步
if settings.COOKIECLOUD_INTERVAL:
self._scheduler.add_job(CookieCloudChain().process,

View File

@ -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

View File

@ -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