mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-04-14 02:00:31 +08:00
fix blanke
This commit is contained in:
@@ -12,8 +12,8 @@ router = APIRouter()
|
||||
|
||||
@router.get("/credits/{bangumiid}", summary="查询Bangumi演职员表", response_model=List[schemas.MediaPerson])
|
||||
def bangumi_credits(bangumiid: int,
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 20,
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 20,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
查询Bangumi演职员表
|
||||
@@ -26,8 +26,8 @@ def bangumi_credits(bangumiid: int,
|
||||
|
||||
@router.get("/recommend/{bangumiid}", summary="查询Bangumi推荐", response_model=List[schemas.MediaInfo])
|
||||
def bangumi_recommend(bangumiid: int,
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 20,
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 20,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
查询Bangumi推荐
|
||||
@@ -49,8 +49,8 @@ def bangumi_person(person_id: int,
|
||||
|
||||
@router.get("/person/credits/{person_id}", summary="人物参演作品", response_model=List[schemas.MediaInfo])
|
||||
def bangumi_person_credits(person_id: int,
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 20,
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 20,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
根据人物ID查询人物参演作品
|
||||
|
||||
@@ -18,7 +18,7 @@ router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/statistic", summary="媒体数量统计", response_model=schemas.Statistic)
|
||||
def statistic(name: Optional[str] = None, _: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
def statistic(name: Optional[str] = None, _: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
查询媒体数量统计信息
|
||||
"""
|
||||
@@ -82,7 +82,7 @@ def processes(_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
|
||||
|
||||
@router.get("/downloader", summary="下载器信息", response_model=schemas.DownloaderInfo)
|
||||
def downloader(name: Optional[str] = None, _: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
def downloader(name: Optional[str] = None, _: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
查询下载器信息
|
||||
"""
|
||||
@@ -127,7 +127,7 @@ def schedule2(_: Annotated[str, Depends(verify_apitoken)]) -> Any:
|
||||
|
||||
|
||||
@router.get("/transfer", summary="文件整理统计", response_model=List[int])
|
||||
def transfer(days: Optional[int] = 7, db: Session = Depends(get_db),
|
||||
def transfer(days: Optional[int] = 7, db: Session = Depends(get_db),
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
查询文件整理统计信息
|
||||
|
||||
@@ -22,7 +22,7 @@ def douban_person(person_id: int,
|
||||
|
||||
@router.get("/person/credits/{person_id}", summary="人物参演作品", response_model=List[schemas.MediaInfo])
|
||||
def douban_person_credits(person_id: int,
|
||||
page: Optional[int] = 1,
|
||||
page: Optional[int] = 1,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
根据人物ID查询人物参演作品
|
||||
|
||||
@@ -18,7 +18,7 @@ router = APIRouter()
|
||||
|
||||
@router.get("/", summary="正在下载", response_model=List[schemas.DownloadingTorrent])
|
||||
def current(
|
||||
name: Optional[str] = None,
|
||||
name: Optional[str] = None,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
查询正在下载的任务
|
||||
|
||||
@@ -20,8 +20,8 @@ router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/download", summary="查询下载历史记录", response_model=List[schemas.DownloadHistory])
|
||||
def download_history(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
def download_history(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
db: Session = Depends(get_db),
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
@@ -42,10 +42,10 @@ def delete_download_history(history_in: schemas.DownloadHistory,
|
||||
|
||||
|
||||
@router.get("/transfer", summary="查询整理记录", response_model=schemas.Response)
|
||||
def transfer_history(title: Optional[str] = None,
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
status: Optional[bool] = None,
|
||||
def transfer_history(title: Optional[str] = None,
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
status: Optional[bool] = None,
|
||||
db: Session = Depends(get_db),
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
@@ -78,8 +78,8 @@ def transfer_history(title: Optional[str] = None,
|
||||
|
||||
@router.delete("/transfer", summary="删除整理记录", response_model=schemas.Response)
|
||||
def delete_transfer_history(history_in: schemas.TransferHistory,
|
||||
deletesrc: Optional[bool] = False,
|
||||
deletedest: Optional[bool] = False,
|
||||
deletesrc: Optional[bool] = False,
|
||||
deletedest: Optional[bool] = False,
|
||||
db: Session = Depends(get_db),
|
||||
_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any:
|
||||
"""
|
||||
|
||||
@@ -19,7 +19,7 @@ router = APIRouter()
|
||||
|
||||
@router.get("/recognize", summary="识别媒体信息(种子)", response_model=schemas.Context)
|
||||
def recognize(title: str,
|
||||
subtitle: Optional[str] = None,
|
||||
subtitle: Optional[str] = None,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
根据标题、副标题识别媒体信息
|
||||
@@ -35,7 +35,7 @@ def recognize(title: str,
|
||||
@router.get("/recognize2", summary="识别种子媒体信息(API_TOKEN)", response_model=schemas.Context)
|
||||
def recognize2(_: Annotated[str, Depends(verify_apitoken)],
|
||||
title: str,
|
||||
subtitle: Optional[str] = None
|
||||
subtitle: Optional[str] = None
|
||||
) -> Any:
|
||||
"""
|
||||
根据标题、副标题识别媒体信息 API_TOKEN认证(?token=xxx)
|
||||
@@ -69,7 +69,7 @@ def recognize_file2(path: str,
|
||||
|
||||
@router.get("/search", summary="搜索媒体/人物信息", response_model=List[dict])
|
||||
def search(title: str,
|
||||
type: Optional[str] = "media",
|
||||
type: Optional[str] = "media",
|
||||
page: int = 1,
|
||||
count: int = 8,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
@@ -106,7 +106,7 @@ def search(title: str,
|
||||
|
||||
@router.post("/scrape/{storage}", summary="刮削媒体信息", response_model=schemas.Response)
|
||||
def scrape(fileitem: schemas.FileItem,
|
||||
storage: Optional[str] = "local",
|
||||
storage: Optional[str] = "local",
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
刮削媒体信息
|
||||
@@ -137,8 +137,8 @@ def category(_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
|
||||
|
||||
@router.get("/seasons", summary="查询媒体季信息", response_model=List[schemas.MediaSeason])
|
||||
def seasons(mediaid: Optional[str] = None,
|
||||
title: Optional[str] = None,
|
||||
def seasons(mediaid: Optional[str] = None,
|
||||
title: Optional[str] = None,
|
||||
year: int = None,
|
||||
season: int = None,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
@@ -180,7 +180,7 @@ def seasons(mediaid: Optional[str] = None,
|
||||
|
||||
|
||||
@router.get("/{mediaid}", summary="查询媒体详情", response_model=schemas.MediaInfo)
|
||||
def detail(mediaid: str, type_name: str, title: Optional[str] = None, year: int = None,
|
||||
def detail(mediaid: str, type_name: str, title: Optional[str] = None, year: int = None,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
根据媒体ID查询themoviedb或豆瓣媒体信息,type_name: 电影/电视剧
|
||||
|
||||
@@ -43,11 +43,11 @@ def play_item(itemid: str, _: schemas.TokenPayload = Depends(verify_token)) -> s
|
||||
|
||||
|
||||
@router.get("/exists", summary="查询本地是否存在(数据库)", response_model=schemas.Response)
|
||||
def exists_local(title: Optional[str] = None,
|
||||
year: Optional[str] = None,
|
||||
mtype: Optional[str] = None,
|
||||
tmdbid: Optional[int] = None,
|
||||
season: Optional[int] = None,
|
||||
def exists_local(title: Optional[str] = None,
|
||||
year: Optional[str] = None,
|
||||
mtype: Optional[str] = None,
|
||||
tmdbid: Optional[int] = None,
|
||||
season: Optional[int] = None,
|
||||
db: Session = Depends(get_db),
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
@@ -121,7 +121,7 @@ def not_exists(media_in: schemas.MediaInfo,
|
||||
|
||||
|
||||
@router.get("/latest", summary="最新入库条目", response_model=List[schemas.MediaServerPlayItem])
|
||||
def latest(server: str, count: Optional[int] = 18,
|
||||
def latest(server: str, count: Optional[int] = 18,
|
||||
userinfo: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
获取媒体服务器最新入库条目
|
||||
@@ -130,7 +130,7 @@ def latest(server: str, count: Optional[int] = 18,
|
||||
|
||||
|
||||
@router.get("/playing", summary="正在播放条目", response_model=List[schemas.MediaServerPlayItem])
|
||||
def playing(server: str, count: Optional[int] = 12,
|
||||
def playing(server: str, count: Optional[int] = 12,
|
||||
userinfo: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
获取媒体服务器正在播放条目
|
||||
@@ -139,7 +139,7 @@ def playing(server: str, count: Optional[int] = 12,
|
||||
|
||||
|
||||
@router.get("/library", summary="媒体库列表", response_model=List[schemas.MediaServerLibrary])
|
||||
def library(server: str, hidden: Optional[bool] = False,
|
||||
def library(server: str, hidden: Optional[bool] = False,
|
||||
userinfo: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
获取媒体服务器媒体库列表
|
||||
|
||||
@@ -60,8 +60,8 @@ def web_message(text: str, current_user: User = Depends(get_current_active_super
|
||||
@router.get("/web", summary="获取WEB消息", response_model=List[dict])
|
||||
def get_web_message(_: schemas.TokenPayload = Depends(verify_token),
|
||||
db: Session = Depends(get_db),
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 20):
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 20):
|
||||
"""
|
||||
获取WEB消息列表
|
||||
"""
|
||||
@@ -77,7 +77,7 @@ def get_web_message(_: schemas.TokenPayload = Depends(verify_token),
|
||||
|
||||
|
||||
def wechat_verify(echostr: str, msg_signature: str, timestamp: Union[str, int], nonce: str,
|
||||
source: Optional[str] = None) -> Any:
|
||||
source: Optional[str] = None) -> Any:
|
||||
"""
|
||||
微信验证响应
|
||||
"""
|
||||
@@ -114,8 +114,8 @@ def vocechat_verify() -> Any:
|
||||
|
||||
|
||||
@router.get("/", summary="回调请求验证")
|
||||
def incoming_verify(token: Optional[str] = None, echostr: Optional[str] = None, msg_signature: Optional[str] = None,
|
||||
timestamp: Union[str, int] = None, nonce: Optional[str] = None, source: Optional[str] = None,
|
||||
def incoming_verify(token: Optional[str] = None, echostr: Optional[str] = None, msg_signature: Optional[str] = None,
|
||||
timestamp: Union[str, int] = None, nonce: Optional[str] = None, source: Optional[str] = None,
|
||||
_: schemas.TokenPayload = Depends(verify_apitoken)) -> Any:
|
||||
"""
|
||||
微信/VoceChat等验证响应
|
||||
|
||||
@@ -118,7 +118,7 @@ def _clean_protected_routes(existing_paths: dict):
|
||||
|
||||
@router.get("/", summary="所有插件", response_model=List[schemas.Plugin])
|
||||
def all_plugins(_: schemas.TokenPayload = Depends(get_current_active_superuser),
|
||||
state: Optional[str] = "all") -> List[schemas.Plugin]:
|
||||
state: Optional[str] = "all") -> List[schemas.Plugin]:
|
||||
"""
|
||||
查询所有插件清单,包括本地插件和在线插件,插件状态:installed, market, all
|
||||
"""
|
||||
@@ -181,8 +181,8 @@ def statistic(_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
|
||||
@router.get("/install/{plugin_id}", summary="安装插件", response_model=schemas.Response)
|
||||
def install(plugin_id: str,
|
||||
repo_url: Optional[str] = "",
|
||||
force: Optional[bool] = False,
|
||||
repo_url: Optional[str] = "",
|
||||
force: Optional[bool] = False,
|
||||
_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any:
|
||||
"""
|
||||
安装插件
|
||||
|
||||
@@ -29,8 +29,8 @@ def source(_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
|
||||
|
||||
@router.get("/bangumi_calendar", summary="Bangumi每日放送", response_model=List[schemas.MediaInfo])
|
||||
def bangumi_calendar(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
def bangumi_calendar(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
浏览Bangumi每日放送
|
||||
@@ -39,8 +39,8 @@ def bangumi_calendar(page: Optional[int] = 1,
|
||||
|
||||
|
||||
@router.get("/douban_showing", summary="豆瓣正在热映", response_model=List[schemas.MediaInfo])
|
||||
def douban_showing(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
def douban_showing(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
浏览豆瓣正在热映
|
||||
@@ -49,10 +49,10 @@ def douban_showing(page: Optional[int] = 1,
|
||||
|
||||
|
||||
@router.get("/douban_movies", summary="豆瓣电影", response_model=List[schemas.MediaInfo])
|
||||
def douban_movies(sort: Optional[str] = "R",
|
||||
tags: Optional[str] = "",
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
def douban_movies(sort: Optional[str] = "R",
|
||||
tags: Optional[str] = "",
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
浏览豆瓣电影信息
|
||||
@@ -61,10 +61,10 @@ def douban_movies(sort: Optional[str] = "R",
|
||||
|
||||
|
||||
@router.get("/douban_tvs", summary="豆瓣剧集", response_model=List[schemas.MediaInfo])
|
||||
def douban_tvs(sort: Optional[str] = "R",
|
||||
tags: Optional[str] = "",
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
def douban_tvs(sort: Optional[str] = "R",
|
||||
tags: Optional[str] = "",
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
浏览豆瓣剧集信息
|
||||
@@ -73,8 +73,8 @@ def douban_tvs(sort: Optional[str] = "R",
|
||||
|
||||
|
||||
@router.get("/douban_movie_top250", summary="豆瓣电影TOP250", response_model=List[schemas.MediaInfo])
|
||||
def douban_movie_top250(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
def douban_movie_top250(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
浏览豆瓣剧集信息
|
||||
@@ -83,8 +83,8 @@ def douban_movie_top250(page: Optional[int] = 1,
|
||||
|
||||
|
||||
@router.get("/douban_tv_weekly_chinese", summary="豆瓣国产剧集周榜", response_model=List[schemas.MediaInfo])
|
||||
def douban_tv_weekly_chinese(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
def douban_tv_weekly_chinese(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
中国每周剧集口碑榜
|
||||
@@ -93,8 +93,8 @@ def douban_tv_weekly_chinese(page: Optional[int] = 1,
|
||||
|
||||
|
||||
@router.get("/douban_tv_weekly_global", summary="豆瓣全球剧集周榜", response_model=List[schemas.MediaInfo])
|
||||
def douban_tv_weekly_global(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
def douban_tv_weekly_global(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
全球每周剧集口碑榜
|
||||
@@ -103,8 +103,8 @@ def douban_tv_weekly_global(page: Optional[int] = 1,
|
||||
|
||||
|
||||
@router.get("/douban_tv_animation", summary="豆瓣动画剧集", response_model=List[schemas.MediaInfo])
|
||||
def douban_tv_animation(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
def douban_tv_animation(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
热门动画剧集
|
||||
@@ -113,8 +113,8 @@ def douban_tv_animation(page: Optional[int] = 1,
|
||||
|
||||
|
||||
@router.get("/douban_movie_hot", summary="豆瓣热门电影", response_model=List[schemas.MediaInfo])
|
||||
def douban_movie_hot(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
def douban_movie_hot(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
热门电影
|
||||
@@ -123,8 +123,8 @@ def douban_movie_hot(page: Optional[int] = 1,
|
||||
|
||||
|
||||
@router.get("/douban_tv_hot", summary="豆瓣热门电视剧", response_model=List[schemas.MediaInfo])
|
||||
def douban_tv_hot(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
def douban_tv_hot(page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
热门电视剧
|
||||
@@ -133,15 +133,15 @@ def douban_tv_hot(page: Optional[int] = 1,
|
||||
|
||||
|
||||
@router.get("/tmdb_movies", summary="TMDB电影", response_model=List[schemas.MediaInfo])
|
||||
def tmdb_movies(sort_by: Optional[str] = "popularity.desc",
|
||||
with_genres: Optional[str] = "",
|
||||
with_original_language: Optional[str] = "",
|
||||
with_keywords: Optional[str] = "",
|
||||
with_watch_providers: Optional[str] = "",
|
||||
vote_average: Optional[float] = 0,
|
||||
vote_count: Optional[int] = 0,
|
||||
release_date: Optional[str] = "",
|
||||
page: Optional[int] = 1,
|
||||
def tmdb_movies(sort_by: Optional[str] = "popularity.desc",
|
||||
with_genres: Optional[str] = "",
|
||||
with_original_language: Optional[str] = "",
|
||||
with_keywords: Optional[str] = "",
|
||||
with_watch_providers: Optional[str] = "",
|
||||
vote_average: Optional[float] = 0.0,
|
||||
vote_count: Optional[int] = 0,
|
||||
release_date: Optional[str] = "",
|
||||
page: Optional[int] = 1,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
浏览TMDB电影信息
|
||||
@@ -158,15 +158,15 @@ def tmdb_movies(sort_by: Optional[str] = "popularity.desc",
|
||||
|
||||
|
||||
@router.get("/tmdb_tvs", summary="TMDB剧集", response_model=List[schemas.MediaInfo])
|
||||
def tmdb_tvs(sort_by: Optional[str] = "popularity.desc",
|
||||
with_genres: Optional[str] = "",
|
||||
with_original_language: Optional[str] = "",
|
||||
with_keywords: Optional[str] = "",
|
||||
with_watch_providers: Optional[str] = "",
|
||||
vote_average: Optional[float] = 0,
|
||||
vote_count: Optional[int] = 0,
|
||||
release_date: Optional[str] = "",
|
||||
page: Optional[int] = 1,
|
||||
def tmdb_tvs(sort_by: Optional[str] = "popularity.desc",
|
||||
with_genres: Optional[str] = "",
|
||||
with_original_language: Optional[str] = "",
|
||||
with_keywords: Optional[str] = "",
|
||||
with_watch_providers: Optional[str] = "",
|
||||
vote_average: Optional[float] = 0.0,
|
||||
vote_count: Optional[int] = 0,
|
||||
release_date: Optional[str] = "",
|
||||
page: Optional[int] = 1,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
浏览TMDB剧集信息
|
||||
@@ -183,7 +183,7 @@ def tmdb_tvs(sort_by: Optional[str] = "popularity.desc",
|
||||
|
||||
|
||||
@router.get("/tmdb_trending", summary="TMDB流行趋势", response_model=List[schemas.MediaInfo])
|
||||
def tmdb_trending(page: Optional[int] = 1,
|
||||
def tmdb_trending(page: Optional[int] = 1,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
TMDB流行趋势
|
||||
|
||||
@@ -26,12 +26,12 @@ def search_latest(_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
|
||||
@router.get("/media/{mediaid}", summary="精确搜索资源", response_model=schemas.Response)
|
||||
def search_by_id(mediaid: str,
|
||||
mtype: Optional[str] = None,
|
||||
area: Optional[str] = "title",
|
||||
title: Optional[str] = None,
|
||||
year: Optional[str] = None,
|
||||
season: Optional[str] = None,
|
||||
sites: Optional[str] = None,
|
||||
mtype: Optional[str] = None,
|
||||
area: Optional[str] = "title",
|
||||
title: Optional[str] = None,
|
||||
year: Optional[str] = None,
|
||||
season: Optional[str] = None,
|
||||
sites: Optional[str] = None,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
根据TMDBID/豆瓣ID精确搜索站点资源 tmdb:/douban:/bangumi:
|
||||
@@ -146,9 +146,9 @@ def search_by_id(mediaid: str,
|
||||
|
||||
|
||||
@router.get("/title", summary="模糊搜索资源", response_model=schemas.Response)
|
||||
def search_by_title(keyword: Optional[str] = None,
|
||||
page: Optional[int] = 0,
|
||||
sites: Optional[str] = None,
|
||||
def search_by_title(keyword: Optional[str] = None,
|
||||
page: Optional[int] = 0,
|
||||
sites: Optional[str] = None,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
根据名称模糊搜索站点资源,支持分页,关键词为空是返回首页资源
|
||||
|
||||
@@ -145,7 +145,7 @@ def update_cookie(
|
||||
site_id: int,
|
||||
username: str,
|
||||
password: str,
|
||||
code: Optional[str] = None,
|
||||
code: Optional[str] = None,
|
||||
db: Session = Depends(get_db),
|
||||
_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any:
|
||||
"""
|
||||
@@ -203,7 +203,7 @@ def read_userdata_latest(
|
||||
@router.get("/userdata/{site_id}", summary="查询某站点用户数据", response_model=schemas.Response)
|
||||
def read_userdata(
|
||||
site_id: int,
|
||||
workdate: Optional[str] = None,
|
||||
workdate: Optional[str] = None,
|
||||
db: Session = Depends(get_db),
|
||||
_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any:
|
||||
"""
|
||||
@@ -291,9 +291,9 @@ def site_category(site_id: int,
|
||||
|
||||
@router.get("/resource/{site_id}", summary="站点资源", response_model=List[schemas.TorrentInfo])
|
||||
def site_resource(site_id: int,
|
||||
keyword: Optional[str] = None,
|
||||
cat: Optional[str] = None,
|
||||
page: Optional[int] = 0,
|
||||
keyword: Optional[str] = None,
|
||||
cat: Optional[str] = None,
|
||||
page: Optional[int] = 0,
|
||||
db: Session = Depends(get_db),
|
||||
_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any:
|
||||
"""
|
||||
|
||||
@@ -31,7 +31,7 @@ def qrcode(name: str, _: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
|
||||
|
||||
@router.get("/check/{name}", summary="二维码登录确认", response_model=schemas.Response)
|
||||
def check(name: str, ck: Optional[str] = None, t: Optional[str] = None,
|
||||
def check(name: str, ck: Optional[str] = None, t: Optional[str] = None,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
二维码登录确认
|
||||
@@ -58,7 +58,7 @@ def save(name: str,
|
||||
|
||||
@router.post("/list", summary="所有目录和文件", response_model=List[schemas.FileItem])
|
||||
def list_files(fileitem: schemas.FileItem,
|
||||
sort: Optional[str] = 'updated_at',
|
||||
sort: Optional[str] = 'updated_at',
|
||||
_: User = Depends(get_current_active_superuser)) -> Any:
|
||||
"""
|
||||
查询当前目录下所有目录和文件
|
||||
@@ -141,7 +141,7 @@ def image(fileitem: schemas.FileItem,
|
||||
@router.post("/rename", summary="重命名文件或目录", response_model=schemas.Response)
|
||||
def rename(fileitem: schemas.FileItem,
|
||||
new_name: str,
|
||||
recursive: Optional[bool] = False,
|
||||
recursive: Optional[bool] = False,
|
||||
_: User = Depends(get_current_active_superuser)) -> Any:
|
||||
"""
|
||||
重命名文件或目录
|
||||
|
||||
@@ -165,8 +165,8 @@ def update_subscribe_status(
|
||||
@router.get("/media/{mediaid}", summary="查询订阅", response_model=schemas.Subscribe)
|
||||
def subscribe_mediaid(
|
||||
mediaid: str,
|
||||
season: Optional[int] = None,
|
||||
title: Optional[str] = None,
|
||||
season: Optional[int] = None,
|
||||
title: Optional[str] = None,
|
||||
db: Session = Depends(get_db),
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
@@ -294,7 +294,7 @@ def search_subscribe(
|
||||
@router.delete("/media/{mediaid}", summary="删除订阅", response_model=schemas.Response)
|
||||
def delete_subscribe_by_mediaid(
|
||||
mediaid: str,
|
||||
season: Optional[int] = None,
|
||||
season: Optional[int] = None,
|
||||
db: Session = Depends(get_db),
|
||||
_: schemas.TokenPayload = Depends(verify_token)
|
||||
) -> Any:
|
||||
@@ -385,8 +385,8 @@ async def seerr_subscribe(request: Request, background_tasks: BackgroundTasks,
|
||||
@router.get("/history/{mtype}", summary="查询订阅历史", response_model=List[schemas.Subscribe])
|
||||
def subscribe_history(
|
||||
mtype: str,
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
db: Session = Depends(get_db),
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
@@ -411,9 +411,9 @@ def delete_subscribe(
|
||||
@router.get("/popular", summary="热门订阅(基于用户共享数据)", response_model=List[schemas.MediaInfo])
|
||||
def popular_subscribes(
|
||||
stype: str,
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
min_sub: Optional[int] = None,
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
min_sub: Optional[int] = None,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
查询热门订阅
|
||||
@@ -532,7 +532,7 @@ def followed_subscribers(_: schemas.TokenPayload = Depends(verify_token)) -> Any
|
||||
|
||||
@router.post("/follow", summary="Follow订阅分享人", response_model=schemas.Response)
|
||||
def follow_subscriber(
|
||||
share_uid: Optional[str] = None,
|
||||
share_uid: Optional[str] = None,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
Follow订阅分享人
|
||||
@@ -546,7 +546,7 @@ def follow_subscriber(
|
||||
|
||||
@router.delete("/follow", summary="取消Follow订阅分享人", response_model=schemas.Response)
|
||||
def unfollow_subscriber(
|
||||
share_uid: Optional[str] = None,
|
||||
share_uid: Optional[str] = None,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
取消Follow订阅分享人
|
||||
@@ -560,9 +560,9 @@ def unfollow_subscriber(
|
||||
|
||||
@router.get("/shares", summary="查询分享的订阅", response_model=List[schemas.SubscribeShare])
|
||||
def popular_subscribes(
|
||||
name: Optional[str] = None,
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
name: Optional[str] = None,
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 30,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
查询分享的订阅
|
||||
|
||||
@@ -288,7 +288,7 @@ def set_setting(key: str, value: Union[list, dict, bool, int, str] = None,
|
||||
|
||||
|
||||
@router.get("/message", summary="实时消息")
|
||||
async def get_message(request: Request, role: Optional[str] = "system",
|
||||
async def get_message(request: Request, role: Optional[str] = "system",
|
||||
_: schemas.TokenPayload = Depends(verify_resource_token)):
|
||||
"""
|
||||
实时获取系统消息,返回格式为SSE
|
||||
@@ -310,7 +310,7 @@ async def get_message(request: Request, role: Optional[str] = "system",
|
||||
|
||||
|
||||
@router.get("/logging", summary="实时日志")
|
||||
async def get_logging(request: Request, length: Optional[int] = 50, logfile: Optional[str] = "moviepilot.log",
|
||||
async def get_logging(request: Request, length: Optional[int] = 50, logfile: Optional[str] = "moviepilot.log",
|
||||
_: schemas.TokenPayload = Depends(verify_resource_token)):
|
||||
"""
|
||||
实时获取系统日志
|
||||
@@ -382,7 +382,7 @@ def latest_version(_: schemas.TokenPayload = Depends(verify_token)):
|
||||
@router.get("/ruletest", summary="过滤规则测试", response_model=schemas.Response)
|
||||
def ruletest(title: str,
|
||||
rulegroup_name: str,
|
||||
subtitle: Optional[str] = None,
|
||||
subtitle: Optional[str] = None,
|
||||
_: schemas.TokenPayload = Depends(verify_token)):
|
||||
"""
|
||||
过滤规则测试,规则类型 1-订阅,2-洗版,3-搜索
|
||||
|
||||
@@ -61,8 +61,8 @@ def tmdb_recommend(tmdbid: int,
|
||||
|
||||
@router.get("/collection/{collection_id}", summary="系列合集详情", response_model=List[schemas.MediaInfo])
|
||||
def tmdb_collection(collection_id: int,
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 20,
|
||||
page: Optional[int] = 1,
|
||||
count: Optional[int] = 20,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
根据合集ID查询合集详情
|
||||
@@ -76,7 +76,7 @@ def tmdb_collection(collection_id: int,
|
||||
@router.get("/credits/{tmdbid}/{type_name}", summary="演员阵容", response_model=List[schemas.MediaPerson])
|
||||
def tmdb_credits(tmdbid: int,
|
||||
type_name: str,
|
||||
page: Optional[int] = 1,
|
||||
page: Optional[int] = 1,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
根据TMDBID查询演员阵容,type_name: 电影/电视剧
|
||||
@@ -102,7 +102,7 @@ def tmdb_person(person_id: int,
|
||||
|
||||
@router.get("/person/credits/{person_id}", summary="人物参演作品", response_model=List[schemas.MediaInfo])
|
||||
def tmdb_person_credits(person_id: int,
|
||||
page: Optional[int] = 1,
|
||||
page: Optional[int] = 1,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
根据人物ID查询人物参演作品
|
||||
|
||||
@@ -69,7 +69,7 @@ def remove_queue(fileitem: schemas.FileItem, _: schemas.TokenPayload = Depends(v
|
||||
|
||||
@router.post("/manual", summary="手动转移", response_model=schemas.Response)
|
||||
def manual_transfer(transer_item: ManualTransferItem,
|
||||
background: Optional[bool] = False,
|
||||
background: Optional[bool] = False,
|
||||
db: Session = Depends(get_db),
|
||||
_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any:
|
||||
"""
|
||||
|
||||
@@ -96,7 +96,7 @@ def delete_workflow(workflow_id: int,
|
||||
|
||||
@router.post("/{workflow_id}/run", summary="执行工作流", response_model=schemas.Response)
|
||||
def run_workflow(workflow_id: int,
|
||||
from_begin: Optional[bool] = True,
|
||||
from_begin: Optional[bool] = True,
|
||||
_: schemas.TokenPayload = Depends(get_current_active_user)) -> Any:
|
||||
"""
|
||||
执行工作流
|
||||
|
||||
@@ -610,7 +610,7 @@ class SiteChain(ChainBase):
|
||||
return True, "连接成功"
|
||||
|
||||
def remote_list(self, channel: MessageChannel,
|
||||
userid: Union[str, int] = None, source: Optional[str] = None):
|
||||
userid: Union[str, int] = None, source: Optional[str] = None):
|
||||
"""
|
||||
查询所有站点,发送消息
|
||||
"""
|
||||
@@ -644,7 +644,7 @@ class SiteChain(ChainBase):
|
||||
)
|
||||
|
||||
def remote_disable(self, arg_str: str, channel: MessageChannel,
|
||||
userid: Union[str, int] = None, source: Optional[str] = None):
|
||||
userid: Union[str, int] = None, source: Optional[str] = None):
|
||||
"""
|
||||
禁用站点
|
||||
"""
|
||||
@@ -669,7 +669,7 @@ class SiteChain(ChainBase):
|
||||
self.remote_list(channel=channel, userid=userid, source=source)
|
||||
|
||||
def remote_enable(self, arg_str: str, channel: MessageChannel,
|
||||
userid: Union[str, int] = None, source: Optional[str] = None):
|
||||
userid: Union[str, int] = None, source: Optional[str] = None):
|
||||
"""
|
||||
启用站点
|
||||
"""
|
||||
@@ -695,7 +695,7 @@ class SiteChain(ChainBase):
|
||||
self.remote_list(channel=channel, userid=userid, source=source)
|
||||
|
||||
def update_cookie(self, site_info: Site,
|
||||
username: str, password: str, two_step_code: Optional[str] = None) -> Tuple[bool, str]:
|
||||
username: str, password: str, two_step_code: Optional[str] = None) -> Tuple[bool, str]:
|
||||
"""
|
||||
根据用户名密码更新站点Cookie
|
||||
:param site_info: 站点信息
|
||||
@@ -724,7 +724,7 @@ class SiteChain(ChainBase):
|
||||
return False, "未知错误"
|
||||
|
||||
def remote_cookie(self, arg_str: str, channel: MessageChannel,
|
||||
userid: Union[str, int] = None, source: Optional[str] = None):
|
||||
userid: Union[str, int] = None, source: Optional[str] = None):
|
||||
"""
|
||||
使用用户名密码更新站点Cookie
|
||||
"""
|
||||
@@ -794,7 +794,7 @@ class SiteChain(ChainBase):
|
||||
userid=userid))
|
||||
|
||||
def remote_refresh_userdatas(self, channel: MessageChannel,
|
||||
userid: Union[str, int] = None, source: Optional[str] = None):
|
||||
userid: Union[str, int] = None, source: Optional[str] = None):
|
||||
"""
|
||||
刷新所有站点用户数据
|
||||
"""
|
||||
|
||||
@@ -63,7 +63,7 @@ class StorageChain(ChainBase):
|
||||
return self.run_module("download_file", fileitem=fileitem, path=path)
|
||||
|
||||
def upload_file(self, fileitem: schemas.FileItem, path: Path,
|
||||
new_name: Optional[str] = None) -> Optional[schemas.FileItem]:
|
||||
new_name: Optional[str] = None) -> Optional[schemas.FileItem]:
|
||||
"""
|
||||
上传文件
|
||||
:param fileitem: 保存目录项
|
||||
|
||||
@@ -56,17 +56,17 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
|
||||
|
||||
def add(self, title: str, year: str,
|
||||
mtype: MediaType = None,
|
||||
tmdbid: Optional[int] = None,
|
||||
doubanid: Optional[str] = None,
|
||||
bangumiid: Optional[int] = None,
|
||||
mediaid: Optional[str] = None,
|
||||
season: Optional[int] = None,
|
||||
tmdbid: Optional[int] = None,
|
||||
doubanid: Optional[str] = None,
|
||||
bangumiid: Optional[int] = None,
|
||||
mediaid: Optional[str] = None,
|
||||
season: Optional[int] = None,
|
||||
channel: MessageChannel = None,
|
||||
source: Optional[str] = None,
|
||||
userid: Optional[str] = None,
|
||||
username: Optional[str] = None,
|
||||
message: Optional[bool] = True,
|
||||
exist_ok: Optional[bool] = False,
|
||||
source: Optional[str] = None,
|
||||
userid: Optional[str] = None,
|
||||
username: Optional[str] = None,
|
||||
message: Optional[bool] = True,
|
||||
exist_ok: Optional[bool] = False,
|
||||
**kwargs) -> Tuple[Optional[int], str]:
|
||||
"""
|
||||
识别媒体信息并添加订阅
|
||||
@@ -275,7 +275,7 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
|
||||
return True
|
||||
return False
|
||||
|
||||
def search(self, sid: Optional[int] = None, state: Optional[str] = 'N', manual: Optional[bool] = False):
|
||||
def search(self, sid: Optional[int] = None, state: Optional[str] = 'N', manual: Optional[bool] = False):
|
||||
"""
|
||||
订阅搜索
|
||||
:param sid: 订阅ID,有值时只处理该订阅
|
||||
@@ -452,7 +452,7 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
|
||||
def finish_subscribe_or_not(self, subscribe: Subscribe, meta: MetaBase, mediainfo: MediaInfo,
|
||||
downloads: List[Context] = None,
|
||||
lefts: Dict[Union[int | str], Dict[int, schemas.NotExistMediaInfo]] = None,
|
||||
force: Optional[bool] = False):
|
||||
force: Optional[bool] = False):
|
||||
"""
|
||||
判断是否应完成订阅
|
||||
"""
|
||||
@@ -944,7 +944,7 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
|
||||
def __update_lack_episodes(self, lefts: Dict[Union[int, str], Dict[int, schemas.NotExistMediaInfo]],
|
||||
subscribe: Subscribe,
|
||||
mediainfo: MediaInfo,
|
||||
update_date: Optional[bool] = False):
|
||||
update_date: Optional[bool] = False):
|
||||
"""
|
||||
更新订阅剩余集数及时间
|
||||
"""
|
||||
@@ -1014,7 +1014,7 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
|
||||
})
|
||||
|
||||
def remote_list(self, channel: MessageChannel,
|
||||
userid: Union[str, int] = None, source: Optional[str] = None):
|
||||
userid: Union[str, int] = None, source: Optional[str] = None):
|
||||
"""
|
||||
查询订阅并发送消息
|
||||
"""
|
||||
@@ -1042,7 +1042,7 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
|
||||
title=title, text='\n'.join(messages), userid=userid))
|
||||
|
||||
def remote_delete(self, arg_str: str, channel: MessageChannel,
|
||||
userid: Union[str, int] = None, source: Optional[str] = None):
|
||||
userid: Union[str, int] = None, source: Optional[str] = None):
|
||||
"""
|
||||
删除订阅
|
||||
"""
|
||||
|
||||
@@ -25,7 +25,7 @@ class SystemChain(ChainBase, metaclass=Singleton):
|
||||
# 重启完成检测
|
||||
self.restart_finish()
|
||||
|
||||
def remote_clear_cache(self, channel: MessageChannel, userid: Union[int, str], source: Optional[str] = None):
|
||||
def remote_clear_cache(self, channel: MessageChannel, userid: Union[int, str], source: Optional[str] = None):
|
||||
"""
|
||||
清理系统缓存
|
||||
"""
|
||||
@@ -33,7 +33,7 @@ class SystemChain(ChainBase, metaclass=Singleton):
|
||||
self.post_message(Notification(channel=channel, source=source,
|
||||
title=f"缓存清理完成!", userid=userid))
|
||||
|
||||
def restart(self, channel: MessageChannel, userid: Union[int, str], source: Optional[str] = None):
|
||||
def restart(self, channel: MessageChannel, userid: Union[int, str], source: Optional[str] = None):
|
||||
"""
|
||||
重启系统
|
||||
"""
|
||||
@@ -65,7 +65,7 @@ class SystemChain(ChainBase, metaclass=Singleton):
|
||||
title += f"当前前端版本:{front_local_version},远程版本:{front_release_version}"
|
||||
return title
|
||||
|
||||
def version(self, channel: MessageChannel, userid: Union[int, str], source: Optional[str] = None):
|
||||
def version(self, channel: MessageChannel, userid: Union[int, str], source: Optional[str] = None):
|
||||
"""
|
||||
查看当前版本、远程版本
|
||||
"""
|
||||
|
||||
@@ -23,7 +23,7 @@ class TmdbChain(ChainBase, metaclass=Singleton):
|
||||
vote_average: float,
|
||||
vote_count: int,
|
||||
release_date: str,
|
||||
page: Optional[int] = 1) -> Optional[List[MediaInfo]]:
|
||||
page: Optional[int] = 1) -> Optional[List[MediaInfo]]:
|
||||
"""
|
||||
:param mtype: 媒体类型
|
||||
:param sort_by: 排序方式
|
||||
@@ -48,7 +48,7 @@ class TmdbChain(ChainBase, metaclass=Singleton):
|
||||
release_date=release_date,
|
||||
page=page)
|
||||
|
||||
def tmdb_trending(self, page: Optional[int] = 1) -> Optional[List[MediaInfo]]:
|
||||
def tmdb_trending(self, page: Optional[int] = 1) -> Optional[List[MediaInfo]]:
|
||||
"""
|
||||
TMDB流行趋势
|
||||
:param page: 第几页
|
||||
@@ -106,7 +106,7 @@ class TmdbChain(ChainBase, metaclass=Singleton):
|
||||
"""
|
||||
return self.run_module("tmdb_tv_recommend", tmdbid=tmdbid)
|
||||
|
||||
def movie_credits(self, tmdbid: int, page: Optional[int] = 1) -> Optional[List[schemas.MediaPerson]]:
|
||||
def movie_credits(self, tmdbid: int, page: Optional[int] = 1) -> Optional[List[schemas.MediaPerson]]:
|
||||
"""
|
||||
根据TMDBID查询电影演职人员
|
||||
:param tmdbid: TMDBID
|
||||
@@ -114,7 +114,7 @@ class TmdbChain(ChainBase, metaclass=Singleton):
|
||||
"""
|
||||
return self.run_module("tmdb_movie_credits", tmdbid=tmdbid, page=page)
|
||||
|
||||
def tv_credits(self, tmdbid: int, page: Optional[int] = 1) -> Optional[List[schemas.MediaPerson]]:
|
||||
def tv_credits(self, tmdbid: int, page: Optional[int] = 1) -> Optional[List[schemas.MediaPerson]]:
|
||||
"""
|
||||
根据TMDBID查询电视剧演职人员
|
||||
:param tmdbid: TMDBID
|
||||
@@ -129,7 +129,7 @@ class TmdbChain(ChainBase, metaclass=Singleton):
|
||||
"""
|
||||
return self.run_module("tmdb_person_detail", person_id=person_id)
|
||||
|
||||
def person_credits(self, person_id: int, page: Optional[int] = 1) -> Optional[List[MediaInfo]]:
|
||||
def person_credits(self, person_id: int, page: Optional[int] = 1) -> Optional[List[MediaInfo]]:
|
||||
"""
|
||||
根据人物ID查询人物参演作品
|
||||
:param person_id: 人物ID
|
||||
@@ -152,7 +152,7 @@ class TmdbChain(ChainBase, metaclass=Singleton):
|
||||
return None
|
||||
|
||||
@cached(maxsize=1, ttl=3600)
|
||||
def get_trending_wallpapers(self, num: Optional[int] = 10) -> List[str]:
|
||||
def get_trending_wallpapers(self, num: Optional[int] = 10) -> List[str]:
|
||||
"""
|
||||
获取所有流行壁纸
|
||||
"""
|
||||
|
||||
@@ -48,7 +48,7 @@ class TorrentsChain(ChainBase, metaclass=Singleton):
|
||||
self.post_message(Notification(channel=channel,
|
||||
title=f"种子刷新完成!", userid=userid))
|
||||
|
||||
def get_torrents(self, stype: Optional[str] = None) -> Dict[str, List[Context]]:
|
||||
def get_torrents(self, stype: Optional[str] = None) -> Dict[str, List[Context]]:
|
||||
"""
|
||||
获取当前缓存的种子
|
||||
:param stype: 强制指定缓存类型,spider:爬虫缓存,rss:rss缓存
|
||||
@@ -73,8 +73,8 @@ class TorrentsChain(ChainBase, metaclass=Singleton):
|
||||
logger.info(f'种子缓存数据清理完成')
|
||||
|
||||
@cached(cache=TTLCache(maxsize=128, ttl=595))
|
||||
def browse(self, domain: str, keyword: Optional[str] = None, cat: Optional[str] = None,
|
||||
page: Optional[int] = 0) -> List[TorrentInfo]:
|
||||
def browse(self, domain: str, keyword: Optional[str] = None, cat: Optional[str] = None,
|
||||
page: Optional[int] = 0) -> List[TorrentInfo]:
|
||||
"""
|
||||
浏览站点首页内容,返回种子清单,TTL缓存10分钟
|
||||
:param domain: 站点域名
|
||||
@@ -135,7 +135,7 @@ class TorrentsChain(ChainBase, metaclass=Singleton):
|
||||
|
||||
return ret_torrents
|
||||
|
||||
def refresh(self, stype: Optional[str] = None, sites: List[int] = None) -> Dict[str, List[Context]]:
|
||||
def refresh(self, stype: Optional[str] = None, sites: List[int] = None) -> Dict[str, List[Context]]:
|
||||
"""
|
||||
刷新站点最新资源,识别并缓存起来
|
||||
:param stype: 强制指定缓存类型,spider:爬虫缓存,rss:rss缓存
|
||||
|
||||
@@ -53,14 +53,14 @@ class JobManager:
|
||||
self._season_episodes = {}
|
||||
|
||||
@staticmethod
|
||||
def __get_meta_id(meta: MetaBase = None, season: Optional[int] = None) -> Tuple:
|
||||
def __get_meta_id(meta: MetaBase = None, season: Optional[int] = None) -> Tuple:
|
||||
"""
|
||||
获取元数据ID
|
||||
"""
|
||||
return meta.name, season
|
||||
|
||||
@staticmethod
|
||||
def __get_media_id(media: MediaInfo = None, season: Optional[int] = None) -> Tuple:
|
||||
def __get_media_id(media: MediaInfo = None, season: Optional[int] = None) -> Tuple:
|
||||
"""
|
||||
获取媒体ID
|
||||
"""
|
||||
@@ -104,7 +104,7 @@ class JobManager:
|
||||
"""
|
||||
return schemas.MetaInfo(**task.meta.to_dict())
|
||||
|
||||
def add_task(self, task: TransferTask, state: Optional[str] = "waiting"):
|
||||
def add_task(self, task: TransferTask, state: Optional[str] = "waiting"):
|
||||
"""
|
||||
添加整理任务
|
||||
"""
|
||||
@@ -296,7 +296,7 @@ class JobManager:
|
||||
media_success = True
|
||||
return meta_success and media_success
|
||||
|
||||
def success_tasks(self, media: MediaInfo, season: Optional[int] = None) -> List[TransferJobTask]:
|
||||
def success_tasks(self, media: MediaInfo, season: Optional[int] = None) -> List[TransferJobTask]:
|
||||
"""
|
||||
获取某项任务成功的任务
|
||||
"""
|
||||
@@ -306,7 +306,7 @@ class JobManager:
|
||||
return []
|
||||
return [task for task in self._job_view[__mediaid__].tasks if task.state == "completed"]
|
||||
|
||||
def count(self, media: MediaInfo, season: Optional[int] = None) -> int:
|
||||
def count(self, media: MediaInfo, season: Optional[int] = None) -> int:
|
||||
"""
|
||||
获取某项任务总数
|
||||
"""
|
||||
@@ -317,7 +317,7 @@ class JobManager:
|
||||
return 0
|
||||
return len([task for task in self._job_view[__mediaid__].tasks if task.state == "completed"])
|
||||
|
||||
def size(self, media: MediaInfo, season: Optional[int] = None) -> int:
|
||||
def size(self, media: MediaInfo, season: Optional[int] = None) -> int:
|
||||
"""
|
||||
获取某项任务总大小
|
||||
"""
|
||||
@@ -341,7 +341,7 @@ class JobManager:
|
||||
"""
|
||||
return list(self._job_view.values())
|
||||
|
||||
def season_episodes(self, media: MediaInfo, season: Optional[int] = None) -> List[int]:
|
||||
def season_episodes(self, media: MediaInfo, season: Optional[int] = None) -> List[int]:
|
||||
"""
|
||||
获取季集清单
|
||||
"""
|
||||
@@ -907,13 +907,13 @@ class TransferChain(ChainBase, metaclass=Singleton):
|
||||
def do_transfer(self, fileitem: FileItem,
|
||||
meta: MetaBase = None, mediainfo: MediaInfo = None,
|
||||
target_directory: TransferDirectoryConf = None,
|
||||
target_storage: Optional[str] = None, target_path: Path = None,
|
||||
transfer_type: Optional[str] = None, scrape: Optional[bool] = None,
|
||||
library_type_folder: Optional[bool] = None, library_category_folder: Optional[bool] = None,
|
||||
season: Optional[int] = None, epformat: EpisodeFormat = None, min_filesize: Optional[int] = 0,
|
||||
downloader: Optional[str] = None, download_hash: Optional[str] = None,
|
||||
force: Optional[bool] = False, background: Optional[bool] = True,
|
||||
manual: Optional[bool] = False, continue_callback: Callable = None) -> Tuple[bool, str]:
|
||||
target_storage: Optional[str] = None, target_path: Path = None,
|
||||
transfer_type: Optional[str] = None, scrape: Optional[bool] = None,
|
||||
library_type_folder: Optional[bool] = None, library_category_folder: Optional[bool] = None,
|
||||
season: Optional[int] = None, epformat: EpisodeFormat = None, min_filesize: Optional[int] = 0,
|
||||
downloader: Optional[str] = None, download_hash: Optional[str] = None,
|
||||
force: Optional[bool] = False, background: Optional[bool] = True,
|
||||
manual: Optional[bool] = False, continue_callback: Callable = None) -> Tuple[bool, str]:
|
||||
"""
|
||||
执行一个复杂目录的整理操作
|
||||
:param fileitem: 文件项
|
||||
@@ -1153,7 +1153,7 @@ class TransferChain(ChainBase, metaclass=Singleton):
|
||||
return all_success, ",".join(err_msgs)
|
||||
|
||||
def remote_transfer(self, arg_str: str, channel: MessageChannel,
|
||||
userid: Union[str, int] = None, source: Optional[str] = None):
|
||||
userid: Union[str, int] = None, source: Optional[str] = None):
|
||||
"""
|
||||
远程重新整理,参数 历史记录ID TMDBID|类型
|
||||
"""
|
||||
@@ -1195,7 +1195,7 @@ class TransferChain(ChainBase, metaclass=Singleton):
|
||||
return
|
||||
|
||||
def __re_transfer(self, logid: int, mtype: MediaType = None,
|
||||
mediaid: Optional[str] = None) -> Tuple[bool, str]:
|
||||
mediaid: Optional[str] = None) -> Tuple[bool, str]:
|
||||
"""
|
||||
根据历史记录,重新识别整理,只支持简单条件
|
||||
:param logid: 历史记录ID
|
||||
@@ -1246,20 +1246,20 @@ class TransferChain(ChainBase, metaclass=Singleton):
|
||||
|
||||
def manual_transfer(self,
|
||||
fileitem: FileItem,
|
||||
target_storage: Optional[str] = None,
|
||||
target_storage: Optional[str] = None,
|
||||
target_path: Path = None,
|
||||
tmdbid: Optional[int] = None,
|
||||
doubanid: Optional[str] = None,
|
||||
tmdbid: Optional[int] = None,
|
||||
doubanid: Optional[str] = None,
|
||||
mtype: MediaType = None,
|
||||
season: Optional[int] = None,
|
||||
transfer_type: Optional[str] = None,
|
||||
season: Optional[int] = None,
|
||||
transfer_type: Optional[str] = None,
|
||||
epformat: EpisodeFormat = None,
|
||||
min_filesize: Optional[int] = 0,
|
||||
scrape: Optional[bool] = None,
|
||||
library_type_folder: Optional[bool] = None,
|
||||
library_category_folder: Optional[bool] = None,
|
||||
force: Optional[bool] = False,
|
||||
background: Optional[bool] = False) -> Tuple[bool, Union[str, list]]:
|
||||
min_filesize: Optional[int] = 0,
|
||||
scrape: Optional[bool] = None,
|
||||
library_type_folder: Optional[bool] = None,
|
||||
library_category_folder: Optional[bool] = None,
|
||||
force: Optional[bool] = False,
|
||||
background: Optional[bool] = False) -> Tuple[bool, Union[str, list]]:
|
||||
"""
|
||||
手动整理,支持复杂条件,带进度显示
|
||||
:param fileitem: 文件项
|
||||
@@ -1334,7 +1334,7 @@ class TransferChain(ChainBase, metaclass=Singleton):
|
||||
return state, errmsg
|
||||
|
||||
def send_transfer_message(self, meta: MetaBase, mediainfo: MediaInfo,
|
||||
transferinfo: TransferInfo, season_episode: Optional[str] = None, username: Optional[str] = None):
|
||||
transferinfo: TransferInfo, season_episode: Optional[str] = None, username: Optional[str] = None):
|
||||
"""
|
||||
发送入库成功的消息
|
||||
"""
|
||||
|
||||
@@ -30,7 +30,7 @@ class UserChain(ChainBase, metaclass=Singleton):
|
||||
password: Optional[str] = None,
|
||||
mfa_code: Optional[str] = None,
|
||||
code: Optional[str] = None,
|
||||
grant_type: Optional[str] = "password"
|
||||
grant_type: Optional[str] = "password"
|
||||
) -> Union[Tuple[bool, Optional[str]], Tuple[bool, Optional[User]]]:
|
||||
"""
|
||||
认证用户,根据不同的 grant_type 处理不同的认证流程
|
||||
|
||||
@@ -192,7 +192,7 @@ class WorkflowChain(ChainBase):
|
||||
super().__init__()
|
||||
self.workflowoper = WorkflowOper()
|
||||
|
||||
def process(self, workflow_id: int, from_begin: Optional[bool] = True) -> Tuple[bool, str]:
|
||||
def process(self, workflow_id: int, from_begin: Optional[bool] = True) -> Tuple[bool, str]:
|
||||
"""
|
||||
处理工作流
|
||||
:param workflow_id: 工作流ID
|
||||
|
||||
@@ -26,7 +26,7 @@ class CacheBackend(ABC):
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def set(self, key: str, value: Any, ttl: int, region: Optional[str] = DEFAULT_CACHE_REGION, **kwargs) -> None:
|
||||
def set(self, key: str, value: Any, ttl: int, region: Optional[str] = DEFAULT_CACHE_REGION, **kwargs) -> None:
|
||||
"""
|
||||
设置缓存
|
||||
|
||||
@@ -39,7 +39,7 @@ class CacheBackend(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def exists(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> bool:
|
||||
def exists(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> bool:
|
||||
"""
|
||||
判断缓存键是否存在
|
||||
|
||||
@@ -50,7 +50,7 @@ class CacheBackend(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> Any:
|
||||
def get(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> Any:
|
||||
"""
|
||||
获取缓存
|
||||
|
||||
@@ -61,7 +61,7 @@ class CacheBackend(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def delete(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> None:
|
||||
def delete(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> None:
|
||||
"""
|
||||
删除缓存
|
||||
|
||||
@@ -87,7 +87,7 @@ class CacheBackend(ABC):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def get_region(region: Optional[str] = DEFAULT_CACHE_REGION):
|
||||
def get_region(region: Optional[str] = DEFAULT_CACHE_REGION):
|
||||
"""
|
||||
获取缓存的区
|
||||
"""
|
||||
@@ -131,7 +131,7 @@ class CacheToolsBackend(CacheBackend):
|
||||
- 不支持按 `key` 独立隔离 TTL 和 Maxsize,仅支持作用于 region 级别
|
||||
"""
|
||||
|
||||
def __init__(self, maxsize: Optional[int] = 1000, ttl: Optional[int] = 1800):
|
||||
def __init__(self, maxsize: Optional[int] = 1000, ttl: Optional[int] = 1800):
|
||||
"""
|
||||
初始化缓存实例
|
||||
|
||||
@@ -150,8 +150,8 @@ class CacheToolsBackend(CacheBackend):
|
||||
region = self.get_region(region)
|
||||
return self._region_caches.get(region)
|
||||
|
||||
def set(self, key: str, value: Any, ttl: Optional[int] = None,
|
||||
region: Optional[str] = DEFAULT_CACHE_REGION, **kwargs) -> None:
|
||||
def set(self, key: str, value: Any, ttl: Optional[int] = None,
|
||||
region: Optional[str] = DEFAULT_CACHE_REGION, **kwargs) -> None:
|
||||
"""
|
||||
设置缓存值支持每个 key 独立配置 TTL 和 Maxsize
|
||||
|
||||
@@ -170,7 +170,7 @@ class CacheToolsBackend(CacheBackend):
|
||||
with lock:
|
||||
region_cache[key] = value
|
||||
|
||||
def exists(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> bool:
|
||||
def exists(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> bool:
|
||||
"""
|
||||
判断缓存键是否存在
|
||||
|
||||
@@ -183,7 +183,7 @@ class CacheToolsBackend(CacheBackend):
|
||||
return False
|
||||
return key in region_cache
|
||||
|
||||
def get(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> Any:
|
||||
def get(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> Any:
|
||||
"""
|
||||
获取缓存的值
|
||||
|
||||
@@ -196,7 +196,7 @@ class CacheToolsBackend(CacheBackend):
|
||||
return None
|
||||
return region_cache.get(key)
|
||||
|
||||
def delete(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> None:
|
||||
def delete(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> None:
|
||||
"""
|
||||
删除缓存
|
||||
|
||||
@@ -254,7 +254,7 @@ class RedisBackend(CacheBackend):
|
||||
_complex_serializable_types = set()
|
||||
_simple_serializable_types = set()
|
||||
|
||||
def __init__(self, redis_url: Optional[str] = "redis://localhost", ttl: Optional[int] = 1800):
|
||||
def __init__(self, redis_url: Optional[str] = "redis://localhost", ttl: Optional[int] = 1800):
|
||||
"""
|
||||
初始化 Redis 缓存实例
|
||||
|
||||
@@ -279,7 +279,7 @@ class RedisBackend(CacheBackend):
|
||||
logger.error(f"Failed to connect to Redis: {e}")
|
||||
raise RuntimeError("Redis connection failed") from e
|
||||
|
||||
def set_memory_limit(self, policy: Optional[str] = "allkeys-lru"):
|
||||
def set_memory_limit(self, policy: Optional[str] = "allkeys-lru"):
|
||||
"""
|
||||
动态设置 Redis 最大内存和内存淘汰策略
|
||||
:param policy: 淘汰策略(如 'allkeys-lru')
|
||||
@@ -357,8 +357,8 @@ class RedisBackend(CacheBackend):
|
||||
region = self.get_region(quote(region))
|
||||
return f"{region}:key:{quote(key)}"
|
||||
|
||||
def set(self, key: str, value: Any, ttl: Optional[int] = None,
|
||||
region: Optional[str] = DEFAULT_CACHE_REGION, **kwargs) -> None:
|
||||
def set(self, key: str, value: Any, ttl: Optional[int] = None,
|
||||
region: Optional[str] = DEFAULT_CACHE_REGION, **kwargs) -> None:
|
||||
"""
|
||||
设置缓存
|
||||
|
||||
@@ -378,7 +378,7 @@ class RedisBackend(CacheBackend):
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to set key: {key} in region: {region}, error: {e}")
|
||||
|
||||
def exists(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> bool:
|
||||
def exists(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> bool:
|
||||
"""
|
||||
判断缓存键是否存在
|
||||
|
||||
@@ -393,7 +393,7 @@ class RedisBackend(CacheBackend):
|
||||
logger.error(f"Failed to exists key: {key} region: {region}, error: {e}")
|
||||
return False
|
||||
|
||||
def get(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> Optional[Any]:
|
||||
def get(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> Optional[Any]:
|
||||
"""
|
||||
获取缓存的值
|
||||
|
||||
@@ -411,7 +411,7 @@ class RedisBackend(CacheBackend):
|
||||
logger.error(f"Failed to get key: {key} in region: {region}, error: {e}")
|
||||
return None
|
||||
|
||||
def delete(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> None:
|
||||
def delete(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> None:
|
||||
"""
|
||||
删除缓存
|
||||
|
||||
@@ -454,7 +454,7 @@ class RedisBackend(CacheBackend):
|
||||
self.client.close()
|
||||
|
||||
|
||||
def get_cache_backend(maxsize: Optional[int] = 1000, ttl: Optional[int] = 1800) -> CacheBackend:
|
||||
def get_cache_backend(maxsize: Optional[int] = 1000, ttl: Optional[int] = 1800) -> CacheBackend:
|
||||
"""
|
||||
根据配置获取缓存后端实例
|
||||
|
||||
@@ -482,8 +482,8 @@ def get_cache_backend(maxsize: Optional[int] = 1000, ttl: Optional[int] = 1800
|
||||
return CacheToolsBackend(maxsize=maxsize, ttl=ttl)
|
||||
|
||||
|
||||
def cached(region: Optional[str] = None, maxsize: Optional[int] = 1000, ttl: Optional[int] = 1800,
|
||||
skip_none: Optional[bool] = True, skip_empty: Optional[bool] = False):
|
||||
def cached(region: Optional[str] = None, maxsize: Optional[int] = 1000, ttl: Optional[int] = 1800,
|
||||
skip_none: Optional[bool] = True, skip_empty: Optional[bool] = False):
|
||||
"""
|
||||
自定义缓存装饰器,支持为每个 key 动态传递 maxsize 和 ttl
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ class TorrentInfo:
|
||||
# 详情页面
|
||||
page_url: str = None
|
||||
# 种子大小
|
||||
size: float = 0
|
||||
size: float = 0.0
|
||||
# 做种者
|
||||
seeders: int = 0
|
||||
# 下载者
|
||||
@@ -193,7 +193,7 @@ class MediaInfo:
|
||||
# LOGO
|
||||
logo_path: str = None
|
||||
# 评分
|
||||
vote_average: float = 0
|
||||
vote_average: float = 0.0
|
||||
# 描述
|
||||
overview: str = None
|
||||
# 风格ID
|
||||
@@ -714,7 +714,7 @@ class MediaInfo:
|
||||
return self.backdrop_path.replace("original", "w500")
|
||||
return default or ""
|
||||
|
||||
def get_message_image(self, default: Optional[bool] = None):
|
||||
def get_message_image(self, default: Optional[bool] = None):
|
||||
"""
|
||||
返回消息图片地址
|
||||
"""
|
||||
@@ -722,7 +722,7 @@ class MediaInfo:
|
||||
return self.backdrop_path.replace("original", "w500")
|
||||
return self.get_poster_image(default=default)
|
||||
|
||||
def get_poster_image(self, default: Optional[bool] = None):
|
||||
def get_poster_image(self, default: Optional[bool] = None):
|
||||
"""
|
||||
返回海报图片地址
|
||||
"""
|
||||
|
||||
@@ -31,7 +31,7 @@ class Event:
|
||||
|
||||
def __init__(self, event_type: Union[EventType, ChainEventType],
|
||||
event_data: Optional[Union[Dict, ChainEventData]] = None,
|
||||
priority: Optional[int] = DEFAULT_EVENT_PRIORITY):
|
||||
priority: Optional[int] = DEFAULT_EVENT_PRIORITY):
|
||||
"""
|
||||
:param event_type: 事件的类型,支持 EventType 或 ChainEventType
|
||||
:param event_data: 可选,事件携带的数据,默认为空字典
|
||||
@@ -130,7 +130,7 @@ class EventManager(metaclass=Singleton):
|
||||
)
|
||||
|
||||
def send_event(self, etype: Union[EventType, ChainEventType], data: Optional[Union[Dict, ChainEventData]] = None,
|
||||
priority: Optional[int] = DEFAULT_EVENT_PRIORITY) -> Optional[Event]:
|
||||
priority: Optional[int] = DEFAULT_EVENT_PRIORITY) -> Optional[Event]:
|
||||
"""
|
||||
发送事件,根据事件类型决定是广播事件还是链式事件
|
||||
:param etype: 事件类型 (EventType 或 ChainEventType)
|
||||
@@ -147,7 +147,7 @@ class EventManager(metaclass=Singleton):
|
||||
logger.error(f"Unknown event type: {etype}")
|
||||
|
||||
def add_event_listener(self, event_type: Union[EventType, ChainEventType], handler: Callable,
|
||||
priority: Optional[int] = DEFAULT_EVENT_PRIORITY):
|
||||
priority: Optional[int] = DEFAULT_EVENT_PRIORITY):
|
||||
"""
|
||||
注册事件处理器,将处理器添加到对应的事件订阅列表中
|
||||
:param event_type: 事件类型 (EventType 或 ChainEventType)
|
||||
@@ -506,7 +506,7 @@ class EventManager(metaclass=Singleton):
|
||||
)
|
||||
|
||||
def register(self, etype: Union[EventType, ChainEventType, List[Union[EventType, ChainEventType]], type],
|
||||
priority: Optional[int] = DEFAULT_EVENT_PRIORITY):
|
||||
priority: Optional[int] = DEFAULT_EVENT_PRIORITY):
|
||||
"""
|
||||
事件注册装饰器,用于将函数注册为事件的处理器
|
||||
:param etype:
|
||||
|
||||
@@ -10,7 +10,7 @@ from app.log import logger
|
||||
from app.schemas.types import MediaType
|
||||
|
||||
|
||||
def MetaInfo(title: str, subtitle: Optional[str] = None, custom_words: List[str] = None) -> MetaBase:
|
||||
def MetaInfo(title: str, subtitle: Optional[str] = None, custom_words: List[str] = None) -> MetaBase:
|
||||
"""
|
||||
根据标题和副标题识别元数据
|
||||
:param title: 标题、种子名、文件名
|
||||
|
||||
@@ -111,7 +111,7 @@ class PluginManager(metaclass=Singleton):
|
||||
# 启动插件
|
||||
self.start()
|
||||
|
||||
def start(self, pid: Optional[str] = None):
|
||||
def start(self, pid: Optional[str] = None):
|
||||
"""
|
||||
启动加载插件
|
||||
:param pid: 插件ID,为空加载所有插件
|
||||
@@ -194,7 +194,7 @@ class PluginManager(metaclass=Singleton):
|
||||
# 禁用插件类的事件处理器
|
||||
eventmanager.disable_event_handler(type(plugin))
|
||||
|
||||
def stop(self, pid: Optional[str] = None):
|
||||
def stop(self, pid: Optional[str] = None):
|
||||
"""
|
||||
停止插件服务
|
||||
:param pid: 插件ID,为空停止所有插件
|
||||
@@ -431,7 +431,7 @@ class PluginManager(metaclass=Singleton):
|
||||
return plugin.get_page() or []
|
||||
return []
|
||||
|
||||
def get_plugin_dashboard(self, pid: str, key: Optional[str] = None, **kwargs) -> Optional[schemas.PluginDashboard]:
|
||||
def get_plugin_dashboard(self, pid: str, key: Optional[str] = None, **kwargs) -> Optional[schemas.PluginDashboard]:
|
||||
"""
|
||||
获取插件仪表盘
|
||||
:param pid: 插件ID
|
||||
@@ -781,7 +781,7 @@ class PluginManager(metaclass=Singleton):
|
||||
logger.debug(f"获取插件是否在本地包中存在失败,{e}")
|
||||
return False
|
||||
|
||||
def get_plugins_from_market(self, market: str, package_version: Optional[str] = None) -> Optional[List[schemas.Plugin]]:
|
||||
def get_plugins_from_market(self, market: str, package_version: Optional[str] = None) -> Optional[List[schemas.Plugin]]:
|
||||
"""
|
||||
从指定的市场获取插件信息
|
||||
:param market: 市场的 URL 或标识
|
||||
|
||||
@@ -44,9 +44,9 @@ api_key_query = APIKeyQuery(name="apikey", auto_error=False, scheme_name="api_ke
|
||||
def create_access_token(
|
||||
userid: Union[str, Any],
|
||||
username: str,
|
||||
super_user: Optional[bool] = False,
|
||||
super_user: Optional[bool] = False,
|
||||
expires_delta: Optional[timedelta] = None,
|
||||
level: Optional[int] = 1,
|
||||
level: Optional[int] = 1,
|
||||
purpose: Optional[str] = "authentication"
|
||||
) -> str:
|
||||
"""
|
||||
@@ -136,7 +136,7 @@ def __set_or_refresh_resource_token_cookie(request: Request, response: Response,
|
||||
)
|
||||
|
||||
|
||||
def __verify_token(token: str, purpose: Optional[str] = "authentication") -> schemas.TokenPayload:
|
||||
def __verify_token(token: str, purpose: Optional[str] = "authentication") -> schemas.TokenPayload:
|
||||
"""
|
||||
使用 JWT Token 进行身份认证并解析 Token 的内容
|
||||
:param token: JWT 令牌
|
||||
|
||||
@@ -51,7 +51,7 @@ class DownloadHistoryOper(DbOper):
|
||||
"""
|
||||
DownloadFiles.truncate(self._db)
|
||||
|
||||
def get_files_by_hash(self, download_hash: str, state: Optional[int] = None) -> List[DownloadFiles]:
|
||||
def get_files_by_hash(self, download_hash: str, state: Optional[int] = None) -> List[DownloadFiles]:
|
||||
"""
|
||||
按Hash查询下载文件记录
|
||||
:param download_hash: 数据key
|
||||
@@ -97,7 +97,7 @@ class DownloadHistoryOper(DbOper):
|
||||
return fileinfo.download_hash
|
||||
return ""
|
||||
|
||||
def list_by_page(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[DownloadHistory]:
|
||||
def list_by_page(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[DownloadHistory]:
|
||||
"""
|
||||
分页查询下载历史
|
||||
"""
|
||||
@@ -109,8 +109,8 @@ class DownloadHistoryOper(DbOper):
|
||||
"""
|
||||
DownloadHistory.truncate(self._db)
|
||||
|
||||
def get_last_by(self, mtype=None, title: Optional[str] = None, year: Optional[str] = None,
|
||||
season: Optional[str] = None, episode: Optional[str] = None, tmdbid=None) -> List[DownloadHistory]:
|
||||
def get_last_by(self, mtype=None, title: Optional[str] = None, year: Optional[str] = None,
|
||||
season: Optional[str] = None, episode: Optional[str] = None, tmdbid=None) -> List[DownloadHistory]:
|
||||
"""
|
||||
按类型、标题、年份、季集查询下载记录
|
||||
"""
|
||||
@@ -122,7 +122,7 @@ class DownloadHistoryOper(DbOper):
|
||||
episode=episode,
|
||||
tmdbid=tmdbid)
|
||||
|
||||
def list_by_user_date(self, date: str, username: Optional[str] = None) -> List[DownloadHistory]:
|
||||
def list_by_user_date(self, date: str, username: Optional[str] = None) -> List[DownloadHistory]:
|
||||
"""
|
||||
查询某用户某时间之前的下载历史
|
||||
"""
|
||||
@@ -130,7 +130,7 @@ class DownloadHistoryOper(DbOper):
|
||||
date=date,
|
||||
username=username)
|
||||
|
||||
def list_by_date(self, date: str, type: str, tmdbid: str, seasons: Optional[str] = None) -> List[DownloadHistory]:
|
||||
def list_by_date(self, date: str, type: str, tmdbid: str, seasons: Optional[str] = None) -> List[DownloadHistory]:
|
||||
"""
|
||||
查询某时间之后的下载历史
|
||||
"""
|
||||
@@ -140,7 +140,7 @@ class DownloadHistoryOper(DbOper):
|
||||
tmdbid=tmdbid,
|
||||
seasons=seasons)
|
||||
|
||||
def list_by_type(self, mtype: str, days: Optional[int] = 7) -> List[DownloadHistory]:
|
||||
def list_by_type(self, mtype: str, days: Optional[int] = 7) -> List[DownloadHistory]:
|
||||
"""
|
||||
获取指定类型的下载历史
|
||||
"""
|
||||
|
||||
@@ -18,14 +18,14 @@ class MessageOper(DbOper):
|
||||
|
||||
def add(self,
|
||||
channel: MessageChannel = None,
|
||||
source: Optional[str] = None,
|
||||
source: Optional[str] = None,
|
||||
mtype: NotificationType = None,
|
||||
title: Optional[str] = None,
|
||||
text: Optional[str] = None,
|
||||
image: Optional[str] = None,
|
||||
link: Optional[str] = None,
|
||||
userid: Optional[str] = None,
|
||||
action: Optional[int] = 1,
|
||||
title: Optional[str] = None,
|
||||
text: Optional[str] = None,
|
||||
image: Optional[str] = None,
|
||||
link: Optional[str] = None,
|
||||
userid: Optional[str] = None,
|
||||
action: Optional[int] = 1,
|
||||
note: Union[list, dict] = None,
|
||||
**kwargs):
|
||||
"""
|
||||
@@ -62,7 +62,7 @@ class MessageOper(DbOper):
|
||||
|
||||
Message(**kwargs).create(self._db)
|
||||
|
||||
def list_by_page(self, page: Optional[int] = 1, count: Optional[int] = 30) -> Optional[str]:
|
||||
def list_by_page(self, page: Optional[int] = 1, count: Optional[int] = 30) -> Optional[str]:
|
||||
"""
|
||||
获取媒体服务器数据ID
|
||||
"""
|
||||
|
||||
@@ -68,7 +68,7 @@ class DownloadHistory(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def list_by_page(db: Session, page: Optional[int] = 1, count: Optional[int] = 30):
|
||||
def list_by_page(db: Session, page: Optional[int] = 1, count: Optional[int] = 30):
|
||||
result = db.query(DownloadHistory).offset((page - 1) * count).limit(count).all()
|
||||
return list(result)
|
||||
|
||||
@@ -79,9 +79,9 @@ class DownloadHistory(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def get_last_by(db: Session, mtype: Optional[str] = None, title: Optional[str] = None,
|
||||
year: Optional[int] = None, season: Optional[str] = None,
|
||||
episode: Optional[str] = None, tmdbid: Optional[int] = None):
|
||||
def get_last_by(db: Session, mtype: Optional[str] = None, title: Optional[str] = None,
|
||||
year: Optional[int] = None, season: Optional[str] = None,
|
||||
episode: Optional[str] = None, tmdbid: Optional[int] = None):
|
||||
"""
|
||||
据tmdbid、season、season_episode查询转移记录
|
||||
"""
|
||||
@@ -125,7 +125,7 @@ class DownloadHistory(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def list_by_user_date(db: Session, date: str, username: Optional[str] = None):
|
||||
def list_by_user_date(db: Session, date: str, username: Optional[str] = None):
|
||||
"""
|
||||
查询某用户某时间之后的下载历史
|
||||
"""
|
||||
@@ -140,7 +140,7 @@ class DownloadHistory(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def list_by_date(db: Session, date: str, type: str, tmdbid: str, seasons: Optional[str] = None):
|
||||
def list_by_date(db: Session, date: str, type: str, tmdbid: str, seasons: Optional[str] = None):
|
||||
"""
|
||||
查询某时间之后的下载历史
|
||||
"""
|
||||
@@ -189,7 +189,7 @@ class DownloadFiles(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def get_by_hash(db: Session, download_hash: str, state: Optional[int] = None):
|
||||
def get_by_hash(db: Session, download_hash: str, state: Optional[int] = None):
|
||||
if state:
|
||||
result = db.query(DownloadFiles).filter(DownloadFiles.download_hash == download_hash,
|
||||
DownloadFiles.state == state).all()
|
||||
|
||||
@@ -36,7 +36,7 @@ class Message(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def list_by_page(db: Session, page: Optional[int] = 1, count: Optional[int] = 30):
|
||||
def list_by_page(db: Session, page: Optional[int] = 1, count: Optional[int] = 30):
|
||||
result = db.query(Message).order_by(Message.reg_time.desc()).offset((page - 1) * count).limit(
|
||||
count).all()
|
||||
result.sort(key=lambda x: x.reg_time, reverse=False)
|
||||
|
||||
@@ -55,7 +55,7 @@ class SiteUserData(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def get_by_domain(db: Session, domain: str, workdate: Optional[str] = None, worktime: Optional[str] = None):
|
||||
def get_by_domain(db: Session, domain: str, workdate: Optional[str] = None, worktime: Optional[str] = None):
|
||||
if workdate and worktime:
|
||||
return db.query(SiteUserData).filter(SiteUserData.domain == domain,
|
||||
SiteUserData.updated_day == workdate,
|
||||
|
||||
@@ -87,7 +87,7 @@ class Subscribe(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def exists(db: Session, tmdbid: Optional[int] = None, doubanid: Optional[str] = None, season: Optional[int] = None):
|
||||
def exists(db: Session, tmdbid: Optional[int] = None, doubanid: Optional[str] = None, season: Optional[int] = None):
|
||||
if tmdbid:
|
||||
if season:
|
||||
return db.query(Subscribe).filter(Subscribe.tmdbid == tmdbid,
|
||||
@@ -111,7 +111,7 @@ class Subscribe(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def get_by_title(db: Session, title: str, season: Optional[int] = None):
|
||||
def get_by_title(db: Session, title: str, season: Optional[int] = None):
|
||||
if season:
|
||||
return db.query(Subscribe).filter(Subscribe.name == title,
|
||||
Subscribe.season == season).first()
|
||||
@@ -119,7 +119,7 @@ class Subscribe(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def get_by_tmdbid(db: Session, tmdbid: int, season: Optional[int] = None):
|
||||
def get_by_tmdbid(db: Session, tmdbid: int, season: Optional[int] = None):
|
||||
if season:
|
||||
result = db.query(Subscribe).filter(Subscribe.tmdbid == tmdbid,
|
||||
Subscribe.season == season).all()
|
||||
@@ -165,7 +165,7 @@ class Subscribe(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def list_by_username(db: Session, username: str, state: Optional[str] = None, mtype: Optional[str] = None):
|
||||
def list_by_username(db: Session, username: str, state: Optional[str] = None, mtype: Optional[str] = None):
|
||||
if mtype:
|
||||
if state:
|
||||
result = db.query(Subscribe).filter(Subscribe.state == state,
|
||||
|
||||
@@ -72,7 +72,7 @@ class SubscribeHistory(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def list_by_type(db: Session, mtype: str, page: Optional[int] = 1, count: Optional[int] = 30):
|
||||
def list_by_type(db: Session, mtype: str, page: Optional[int] = 1, count: Optional[int] = 30):
|
||||
result = db.query(SubscribeHistory).filter(
|
||||
SubscribeHistory.type == mtype
|
||||
).order_by(
|
||||
@@ -82,7 +82,7 @@ class SubscribeHistory(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def exists(db: Session, tmdbid: Optional[int] = None, doubanid: Optional[str] = None, season: Optional[int] = None):
|
||||
def exists(db: Session, tmdbid: Optional[int] = None, doubanid: Optional[str] = None, season: Optional[int] = None):
|
||||
if tmdbid:
|
||||
if season:
|
||||
return db.query(SubscribeHistory).filter(SubscribeHistory.tmdbid == tmdbid,
|
||||
|
||||
@@ -59,7 +59,7 @@ class TransferHistory(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def list_by_title(db: Session, title: str, page: Optional[int] = 1, count: Optional[int] = 30, status: bool = None):
|
||||
def list_by_title(db: Session, title: str, page: Optional[int] = 1, count: Optional[int] = 30, status: bool = None):
|
||||
if status is not None:
|
||||
result = db.query(TransferHistory).filter(
|
||||
TransferHistory.status == status
|
||||
@@ -78,7 +78,7 @@ class TransferHistory(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def list_by_page(db: Session, page: Optional[int] = 1, count: Optional[int] = 30, status: bool = None):
|
||||
def list_by_page(db: Session, page: Optional[int] = 1, count: Optional[int] = 30, status: bool = None):
|
||||
if status is not None:
|
||||
result = db.query(TransferHistory).filter(
|
||||
TransferHistory.status == status
|
||||
@@ -98,7 +98,7 @@ class TransferHistory(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def get_by_src(db: Session, src: str, storage: Optional[str] = None):
|
||||
def get_by_src(db: Session, src: str, storage: Optional[str] = None):
|
||||
if storage:
|
||||
return db.query(TransferHistory).filter(TransferHistory.src == src,
|
||||
TransferHistory.src_storage == storage).first()
|
||||
@@ -118,7 +118,7 @@ class TransferHistory(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def statistic(db: Session, days: Optional[int] = 7):
|
||||
def statistic(db: Session, days: Optional[int] = 7):
|
||||
"""
|
||||
统计最近days天的下载历史数量,按日期分组返回每日数量
|
||||
"""
|
||||
@@ -151,8 +151,8 @@ class TransferHistory(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def list_by(db: Session, mtype: Optional[str] = None, title: Optional[str] = None, year: Optional[str] = None, season: Optional[str] = None,
|
||||
episode: Optional[str] = None, tmdbid: Optional[int] = None, dest: Optional[str] = None):
|
||||
def list_by(db: Session, mtype: Optional[str] = None, title: Optional[str] = None, year: Optional[str] = None, season: Optional[str] = None,
|
||||
episode: Optional[str] = None, tmdbid: Optional[int] = None, dest: Optional[str] = None):
|
||||
"""
|
||||
据tmdbid、season、season_episode查询转移记录
|
||||
tmdbid + mtype 或 title + year 必输
|
||||
@@ -219,7 +219,7 @@ class TransferHistory(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_query
|
||||
def get_by_type_tmdbid(db: Session, mtype: Optional[str] = None, tmdbid: Optional[int] = None):
|
||||
def get_by_type_tmdbid(db: Session, mtype: Optional[str] = None, tmdbid: Optional[int] = None):
|
||||
"""
|
||||
据tmdbid、type查询转移记录
|
||||
"""
|
||||
@@ -228,7 +228,7 @@ class TransferHistory(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_update
|
||||
def update_download_hash(db: Session, historyid: Optional[int] = None, download_hash: Optional[str] = None):
|
||||
def update_download_hash(db: Session, historyid: Optional[int] = None, download_hash: Optional[str] = None):
|
||||
db.query(TransferHistory).filter(TransferHistory.id == historyid).update(
|
||||
{
|
||||
"download_hash": download_hash
|
||||
|
||||
@@ -73,7 +73,7 @@ class Workflow(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_update
|
||||
def success(db, wid: int, result: Optional[str] = None):
|
||||
def success(db, wid: int, result: Optional[str] = None):
|
||||
db.query(Workflow).filter(and_(Workflow.id == wid, Workflow.state != "P")).update({
|
||||
"state": 'S',
|
||||
"result": result,
|
||||
@@ -84,7 +84,7 @@ class Workflow(Base):
|
||||
|
||||
@staticmethod
|
||||
@db_update
|
||||
def reset(db, wid: int, reset_count: Optional[bool] = False):
|
||||
def reset(db, wid: int, reset_count: Optional[bool] = False):
|
||||
db.query(Workflow).filter(Workflow.id == wid).update({
|
||||
"state": 'W',
|
||||
"result": None,
|
||||
|
||||
@@ -24,7 +24,7 @@ class PluginDataOper(DbOper):
|
||||
else:
|
||||
PluginData(plugin_id=plugin_id, key=key, value=value).create(self._db)
|
||||
|
||||
def get_data(self, plugin_id: str, key: Optional[str] = None) -> Any:
|
||||
def get_data(self, plugin_id: str, key: Optional[str] = None) -> Any:
|
||||
"""
|
||||
获取插件数据
|
||||
:param plugin_id: 插件id
|
||||
@@ -38,7 +38,7 @@ class PluginDataOper(DbOper):
|
||||
else:
|
||||
return PluginData.get_plugin_data(self._db, plugin_id)
|
||||
|
||||
def del_data(self, plugin_id: str, key: Optional[str] = None) -> Any:
|
||||
def del_data(self, plugin_id: str, key: Optional[str] = None) -> Any:
|
||||
"""
|
||||
删除插件数据
|
||||
:param plugin_id: 插件id
|
||||
|
||||
@@ -134,7 +134,7 @@ class SiteOper(DbOper):
|
||||
"""
|
||||
return SiteUserData.list(self._db)
|
||||
|
||||
def get_userdata_by_domain(self, domain: str, workdate: Optional[str] = None) -> List[SiteUserData]:
|
||||
def get_userdata_by_domain(self, domain: str, workdate: Optional[str] = None) -> List[SiteUserData]:
|
||||
"""
|
||||
获取站点用户数据
|
||||
"""
|
||||
@@ -173,7 +173,7 @@ class SiteOper(DbOper):
|
||||
})
|
||||
return True
|
||||
|
||||
def success(self, domain: str, seconds: Optional[int] = None):
|
||||
def success(self, domain: str, seconds: Optional[int] = None):
|
||||
"""
|
||||
站点访问成功
|
||||
"""
|
||||
|
||||
@@ -45,7 +45,7 @@ class SubscribeOper(DbOper):
|
||||
else:
|
||||
return subscribe.id, "订阅已存在"
|
||||
|
||||
def exists(self, tmdbid: Optional[int] = None, doubanid: Optional[str] = None, season: Optional[int] = None) -> bool:
|
||||
def exists(self, tmdbid: Optional[int] = None, doubanid: Optional[str] = None, season: Optional[int] = None) -> bool:
|
||||
"""
|
||||
判断是否存在
|
||||
"""
|
||||
@@ -64,7 +64,7 @@ class SubscribeOper(DbOper):
|
||||
"""
|
||||
return Subscribe.get(self._db, rid=sid)
|
||||
|
||||
def list(self, state: Optional[str] = None) -> List[Subscribe]:
|
||||
def list(self, state: Optional[str] = None) -> List[Subscribe]:
|
||||
"""
|
||||
获取订阅列表
|
||||
"""
|
||||
@@ -87,19 +87,19 @@ class SubscribeOper(DbOper):
|
||||
subscribe.update(self._db, payload)
|
||||
return subscribe
|
||||
|
||||
def list_by_tmdbid(self, tmdbid: int, season: Optional[int] = None) -> List[Subscribe]:
|
||||
def list_by_tmdbid(self, tmdbid: int, season: Optional[int] = None) -> List[Subscribe]:
|
||||
"""
|
||||
获取指定tmdb_id的订阅
|
||||
"""
|
||||
return Subscribe.get_by_tmdbid(self._db, tmdbid=tmdbid, season=season)
|
||||
|
||||
def list_by_username(self, username: str, state: Optional[str] = None, mtype: Optional[str] = None) -> List[Subscribe]:
|
||||
def list_by_username(self, username: str, state: Optional[str] = None, mtype: Optional[str] = None) -> List[Subscribe]:
|
||||
"""
|
||||
获取指定用户的订阅
|
||||
"""
|
||||
return Subscribe.list_by_username(self._db, username=username, state=state, mtype=mtype)
|
||||
|
||||
def list_by_type(self, mtype: str, days: Optional[int] = 7) -> Subscribe:
|
||||
def list_by_type(self, mtype: str, days: Optional[int] = 7) -> Subscribe:
|
||||
"""
|
||||
获取指定类型的订阅
|
||||
"""
|
||||
@@ -119,7 +119,7 @@ class SubscribeOper(DbOper):
|
||||
subscribe = SubscribeHistory(**kwargs)
|
||||
subscribe.create(self._db)
|
||||
|
||||
def exist_history(self, tmdbid: Optional[int] = None, doubanid: Optional[str] = None, season: Optional[int] = None):
|
||||
def exist_history(self, tmdbid: Optional[int] = None, doubanid: Optional[str] = None, season: Optional[int] = None):
|
||||
"""
|
||||
判断是否存在订阅历史
|
||||
"""
|
||||
|
||||
@@ -27,7 +27,7 @@ class TransferHistoryOper(DbOper):
|
||||
"""
|
||||
return TransferHistory.list_by_title(self._db, title)
|
||||
|
||||
def get_by_src(self, src: str, storage: Optional[str] = None) -> TransferHistory:
|
||||
def get_by_src(self, src: str, storage: Optional[str] = None) -> TransferHistory:
|
||||
"""
|
||||
按源查询转移记录
|
||||
:param src: 数据key
|
||||
@@ -58,15 +58,15 @@ class TransferHistoryOper(DbOper):
|
||||
})
|
||||
TransferHistory(**kwargs).create(self._db)
|
||||
|
||||
def statistic(self, days: Optional[int] = 7) -> List[Any]:
|
||||
def statistic(self, days: Optional[int] = 7) -> List[Any]:
|
||||
"""
|
||||
统计最近days天的下载历史数量
|
||||
"""
|
||||
return TransferHistory.statistic(self._db, days)
|
||||
|
||||
def get_by(self, title: Optional[str] = None, year: Optional[str] = None, mtype: Optional[str] = None,
|
||||
season: Optional[str] = None, episode: Optional[str] = None, tmdbid: Optional[int] = None,
|
||||
dest: Optional[str] = None) -> List[TransferHistory]:
|
||||
def get_by(self, title: Optional[str] = None, year: Optional[str] = None, mtype: Optional[str] = None,
|
||||
season: Optional[str] = None, episode: Optional[str] = None, tmdbid: Optional[int] = None,
|
||||
dest: Optional[str] = None) -> List[TransferHistory]:
|
||||
"""
|
||||
按类型、标题、年份、季集查询转移记录
|
||||
"""
|
||||
@@ -79,7 +79,7 @@ class TransferHistoryOper(DbOper):
|
||||
episode=episode,
|
||||
tmdbid=tmdbid)
|
||||
|
||||
def get_by_type_tmdbid(self, mtype: Optional[str] = None, tmdbid: Optional[int] = None) -> TransferHistory:
|
||||
def get_by_type_tmdbid(self, mtype: Optional[str] = None, tmdbid: Optional[int] = None) -> TransferHistory:
|
||||
"""
|
||||
按类型、tmdb查询转移记录
|
||||
"""
|
||||
@@ -121,7 +121,7 @@ class TransferHistoryOper(DbOper):
|
||||
|
||||
def add_success(self, fileitem: FileItem, mode: str, meta: MetaBase,
|
||||
mediainfo: MediaInfo, transferinfo: TransferInfo,
|
||||
downloader: Optional[str] = None, download_hash: Optional[str] = None):
|
||||
downloader: Optional[str] = None, download_hash: Optional[str] = None):
|
||||
"""
|
||||
新增转移成功历史记录
|
||||
"""
|
||||
@@ -151,7 +151,7 @@ class TransferHistoryOper(DbOper):
|
||||
)
|
||||
|
||||
def add_fail(self, fileitem: FileItem, mode: str, meta: MetaBase, mediainfo: MediaInfo = None,
|
||||
transferinfo: TransferInfo = None, downloader: Optional[str] = None, download_hash: Optional[str] = None):
|
||||
transferinfo: TransferInfo = None, downloader: Optional[str] = None, download_hash: Optional[str] = None):
|
||||
"""
|
||||
新增转移失败历史记录
|
||||
"""
|
||||
|
||||
@@ -43,7 +43,7 @@ class WorkflowOper(DbOper):
|
||||
"""
|
||||
return Workflow.start(self._db, wid)
|
||||
|
||||
def success(self, wid: int, result: Optional[str] = None) -> bool:
|
||||
def success(self, wid: int, result: Optional[str] = None) -> bool:
|
||||
"""
|
||||
成功
|
||||
"""
|
||||
|
||||
@@ -20,11 +20,11 @@ class PlaywrightHelper:
|
||||
|
||||
def action(self, url: str,
|
||||
callback: Callable,
|
||||
cookies: Optional[str] = None,
|
||||
ua: Optional[str] = None,
|
||||
proxies: Optional[dict] = None,
|
||||
headless: Optional[bool] = False,
|
||||
timeout: Optional[int] = 30) -> Any:
|
||||
cookies: Optional[str] = None,
|
||||
ua: Optional[str] = None,
|
||||
proxies: Optional[dict] = None,
|
||||
headless: Optional[bool] = False,
|
||||
timeout: Optional[int] = 30) -> Any:
|
||||
"""
|
||||
访问网页,接收Page对象并执行操作
|
||||
:param url: 网页地址
|
||||
@@ -57,11 +57,11 @@ class PlaywrightHelper:
|
||||
return None
|
||||
|
||||
def get_page_source(self, url: str,
|
||||
cookies: Optional[str] = None,
|
||||
ua: Optional[str] = None,
|
||||
proxies: Optional[dict] = None,
|
||||
headless: Optional[bool] = False,
|
||||
timeout: Optional[int] = 20) -> Optional[str]:
|
||||
cookies: Optional[str] = None,
|
||||
ua: Optional[str] = None,
|
||||
proxies: Optional[dict] = None,
|
||||
headless: Optional[bool] = False,
|
||||
timeout: Optional[int] = 20) -> Optional[str]:
|
||||
"""
|
||||
获取网页源码
|
||||
:param url: 网页地址
|
||||
|
||||
@@ -73,8 +73,8 @@ class CookieHelper:
|
||||
url: str,
|
||||
username: str,
|
||||
password: str,
|
||||
two_step_code: Optional[str] = None,
|
||||
proxies: Optional[dict] = None) -> Tuple[Optional[str], Optional[str], str]:
|
||||
two_step_code: Optional[str] = None,
|
||||
proxies: Optional[dict] = None) -> Tuple[Optional[str], Optional[str], str]:
|
||||
"""
|
||||
获取站点cookie和ua
|
||||
:param url: 站点地址
|
||||
|
||||
@@ -49,9 +49,9 @@ class DirectoryHelper:
|
||||
"""
|
||||
return [d for d in self.get_library_dirs() if d.library_storage == "local"]
|
||||
|
||||
def get_dir(self, media: MediaInfo, include_unsorted: Optional[bool] = False,
|
||||
storage: Optional[str] = None, src_path: Path = None,
|
||||
target_storage: Optional[str] = None, dest_path: Path = None
|
||||
def get_dir(self, media: MediaInfo, include_unsorted: Optional[bool] = False,
|
||||
storage: Optional[str] = None, src_path: Path = None,
|
||||
target_storage: Optional[str] = None, dest_path: Path = None
|
||||
) -> Optional[schemas.TransferDirectoryConf]:
|
||||
"""
|
||||
根据媒体信息获取下载目录、媒体库目录配置
|
||||
|
||||
@@ -129,7 +129,7 @@ def doh_query_json(resolver: str, host: str) -> Optional[str]:
|
||||
if response.status != 200:
|
||||
return None
|
||||
response_body = response.read().decode("utf-8")
|
||||
logger.debug("<== body: %s", response_body)
|
||||
logger.debug("<== body: %s", response_body)
|
||||
answer = json.loads(response_body)["Answer"]
|
||||
return answer[0]["data"]
|
||||
except Exception as e:
|
||||
|
||||
@@ -10,8 +10,8 @@ class FormatParser(object):
|
||||
_key = ""
|
||||
_split_chars = r"\.|\s+|\(|\)|\[|]|-|\+|【|】|/|~|;|&|\||#|_|「|」|~"
|
||||
|
||||
def __init__(self, eformat: str, details: Optional[str] = None, part: Optional[str] = None,
|
||||
offset: Optional[str] = None, key: Optional[str] = "ep"):
|
||||
def __init__(self, eformat: str, details: Optional[str] = None, part: Optional[str] = None,
|
||||
offset: Optional[str] = None, key: Optional[str] = "ep"):
|
||||
"""
|
||||
:params eformat: 格式化字符串
|
||||
:params details: 格式化详情
|
||||
|
||||
@@ -25,7 +25,7 @@ class MessageQueueManager(metaclass=SingletonClass):
|
||||
def __init__(
|
||||
self,
|
||||
send_callback: Optional[Callable] = None,
|
||||
check_interval: Optional[int] = 10
|
||||
check_interval: Optional[int] = 10
|
||||
) -> None:
|
||||
"""
|
||||
消息队列管理器初始化
|
||||
|
||||
@@ -9,8 +9,8 @@ class OcrHelper:
|
||||
|
||||
_ocr_b64_url = f"{settings.OCR_HOST}/captcha/base64"
|
||||
|
||||
def get_captcha_text(self, image_url: Optional[str] = None, image_b64: Optional[str] = None,
|
||||
cookie: Optional[str] = None, ua: Optional[str] = None):
|
||||
def get_captcha_text(self, image_url: Optional[str] = None, image_b64: Optional[str] = None,
|
||||
cookie: Optional[str] = None, ua: Optional[str] = None):
|
||||
"""
|
||||
根据图片地址,获取验证码图片,并识别内容
|
||||
:param image_url: 图片地址
|
||||
|
||||
@@ -21,7 +21,7 @@ class TransferTorrent(BaseModel):
|
||||
tags: Optional[str] = None
|
||||
size: Optional[int] = 0
|
||||
userid: Optional[str] = None
|
||||
progress: Optional[float] = 0
|
||||
progress: Optional[float] = 0.0
|
||||
state: Optional[str] = None
|
||||
|
||||
|
||||
@@ -35,8 +35,8 @@ class DownloadingTorrent(BaseModel):
|
||||
name: Optional[str] = None
|
||||
year: Optional[str] = None
|
||||
season_episode: Optional[str] = None
|
||||
size: Optional[float] = 0
|
||||
progress: Optional[float] = 0
|
||||
size: Optional[float] = 0.0
|
||||
progress: Optional[float] = 0.0
|
||||
state: Optional[str] = 'downloading'
|
||||
upspeed: Optional[str] = None
|
||||
dlspeed: Optional[str] = None
|
||||
@@ -121,7 +121,7 @@ class TransferInfo(BaseModel):
|
||||
# 目标文件清单
|
||||
file_list_new: Optional[list] = Field(default_factory=list)
|
||||
# 总文件大小
|
||||
total_size: Optional[float] = 0
|
||||
total_size: Optional[float] = 0.0
|
||||
# 失败清单
|
||||
fail_list: Optional[list] = Field(default_factory=list)
|
||||
# 错误信息
|
||||
|
||||
Reference in New Issue
Block a user