From f9b0db623ddc32f90801ab75d9384653dd218d74 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sun, 23 Mar 2025 21:39:37 +0800 Subject: [PATCH] fix cython type error --- app/api/endpoints/bangumi.py | 14 ++-- app/api/endpoints/dashboard.py | 6 +- app/api/endpoints/discover.py | 66 ++++++++-------- app/api/endpoints/douban.py | 4 +- app/api/endpoints/download.py | 4 +- app/api/endpoints/history.py | 18 ++--- app/api/endpoints/media.py | 16 ++-- app/api/endpoints/mediaserver.py | 18 ++--- app/api/endpoints/message.py | 12 +-- app/api/endpoints/plugin.py | 6 +- app/api/endpoints/recommend.py | 88 ++++++++++----------- app/api/endpoints/search.py | 20 ++--- app/api/endpoints/site.py | 12 +-- app/api/endpoints/storage.py | 9 ++- app/api/endpoints/subscribe.py | 28 +++---- app/api/endpoints/system.py | 7 +- app/api/endpoints/tmdb.py | 10 +-- app/api/endpoints/transfer.py | 4 +- app/api/endpoints/workflow.py | 4 +- app/chain/__init__.py | 58 +++++++------- app/chain/dashboard.py | 4 +- app/chain/douban.py | 18 ++--- app/chain/download.py | 36 ++++----- app/chain/media.py | 4 +- app/chain/mediaserver.py | 18 +++-- app/chain/recommend.py | 62 ++++++++------- app/chain/search.py | 16 ++-- app/chain/site.py | 12 +-- app/chain/storage.py | 2 +- app/chain/subscribe.py | 35 ++++---- app/chain/system.py | 8 +- app/chain/tmdb.py | 12 +-- app/chain/torrents.py | 9 ++- app/chain/transfer.py | 56 ++++++------- app/chain/user.py | 2 +- app/chain/workflow.py | 4 +- app/command.py | 12 +-- app/core/cache.py | 40 +++++----- app/core/config.py | 8 +- app/core/context.py | 8 +- app/core/event.py | 8 +- app/core/metainfo.py | 7 +- app/core/plugin.py | 8 +- app/core/security.py | 10 +-- app/db/downloadhistory_oper.py | 16 ++-- app/db/message_oper.py | 16 ++-- app/db/models/downloadhistory.py | 14 ++-- app/db/models/message.py | 4 +- app/db/models/siteuserdata.py | 3 +- app/db/models/subscribe.py | 9 ++- app/db/models/subscribehistory.py | 6 +- app/db/models/transferhistory.py | 17 ++-- app/db/models/workflow.py | 5 +- app/db/plugindata_oper.py | 6 +- app/db/site_oper.py | 6 +- app/db/subscribe_oper.py | 14 ++-- app/db/transferhistory_oper.py | 17 ++-- app/db/workflow_oper.py | 4 +- app/helper/browser.py | 20 ++--- app/helper/cookie.py | 4 +- app/helper/directory.py | 6 +- app/helper/format.py | 4 +- app/helper/message.py | 2 +- app/helper/ocr.py | 4 +- app/helper/plugin.py | 12 +-- app/helper/progress.py | 4 +- app/helper/rss.py | 4 +- app/helper/subscribe.py | 6 +- app/helper/thread.py | 3 +- app/helper/torrent.py | 8 +- app/modules/bangumi/bangumi.py | 3 +- app/modules/douban/apiv2.py | 58 +++++++------- app/modules/douban/douban_cache.py | 2 +- app/modules/douban/scraper.py | 4 +- app/modules/emby/__init__.py | 26 +++--- app/modules/emby/emby.py | 38 ++++----- app/modules/filemanager/__init__.py | 30 +++---- app/modules/indexer/__init__.py | 12 +-- app/modules/indexer/parser/__init__.py | 2 +- app/modules/indexer/parser/file_list.py | 2 +- app/modules/indexer/parser/gazelle.py | 2 +- app/modules/indexer/parser/hddolby.py | 2 +- app/modules/indexer/parser/mtorrent.py | 2 +- app/modules/indexer/parser/nexus_php.py | 2 +- app/modules/indexer/parser/nexus_rabbit.py | 4 +- app/modules/indexer/parser/small_horse.py | 2 +- app/modules/indexer/parser/tnode.py | 2 +- app/modules/indexer/parser/torrent_leech.py | 2 +- app/modules/indexer/parser/unit3d.py | 2 +- app/modules/indexer/parser/yema.py | 2 +- app/modules/indexer/spider/hddolby.py | 4 +- app/modules/indexer/spider/mtorrent.py | 4 +- app/modules/indexer/spider/tnode.py | 4 +- app/modules/indexer/spider/torrentleech.py | 4 +- app/modules/indexer/spider/yema.py | 4 +- app/modules/jellyfin/__init__.py | 28 +++---- app/modules/jellyfin/jellyfin.py | 38 ++++----- app/modules/plex/__init__.py | 20 ++--- app/modules/plex/plex.py | 32 ++++---- app/modules/qbittorrent/__init__.py | 20 ++--- app/modules/qbittorrent/qbittorrent.py | 28 +++---- app/modules/slack/slack.py | 9 ++- app/modules/synologychat/synologychat.py | 10 +-- app/modules/telegram/telegram.py | 14 ++-- app/modules/themoviedb/__init__.py | 26 +++--- app/modules/themoviedb/scraper.py | 4 +- app/modules/themoviedb/tmdbapi.py | 32 ++++---- app/modules/transmission/__init__.py | 20 ++--- app/modules/transmission/transmission.py | 15 ++-- app/modules/vocechat/vocechat.py | 12 +-- app/modules/wechat/wechat.py | 20 ++--- app/plugins/__init__.py | 23 +++--- app/scheduler.py | 4 +- 113 files changed, 812 insertions(+), 779 deletions(-) diff --git a/app/api/endpoints/bangumi.py b/app/api/endpoints/bangumi.py index 05cb9709..c2e0304a 100644 --- a/app/api/endpoints/bangumi.py +++ b/app/api/endpoints/bangumi.py @@ -1,4 +1,4 @@ -from typing import List, Any +from typing import List, Any, Optional from fastapi import APIRouter, Depends @@ -12,8 +12,8 @@ router = APIRouter() @router.get("/credits/{bangumiid}", summary="查询Bangumi演职员表", response_model=List[schemas.MediaPerson]) def bangumi_credits(bangumiid: int, - page: int = 1, - count: 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: int = 1, - count: 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: int = 1, - count: int = 20, + page: Optional[int] = 1, + count: Optional[int] = 20, _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 根据人物ID查询人物参演作品 diff --git a/app/api/endpoints/dashboard.py b/app/api/endpoints/dashboard.py index a88dbc0e..5bb1f19e 100644 --- a/app/api/endpoints/dashboard.py +++ b/app/api/endpoints/dashboard.py @@ -18,7 +18,7 @@ router = APIRouter() @router.get("/statistic", summary="媒体数量统计", response_model=schemas.Statistic) -def statistic(name: 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: 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: int = 7, db: Session = Depends(get_db), +def transfer(days: Optional[int] = 7, db: Session = Depends(get_db), _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 查询文件整理统计信息 diff --git a/app/api/endpoints/discover.py b/app/api/endpoints/discover.py index d3500f23..c530094d 100644 --- a/app/api/endpoints/discover.py +++ b/app/api/endpoints/discover.py @@ -1,4 +1,4 @@ -from typing import Any, List +from typing import Any, List, Optional from fastapi import APIRouter, Depends @@ -31,12 +31,12 @@ def source(_: schemas.TokenPayload = Depends(verify_token)) -> Any: @router.get("/bangumi", summary="探索Bangumi", response_model=List[schemas.MediaInfo]) -def bangumi(type: int = 2, - cat: int = None, - sort: str = 'rank', - year: int = None, - page: int = 1, - count: int = 30, +def bangumi(type: Optional[int] = 2, + cat: Optional[int] = None, + sort: Optional[str] = 'rank', + year: Optional[int] = None, + page: Optional[int] = 1, + count: Optional[int] = 30, _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 探索Bangumi @@ -49,10 +49,10 @@ def bangumi(type: int = 2, @router.get("/douban_movies", summary="探索豆瓣电影", response_model=List[schemas.MediaInfo]) -def douban_movies(sort: str = "R", - tags: str = "", - page: int = 1, - count: 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: """ 浏览豆瓣电影信息 @@ -63,10 +63,10 @@ def douban_movies(sort: str = "R", @router.get("/douban_tvs", summary="探索豆瓣剧集", response_model=List[schemas.MediaInfo]) -def douban_tvs(sort: str = "R", - tags: str = "", - page: int = 1, - count: 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: """ 浏览豆瓣剧集信息 @@ -77,15 +77,15 @@ def douban_tvs(sort: str = "R", @router.get("/tmdb_movies", summary="探索TMDB电影", response_model=List[schemas.MediaInfo]) -def tmdb_movies(sort_by: str = "popularity.desc", - with_genres: str = "", - with_original_language: str = "", - with_keywords: str = "", - with_watch_providers: str = "", - vote_average: float = 0, - vote_count: int = 0, - release_date: str = "", - page: 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, + vote_count: Optional[int] = 0, + release_date: Optional[str] = "", + page: Optional[int] = 1, _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 浏览TMDB电影信息 @@ -104,15 +104,15 @@ def tmdb_movies(sort_by: str = "popularity.desc", @router.get("/tmdb_tvs", summary="探索TMDB剧集", response_model=List[schemas.MediaInfo]) -def tmdb_tvs(sort_by: str = "popularity.desc", - with_genres: str = "", - with_original_language: str = "", - with_keywords: str = "", - with_watch_providers: str = "", - vote_average: float = 0, - vote_count: int = 0, - release_date: str = "", - page: 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, + vote_count: Optional[int] = 0, + release_date: Optional[str] = "", + page: Optional[int] = 1, _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 浏览TMDB剧集信息 diff --git a/app/api/endpoints/douban.py b/app/api/endpoints/douban.py index 5717ab3b..ee08590d 100644 --- a/app/api/endpoints/douban.py +++ b/app/api/endpoints/douban.py @@ -1,4 +1,4 @@ -from typing import Any, List +from typing import Any, List, Optional from fastapi import APIRouter, Depends @@ -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: int = 1, + page: Optional[int] = 1, _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 根据人物ID查询人物参演作品 diff --git a/app/api/endpoints/download.py b/app/api/endpoints/download.py index 76e847de..49133482 100644 --- a/app/api/endpoints/download.py +++ b/app/api/endpoints/download.py @@ -1,4 +1,4 @@ -from typing import Any, List, Annotated +from typing import Any, List, Annotated, Optional from fastapi import APIRouter, Depends, Body @@ -18,7 +18,7 @@ router = APIRouter() @router.get("/", summary="正在下载", response_model=List[schemas.DownloadingTorrent]) def current( - name: str = None, + name: Optional[str] = None, _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 查询正在下载的任务 diff --git a/app/api/endpoints/history.py b/app/api/endpoints/history.py index 6057c0c0..62dc29e1 100644 --- a/app/api/endpoints/history.py +++ b/app/api/endpoints/history.py @@ -1,4 +1,4 @@ -from typing import List, Any +from typing import List, Any, Optional import jieba from fastapi import APIRouter, Depends @@ -20,8 +20,8 @@ router = APIRouter() @router.get("/download", summary="查询下载历史记录", response_model=List[schemas.DownloadHistory]) -def download_history(page: int = 1, - count: 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: str = None, - page: int = 1, - count: int = 30, - status: 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: str = None, @router.delete("/transfer", summary="删除整理记录", response_model=schemas.Response) def delete_transfer_history(history_in: schemas.TransferHistory, - deletesrc: bool = False, - deletedest: bool = False, + deletesrc: Optional[bool] = False, + deletedest: Optional[bool] = False, db: Session = Depends(get_db), _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ diff --git a/app/api/endpoints/media.py b/app/api/endpoints/media.py index 1959d263..5be7ba02 100644 --- a/app/api/endpoints/media.py +++ b/app/api/endpoints/media.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import List, Any, Union, Annotated +from typing import List, Any, Union, Annotated, Optional from fastapi import APIRouter, Depends @@ -19,7 +19,7 @@ router = APIRouter() @router.get("/recognize", summary="识别媒体信息(种子)", response_model=schemas.Context) def recognize(title: str, - subtitle: 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: 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: 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: 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: str = None, - title: 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: str = None, @router.get("/{mediaid}", summary="查询媒体详情", response_model=schemas.MediaInfo) -def detail(mediaid: str, type_name: str, title: 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: 电影/电视剧 diff --git a/app/api/endpoints/mediaserver.py b/app/api/endpoints/mediaserver.py index 98d14e85..f3079fc8 100644 --- a/app/api/endpoints/mediaserver.py +++ b/app/api/endpoints/mediaserver.py @@ -1,4 +1,4 @@ -from typing import Any, List, Dict +from typing import Any, List, Dict, Optional from fastapi import APIRouter, Depends from sqlalchemy.orm import Session @@ -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: str = None, - year: str = None, - mtype: str = None, - tmdbid: int = None, - season: 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: 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: int = 18, @router.get("/playing", summary="正在播放条目", response_model=List[schemas.MediaServerPlayItem]) -def playing(server: str, count: 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: int = 12, @router.get("/library", summary="媒体库列表", response_model=List[schemas.MediaServerLibrary]) -def library(server: str, hidden: bool = False, +def library(server: str, hidden: Optional[bool] = False, userinfo: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 获取媒体服务器媒体库列表 diff --git a/app/api/endpoints/message.py b/app/api/endpoints/message.py index f438e9e7..752903a2 100644 --- a/app/api/endpoints/message.py +++ b/app/api/endpoints/message.py @@ -1,5 +1,5 @@ import json -from typing import Union, Any, List +from typing import Union, Any, List, Optional from fastapi import APIRouter, BackgroundTasks, Depends, Request from pywebpush import WebPushException, webpush @@ -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: int = 1, - count: 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: str = None) -> Any: + source: Optional[str] = None) -> Any: """ 微信验证响应 """ @@ -114,8 +114,8 @@ def vocechat_verify() -> Any: @router.get("/", summary="回调请求验证") -def incoming_verify(token: str = None, echostr: str = None, msg_signature: str = None, - timestamp: Union[str, int] = None, nonce: str = None, source: 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等验证响应 diff --git a/app/api/endpoints/plugin.py b/app/api/endpoints/plugin.py index 86552591..24f8db9e 100644 --- a/app/api/endpoints/plugin.py +++ b/app/api/endpoints/plugin.py @@ -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: 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: str = "", - force: bool = False, + repo_url: Optional[str] = "", + force: Optional[bool] = False, _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ 安装插件 diff --git a/app/api/endpoints/recommend.py b/app/api/endpoints/recommend.py index 86b1d2ac..0edfd732 100644 --- a/app/api/endpoints/recommend.py +++ b/app/api/endpoints/recommend.py @@ -1,4 +1,4 @@ -from typing import Any, List +from typing import Any, List, Optional from fastapi import APIRouter, Depends @@ -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: int = 1, - count: 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: int = 1, @router.get("/douban_showing", summary="豆瓣正在热映", response_model=List[schemas.MediaInfo]) -def douban_showing(page: int = 1, - count: 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: int = 1, @router.get("/douban_movies", summary="豆瓣电影", response_model=List[schemas.MediaInfo]) -def douban_movies(sort: str = "R", - tags: str = "", - page: int = 1, - count: 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: str = "R", @router.get("/douban_tvs", summary="豆瓣剧集", response_model=List[schemas.MediaInfo]) -def douban_tvs(sort: str = "R", - tags: str = "", - page: int = 1, - count: 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: str = "R", @router.get("/douban_movie_top250", summary="豆瓣电影TOP250", response_model=List[schemas.MediaInfo]) -def douban_movie_top250(page: int = 1, - count: 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: int = 1, @router.get("/douban_tv_weekly_chinese", summary="豆瓣国产剧集周榜", response_model=List[schemas.MediaInfo]) -def douban_tv_weekly_chinese(page: int = 1, - count: 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: int = 1, @router.get("/douban_tv_weekly_global", summary="豆瓣全球剧集周榜", response_model=List[schemas.MediaInfo]) -def douban_tv_weekly_global(page: int = 1, - count: 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: int = 1, @router.get("/douban_tv_animation", summary="豆瓣动画剧集", response_model=List[schemas.MediaInfo]) -def douban_tv_animation(page: int = 1, - count: 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: int = 1, @router.get("/douban_movie_hot", summary="豆瓣热门电影", response_model=List[schemas.MediaInfo]) -def douban_movie_hot(page: int = 1, - count: 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: int = 1, @router.get("/douban_tv_hot", summary="豆瓣热门电视剧", response_model=List[schemas.MediaInfo]) -def douban_tv_hot(page: int = 1, - count: 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: int = 1, @router.get("/tmdb_movies", summary="TMDB电影", response_model=List[schemas.MediaInfo]) -def tmdb_movies(sort_by: str = "popularity.desc", - with_genres: str = "", - with_original_language: str = "", - with_keywords: str = "", - with_watch_providers: str = "", - vote_average: float = 0, - vote_count: int = 0, - release_date: str = "", - page: 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, + 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: str = "popularity.desc", @router.get("/tmdb_tvs", summary="TMDB剧集", response_model=List[schemas.MediaInfo]) -def tmdb_tvs(sort_by: str = "popularity.desc", - with_genres: str = "", - with_original_language: str = "", - with_keywords: str = "", - with_watch_providers: str = "", - vote_average: float = 0, - vote_count: int = 0, - release_date: str = "", - page: 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, + 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: str = "popularity.desc", @router.get("/tmdb_trending", summary="TMDB流行趋势", response_model=List[schemas.MediaInfo]) -def tmdb_trending(page: int = 1, +def tmdb_trending(page: Optional[int] = 1, _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ TMDB流行趋势 diff --git a/app/api/endpoints/search.py b/app/api/endpoints/search.py index 83c61f0d..0eebf40e 100644 --- a/app/api/endpoints/search.py +++ b/app/api/endpoints/search.py @@ -1,4 +1,4 @@ -from typing import List, Any +from typing import List, Any, Optional from fastapi import APIRouter, Depends @@ -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: str = None, - area: str = "title", - title: str = None, - year: str = None, - season: str = None, - sites: 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: str = None, - page: int = 0, - sites: str = None, +def search_by_title(keyword: Optional[str] = None, + page: Optional[int] = 0, + sites: Optional[str] = None, _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 根据名称模糊搜索站点资源,支持分页,关键词为空是返回首页资源 diff --git a/app/api/endpoints/site.py b/app/api/endpoints/site.py index 5cd43542..cbd5337c 100644 --- a/app/api/endpoints/site.py +++ b/app/api/endpoints/site.py @@ -1,4 +1,4 @@ -from typing import List, Any, Dict +from typing import List, Any, Dict, Optional from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session @@ -145,7 +145,7 @@ def update_cookie( site_id: int, username: str, password: str, - code: 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: 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: str = None, - cat: str = None, - page: 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: """ diff --git a/app/api/endpoints/storage.py b/app/api/endpoints/storage.py index b97d8450..c7534f8b 100644 --- a/app/api/endpoints/storage.py +++ b/app/api/endpoints/storage.py @@ -1,6 +1,6 @@ from datetime import datetime from pathlib import Path -from typing import Any, List +from typing import Any, List, Optional from fastapi import APIRouter, Depends, HTTPException from starlette.responses import FileResponse, Response @@ -31,7 +31,8 @@ def qrcode(name: str, _: schemas.TokenPayload = Depends(verify_token)) -> Any: @router.get("/check/{name}", summary="二维码登录确认", response_model=schemas.Response) -def check(name: str, ck: str = None, t: str = None, _: schemas.TokenPayload = Depends(verify_token)) -> Any: +def check(name: str, ck: Optional[str] = None, t: Optional[str] = None, + _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 二维码登录确认 """ @@ -57,7 +58,7 @@ def save(name: str, @router.post("/list", summary="所有目录和文件", response_model=List[schemas.FileItem]) def list_files(fileitem: schemas.FileItem, - sort: str = 'updated_at', + sort: Optional[str] = 'updated_at', _: User = Depends(get_current_active_superuser)) -> Any: """ 查询当前目录下所有目录和文件 @@ -140,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: bool = False, + recursive: Optional[bool] = False, _: User = Depends(get_current_active_superuser)) -> Any: """ 重命名文件或目录 diff --git a/app/api/endpoints/subscribe.py b/app/api/endpoints/subscribe.py index f9e33b4e..fa78ffb9 100644 --- a/app/api/endpoints/subscribe.py +++ b/app/api/endpoints/subscribe.py @@ -1,4 +1,4 @@ -from typing import List, Any, Annotated +from typing import List, Any, Annotated, Optional import cn2an from fastapi import APIRouter, Request, BackgroundTasks, Depends, HTTPException, Header @@ -165,8 +165,8 @@ def update_subscribe_status( @router.get("/media/{mediaid}", summary="查询订阅", response_model=schemas.Subscribe) def subscribe_mediaid( mediaid: str, - season: int = None, - title: 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: 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: int = 1, - count: 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: int = 1, - count: int = 30, - min_sub: 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: 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: 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: str = None, - page: int = 1, - count: int = 30, + name: Optional[str] = None, + page: Optional[int] = 1, + count: Optional[int] = 30, _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 查询分享的订阅 diff --git a/app/api/endpoints/system.py b/app/api/endpoints/system.py index 76f5ed42..a71f21d0 100644 --- a/app/api/endpoints/system.py +++ b/app/api/endpoints/system.py @@ -288,7 +288,8 @@ def set_setting(key: str, value: Union[list, dict, bool, int, str] = None, @router.get("/message", summary="实时消息") -async def get_message(request: Request, role: str = "system", _: schemas.TokenPayload = Depends(verify_resource_token)): +async def get_message(request: Request, role: Optional[str] = "system", + _: schemas.TokenPayload = Depends(verify_resource_token)): """ 实时获取系统消息,返回格式为SSE """ @@ -309,7 +310,7 @@ async def get_message(request: Request, role: str = "system", _: schemas.TokenPa @router.get("/logging", summary="实时日志") -async def get_logging(request: Request, length: int = 50, logfile: str = "moviepilot.log", +async def get_logging(request: Request, length: Optional[int] = 50, logfile: Optional[str] = "moviepilot.log", _: schemas.TokenPayload = Depends(verify_resource_token)): """ 实时获取系统日志 @@ -381,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: str = None, + subtitle: Optional[str] = None, _: schemas.TokenPayload = Depends(verify_token)): """ 过滤规则测试,规则类型 1-订阅,2-洗版,3-搜索 diff --git a/app/api/endpoints/tmdb.py b/app/api/endpoints/tmdb.py index e75efcf2..12f77f24 100644 --- a/app/api/endpoints/tmdb.py +++ b/app/api/endpoints/tmdb.py @@ -1,4 +1,4 @@ -from typing import List, Any +from typing import List, Any, Optional from fastapi import APIRouter, Depends @@ -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: int = 1, - count: 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: 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: int = 1, + page: Optional[int] = 1, _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 根据人物ID查询人物参演作品 diff --git a/app/api/endpoints/transfer.py b/app/api/endpoints/transfer.py index f28ed16e..d2774dd4 100644 --- a/app/api/endpoints/transfer.py +++ b/app/api/endpoints/transfer.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Any, List, Annotated +from typing import Any, List, Annotated, Optional from fastapi import APIRouter, Depends from sqlalchemy.orm import Session @@ -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: bool = False, + background: Optional[bool] = False, db: Session = Depends(get_db), _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: """ diff --git a/app/api/endpoints/workflow.py b/app/api/endpoints/workflow.py index 34232708..db255ef5 100644 --- a/app/api/endpoints/workflow.py +++ b/app/api/endpoints/workflow.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import List, Any +from typing import List, Any, Optional from fastapi import APIRouter, Depends from sqlalchemy.orm import Session @@ -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: bool = True, + from_begin: Optional[bool] = True, _: schemas.TokenPayload = Depends(get_current_active_user)) -> Any: """ 执行工作流 diff --git a/app/chain/__init__.py b/app/chain/__init__.py index 9b6ed70b..3cb6a4ff 100644 --- a/app/chain/__init__.py +++ b/app/chain/__init__.py @@ -148,10 +148,10 @@ class ChainBase(metaclass=ABCMeta): return result def recognize_media(self, meta: MetaBase = None, - mtype: MediaType = None, - tmdbid: int = None, - doubanid: str = None, - bangumiid: int = None, + mtype: Optional[MediaType] = None, + tmdbid: Optional[int] = None, + doubanid: Optional[str] = None, + bangumiid: Optional[int] = None, cache: bool = True) -> Optional[MediaInfo]: """ 识别媒体信息,不含Fanart图片 @@ -177,8 +177,8 @@ class ChainBase(metaclass=ABCMeta): return self.run_module("recognize_media", meta=meta, mtype=mtype, tmdbid=tmdbid, doubanid=doubanid, bangumiid=bangumiid, cache=cache) - def match_doubaninfo(self, name: str, imdbid: str = None, - mtype: MediaType = None, year: str = None, season: int = None, + def match_doubaninfo(self, name: str, imdbid: Optional[str] = None, + mtype: Optional[MediaType] = None, year: Optional[str] = None, season: Optional[int] = None, raise_exception: bool = False) -> Optional[dict]: """ 搜索和匹配豆瓣信息 @@ -192,8 +192,8 @@ class ChainBase(metaclass=ABCMeta): return self.run_module("match_doubaninfo", name=name, imdbid=imdbid, mtype=mtype, year=year, season=season, raise_exception=raise_exception) - def match_tmdbinfo(self, name: str, mtype: MediaType = None, - year: str = None, season: int = None) -> Optional[dict]: + def match_tmdbinfo(self, name: str, mtype: Optional[MediaType] = None, + year: Optional[str] = None, season: Optional[int] = None) -> Optional[dict]: """ 搜索和匹配TMDB信息 :param name: 标题 @@ -213,8 +213,8 @@ class ChainBase(metaclass=ABCMeta): return self.run_module("obtain_images", mediainfo=mediainfo) def obtain_specific_image(self, mediaid: Union[str, int], mtype: MediaType, - image_type: MediaImageType, image_prefix: str = None, - season: int = None, episode: int = None) -> Optional[str]: + image_type: MediaImageType, image_prefix: Optional[str] = None, + season: Optional[int] = None, episode: Optional[int] = None) -> Optional[str]: """ 获取指定媒体信息图片,返回图片地址 :param mediaid: 媒体ID @@ -228,7 +228,7 @@ class ChainBase(metaclass=ABCMeta): image_prefix=image_prefix, image_type=image_type, season=season, episode=episode) - def douban_info(self, doubanid: str, mtype: MediaType = None, + def douban_info(self, doubanid: str, mtype: Optional[MediaType] = None, raise_exception: bool = False) -> Optional[dict]: """ 获取豆瓣信息 @@ -247,7 +247,7 @@ class ChainBase(metaclass=ABCMeta): """ return self.run_module("tvdb_info", tvdbid=tvdbid) - def tmdb_info(self, tmdbid: int, mtype: MediaType, season: int = None) -> Optional[dict]: + def tmdb_info(self, tmdbid: int, mtype: MediaType, season: Optional[int] = None) -> Optional[dict]: """ 获取TMDB信息 :param tmdbid: int @@ -314,8 +314,8 @@ class ChainBase(metaclass=ABCMeta): def search_torrents(self, site: dict, keywords: List[str], - mtype: MediaType = None, - page: int = 0) -> List[TorrentInfo]: + mtype: Optional[MediaType] = None, + page: Optional[int] = 0) -> List[TorrentInfo]: """ 搜索一个站点的种子资源 :param site: 站点 @@ -327,7 +327,8 @@ class ChainBase(metaclass=ABCMeta): return self.run_module("search_torrents", site=site, keywords=keywords, mtype=mtype, page=page) - def refresh_torrents(self, site: dict, keyword: str = None, cat: str = None, page: int = 0) -> List[TorrentInfo]: + def refresh_torrents(self, site: dict, keyword: Optional[str] = None, + cat: Optional[str] = None, page: Optional[int] = 0) -> List[TorrentInfo]: """ 获取站点最新一页的种子,多个站点需要多线程处理 :param site: 站点 @@ -352,8 +353,8 @@ class ChainBase(metaclass=ABCMeta): torrent_list=torrent_list, mediainfo=mediainfo) def download(self, content: Union[Path, str], download_dir: Path, cookie: str, - episodes: Set[int] = None, category: str = None, label: str = None, - downloader: str = None + episodes: Set[int] = None, category: Optional[str] = None, label: Optional[str] = None, + downloader: Optional[str] = None ) -> Optional[Tuple[Optional[str], Optional[str], Optional[str], str]]: """ 根据种子文件,选择并添加下载任务 @@ -383,7 +384,7 @@ class ChainBase(metaclass=ABCMeta): def list_torrents(self, status: TorrentStatus = None, hashs: Union[list, str] = None, - downloader: str = None + downloader: Optional[str] = None ) -> Optional[List[Union[TransferTorrent, DownloadingTorrent]]]: """ 获取下载器种子列表 @@ -396,8 +397,8 @@ class ChainBase(metaclass=ABCMeta): def transfer(self, fileitem: FileItem, meta: MetaBase, mediainfo: MediaInfo, target_directory: TransferDirectoryConf = None, - target_storage: str = None, target_path: Path = None, - transfer_type: str = None, scrape: bool = None, + target_storage: Optional[str] = None, target_path: Path = None, + transfer_type: Optional[str] = None, scrape: bool = None, library_type_folder: bool = None, library_category_folder: bool = None, episodes_info: List[TmdbEpisode] = None) -> Optional[TransferInfo]: """ @@ -424,7 +425,7 @@ class ChainBase(metaclass=ABCMeta): library_category_folder=library_category_folder, episodes_info=episodes_info) - def transfer_completed(self, hashs: str, downloader: str = None) -> None: + def transfer_completed(self, hashs: str, downloader: Optional[str] = None) -> None: """ 下载器转移完成后的处理 :param hashs: 种子Hash @@ -433,7 +434,7 @@ class ChainBase(metaclass=ABCMeta): return self.run_module("transfer_completed", hashs=hashs, downloader=downloader) def remove_torrents(self, hashs: Union[str, list], delete_file: bool = True, - downloader: str = None) -> bool: + downloader: Optional[str] = None) -> bool: """ 删除下载器种子 :param hashs: 种子Hash @@ -443,7 +444,7 @@ class ChainBase(metaclass=ABCMeta): """ return self.run_module("remove_torrents", hashs=hashs, delete_file=delete_file, downloader=downloader) - def start_torrents(self, hashs: Union[list, str], downloader: str = None) -> bool: + def start_torrents(self, hashs: Union[list, str], downloader: Optional[str] = None) -> bool: """ 开始下载 :param hashs: 种子Hash @@ -452,7 +453,7 @@ class ChainBase(metaclass=ABCMeta): """ return self.run_module("start_torrents", hashs=hashs, downloader=downloader) - def stop_torrents(self, hashs: Union[list, str], downloader: str = None) -> bool: + def stop_torrents(self, hashs: Union[list, str], downloader: Optional[str] = None) -> bool: """ 停止下载 :param hashs: 种子Hash @@ -462,7 +463,7 @@ class ChainBase(metaclass=ABCMeta): return self.run_module("stop_torrents", hashs=hashs, downloader=downloader) def torrent_files(self, tid: str, - downloader: str = None) -> Optional[Union[TorrentFilesList, List[File]]]: + downloader: Optional[str] = None) -> Optional[Union[TorrentFilesList, List[File]]]: """ 获取种子文件 :param tid: 种子Hash @@ -471,8 +472,8 @@ class ChainBase(metaclass=ABCMeta): """ return self.run_module("torrent_files", tid=tid, downloader=downloader) - def media_exists(self, mediainfo: MediaInfo, itemid: str = None, - server: str = None) -> Optional[ExistMediaInfo]: + def media_exists(self, mediainfo: MediaInfo, itemid: Optional[str] = None, + server: Optional[str] = None) -> Optional[ExistMediaInfo]: """ 判断媒体文件是否存在 :param mediainfo: 识别的媒体信息 @@ -577,7 +578,8 @@ class ChainBase(metaclass=ABCMeta): self.messageoper.add(**message.dict(), note=note_list) return self.messagequeue.send_message("post_torrents_message", message=message, torrents=torrents) - def metadata_img(self, mediainfo: MediaInfo, season: int = None, episode: int = None) -> Optional[dict]: + def metadata_img(self, mediainfo: MediaInfo, + season: Optional[int] = None, episode: Optional[int] = None) -> Optional[dict]: """ 获取图片名称和url :param mediainfo: 媒体信息 diff --git a/app/chain/dashboard.py b/app/chain/dashboard.py index 8b7ddd86..e0a945ef 100644 --- a/app/chain/dashboard.py +++ b/app/chain/dashboard.py @@ -9,13 +9,13 @@ class DashboardChain(ChainBase, metaclass=Singleton): """ 各类仪表板统计处理链 """ - def media_statistic(self, server: str = None) -> Optional[List[schemas.Statistic]]: + def media_statistic(self, server: Optional[str] = None) -> Optional[List[schemas.Statistic]]: """ 媒体数量统计 """ return self.run_module("media_statistic", server=server) - def downloader_info(self, downloader: str = None) -> Optional[List[schemas.DownloaderInfo]]: + def downloader_info(self, downloader: Optional[str] = None) -> Optional[List[schemas.DownloaderInfo]]: """ 下载器信息 """ diff --git a/app/chain/douban.py b/app/chain/douban.py index 583cf84f..cb0da130 100644 --- a/app/chain/douban.py +++ b/app/chain/douban.py @@ -19,7 +19,7 @@ class DoubanChain(ChainBase, metaclass=Singleton): """ return self.run_module("douban_person_detail", person_id=person_id) - def person_credits(self, person_id: int, page: int = 1) -> List[MediaInfo]: + def person_credits(self, person_id: int, page: Optional[int] = 1) -> List[MediaInfo]: """ 根据人物ID查询人物参演作品 :param person_id: 人物ID @@ -27,7 +27,7 @@ class DoubanChain(ChainBase, metaclass=Singleton): """ return self.run_module("douban_person_credits", person_id=person_id, page=page) - def movie_top250(self, page: int = 1, count: int = 30) -> Optional[List[MediaInfo]]: + def movie_top250(self, page: Optional[int] = 1, count: Optional[int] = 30) -> Optional[List[MediaInfo]]: """ 获取豆瓣电影TOP250 :param page: 页码 @@ -35,26 +35,26 @@ class DoubanChain(ChainBase, metaclass=Singleton): """ return self.run_module("movie_top250", page=page, count=count) - def movie_showing(self, page: int = 1, count: int = 30) -> Optional[List[MediaInfo]]: + def movie_showing(self, page: Optional[int] = 1, count: Optional[int] = 30) -> Optional[List[MediaInfo]]: """ 获取正在上映的电影 """ return self.run_module("movie_showing", page=page, count=count) - def tv_weekly_chinese(self, page: int = 1, count: int = 30) -> Optional[List[MediaInfo]]: + def tv_weekly_chinese(self, page: Optional[int] = 1, count: Optional[int] = 30) -> Optional[List[MediaInfo]]: """ 获取本周中国剧集榜 """ return self.run_module("tv_weekly_chinese", page=page, count=count) - def tv_weekly_global(self, page: int = 1, count: int = 30) -> Optional[List[MediaInfo]]: + def tv_weekly_global(self, page: Optional[int] = 1, count: Optional[int] = 30) -> Optional[List[MediaInfo]]: """ 获取本周全球剧集榜 """ return self.run_module("tv_weekly_global", page=page, count=count) def douban_discover(self, mtype: MediaType, sort: str, tags: str, - page: int = 0, count: int = 30) -> Optional[List[MediaInfo]]: + page: Optional[int] = 0, count: Optional[int] = 30) -> Optional[List[MediaInfo]]: """ 发现豆瓣电影、剧集 :param mtype: 媒体类型 @@ -67,19 +67,19 @@ class DoubanChain(ChainBase, metaclass=Singleton): return self.run_module("douban_discover", mtype=mtype, sort=sort, tags=tags, page=page, count=count) - def tv_animation(self, page: int = 1, count: int = 30) -> Optional[List[MediaInfo]]: + def tv_animation(self, page: Optional[int] = 1, count: Optional[int] = 30) -> Optional[List[MediaInfo]]: """ 获取动画剧集 """ return self.run_module("tv_animation", page=page, count=count) - def movie_hot(self, page: int = 1, count: int = 30) -> Optional[List[MediaInfo]]: + def movie_hot(self, page: Optional[int] = 1, count: Optional[int] = 30) -> Optional[List[MediaInfo]]: """ 获取热门电影 """ return self.run_module("movie_hot", page=page, count=count) - def tv_hot(self, page: int = 1, count: int = 30) -> Optional[List[MediaInfo]]: + def tv_hot(self, page: Optional[int] = 1, count: Optional[int] = 30) -> Optional[List[MediaInfo]]: """ 获取热门剧集 """ diff --git a/app/chain/download.py b/app/chain/download.py index d7b4b9ed..ec7a485b 100644 --- a/app/chain/download.py +++ b/app/chain/download.py @@ -39,8 +39,8 @@ class DownloadChain(ChainBase): self.messagehelper = MessageHelper() def post_download_message(self, meta: MetaBase, mediainfo: MediaInfo, torrent: TorrentInfo, - channel: MessageChannel = None, username: str = None, - download_episodes: str = None): + channel: MessageChannel = None, username: Optional[str] = None, + download_episodes: Optional[str] = None): """ 发送添加下载的消息,根据消息场景开关决定发给谁 :param meta: 元数据 @@ -97,7 +97,7 @@ class DownloadChain(ChainBase): def download_torrent(self, torrent: TorrentInfo, channel: MessageChannel = None, - source: str = None, + source: Optional[str] = None, userid: Union[str, int] = None ) -> Tuple[Optional[Union[Path, str]], str, list]: """ @@ -105,7 +105,7 @@ class DownloadChain(ChainBase): :return: 种子路径,种子目录名,种子文件清单 """ - def __get_redict_url(url: str, ua: str = None, cookie: str = None) -> Optional[str]: + def __get_redict_url(url: str, ua: Optional[str] = None, cookie: Optional[str] = None) -> Optional[str]: """ 获取下载链接, url格式:[base64]url """ @@ -204,13 +204,13 @@ class DownloadChain(ChainBase): def download_single(self, context: Context, torrent_file: Path = None, episodes: Set[int] = None, channel: MessageChannel = None, - source: str = None, - downloader: str = None, - save_path: str = None, + source: Optional[str] = None, + downloader: Optional[str] = None, + save_path: Optional[str] = None, userid: Union[str, int] = None, - username: str = None, - media_category: str = None, - label: str = None) -> Optional[str]: + username: Optional[str] = None, + media_category: Optional[str] = None, + label: Optional[str] = None) -> Optional[str]: """ 下载及发送通知 :param context: 资源上下文 @@ -418,13 +418,13 @@ class DownloadChain(ChainBase): def batch_download(self, contexts: List[Context], no_exists: Dict[Union[int, str], Dict[int, NotExistMediaInfo]] = None, - save_path: str = None, + save_path: Optional[str] = None, channel: MessageChannel = None, - source: str = None, - userid: str = None, - username: str = None, - media_category: str = None, - downloader: str = None + source: Optional[str] = None, + userid: Optional[str] = None, + username: Optional[str] = None, + media_category: Optional[str] = None, + downloader: Optional[str] = None ) -> Tuple[List[Context], Dict[Union[int, str], Dict[int, NotExistMediaInfo]]]: """ 根据缺失数据,自动种子列表中组合择优下载 @@ -933,7 +933,7 @@ class DownloadChain(ChainBase): # 全部存在 return True, no_exists - def remote_downloading(self, channel: MessageChannel, userid: Union[str, int] = None, source: str = None): + def remote_downloading(self, channel: MessageChannel, userid: Union[str, int] = None, source: Optional[str] = None): """ 查询正在下载的任务,并发送消息 """ @@ -967,7 +967,7 @@ class DownloadChain(ChainBase): link=settings.MP_DOMAIN('#/downloading') )) - def downloading(self, name: str = None) -> List[DownloadingTorrent]: + def downloading(self, name: Optional[str] = None) -> List[DownloadingTorrent]: """ 查询正在下载的任务 """ diff --git a/app/chain/media.py b/app/chain/media.py index c12e8fe7..34ceb92b 100644 --- a/app/chain/media.py +++ b/app/chain/media.py @@ -32,7 +32,7 @@ class MediaChain(ChainBase, metaclass=Singleton): self.storagechain = StorageChain() def metadata_nfo(self, meta: MetaBase, mediainfo: MediaInfo, - season: int = None, episode: int = None) -> Optional[str]: + season: Optional[int] = None, episode: Optional[int] = None) -> Optional[str]: """ 获取NFO文件内容文本 :param meta: 元数据 @@ -238,7 +238,7 @@ class MediaChain(ChainBase, metaclass=Singleton): return None def get_doubaninfo_by_tmdbid(self, tmdbid: int, - mtype: MediaType = None, season: int = None) -> Optional[dict]: + mtype: MediaType = None, season: Optional[int] = None) -> Optional[dict]: """ 根据TMDBID获取豆瓣信息 """ diff --git a/app/chain/mediaserver.py b/app/chain/mediaserver.py index 50d06c66..55689264 100644 --- a/app/chain/mediaserver.py +++ b/app/chain/mediaserver.py @@ -21,14 +21,15 @@ class MediaServerChain(ChainBase): super().__init__() self.dboper = MediaServerOper() - def librarys(self, server: str, username: str = None, hidden: bool = False) -> List[MediaServerLibrary]: + def librarys(self, server: str, username: Optional[str] = None, + hidden: bool = False) -> List[MediaServerLibrary]: """ 获取媒体服务器所有媒体库 """ return self.run_module("mediaserver_librarys", server=server, username=username, hidden=hidden) def items(self, server: str, library_id: Union[str, int], - start_index: int = 0, limit: Optional[int] = -1) -> Generator[Any, None, None]: + start_index: Optional[int] = 0, limit: Optional[int] = -1) -> Generator[Any, None, None]: """ 获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据 @@ -81,28 +82,31 @@ class MediaServerChain(ChainBase): """ return self.run_module("mediaserver_tv_episodes", server=server, item_id=item_id) - def playing(self, server: str, count: int = 20, username: str = None) -> List[MediaServerPlayItem]: + def playing(self, server: str, count: Optional[int] = 20, + username: Optional[str] = None) -> List[MediaServerPlayItem]: """ 获取媒体服务器正在播放信息 """ return self.run_module("mediaserver_playing", count=count, server=server, username=username) - def latest(self, server: str, count: int = 20, username: str = None) -> List[MediaServerPlayItem]: + def latest(self, server: str, count: Optional[int] = 20, + username: Optional[str] = None) -> List[MediaServerPlayItem]: """ 获取媒体服务器最新入库条目 """ return self.run_module("mediaserver_latest", count=count, server=server, username=username) @cached(maxsize=1, ttl=3600) - def get_latest_wallpapers(self, server: str = None, count: int = 10, - remote: bool = True, username: str = None) -> List[str]: + def get_latest_wallpapers(self, server: Optional[str] = None, count: Optional[int] = 10, + remote: bool = True, username: Optional[str] = None) -> List[str]: """ 获取最新最新入库条目海报作为壁纸,缓存1小时 """ return self.run_module("mediaserver_latest_images", server=server, count=count, remote=remote, username=username) - def get_latest_wallpaper(self, server: str = None, remote: bool = True, username: str = None) -> Optional[str]: + def get_latest_wallpaper(self, server: Optional[str] = None, + remote: bool = True, username: Optional[str] = None) -> Optional[str]: """ 获取最新最新入库条目海报作为壁纸,缓存1小时 """ diff --git a/app/chain/recommend.py b/app/chain/recommend.py index d461045c..e6744ebf 100644 --- a/app/chain/recommend.py +++ b/app/chain/recommend.py @@ -1,7 +1,7 @@ import io import tempfile from pathlib import Path -from typing import List +from typing import List, Optional import pillow_avif # noqa 用于自动注册AVIF支持 from PIL import Image @@ -162,15 +162,15 @@ class RecommendChain(ChainBase, metaclass=Singleton): @log_execution_time(logger=logger) @cached(ttl=recommend_ttl, region=recommend_cache_region) - def tmdb_movies(self, sort_by: str = "popularity.desc", - with_genres: str = "", - with_original_language: str = "", - with_keywords: str = "", - with_watch_providers: str = "", - vote_average: float = 0, - vote_count: int = 0, - release_date: str = "", - page: int = 1) -> List[dict]: + def tmdb_movies(self, 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) -> List[dict]: """ TMDB热门电影 """ @@ -188,15 +188,15 @@ class RecommendChain(ChainBase, metaclass=Singleton): @log_execution_time(logger=logger) @cached(ttl=recommend_ttl, region=recommend_cache_region) - def tmdb_tvs(self, sort_by: str = "popularity.desc", - with_genres: str = "", - with_original_language: str = "zh|en|ja|ko", - with_keywords: str = "", - with_watch_providers: str = "", - vote_average: float = 0, - vote_count: int = 0, - release_date: str = "", - page: int = 1) -> List[dict]: + def tmdb_tvs(self, sort_by: Optional[str] = "popularity.desc", + with_genres: Optional[str] = "", + with_original_language: Optional[str] = "zh|en|ja|ko", + 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) -> List[dict]: """ TMDB热门电视剧 """ @@ -214,7 +214,7 @@ class RecommendChain(ChainBase, metaclass=Singleton): @log_execution_time(logger=logger) @cached(ttl=recommend_ttl, region=recommend_cache_region) - def tmdb_trending(self, page: int = 1) -> List[dict]: + def tmdb_trending(self, page: Optional[int] = 1) -> List[dict]: """ TMDB流行趋势 """ @@ -223,7 +223,7 @@ class RecommendChain(ChainBase, metaclass=Singleton): @log_execution_time(logger=logger) @cached(ttl=recommend_ttl, region=recommend_cache_region) - def bangumi_calendar(self, page: int = 1, count: int = 30) -> List[dict]: + def bangumi_calendar(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]: """ Bangumi每日放送 """ @@ -232,7 +232,7 @@ class RecommendChain(ChainBase, metaclass=Singleton): @log_execution_time(logger=logger) @cached(ttl=recommend_ttl, region=recommend_cache_region) - def douban_movie_showing(self, page: int = 1, count: int = 30) -> List[dict]: + def douban_movie_showing(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]: """ 豆瓣正在热映 """ @@ -241,7 +241,8 @@ class RecommendChain(ChainBase, metaclass=Singleton): @log_execution_time(logger=logger) @cached(ttl=recommend_ttl, region=recommend_cache_region) - def douban_movies(self, sort: str = "R", tags: str = "", page: int = 1, count: int = 30) -> List[dict]: + def douban_movies(self, sort: Optional[str] = "R", tags: Optional[str] = "", + page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]: """ 豆瓣最新电影 """ @@ -251,7 +252,8 @@ class RecommendChain(ChainBase, metaclass=Singleton): @log_execution_time(logger=logger) @cached(ttl=recommend_ttl, region=recommend_cache_region) - def douban_tvs(self, sort: str = "R", tags: str = "", page: int = 1, count: int = 30) -> List[dict]: + def douban_tvs(self, sort: Optional[str] = "R", tags: Optional[str] = "", + page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]: """ 豆瓣最新电视剧 """ @@ -261,7 +263,7 @@ class RecommendChain(ChainBase, metaclass=Singleton): @log_execution_time(logger=logger) @cached(ttl=recommend_ttl, region=recommend_cache_region) - def douban_movie_top250(self, page: int = 1, count: int = 30) -> List[dict]: + def douban_movie_top250(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]: """ 豆瓣电影TOP250 """ @@ -270,7 +272,7 @@ class RecommendChain(ChainBase, metaclass=Singleton): @log_execution_time(logger=logger) @cached(ttl=recommend_ttl, region=recommend_cache_region) - def douban_tv_weekly_chinese(self, page: int = 1, count: int = 30) -> List[dict]: + def douban_tv_weekly_chinese(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]: """ 豆瓣国产剧集榜 """ @@ -279,7 +281,7 @@ class RecommendChain(ChainBase, metaclass=Singleton): @log_execution_time(logger=logger) @cached(ttl=recommend_ttl, region=recommend_cache_region) - def douban_tv_weekly_global(self, page: int = 1, count: int = 30) -> List[dict]: + def douban_tv_weekly_global(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]: """ 豆瓣全球剧集榜 """ @@ -288,7 +290,7 @@ class RecommendChain(ChainBase, metaclass=Singleton): @log_execution_time(logger=logger) @cached(ttl=recommend_ttl, region=recommend_cache_region) - def douban_tv_animation(self, page: int = 1, count: int = 30) -> List[dict]: + def douban_tv_animation(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]: """ 豆瓣热门动漫 """ @@ -297,7 +299,7 @@ class RecommendChain(ChainBase, metaclass=Singleton): @log_execution_time(logger=logger) @cached(ttl=recommend_ttl, region=recommend_cache_region) - def douban_movie_hot(self, page: int = 1, count: int = 30) -> List[dict]: + def douban_movie_hot(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]: """ 豆瓣热门电影 """ @@ -306,7 +308,7 @@ class RecommendChain(ChainBase, metaclass=Singleton): @log_execution_time(logger=logger) @cached(ttl=recommend_ttl, region=recommend_cache_region) - def douban_tv_hot(self, page: int = 1, count: int = 30) -> List[dict]: + def douban_tv_hot(self, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]: """ 豆瓣热门电视剧 """ diff --git a/app/chain/search.py b/app/chain/search.py index 8b856f9b..a67da281 100644 --- a/app/chain/search.py +++ b/app/chain/search.py @@ -34,8 +34,8 @@ class SearchChain(ChainBase): self.systemconfig = SystemConfigOper() self.torrenthelper = TorrentHelper() - def search_by_id(self, tmdbid: int = None, doubanid: str = None, - mtype: MediaType = None, area: str = "title", season: int = None, + def search_by_id(self, tmdbid: Optional[int] = None, doubanid: Optional[str] = None, + mtype: MediaType = None, area: Optional[str] = "title", season: Optional[int] = None, sites: List[int] = None) -> List[Context]: """ 根据TMDBID/豆瓣ID搜索资源,精确匹配,不过滤本地存在的资源 @@ -63,8 +63,8 @@ class SearchChain(ChainBase): self.save_cache(bytes_results, self.__result_temp_file) return results - def search_by_title(self, title: str, page: int = 0, - sites: List[int] = None, cache_local: bool = True) -> List[Context]: + def search_by_title(self, title: str, page: Optional[int] = 0, + sites: List[int] = None, cache_local: Optional[bool] = True) -> List[Context]: """ 根据标题搜索资源,不识别不过滤,直接返回站点内容 :param title: 标题,为空时返回所有站点首页内容 @@ -105,11 +105,11 @@ class SearchChain(ChainBase): return [] def process(self, mediainfo: MediaInfo, - keyword: str = None, + keyword: Optional[str] = None, no_exists: Dict[int, Dict[int, NotExistMediaInfo]] = None, sites: List[int] = None, rule_groups: List[str] = None, - area: str = "title", + area: Optional[str] = "title", custom_words: List[str] = None, filter_params: Dict[str, str] = None) -> List[Context]: """ @@ -291,8 +291,8 @@ class SearchChain(ChainBase): def __search_all_sites(self, keywords: List[str], mediainfo: Optional[MediaInfo] = None, sites: List[int] = None, - page: int = 0, - area: str = "title") -> Optional[List[TorrentInfo]]: + page: Optional[int] = 0, + area: Optional[str] = "title") -> Optional[List[TorrentInfo]]: """ 多线程搜索多个站点 :param mediainfo: 识别的媒体信息 diff --git a/app/chain/site.py b/app/chain/site.py index 13d854a4..f89d138d 100644 --- a/app/chain/site.py +++ b/app/chain/site.py @@ -610,7 +610,7 @@ class SiteChain(ChainBase): return True, "连接成功" def remote_list(self, channel: MessageChannel, - userid: Union[str, int] = None, source: 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: 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: 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: 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: 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: str = None): + userid: Union[str, int] = None, source: Optional[str] = None): """ 刷新所有站点用户数据 """ diff --git a/app/chain/storage.py b/app/chain/storage.py index 19bcfdbd..f41ce64e 100644 --- a/app/chain/storage.py +++ b/app/chain/storage.py @@ -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: str = None) -> Optional[schemas.FileItem]: + new_name: Optional[str] = None) -> Optional[schemas.FileItem]: """ 上传文件 :param fileitem: 保存目录项 diff --git a/app/chain/subscribe.py b/app/chain/subscribe.py index 6e63c82e..6fe13f4b 100644 --- a/app/chain/subscribe.py +++ b/app/chain/subscribe.py @@ -56,17 +56,17 @@ class SubscribeChain(ChainBase, metaclass=Singleton): def add(self, title: str, year: str, mtype: MediaType = None, - tmdbid: int = None, - doubanid: str = None, - bangumiid: int = None, - mediaid: str = None, - season: 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: str = None, - userid: str = None, - username: str = None, - message: bool = True, - exist_ok: 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: int = None, state: Optional[str] = 'N', manual: bool = False): + def search(self, sid: Optional[int] = None, state: Optional[str] = 'N', manual: Optional[bool] = False): """ 订阅搜索 :param sid: 订阅ID,有值时只处理该订阅 @@ -330,7 +330,8 @@ class SubscribeChain(ChainBase, metaclass=Singleton): continue # 如果媒体已存在或已下载完毕,跳过当前订阅处理 - exist_flag, no_exists = self.check_and_handle_existing_media(subscribe=subscribe, meta=meta, + exist_flag, no_exists = self.check_and_handle_existing_media(subscribe=subscribe, + meta=meta, mediainfo=mediainfo, mediakey=mediakey) if exist_flag: @@ -451,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: bool = False): + force: Optional[bool] = False): """ 判断是否应完成订阅 """ @@ -943,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: bool = False): + update_date: Optional[bool] = False): """ 更新订阅剩余集数及时间 """ @@ -1013,7 +1014,7 @@ class SubscribeChain(ChainBase, metaclass=Singleton): }) def remote_list(self, channel: MessageChannel, - userid: Union[str, int] = None, source: str = None): + userid: Union[str, int] = None, source: Optional[str] = None): """ 查询订阅并发送消息 """ @@ -1041,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: str = None): + userid: Union[str, int] = None, source: Optional[str] = None): """ 删除订阅 """ @@ -1368,7 +1369,7 @@ class SubscribeChain(ChainBase, metaclass=Singleton): return subscribe_info def check_and_handle_existing_media(self, subscribe: Subscribe, meta: MetaBase, - mediainfo: MediaInfo, mediakey: str): + mediainfo: MediaInfo, mediakey: Union[str, int]): """ 检查媒体是否已经存在,并根据情况执行相应的操作 1. 查询缺失的媒体信息 diff --git a/app/chain/system.py b/app/chain/system.py index 1f96ce0a..607daa80 100644 --- a/app/chain/system.py +++ b/app/chain/system.py @@ -1,7 +1,7 @@ import json import re from pathlib import Path -from typing import Union +from typing import Union, Optional from app.chain import ChainBase from app.core.config import settings @@ -25,7 +25,7 @@ class SystemChain(ChainBase, metaclass=Singleton): # 重启完成检测 self.restart_finish() - def remote_clear_cache(self, channel: MessageChannel, userid: Union[int, str], source: 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: 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: str = None): + def version(self, channel: MessageChannel, userid: Union[int, str], source: Optional[str] = None): """ 查看当前版本、远程版本 """ diff --git a/app/chain/tmdb.py b/app/chain/tmdb.py index 8186f1e8..20a4d2e8 100644 --- a/app/chain/tmdb.py +++ b/app/chain/tmdb.py @@ -23,7 +23,7 @@ class TmdbChain(ChainBase, metaclass=Singleton): vote_average: float, vote_count: int, release_date: str, - page: 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: 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: 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: 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: 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: int = 10) -> List[str]: + def get_trending_wallpapers(self, num: Optional[int] = 10) -> List[str]: """ 获取所有流行壁纸 """ diff --git a/app/chain/torrents.py b/app/chain/torrents.py index f0b8e231..774b69ef 100644 --- a/app/chain/torrents.py +++ b/app/chain/torrents.py @@ -1,6 +1,6 @@ import re import traceback -from typing import Dict, List, Union +from typing import Dict, List, Union, Optional from cachetools import cached, TTLCache @@ -48,7 +48,7 @@ class TorrentsChain(ChainBase, metaclass=Singleton): self.post_message(Notification(channel=channel, title=f"种子刷新完成!", userid=userid)) - def get_torrents(self, stype: str = None) -> Dict[str, List[Context]]: + def get_torrents(self, stype: Optional[str] = None) -> Dict[str, List[Context]]: """ 获取当前缓存的种子 :param stype: 强制指定缓存类型,spider:爬虫缓存,rss:rss缓存 @@ -73,7 +73,8 @@ class TorrentsChain(ChainBase, metaclass=Singleton): logger.info(f'种子缓存数据清理完成') @cached(cache=TTLCache(maxsize=128, ttl=595)) - def browse(self, domain: str, keyword: str = None, cat: str = None, page: 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: 站点域名 @@ -134,7 +135,7 @@ class TorrentsChain(ChainBase, metaclass=Singleton): return ret_torrents - def refresh(self, stype: 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缓存 diff --git a/app/chain/transfer.py b/app/chain/transfer.py index 6a369658..eb090f6b 100644 --- a/app/chain/transfer.py +++ b/app/chain/transfer.py @@ -53,14 +53,14 @@ class JobManager: self._season_episodes = {} @staticmethod - def __get_meta_id(meta: MetaBase = None, season: 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: 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: 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: 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: 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: 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: 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: str = None, target_path: Path = None, - transfer_type: str = None, scrape: bool = None, - library_type_folder: bool = None, library_category_folder: bool = None, - season: int = None, epformat: EpisodeFormat = None, min_filesize: int = 0, - downloader: str = None, download_hash: str = None, - force: bool = False, background: bool = True, - manual: 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: 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: 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: str = None, + target_storage: Optional[str] = None, target_path: Path = None, - tmdbid: int = None, - doubanid: str = None, + tmdbid: Optional[int] = None, + doubanid: Optional[str] = None, mtype: MediaType = None, - season: int = None, - transfer_type: str = None, + season: Optional[int] = None, + transfer_type: Optional[str] = None, epformat: EpisodeFormat = None, - min_filesize: int = 0, - scrape: bool = None, - library_type_folder: bool = None, - library_category_folder: bool = None, - force: bool = False, - background: 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: str = None, username: str = None): + transferinfo: TransferInfo, season_episode: Optional[str] = None, username: Optional[str] = None): """ 发送入库成功的消息 """ diff --git a/app/chain/user.py b/app/chain/user.py index 26601931..352fd9e6 100644 --- a/app/chain/user.py +++ b/app/chain/user.py @@ -30,7 +30,7 @@ class UserChain(ChainBase, metaclass=Singleton): password: Optional[str] = None, mfa_code: Optional[str] = None, code: Optional[str] = None, - grant_type: str = "password" + grant_type: Optional[str] = "password" ) -> Union[Tuple[bool, Optional[str]], Tuple[bool, Optional[User]]]: """ 认证用户,根据不同的 grant_type 处理不同的认证流程 diff --git a/app/chain/workflow.py b/app/chain/workflow.py index f7ccc573..36276a0e 100644 --- a/app/chain/workflow.py +++ b/app/chain/workflow.py @@ -4,7 +4,7 @@ import threading from collections import defaultdict, deque from concurrent.futures import ThreadPoolExecutor from time import sleep -from typing import List, Tuple +from typing import List, Tuple, Optional from pydantic.fields import Callable @@ -192,7 +192,7 @@ class WorkflowChain(ChainBase): super().__init__() self.workflowoper = WorkflowOper() - def process(self, workflow_id: int, from_begin: bool = True) -> Tuple[bool, str]: + def process(self, workflow_id: int, from_begin: Optional[bool] = True) -> Tuple[bool, str]: """ 处理工作流 :param workflow_id: 工作流ID diff --git a/app/command.py b/app/command.py index aa96ff74..e4a4bbd9 100644 --- a/app/command.py +++ b/app/command.py @@ -273,8 +273,8 @@ class Command(metaclass=Singleton): } return plugin_commands - def __run_command(self, command: Dict[str, any], data_str: str = "", - channel: MessageChannel = None, source: str = None, userid: Union[str, int] = None): + def __run_command(self, command: Dict[str, any], data_str: Optional[str] = "", + channel: MessageChannel = None, source: Optional[str] = None, userid: Union[str, int] = None): """ 运行定时服务 """ @@ -339,8 +339,8 @@ class Command(metaclass=Singleton): """ return self._commands.get(cmd, {}) - def register(self, cmd: str, func: Any, data: dict = None, - desc: str = None, category: str = None) -> None: + def register(self, cmd: str, func: Any, data: Optional[dict] = None, + desc: Optional[str] = None, category: Optional[str] = None) -> None: """ 注册单个命令 """ @@ -352,8 +352,8 @@ class Command(metaclass=Singleton): "data": data or {} } - def execute(self, cmd: str, data_str: str = "", - channel: MessageChannel = None, source: str = None, + def execute(self, cmd: str, data_str: Optional[str] = "", + channel: MessageChannel = None, source: Optional[str] = None, userid: Union[str, int] = None) -> None: """ 执行命令 diff --git a/app/core/cache.py b/app/core/cache.py index ee332c11..a9adb7b0 100644 --- a/app/core/cache.py +++ b/app/core/cache.py @@ -26,7 +26,7 @@ class CacheBackend(ABC): """ @abstractmethod - def set(self, key: str, value: Any, ttl: int, region: 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: 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: 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: 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: 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: int = 1000, ttl: int = 1800): + def __init__(self, maxsize: Optional[int] = 1000, ttl: Optional[int] = 1800): """ 初始化缓存实例 @@ -150,7 +150,8 @@ class CacheToolsBackend(CacheBackend): region = self.get_region(region) return self._region_caches.get(region) - def set(self, key: str, value: Any, ttl: int = None, region: 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 @@ -169,7 +170,7 @@ class CacheToolsBackend(CacheBackend): with lock: region_cache[key] = value - def exists(self, key: str, region: str = DEFAULT_CACHE_REGION) -> bool: + def exists(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> bool: """ 判断缓存键是否存在 @@ -182,7 +183,7 @@ class CacheToolsBackend(CacheBackend): return False return key in region_cache - def get(self, key: str, region: str = DEFAULT_CACHE_REGION) -> Any: + def get(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> Any: """ 获取缓存的值 @@ -195,7 +196,7 @@ class CacheToolsBackend(CacheBackend): return None return region_cache.get(key) - def delete(self, key: str, region: str = DEFAULT_CACHE_REGION) -> None: + def delete(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> None: """ 删除缓存 @@ -253,7 +254,7 @@ class RedisBackend(CacheBackend): _complex_serializable_types = set() _simple_serializable_types = set() - def __init__(self, redis_url: str = "redis://localhost", ttl: int = 1800): + def __init__(self, redis_url: Optional[str] = "redis://localhost", ttl: Optional[int] = 1800): """ 初始化 Redis 缓存实例 @@ -278,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: str = "allkeys-lru"): + def set_memory_limit(self, policy: Optional[str] = "allkeys-lru"): """ 动态设置 Redis 最大内存和内存淘汰策略 :param policy: 淘汰策略(如 'allkeys-lru') @@ -356,7 +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: int = None, region: 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: """ 设置缓存 @@ -376,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: str = DEFAULT_CACHE_REGION) -> bool: + def exists(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> bool: """ 判断缓存键是否存在 @@ -391,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: str = DEFAULT_CACHE_REGION) -> Optional[Any]: + def get(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> Optional[Any]: """ 获取缓存的值 @@ -409,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: str = DEFAULT_CACHE_REGION) -> None: + def delete(self, key: str, region: Optional[str] = DEFAULT_CACHE_REGION) -> None: """ 删除缓存 @@ -452,7 +454,7 @@ class RedisBackend(CacheBackend): self.client.close() -def get_cache_backend(maxsize: int = 1000, ttl: int = 1800) -> CacheBackend: +def get_cache_backend(maxsize: Optional[int] = 1000, ttl: Optional[int] = 1800) -> CacheBackend: """ 根据配置获取缓存后端实例 @@ -480,8 +482,8 @@ def get_cache_backend(maxsize: int = 1000, ttl: int = 1800) -> CacheBackend: return CacheToolsBackend(maxsize=maxsize, ttl=ttl) -def cached(region: Optional[str] = None, maxsize: int = 1000, ttl: int = 1800, - skip_none: bool = True, skip_empty: 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 diff --git a/app/core/config.py b/app/core/config.py index 7ec395fb..96b34da1 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -610,7 +610,7 @@ class GlobalVar(object): # webpush订阅 SUBSCRIPTIONS: List[dict] = [] # 需应急停止的工作流 - EMERGENCY_STOP_WORKFLOWS: List[str] = [] + EMERGENCY_STOP_WORKFLOWS: List[int] = [] def stop_system(self): """ @@ -637,21 +637,21 @@ class GlobalVar(object): """ self.SUBSCRIPTIONS.append(subscription) - def stop_workflow(self, workflow_id: str): + def stop_workflow(self, workflow_id: int): """ 停止工作流 """ if workflow_id not in self.EMERGENCY_STOP_WORKFLOWS: self.EMERGENCY_STOP_WORKFLOWS.append(workflow_id) - def workflow_resume(self, workflow_id: str): + def workflow_resume(self, workflow_id: int): """ 恢复工作流 """ if workflow_id in self.EMERGENCY_STOP_WORKFLOWS: self.EMERGENCY_STOP_WORKFLOWS.remove(workflow_id) - def is_workflow_stopped(self, workflow_id: str): + def is_workflow_stopped(self, workflow_id: int): """ 是否停止工作流 """ diff --git a/app/core/context.py b/app/core/context.py index bf869a57..87bbae09 100644 --- a/app/core/context.py +++ b/app/core/context.py @@ -1,7 +1,7 @@ import re from dataclasses import dataclass, field from datetime import datetime -from typing import List, Dict, Any, Tuple +from typing import List, Dict, Any, Tuple, Optional from app.core.config import settings from app.core.meta import MetaBase @@ -714,7 +714,7 @@ class MediaInfo: return self.backdrop_path.replace("original", "w500") return default or "" - def get_message_image(self, default: 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: bool = None): + def get_poster_image(self, default: Optional[bool] = None): """ 返回海报图片地址 """ @@ -730,7 +730,7 @@ class MediaInfo: return self.poster_path.replace("original", "w500") return default or "" - def get_overview_string(self, max_len: int = 140): + def get_overview_string(self, max_len: Optional[int] = 140): """ 返回带限定长度的简介信息 :param max_len: 内容长度 diff --git a/app/core/event.py b/app/core/event.py index b29c1bad..1597e8be 100644 --- a/app/core/event.py +++ b/app/core/event.py @@ -31,7 +31,7 @@ class Event: def __init__(self, event_type: Union[EventType, ChainEventType], event_data: Optional[Union[Dict, ChainEventData]] = None, - priority: 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: 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: 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: int = DEFAULT_EVENT_PRIORITY): + priority: Optional[int] = DEFAULT_EVENT_PRIORITY): """ 事件注册装饰器,用于将函数注册为事件的处理器 :param etype: diff --git a/app/core/metainfo.py b/app/core/metainfo.py index fc8c9c99..9d4e39dd 100644 --- a/app/core/metainfo.py +++ b/app/core/metainfo.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Tuple, List +from typing import Tuple, List, Optional import regex as re @@ -10,7 +10,7 @@ from app.log import logger from app.schemas.types import MediaType -def MetaInfo(title: str, subtitle: str = None, custom_words: List[str] = None) -> MetaBase: +def MetaInfo(title: str, subtitle: Optional[str] = None, custom_words: List[str] = None) -> MetaBase: """ 根据标题和副标题识别元数据 :param title: 标题、种子名、文件名 @@ -92,7 +92,8 @@ def is_anime(name: str) -> bool: return True if re.search(r'\s+-\s+[\dv]{1,4}\s+', name, re.IGNORECASE): return True - if re.search(r"S\d{2}\s*-\s*S\d{2}|S\d{2}|\s+S\d{1,2}|EP?\d{2,4}\s*-\s*EP?\d{2,4}|EP?\d{2,4}|\s+EP?\d{1,4}", name, + if re.search(r"S\d{2}\s*-\s*S\d{2}|S\d{2}|\s+S\d{1,2}|EP?\d{2,4}\s*-\s*EP?\d{2,4}|EP?\d{2,4}|\s+EP?\d{1,4}", + name, re.IGNORECASE): return False if re.search(r'\[[+0-9XVPI-]+]\s*\[', name, re.IGNORECASE): diff --git a/app/core/plugin.py b/app/core/plugin.py index 33441fde..dc90791e 100644 --- a/app/core/plugin.py +++ b/app/core/plugin.py @@ -111,7 +111,7 @@ class PluginManager(metaclass=Singleton): # 启动插件 self.start() - def start(self, pid: 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: 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: 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: 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 或标识 diff --git a/app/core/security.py b/app/core/security.py index ad7b19ce..9cd34984 100644 --- a/app/core/security.py +++ b/app/core/security.py @@ -1,10 +1,10 @@ import base64 +import datetime import hashlib import hmac import json import os import traceback -import datetime from datetime import timedelta from typing import Any, Union, Annotated, Optional @@ -12,7 +12,7 @@ import jwt from Crypto.Cipher import AES from Crypto.Util.Padding import pad from cryptography.fernet import Fernet -from fastapi import HTTPException, status, Security, Request, Response, Depends +from fastapi import HTTPException, status, Security, Request, Response from fastapi.security import OAuth2PasswordBearer, APIKeyHeader, APIKeyQuery, APIKeyCookie from passlib.context import CryptContext @@ -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: bool = False, + super_user: Optional[bool] = False, expires_delta: Optional[timedelta] = None, - level: 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: str = "authentication") -> schemas.TokenPayload: +def __verify_token(token: str, purpose: Optional[str] = "authentication") -> schemas.TokenPayload: """ 使用 JWT Token 进行身份认证并解析 Token 的内容 :param token: JWT 令牌 diff --git a/app/db/downloadhistory_oper.py b/app/db/downloadhistory_oper.py index dfe8b6cf..4349e62f 100644 --- a/app/db/downloadhistory_oper.py +++ b/app/db/downloadhistory_oper.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List, Optional from app.db import DbOper from app.db.models.downloadhistory import DownloadHistory, DownloadFiles @@ -51,7 +51,7 @@ class DownloadHistoryOper(DbOper): """ DownloadFiles.truncate(self._db) - def get_files_by_hash(self, download_hash: str, state: 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: int = 1, count: 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: str = None, year: str = None, - season: str = None, episode: 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: 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: 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: int = 7) -> List[DownloadHistory]: + def list_by_type(self, mtype: str, days: Optional[int] = 7) -> List[DownloadHistory]: """ 获取指定类型的下载历史 """ diff --git a/app/db/message_oper.py b/app/db/message_oper.py index 12dbe095..d5d01f47 100644 --- a/app/db/message_oper.py +++ b/app/db/message_oper.py @@ -18,14 +18,14 @@ class MessageOper(DbOper): def add(self, channel: MessageChannel = None, - source: str = None, + source: Optional[str] = None, mtype: NotificationType = None, - title: str = None, - text: str = None, - image: str = None, - link: str = None, - userid: str = None, - action: 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: int = 1, count: int = 30) -> Optional[str]: + def list_by_page(self, page: Optional[int] = 1, count: Optional[int] = 30) -> Optional[str]: """ 获取媒体服务器数据ID """ diff --git a/app/db/models/downloadhistory.py b/app/db/models/downloadhistory.py index bb7468a3..57ccc380 100644 --- a/app/db/models/downloadhistory.py +++ b/app/db/models/downloadhistory.py @@ -1,4 +1,5 @@ import time +from typing import Optional from sqlalchemy import Column, Integer, String, Sequence, JSON from sqlalchemy.orm import Session @@ -67,7 +68,7 @@ class DownloadHistory(Base): @staticmethod @db_query - def list_by_page(db: Session, page: int = 1, count: 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) @@ -78,8 +79,9 @@ class DownloadHistory(Base): @staticmethod @db_query - def get_last_by(db: Session, mtype: str = None, title: str = None, year: int = None, season: str = None, - episode: str = None, tmdbid: 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查询转移记录 """ @@ -123,7 +125,7 @@ class DownloadHistory(Base): @staticmethod @db_query - def list_by_user_date(db: Session, date: str, username: str = None): + def list_by_user_date(db: Session, date: str, username: Optional[str] = None): """ 查询某用户某时间之后的下载历史 """ @@ -138,7 +140,7 @@ class DownloadHistory(Base): @staticmethod @db_query - def list_by_date(db: Session, date: str, type: str, tmdbid: str, seasons: str = None): + def list_by_date(db: Session, date: str, type: str, tmdbid: str, seasons: Optional[str] = None): """ 查询某时间之后的下载历史 """ @@ -187,7 +189,7 @@ class DownloadFiles(Base): @staticmethod @db_query - def get_by_hash(db: Session, download_hash: str, state: 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() diff --git a/app/db/models/message.py b/app/db/models/message.py index f2d640d5..53c75554 100644 --- a/app/db/models/message.py +++ b/app/db/models/message.py @@ -1,3 +1,5 @@ +from typing import Optional + from sqlalchemy import Column, Integer, String, Sequence, JSON from sqlalchemy.orm import Session @@ -34,7 +36,7 @@ class Message(Base): @staticmethod @db_query - def list_by_page(db: Session, page: int = 1, count: 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) diff --git a/app/db/models/siteuserdata.py b/app/db/models/siteuserdata.py index 3c97ded0..504b58df 100644 --- a/app/db/models/siteuserdata.py +++ b/app/db/models/siteuserdata.py @@ -1,4 +1,5 @@ from datetime import datetime +from typing import Optional from sqlalchemy import Column, Integer, String, Sequence, Float, JSON, func, or_ from sqlalchemy.orm import Session @@ -54,7 +55,7 @@ class SiteUserData(Base): @staticmethod @db_query - def get_by_domain(db: Session, domain: str, workdate: str = None, worktime: 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, diff --git a/app/db/models/subscribe.py b/app/db/models/subscribe.py index c406ee5f..9f54547f 100644 --- a/app/db/models/subscribe.py +++ b/app/db/models/subscribe.py @@ -1,4 +1,5 @@ import time +from typing import Optional from sqlalchemy import Column, Integer, String, Sequence, Float, JSON from sqlalchemy.orm import Session @@ -86,7 +87,7 @@ class Subscribe(Base): @staticmethod @db_query - def exists(db: Session, tmdbid: int = None, doubanid: str = None, season: 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, @@ -110,7 +111,7 @@ class Subscribe(Base): @staticmethod @db_query - def get_by_title(db: Session, title: str, season: 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() @@ -118,7 +119,7 @@ class Subscribe(Base): @staticmethod @db_query - def get_by_tmdbid(db: Session, tmdbid: int, season: 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() @@ -164,7 +165,7 @@ class Subscribe(Base): @staticmethod @db_query - def list_by_username(db: Session, username: str, state: str = None, mtype: 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, diff --git a/app/db/models/subscribehistory.py b/app/db/models/subscribehistory.py index 2abdb4b3..66bcd135 100644 --- a/app/db/models/subscribehistory.py +++ b/app/db/models/subscribehistory.py @@ -1,3 +1,5 @@ +from typing import Optional + from sqlalchemy import Column, Integer, String, Sequence, Float, JSON from sqlalchemy.orm import Session @@ -70,7 +72,7 @@ class SubscribeHistory(Base): @staticmethod @db_query - def list_by_type(db: Session, mtype: str, page: int = 1, count: 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( @@ -80,7 +82,7 @@ class SubscribeHistory(Base): @staticmethod @db_query - def exists(db: Session, tmdbid: int = None, doubanid: str = None, season: 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, diff --git a/app/db/models/transferhistory.py b/app/db/models/transferhistory.py index 1ce3ae96..4941cb11 100644 --- a/app/db/models/transferhistory.py +++ b/app/db/models/transferhistory.py @@ -1,4 +1,5 @@ import time +from typing import Optional from sqlalchemy import Column, Integer, String, Sequence, Boolean, func, or_, JSON from sqlalchemy.orm import Session @@ -58,7 +59,7 @@ class TransferHistory(Base): @staticmethod @db_query - def list_by_title(db: Session, title: str, page: int = 1, count: 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 @@ -77,7 +78,7 @@ class TransferHistory(Base): @staticmethod @db_query - def list_by_page(db: Session, page: int = 1, count: 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 @@ -97,7 +98,7 @@ class TransferHistory(Base): @staticmethod @db_query - def get_by_src(db: Session, src: str, storage: 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() @@ -117,7 +118,7 @@ class TransferHistory(Base): @staticmethod @db_query - def statistic(db: Session, days: int = 7): + def statistic(db: Session, days: Optional[int] = 7): """ 统计最近days天的下载历史数量,按日期分组返回每日数量 """ @@ -150,8 +151,8 @@ class TransferHistory(Base): @staticmethod @db_query - def list_by(db: Session, mtype: str = None, title: str = None, year: str = None, season: str = None, - episode: str = None, tmdbid: int = None, dest: 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 必输 @@ -218,7 +219,7 @@ class TransferHistory(Base): @staticmethod @db_query - def get_by_type_tmdbid(db: Session, mtype: str = None, tmdbid: int = None): + def get_by_type_tmdbid(db: Session, mtype: Optional[str] = None, tmdbid: Optional[int] = None): """ 据tmdbid、type查询转移记录 """ @@ -227,7 +228,7 @@ class TransferHistory(Base): @staticmethod @db_update - def update_download_hash(db: Session, historyid: int = None, download_hash: 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 diff --git a/app/db/models/workflow.py b/app/db/models/workflow.py index dc83c161..e99dafd4 100644 --- a/app/db/models/workflow.py +++ b/app/db/models/workflow.py @@ -1,4 +1,5 @@ from datetime import datetime +from typing import Optional from sqlalchemy import Column, Integer, JSON, Sequence, String, and_ @@ -72,7 +73,7 @@ class Workflow(Base): @staticmethod @db_update - def success(db, wid: int, result: 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, @@ -83,7 +84,7 @@ class Workflow(Base): @staticmethod @db_update - def reset(db, wid: int, reset_count: bool = False): + def reset(db, wid: int, reset_count: Optional[bool] = False): db.query(Workflow).filter(Workflow.id == wid).update({ "state": 'W', "result": None, diff --git a/app/db/plugindata_oper.py b/app/db/plugindata_oper.py index 8a0fcdf3..04a260d1 100644 --- a/app/db/plugindata_oper.py +++ b/app/db/plugindata_oper.py @@ -1,4 +1,4 @@ -from typing import Any +from typing import Any, Optional from app.db import DbOper from app.db.models.plugindata import PluginData @@ -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: 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: str = None) -> Any: + def del_data(self, plugin_id: str, key: Optional[str] = None) -> Any: """ 删除插件数据 :param plugin_id: 插件id diff --git a/app/db/site_oper.py b/app/db/site_oper.py index 8ff4f11c..f9bb076f 100644 --- a/app/db/site_oper.py +++ b/app/db/site_oper.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import List, Tuple +from typing import List, Tuple, Optional from app.db import DbOper from app.db.models import SiteIcon @@ -134,7 +134,7 @@ class SiteOper(DbOper): """ return SiteUserData.list(self._db) - def get_userdata_by_domain(self, domain: str, workdate: 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: int = None): + def success(self, domain: str, seconds: Optional[int] = None): """ 站点访问成功 """ diff --git a/app/db/subscribe_oper.py b/app/db/subscribe_oper.py index 73ad31c2..6f2eb196 100644 --- a/app/db/subscribe_oper.py +++ b/app/db/subscribe_oper.py @@ -1,5 +1,5 @@ import time -from typing import Tuple, List +from typing import Tuple, List, Optional from app.core.context import MediaInfo from app.db import DbOper @@ -45,7 +45,7 @@ class SubscribeOper(DbOper): else: return subscribe.id, "订阅已存在" - def exists(self, tmdbid: int = None, doubanid: str = None, season: 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: 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: 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: str = None, mtype: 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: 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: int = None, doubanid: str = None, season: int = None): + def exist_history(self, tmdbid: Optional[int] = None, doubanid: Optional[str] = None, season: Optional[int] = None): """ 判断是否存在订阅历史 """ diff --git a/app/db/transferhistory_oper.py b/app/db/transferhistory_oper.py index 3b25f1c8..9c7cde51 100644 --- a/app/db/transferhistory_oper.py +++ b/app/db/transferhistory_oper.py @@ -1,5 +1,5 @@ import time -from typing import Any, List +from typing import Any, List, Optional from app.core.context import MediaInfo from app.core.meta import MetaBase @@ -27,7 +27,7 @@ class TransferHistoryOper(DbOper): """ return TransferHistory.list_by_title(self._db, title) - def get_by_src(self, src: str, storage: str = None) -> TransferHistory: + def get_by_src(self, src: str, storage: Optional[str] = None) -> TransferHistory: """ 按源查询转移记录 :param src: 数据key @@ -58,14 +58,15 @@ class TransferHistoryOper(DbOper): }) TransferHistory(**kwargs).create(self._db) - def statistic(self, days: 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: str = None, year: str = None, mtype: str = None, - season: str = None, episode: str = None, tmdbid: int = None, dest: 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]: """ 按类型、标题、年份、季集查询转移记录 """ @@ -78,7 +79,7 @@ class TransferHistoryOper(DbOper): episode=episode, tmdbid=tmdbid) - def get_by_type_tmdbid(self, mtype: str = None, tmdbid: int = None) -> TransferHistory: + def get_by_type_tmdbid(self, mtype: Optional[str] = None, tmdbid: Optional[int] = None) -> TransferHistory: """ 按类型、tmdb查询转移记录 """ @@ -120,7 +121,7 @@ class TransferHistoryOper(DbOper): def add_success(self, fileitem: FileItem, mode: str, meta: MetaBase, mediainfo: MediaInfo, transferinfo: TransferInfo, - downloader: str = None, download_hash: str = None): + downloader: Optional[str] = None, download_hash: Optional[str] = None): """ 新增转移成功历史记录 """ @@ -150,7 +151,7 @@ class TransferHistoryOper(DbOper): ) def add_fail(self, fileitem: FileItem, mode: str, meta: MetaBase, mediainfo: MediaInfo = None, - transferinfo: TransferInfo = None, downloader: str = None, download_hash: str = None): + transferinfo: TransferInfo = None, downloader: Optional[str] = None, download_hash: Optional[str] = None): """ 新增转移失败历史记录 """ diff --git a/app/db/workflow_oper.py b/app/db/workflow_oper.py index 613430be..8b3f17fa 100644 --- a/app/db/workflow_oper.py +++ b/app/db/workflow_oper.py @@ -1,4 +1,4 @@ -from typing import List, Tuple +from typing import List, Tuple, Optional from app.db import DbOper from app.db.models.workflow import Workflow @@ -43,7 +43,7 @@ class WorkflowOper(DbOper): """ return Workflow.start(self._db, wid) - def success(self, wid: int, result: str = None) -> bool: + def success(self, wid: int, result: Optional[str] = None) -> bool: """ 成功 """ diff --git a/app/helper/browser.py b/app/helper/browser.py index 67a98192..bc1f77d0 100644 --- a/app/helper/browser.py +++ b/app/helper/browser.py @@ -20,11 +20,11 @@ class PlaywrightHelper: def action(self, url: str, callback: Callable, - cookies: str = None, - ua: str = None, - proxies: dict = None, - headless: bool = False, - timeout: 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: str = None, - ua: str = None, - proxies: dict = None, - headless: bool = False, - timeout: 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: 网页地址 diff --git a/app/helper/cookie.py b/app/helper/cookie.py index 150f7e91..49c7131a 100644 --- a/app/helper/cookie.py +++ b/app/helper/cookie.py @@ -73,8 +73,8 @@ class CookieHelper: url: str, username: str, password: str, - two_step_code: str = None, - proxies: 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: 站点地址 diff --git a/app/helper/directory.py b/app/helper/directory.py index 90788775..77711ee5 100644 --- a/app/helper/directory.py +++ b/app/helper/directory.py @@ -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: bool = False, - storage: str = None, src_path: Path = None, - target_storage: 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]: """ 根据媒体信息获取下载目录、媒体库目录配置 diff --git a/app/helper/format.py b/app/helper/format.py index 31474e8d..9128c33c 100644 --- a/app/helper/format.py +++ b/app/helper/format.py @@ -10,8 +10,8 @@ class FormatParser(object): _key = "" _split_chars = r"\.|\s+|\(|\)|\[|]|-|\+|【|】|/|~|;|&|\||#|_|「|」|~" - def __init__(self, eformat: str, details: str = None, part: str = None, - offset: str = None, key: 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: 格式化详情 diff --git a/app/helper/message.py b/app/helper/message.py index c7427f35..7871e936 100644 --- a/app/helper/message.py +++ b/app/helper/message.py @@ -25,7 +25,7 @@ class MessageQueueManager(metaclass=SingletonClass): def __init__( self, send_callback: Optional[Callable] = None, - check_interval: int = 10 + check_interval: Optional[int] = 10 ) -> None: """ 消息队列管理器初始化 diff --git a/app/helper/ocr.py b/app/helper/ocr.py index 04f83234..63723ab0 100644 --- a/app/helper/ocr.py +++ b/app/helper/ocr.py @@ -1,4 +1,5 @@ import base64 +from typing import Optional from app.core.config import settings from app.utils.http import RequestUtils @@ -8,7 +9,8 @@ class OcrHelper: _ocr_b64_url = f"{settings.OCR_HOST}/captcha/base64" - def get_captcha_text(self, image_url=None, image_b64=None, cookie=None, ua=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: 图片地址 diff --git a/app/helper/plugin.py b/app/helper/plugin.py index 239eda49..ea0f1eb5 100644 --- a/app/helper/plugin.py +++ b/app/helper/plugin.py @@ -39,7 +39,7 @@ class PluginHelper(metaclass=Singleton): self.systemconfig.set(SystemConfigKey.PluginInstallReport, "1") @cached(maxsize=1000, ttl=1800) - def get_plugins(self, repo_url: str, package_version: str = None) -> Optional[Dict[str, dict]]: + def get_plugins(self, repo_url: str, package_version: Optional[str] = None) -> Optional[Dict[str, dict]]: """ 获取Github所有最新插件列表 :param repo_url: Github仓库地址 @@ -66,7 +66,7 @@ class PluginHelper(metaclass=Singleton): return None return {} - def get_plugin_package_version(self, pid: str, repo_url: str, package_version: str = None) -> Optional[str]: + def get_plugin_package_version(self, pid: str, repo_url: str, package_version: Optional[str] = None) -> Optional[str]: """ 检查并获取指定插件的可用版本,支持多版本优先级加载和版本兼容性检测 1. 如果未指定版本,则使用系统配置的默认版本(通过 settings.VERSION_FLAG 设置) @@ -157,7 +157,7 @@ class PluginHelper(metaclass=Singleton): json={"plugins": [{"plugin_id": plugin} for plugin in plugins]}) return True if res else False - def install(self, pid: str, repo_url: str, package_version: str = None, force_install: bool = False) \ + def install(self, pid: str, repo_url: str, package_version: Optional[str] = None, force_install: bool = False) \ -> Tuple[bool, str]: """ 安装插件,包括依赖安装和文件下载,相关资源支持自动降级策略 @@ -260,7 +260,7 @@ class PluginHelper(metaclass=Singleton): self.install_reg(pid) return True, "" - def __get_file_list(self, pid: str, user_repo: str, package_version: str = None) -> \ + def __get_file_list(self, pid: str, user_repo: str, package_version: Optional[str] = None) -> \ Tuple[Optional[list], Optional[str]]: """ 获取插件的文件列表 @@ -295,7 +295,7 @@ class PluginHelper(metaclass=Singleton): return None, "插件数据解析失败" def __download_files(self, pid: str, file_list: List[dict], user_repo: str, - package_version: str = None, skip_requirements: bool = False) -> Tuple[bool, str]: + package_version: Optional[str] = None, skip_requirements: bool = False) -> Tuple[bool, str]: """ 下载插件文件 :param pid: 插件 ID @@ -480,7 +480,7 @@ class PluginHelper(metaclass=Singleton): @staticmethod def __request_with_fallback(url: str, headers: Optional[dict] = None, - timeout: int = 60, + timeout: Optional[int] = 60, is_api: bool = False) -> Optional[Any]: """ 使用自动降级策略,请求资源,优先级依次为镜像站、代理、直连 diff --git a/app/helper/progress.py b/app/helper/progress.py index e852106f..abcb4b67 100644 --- a/app/helper/progress.py +++ b/app/helper/progress.py @@ -1,5 +1,5 @@ from enum import Enum -from typing import Union, Dict +from typing import Union, Dict, Optional from app.schemas.types import ProgressKey from app.utils.singleton import Singleton @@ -40,7 +40,7 @@ class ProgressHelper(metaclass=Singleton): "text": "正在处理..." } - def update(self, key: Union[ProgressKey, str], value: Union[float, int] = None, text: str = None): + def update(self, key: Union[ProgressKey, str], value: Union[float, int] = None, text: Optional[str] = None): if isinstance(key, Enum): key = key.value if not self._process_detail.get(key, {}).get('enable'): diff --git a/app/helper/rss.py b/app/helper/rss.py index 999f3a64..cebcb137 100644 --- a/app/helper/rss.py +++ b/app/helper/rss.py @@ -1,7 +1,7 @@ import re import traceback import xml.dom.minidom -from typing import List, Tuple, Union +from typing import List, Tuple, Union, Optional from urllib.parse import urljoin import chardet @@ -225,7 +225,7 @@ class RssHelper: } @staticmethod - def parse(url, proxy: bool = False, timeout: int = 15, headers: dict = None) -> Union[List[dict], None, bool]: + def parse(url, proxy: bool = False, timeout: Optional[int] = 15, headers: dict = None) -> Union[List[dict], None, bool]: """ 解析RSS订阅URL,获取RSS中的种子信息 :param url: RSS地址 diff --git a/app/helper/subscribe.py b/app/helper/subscribe.py index b2231136..08b8f794 100644 --- a/app/helper/subscribe.py +++ b/app/helper/subscribe.py @@ -1,5 +1,5 @@ from threading import Thread -from typing import List, Tuple +from typing import List, Tuple, Optional from app.core.cache import cached, cache_backend from app.core.config import settings @@ -41,7 +41,7 @@ class SubscribeHelper(metaclass=Singleton): self.systemconfig.set(SystemConfigKey.SubscribeReport, "1") @cached(maxsize=20, ttl=1800) - def get_statistic(self, stype: str, page: int = 1, count: int = 30) -> List[dict]: + def get_statistic(self, stype: str, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]: """ 获取订阅统计数据 """ @@ -182,7 +182,7 @@ class SubscribeHelper(metaclass=Singleton): return False, res.json().get("message") @cached(region=_shares_cache_region) - def get_shares(self, name: str = None, page: int = 1, count: int = 30) -> List[dict]: + def get_shares(self, name: Optional[str] = None, page: Optional[int] = 1, count: Optional[int] = 30) -> List[dict]: """ 获取订阅分享数据 """ diff --git a/app/helper/thread.py b/app/helper/thread.py index 58d8bbdf..c96eb7d2 100644 --- a/app/helper/thread.py +++ b/app/helper/thread.py @@ -1,4 +1,5 @@ from concurrent.futures import ThreadPoolExecutor +from typing import Optional from app.utils.singleton import Singleton @@ -7,7 +8,7 @@ class ThreadHelper(metaclass=Singleton): """ 线程池管理 """ - def __init__(self, max_workers=50): + def __init__(self, max_workers: Optional[int] = 50): self.pool = ThreadPoolExecutor(max_workers=max_workers) def submit(self, func, *args, **kwargs): diff --git a/app/helper/torrent.py b/app/helper/torrent.py index 3522145b..d616935f 100644 --- a/app/helper/torrent.py +++ b/app/helper/torrent.py @@ -33,10 +33,10 @@ class TorrentHelper(metaclass=Singleton): self.site_oper = SiteOper() def download_torrent(self, url: str, - cookie: str = None, - ua: str = None, - referer: str = None, - proxy: bool = False) \ + cookie: Optional[str] = None, + ua: Optional[str] = None, + referer: Optional[str] = None, + proxy: Optional[bool] = False) \ -> Tuple[Optional[Path], Optional[Union[str, bytes]], Optional[str], Optional[list], Optional[str]]: """ 把种子下载到本地 diff --git a/app/modules/bangumi/bangumi.py b/app/modules/bangumi/bangumi.py index 079b37de..debcafbd 100644 --- a/app/modules/bangumi/bangumi.py +++ b/app/modules/bangumi/bangumi.py @@ -1,4 +1,5 @@ from datetime import datetime +from typing import Optional import requests @@ -31,7 +32,7 @@ class BangumiApi(object): @classmethod @cached(maxsize=settings.CACHE_CONF["bangumi"], ttl=settings.CACHE_CONF["meta"]) - def __invoke(cls, url, key: str = None, **kwargs): + def __invoke(cls, url, key: Optional[str] = None, **kwargs): req_url = cls._base_url + url params = {} if kwargs: diff --git a/app/modules/douban/apiv2.py b/app/modules/douban/apiv2.py index 478c625e..5af0a431 100644 --- a/app/modules/douban/apiv2.py +++ b/app/modules/douban/apiv2.py @@ -4,6 +4,7 @@ import hashlib import hmac from datetime import datetime from random import choice +from typing import Optional from urllib import parse import requests @@ -18,7 +19,6 @@ class DoubanApi(metaclass=Singleton): _urls = { # 搜索类 # sort=U:近期热门 T:标记最多 S:评分最高 R:最新上映 - # q=search_word&start: int = 0&count: int = 20&sort=U # 聚合搜索 "search": "/search/weixin", "search_agg": "/search", @@ -27,21 +27,18 @@ class DoubanApi(metaclass=Singleton): # 电影探索 # sort=U:综合排序 T:近期热度 S:高分优先 R:首播时间 - # tags='日本,动画,2022'&start: int = 0&count: int = 20&sort=U "movie_recommend": "/movie/recommend", # 电视剧探索 "tv_recommend": "/tv/recommend", # 搜索 "movie_tag": "/movie/tag", "tv_tag": "/tv/tag", - # q=search_word&start: int = 0&count: int = 20 "movie_search": "/search/movie", "tv_search": "/search/movie", "book_search": "/search/book", "group_search": "/search/group", # 各类主题合集 - # start: int = 0&count: int = 20 # 正在上映 "movie_showing": "/subject_collection/movie_showing/items", # 热门电影 @@ -252,7 +249,7 @@ class DoubanApi(metaclass=Singleton): """ return self.__post(self._urls["imdbid"] % imdbid, _ts=ts) - def search(self, keyword: str, start: int = 0, count: int = 20, + def search(self, keyword: str, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')) -> dict: """ 关键字搜索 @@ -260,7 +257,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_search(self._urls["search"], q=keyword, start=start, count=count, _ts=ts) - def movie_search(self, keyword: str, start: int = 0, count: int = 20, + def movie_search(self, keyword: str, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 电影搜索 @@ -268,7 +265,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_search(self._urls["movie_search"], q=keyword, start=start, count=count, _ts=ts) - def tv_search(self, keyword: str, start: int = 0, count: int = 20, + def tv_search(self, keyword: str, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 电视搜索 @@ -276,7 +273,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_search(self._urls["tv_search"], q=keyword, start=start, count=count, _ts=ts) - def book_search(self, keyword: str, start: int = 0, count: int = 20, + def book_search(self, keyword: str, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 书籍搜索 @@ -284,7 +281,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_search(self._urls["book_search"], q=keyword, start=start, count=count, _ts=ts) - def group_search(self, keyword: str, start: int = 0, count: int = 20, + def group_search(self, keyword: str, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 小组搜索 @@ -292,7 +289,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_search(self._urls["group_search"], q=keyword, start=start, count=count, _ts=ts) - def person_search(self, keyword: str, start: int = 0, count: int = 20, + def person_search(self, keyword: str, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 人物搜索 @@ -300,7 +297,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_search(self._urls["search_subject"], type="person", q=keyword, start=start, count=count, _ts=ts) - def movie_showing(self, start: int = 0, count: int = 20, + def movie_showing(self, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 正在热映 @@ -308,7 +305,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_recommend(self._urls["movie_showing"], start=start, count=count, _ts=ts) - def movie_soon(self, start: int = 0, count: int = 20, + def movie_soon(self, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 即将上映 @@ -316,7 +313,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_recommend(self._urls["movie_soon"], start=start, count=count, _ts=ts) - def movie_hot_gaia(self, start: int = 0, count: int = 20, + def movie_hot_gaia(self, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 热门电影 @@ -324,7 +321,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_recommend(self._urls["movie_hot_gaia"], start=start, count=count, _ts=ts) - def tv_hot(self, start: int = 0, count: int = 20, + def tv_hot(self, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 热门剧集 @@ -332,7 +329,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_recommend(self._urls["tv_hot"], start=start, count=count, _ts=ts) - def tv_animation(self, start: int = 0, count: int = 20, + def tv_animation(self, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 动画 @@ -340,7 +337,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_recommend(self._urls["tv_animation"], start=start, count=count, _ts=ts) - def tv_variety_show(self, start: int = 0, count: int = 20, + def tv_variety_show(self, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 综艺 @@ -348,7 +345,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_recommend(self._urls["tv_variety_show"], start=start, count=count, _ts=ts) - def tv_rank_list(self, start: int = 0, count: int = 20, + def tv_rank_list(self, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 电视剧排行榜 @@ -356,7 +353,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_recommend(self._urls["tv_rank_list"], start=start, count=count, _ts=ts) - def show_hot(self, start: int = 0, count: int = 20, + def show_hot(self, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 综艺热门 @@ -394,7 +391,7 @@ class DoubanApi(metaclass=Singleton): """ return self.__invoke_search(self._urls["book_detail"] + subject_id) - def movie_top250(self, start: int = 0, count: int = 20, + def movie_top250(self, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 电影TOP250 @@ -402,7 +399,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_recommend(self._urls["movie_top250"], start=start, count=count, _ts=ts) - def movie_recommend(self, tags='', sort='R', start: int = 0, count: int = 20, + def movie_recommend(self, tags='', sort='R', start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 电影探索 @@ -410,7 +407,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_recommend(self._urls["movie_recommend"], tags=tags, sort=sort, start=start, count=count, _ts=ts) - def tv_recommend(self, tags='', sort='R', start: int = 0, count: int = 20, + def tv_recommend(self, tags='', sort='R', start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 电视剧探索 @@ -418,7 +415,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_recommend(self._urls["tv_recommend"], tags=tags, sort=sort, start=start, count=count, _ts=ts) - def tv_chinese_best_weekly(self, start: int = 0, count: int = 20, + def tv_chinese_best_weekly(self, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 华语口碑周榜 @@ -426,7 +423,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_recommend(self._urls["tv_chinese_best_weekly"], start=start, count=count, _ts=ts) - def tv_global_best_weekly(self, start: int = 0, count: int = 20, + def tv_global_best_weekly(self, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 全球口碑周榜 @@ -441,7 +438,7 @@ class DoubanApi(metaclass=Singleton): """ return self.__invoke_search(self._urls["doulist"] + subject_id) - def doulist_items(self, subject_id: str, start: int = 0, count: int = 20, + def doulist_items(self, subject_id: str, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 豆列列表 @@ -453,7 +450,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_search(self._urls["doulist_items"] % subject_id, start=start, count=count, _ts=ts) - def movie_recommendations(self, subject_id: str, start: int = 0, count: int = 20, + def movie_recommendations(self, subject_id: str, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 电影推荐 @@ -465,7 +462,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_recommend(self._urls["movie_recommendations"] % subject_id, start=start, count=count, _ts=ts) - def tv_recommendations(self, subject_id: str, start: int = 0, count: int = 20, + def tv_recommendations(self, subject_id: str, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 电视剧推荐 @@ -477,7 +474,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_recommend(self._urls["tv_recommendations"] % subject_id, start=start, count=count, _ts=ts) - def movie_photos(self, subject_id: str, start: int = 0, count: int = 20, + def movie_photos(self, subject_id: str, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 电影剧照 @@ -489,7 +486,7 @@ class DoubanApi(metaclass=Singleton): return self.__invoke_search(self._urls["movie_photos"] % subject_id, start=start, count=count, _ts=ts) - def tv_photos(self, subject_id: str, start: int = 0, count: int = 20, + def tv_photos(self, subject_id: str, start: Optional[int] = 0, count: Optional[int] = 20, ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 电视剧剧照 @@ -509,8 +506,9 @@ class DoubanApi(metaclass=Singleton): """ return self.__invoke_search(self._urls["person_detail"] + str(subject_id)) - def person_work(self, subject_id: int, start: int = 0, count: int = 20, sort_by: str = "time", - collection_title: str = "影视", + def person_work(self, subject_id: int, start: Optional[int] = 0, count: Optional[int] = 20, + sort_by: Optional[str] = "time", + collection_title: Optional[str] = "影视", ts=datetime.strftime(datetime.now(), '%Y%m%d')): """ 用户作品集 diff --git a/app/modules/douban/douban_cache.py b/app/modules/douban/douban_cache.py index fd4c6add..0ce9666a 100644 --- a/app/modules/douban/douban_cache.py +++ b/app/modules/douban/douban_cache.py @@ -165,7 +165,7 @@ class DoubanCache(metaclass=Singleton): # None时不缓存,此时代表网络错误,允许重复请求 self._meta_data[self.__get_key(meta)] = {'id': "0"} - def save(self, force: bool = False) -> None: + def save(self, force: Optional[bool] = False) -> None: """ 保存缓存数据到文件 """ diff --git a/app/modules/douban/scraper.py b/app/modules/douban/scraper.py index 476f6af1..9b2ad984 100644 --- a/app/modules/douban/scraper.py +++ b/app/modules/douban/scraper.py @@ -11,7 +11,7 @@ class DoubanScraper: _force_nfo = False _force_img = False - def get_metadata_nfo(self, mediainfo: MediaInfo, season: int = None) -> Optional[str]: + def get_metadata_nfo(self, mediainfo: MediaInfo, season: Optional[int] = None) -> Optional[str]: """ 获取NFO文件内容文本 :param mediainfo: 媒体信息 @@ -33,7 +33,7 @@ class DoubanScraper: return None @staticmethod - def get_metadata_img(mediainfo: MediaInfo, season: int = None, episode: int = None) -> Optional[dict]: + def get_metadata_img(mediainfo: MediaInfo, season: Optional[int] = None, episode: Optional[int] = None) -> Optional[dict]: """ 获取图片内容 :param mediainfo: 媒体信息 diff --git a/app/modules/emby/__init__.py b/app/modules/emby/__init__.py index 740901af..139b6072 100644 --- a/app/modules/emby/__init__.py +++ b/app/modules/emby/__init__.py @@ -135,8 +135,8 @@ class EmbyModule(_ModuleBase, _MediaServerBase[Emby]): return result return None - def media_exists(self, mediainfo: MediaInfo, itemid: str = None, - server: str = None) -> Optional[schemas.ExistMediaInfo]: + def media_exists(self, mediainfo: MediaInfo, itemid: Optional[str] = None, + server: Optional[str] = None) -> Optional[schemas.ExistMediaInfo]: """ 判断媒体文件是否存在 :param mediainfo: 识别的媒体信息 @@ -195,7 +195,7 @@ class EmbyModule(_ModuleBase, _MediaServerBase[Emby]): ) return None - def media_statistic(self, server: str = None) -> Optional[List[schemas.Statistic]]: + def media_statistic(self, server: Optional[str] = None) -> Optional[List[schemas.Statistic]]: """ 媒体数量统计 """ @@ -216,8 +216,8 @@ class EmbyModule(_ModuleBase, _MediaServerBase[Emby]): return media_statistics def mediaserver_librarys(self, server: str, - username: str = None, - hidden: bool = False) -> Optional[List[schemas.MediaServerLibrary]]: + username: Optional[str] = None, + hidden: Optional[bool] = False) -> Optional[List[schemas.MediaServerLibrary]]: """ 媒体库列表 """ @@ -226,7 +226,7 @@ class EmbyModule(_ModuleBase, _MediaServerBase[Emby]): return server_obj.get_librarys(username=username, hidden=hidden) return None - def mediaserver_items(self, server: str, library_id: Union[str, int], start_index: int = 0, + def mediaserver_items(self, server: str, library_id: Union[str, int], start_index: Optional[int] = 0, limit: Optional[int] = -1) -> Optional[Generator]: """ 获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据 @@ -269,7 +269,7 @@ class EmbyModule(_ModuleBase, _MediaServerBase[Emby]): ) for season, episodes in seasoninfo.items()] def mediaserver_playing(self, server: str, - count: int = 20, username: str = None) -> List[schemas.MediaServerPlayItem]: + count: Optional[int] = 20, username: Optional[str] = None) -> List[schemas.MediaServerPlayItem]: """ 获取媒体服务器正在播放信息 """ @@ -287,8 +287,8 @@ class EmbyModule(_ModuleBase, _MediaServerBase[Emby]): return None return server_obj.get_play_url(item_id) - def mediaserver_latest(self, server: str = None, - count: int = 20, username: str = None) -> List[schemas.MediaServerPlayItem]: + def mediaserver_latest(self, server: Optional[str] = None, + count: Optional[int] = 20, username: Optional[str] = None) -> List[schemas.MediaServerPlayItem]: """ 获取媒体服务器最新入库条目 """ @@ -298,10 +298,10 @@ class EmbyModule(_ModuleBase, _MediaServerBase[Emby]): return server_obj.get_latest(num=count, username=username) def mediaserver_latest_images(self, - server: str = None, - count: int = 10, - username: str = None, - remote: bool = False + server: Optional[str] = None, + count: Optional[int] = 10, + username: Optional[str] = None, + remote: Optional[bool] = False ) -> List[str]: """ 获取媒体服务器最新入库条目的图片 diff --git a/app/modules/emby/emby.py b/app/modules/emby/emby.py index 4b1e836d..c7e3b1f9 100644 --- a/app/modules/emby/emby.py +++ b/app/modules/emby/emby.py @@ -17,13 +17,13 @@ from schemas import MediaServerItem class Emby: - _host: str = None - _playhost: str = None - _apikey: str = None + _host: Optional[str] = None + _playhost: Optional[str] = None + _apikey: Optional[str] = None _sync_libraries: List[str] = [] user: Optional[Union[str, int]] = None - def __init__(self, host: str = None, apikey: str = None, play_host: str = None, + def __init__(self, host: Optional[str] = None, apikey: Optional[str] = None, play_host: Optional[str] = None, sync_libraries: list = None, **kwargs): if not host or not apikey: logger.error("Emby服务器配置不完整!") @@ -116,7 +116,7 @@ class Emby: logger.error(f"连接Library/VirtualFolders/Query 出错:" + str(e)) return [] - def __get_emby_librarys(self, username: str = None) -> List[dict]: + def __get_emby_librarys(self, username: Optional[str] = None) -> List[dict]: """ 获取Emby媒体库列表 """ @@ -139,7 +139,7 @@ class Emby: logger.error(f"连接User/Views 出错:" + str(e)) return [] - def get_librarys(self, username: str = None, hidden: bool = False) -> List[schemas.MediaServerLibrary]: + def get_librarys(self, username: Optional[str] = None, hidden: Optional[bool] = False) -> List[schemas.MediaServerLibrary]: """ 获取媒体服务器所有媒体库列表 """ @@ -171,7 +171,7 @@ class Emby: ) return libraries - def get_user(self, user_name: str = None) -> Optional[Union[str, int]]: + def get_user(self, user_name: Optional[str] = None) -> Optional[Union[str, int]]: """ 获得管理员用户 """ @@ -342,8 +342,8 @@ class Emby: def get_movies(self, title: str, - year: str = None, - tmdb_id: int = None) -> Optional[List[schemas.MediaServerItem]]: + year: Optional[str] = None, + tmdb_id: Optional[int] = None) -> Optional[List[schemas.MediaServerItem]]: """ 根据标题和年份,检查电影是否在Emby中存在,存在则返回列表 :param title: 标题 @@ -386,11 +386,11 @@ class Emby: return [] def get_tv_episodes(self, - item_id: str = None, - title: str = None, - year: str = None, - tmdb_id: int = None, - season: int = None + item_id: Optional[str] = None, + title: Optional[str] = None, + year: Optional[str] = None, + tmdb_id: Optional[int] = None, + season: Optional[int] = None ) -> Tuple[Optional[str], Optional[Dict[int, List[int]]]]: """ 根据标题和年份和季,返回Emby中的剧集列表 @@ -668,7 +668,7 @@ class Emby: logger.error(f"连接/Users/{self.user}/Items/{itemid}出错:" + str(e)) return None - def get_items(self, parent: Union[str, int], start_index: int = 0, + def get_items(self, parent: Union[str, int], start_index: Optional[int] = 0, limit: Optional[int] = -1) -> Generator[MediaServerItem | None | Any, Any, None]: """ 获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据 @@ -1049,7 +1049,7 @@ class Emby: logger.error(f"连接Emby出错:" + str(e)) return None - def post_data(self, url: str, data: str = None, headers: dict = None) -> Optional[Response]: + def post_data(self, url: str, data: Optional[str] = None, headers: dict = None) -> Optional[Response]: """ 自定义URL从媒体服务器获取数据,其中[HOST]、[APIKEY]、[USER]会被替换成实际的值 :param url: 请求地址 @@ -1077,7 +1077,7 @@ class Emby: return f"{self._playhost or self._host}web/index.html#!" \ f"/item?id={item_id}&context=home&serverId={self.serverid}" - def get_backdrop_url(self, item_id: str, image_tag: str, remote: bool = False) -> str: + def get_backdrop_url(self, item_id: str, image_tag: str, remote: Optional[bool] = False) -> str: """ 获取Emby的Backdrop图片地址 :param: item_id: 在Emby中的ID @@ -1106,7 +1106,7 @@ class Emby: return "" return "%sItems/%s/Images/Primary" % (self._host, item_id) - def get_resume(self, num: int = 12, username: str = None) -> Optional[List[schemas.MediaServerPlayItem]]: + def get_resume(self, num: Optional[int] = 12, username: Optional[str] = None) -> Optional[List[schemas.MediaServerPlayItem]]: """ 获得继续观看 """ @@ -1174,7 +1174,7 @@ class Emby: logger.error(f"连接Users/Items/Resume出错:" + str(e)) return [] - def get_latest(self, num: int = 20, username: str = None) -> Optional[List[schemas.MediaServerPlayItem]]: + def get_latest(self, num: Optional[int] = 20, username: Optional[str] = None) -> Optional[List[schemas.MediaServerPlayItem]]: """ 获得最近更新 """ diff --git a/app/modules/filemanager/__init__.py b/app/modules/filemanager/__init__.py index 34409f5e..d57c36e7 100644 --- a/app/modules/filemanager/__init__.py +++ b/app/modules/filemanager/__init__.py @@ -169,7 +169,7 @@ class FileManagerModule(_ModuleBase): return None return storage_oper.check_login(**kwargs) - def list_files(self, fileitem: FileItem, recursion: bool = False) -> Optional[List[FileItem]]: + def list_files(self, fileitem: FileItem, recursion: Optional[bool] = False) -> Optional[List[FileItem]]: """ 浏览文件 :param fileitem: 源文件 @@ -181,7 +181,7 @@ class FileManagerModule(_ModuleBase): logger.error(f"不支持 {fileitem.storage} 的文件浏览") return None - def __get_files(_item: FileItem, _r: bool = False): + def __get_files(_item: FileItem, _r: Optional[bool] = False): """ 递归处理 """ @@ -275,7 +275,7 @@ class FileManagerModule(_ModuleBase): return None return storage_oper.download(fileitem, path=path) - def upload_file(self, fileitem: FileItem, path: Path, new_name: str = None) -> Optional[FileItem]: + def upload_file(self, fileitem: FileItem, path: Path, new_name: Optional[str] = None) -> Optional[FileItem]: """ 上传文件 """ @@ -327,9 +327,9 @@ class FileManagerModule(_ModuleBase): def transfer(self, fileitem: FileItem, meta: MetaBase, mediainfo: MediaInfo, target_directory: TransferDirectoryConf = None, - target_storage: str = None, target_path: Path = None, - transfer_type: str = None, scrape: bool = None, - library_type_folder: bool = None, library_category_folder: bool = 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, episodes_info: List[TmdbEpisode] = None) -> TransferInfo: """ 文件整理 @@ -413,7 +413,7 @@ class FileManagerModule(_ModuleBase): overwrite_mode=overwrite_mode, episodes_info=episodes_info) - def __get_storage_oper(self, _storage: str, _func: str = None) -> Optional[StorageBase]: + def __get_storage_oper(self, _storage: str, _func: Optional[str] = None) -> Optional[StorageBase]: """ 获取存储操作对象 """ @@ -834,7 +834,7 @@ class FileManagerModule(_ModuleBase): return True, "" def __transfer_file(self, fileitem: FileItem, mediainfo: MediaInfo, target_storage: str, target_file: Path, - transfer_type: str, over_flag: bool = False) -> Tuple[Optional[FileItem], str]: + transfer_type: str, over_flag: Optional[bool] = False) -> Tuple[Optional[FileItem], str]: """ 整理一个文件,同时处理其他相关文件 :param fileitem: 原文件 @@ -888,7 +888,7 @@ class FileManagerModule(_ModuleBase): @staticmethod def __get_dest_path(mediainfo: MediaInfo, target_path: Path, - need_type_folder: bool = False, need_category_folder: bool = False): + need_type_folder: Optional[bool] = False, need_category_folder: Optional[bool] = False): """ 获取目标路径 """ @@ -900,7 +900,7 @@ class FileManagerModule(_ModuleBase): @staticmethod def __get_dest_dir(mediainfo: MediaInfo, target_dir: TransferDirectoryConf, - need_type_folder: bool = None, need_category_folder: bool = None) -> Path: + need_type_folder: Optional[bool] = None, need_category_folder: Optional[bool] = None) -> Path: """ 根据设置并装媒体库目录 :param mediainfo: 媒体信息 @@ -936,10 +936,10 @@ class FileManagerModule(_ModuleBase): target_storage: str, target_path: Path, transfer_type: str, - need_scrape: bool = False, - need_rename: bool = True, - need_notify: bool = True, - overwrite_mode: str = None, + need_scrape: Optional[bool] = False, + need_rename: Optional[bool] = True, + need_notify: Optional[bool] = True, + overwrite_mode: Optional[str] = None, episodes_info: List[TmdbEpisode] = None, ) -> TransferInfo: """ @@ -1133,7 +1133,7 @@ class FileManagerModule(_ModuleBase): need_notify=need_notify) @staticmethod - def __get_naming_dict(meta: MetaBase, mediainfo: MediaInfo, file_ext: str = None, + def __get_naming_dict(meta: MetaBase, mediainfo: MediaInfo, file_ext: Optional[str] = None, episodes_info: List[TmdbEpisode] = None) -> dict: """ 根据媒体信息,返回Format字典 diff --git a/app/modules/indexer/__init__.py b/app/modules/indexer/__init__.py index 548d65d6..98a79f95 100644 --- a/app/modules/indexer/__init__.py +++ b/app/modules/indexer/__init__.py @@ -77,8 +77,8 @@ class IndexerModule(_ModuleBase): def search_torrents(self, site: dict, keywords: List[str] = None, mtype: MediaType = None, - cat: str = None, - page: int = 0) -> List[TorrentInfo]: + cat: Optional[str] = None, + page: Optional[int] = 0) -> List[TorrentInfo]: """ 搜索一个站点 :param site: 站点 @@ -218,10 +218,10 @@ class IndexerModule(_ModuleBase): @staticmethod def __spider_search(indexer: dict, - search_word: str = None, + search_word: Optional[str] = None, mtype: MediaType = None, - cat: str = None, - page: int = 0) -> Tuple[bool, List[dict]]: + cat: Optional[str] = None, + page: Optional[int] = 0) -> Tuple[bool, List[dict]]: """ 根据关键字搜索单个站点 :param: indexer: 站点配置 @@ -241,7 +241,7 @@ class IndexerModule(_ModuleBase): return _spider.is_error, _spider.get_torrents() def refresh_torrents(self, site: dict, - keyword: str = None, cat: str = None, page: int = 0) -> Optional[List[TorrentInfo]]: + keyword: Optional[str] = None, cat: Optional[str] = None, page: Optional[int] = 0) -> Optional[List[TorrentInfo]]: """ 获取站点最新一页的种子,多个站点需要多线程处理 :param site: 站点 diff --git a/app/modules/indexer/parser/__init__.py b/app/modules/indexer/parser/__init__.py index 7b150157..4f004af4 100644 --- a/app/modules/indexer/parser/__init__.py +++ b/app/modules/indexer/parser/__init__.py @@ -47,7 +47,7 @@ class SiteParserBase(metaclass=ABCMeta): apikey: str, token: str, session: Session = None, - ua: str = None, + ua: Optional[str] = None, emulate: bool = False, proxy: bool = None): super().__init__() diff --git a/app/modules/indexer/parser/file_list.py b/app/modules/indexer/parser/file_list.py index f3652409..05bf5f8d 100644 --- a/app/modules/indexer/parser/file_list.py +++ b/app/modules/indexer/parser/file_list.py @@ -74,7 +74,7 @@ class FileListSiteUserInfo(SiteParserBase): self.bonus = StringUtils.str_float(bonus_html[0].xpath("string(.)").strip()) pass - def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: bool = False) -> Optional[str]: + def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: Optional[bool] = False) -> Optional[str]: """ 做种相关信息 :param html_text: diff --git a/app/modules/indexer/parser/gazelle.py b/app/modules/indexer/parser/gazelle.py index 0acf01dd..ea7a867f 100644 --- a/app/modules/indexer/parser/gazelle.py +++ b/app/modules/indexer/parser/gazelle.py @@ -87,7 +87,7 @@ class GazelleSiteUserInfo(SiteParserBase): if join_at_text: self.join_at = StringUtils.unify_datetime_str(join_at_text[0].strip()) - def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: bool = False) -> Optional[str]: + def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: Optional[bool] = False) -> Optional[str]: """ 做种相关信息 :param html_text: diff --git a/app/modules/indexer/parser/hddolby.py b/app/modules/indexer/parser/hddolby.py index 80c0d32f..3ea5b204 100644 --- a/app/modules/indexer/parser/hddolby.py +++ b/app/modules/indexer/parser/hddolby.py @@ -121,7 +121,7 @@ class HDDolbySiteUserInfo(SiteParserBase): """ pass - def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: bool = False) -> Optional[str]: + def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: Optional[bool] = False) -> Optional[str]: """ 解析用户做种信息 """ diff --git a/app/modules/indexer/parser/mtorrent.py b/app/modules/indexer/parser/mtorrent.py index cd13f489..b41a2dcc 100644 --- a/app/modules/indexer/parser/mtorrent.py +++ b/app/modules/indexer/parser/mtorrent.py @@ -111,7 +111,7 @@ class MTorrentSiteUserInfo(SiteParserBase): """ pass - def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: bool = False) -> Optional[str]: + def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: Optional[bool] = False) -> Optional[str]: """ 解析用户做种信息 """ diff --git a/app/modules/indexer/parser/nexus_php.py b/app/modules/indexer/parser/nexus_php.py index 09781c9e..cecd01ad 100644 --- a/app/modules/indexer/parser/nexus_php.py +++ b/app/modules/indexer/parser/nexus_php.py @@ -147,7 +147,7 @@ class NexusPhpSiteUserInfo(SiteParserBase): return True, gold * 100 * 100 + silver * 100 + copper return False, 0.0 - def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: bool = False) -> Optional[str]: + def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: Optional[bool] = False) -> Optional[str]: """ 做种相关信息 :param html_text: diff --git a/app/modules/indexer/parser/nexus_rabbit.py b/app/modules/indexer/parser/nexus_rabbit.py index 90a2e80d..bf72c8eb 100644 --- a/app/modules/indexer/parser/nexus_rabbit.py +++ b/app/modules/indexer/parser/nexus_rabbit.py @@ -66,7 +66,7 @@ class NexusRabbitSiteUserInfo(SiteParserBase): torrents = json.loads(html_text).get("data", []) except Exception as e: logger.error(f"解析做种信息失败: {str(e)}") - return + return None seeding_size = 0 seeding_info = [] @@ -89,7 +89,7 @@ class NexusRabbitSiteUserInfo(SiteParserBase): messages = json.loads(html_text).get("data", []) except Exception as e: logger.error(f"解析未读消息失败: {e}") - return + return None for msg in messages: msg_id, msg_unread = msg.get("id"), msg.get("unread") if not (msg_id and msg_unread) or msg_unread == "no": diff --git a/app/modules/indexer/parser/small_horse.py b/app/modules/indexer/parser/small_horse.py index 1a095495..745592fc 100644 --- a/app/modules/indexer/parser/small_horse.py +++ b/app/modules/indexer/parser/small_horse.py @@ -55,7 +55,7 @@ class SmallHorseSiteUserInfo(SiteParserBase): def _parse_user_detail_info(self, html_text: str): pass - def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: bool = False) -> Optional[str]: + def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: Optional[bool] = False) -> Optional[str]: """ 做种相关信息 :param html_text: diff --git a/app/modules/indexer/parser/tnode.py b/app/modules/indexer/parser/tnode.py index 1100a62d..fc07ab08 100644 --- a/app/modules/indexer/parser/tnode.py +++ b/app/modules/indexer/parser/tnode.py @@ -59,7 +59,7 @@ class TNodeSiteUserInfo(SiteParserBase): "unreadSystem", 0) pass - def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: bool = False) -> Optional[str]: + def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: Optional[bool] = False) -> Optional[str]: """ 解析用户做种信息 """ diff --git a/app/modules/indexer/parser/torrent_leech.py b/app/modules/indexer/parser/torrent_leech.py index 66448db2..55a246ce 100644 --- a/app/modules/indexer/parser/torrent_leech.py +++ b/app/modules/indexer/parser/torrent_leech.py @@ -59,7 +59,7 @@ class TorrentLeechSiteUserInfo(SiteParserBase): def _parse_user_detail_info(self, html_text: str): pass - def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: bool = False) -> Optional[str]: + def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: Optional[bool] = False) -> Optional[str]: """ 做种相关信息 :param html_text: diff --git a/app/modules/indexer/parser/unit3d.py b/app/modules/indexer/parser/unit3d.py index b2bd0e07..b0d3c55a 100644 --- a/app/modules/indexer/parser/unit3d.py +++ b/app/modules/indexer/parser/unit3d.py @@ -56,7 +56,7 @@ class Unit3dSiteUserInfo(SiteParserBase): self.join_at = StringUtils.unify_datetime_str( join_at_text[0].replace('注册日期', '').replace('註冊日期', '').replace('Registration date', '')) - def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: bool = False) -> Optional[str]: + def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: Optional[bool] = False) -> Optional[str]: """ 做种相关信息 :param html_text: diff --git a/app/modules/indexer/parser/yema.py b/app/modules/indexer/parser/yema.py index 03d0e74e..7c43575a 100644 --- a/app/modules/indexer/parser/yema.py +++ b/app/modules/indexer/parser/yema.py @@ -73,7 +73,7 @@ class TYemaSiteUserInfo(SiteParserBase): """ pass - def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: bool = False) -> Optional[str]: + def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: Optional[bool] = False) -> Optional[str]: """ 解析用户做种信息 """ diff --git a/app/modules/indexer/spider/hddolby.py b/app/modules/indexer/spider/hddolby.py index 1dcca020..a614c6b8 100644 --- a/app/modules/indexer/spider/hddolby.py +++ b/app/modules/indexer/spider/hddolby.py @@ -1,4 +1,4 @@ -from typing import Tuple, List +from typing import Tuple, List, Optional from app.core.config import settings from app.db.systemconfig_oper import SystemConfigOper @@ -73,7 +73,7 @@ class HddolbySpider: self._searchurl = f"https://api.{self._domain_host}/api/v1/torrent/search" self._pageurl = f"{self._domain}details.php?id=%s&hit=1" - def search(self, keyword: str, mtype: MediaType = None, page: int = 0) -> Tuple[bool, List[dict]]: + def search(self, keyword: str, mtype: MediaType = None, page: Optional[int] = 0) -> Tuple[bool, List[dict]]: """ 搜索 """ diff --git a/app/modules/indexer/spider/mtorrent.py b/app/modules/indexer/spider/mtorrent.py index 6f407495..7db5fe83 100644 --- a/app/modules/indexer/spider/mtorrent.py +++ b/app/modules/indexer/spider/mtorrent.py @@ -1,7 +1,7 @@ import base64 import json import re -from typing import Tuple, List +from typing import Tuple, List, Optional from app.core.config import settings from app.db.systemconfig_oper import SystemConfigOper @@ -65,7 +65,7 @@ class MTorrentSpider: self._token = indexer.get('token') self._timeout = indexer.get('timeout') or 15 - def search(self, keyword: str, mtype: MediaType = None, page: int = 0) -> Tuple[bool, List[dict]]: + def search(self, keyword: str, mtype: MediaType = None, page: Optional[int] = 0) -> Tuple[bool, List[dict]]: """ 搜索 """ diff --git a/app/modules/indexer/spider/tnode.py b/app/modules/indexer/spider/tnode.py index edd1ce75..4ea51099 100644 --- a/app/modules/indexer/spider/tnode.py +++ b/app/modules/indexer/spider/tnode.py @@ -1,5 +1,5 @@ import re -from typing import Tuple, List +from typing import Tuple, List, Optional from app.core.config import settings from app.log import logger @@ -49,7 +49,7 @@ class TNodeSpider: if csrf_token: self._token = csrf_token.group(1) - def search(self, keyword: str, page: int = 0) -> Tuple[bool, List[dict]]: + def search(self, keyword: str, page: Optional[int] = 0) -> Tuple[bool, List[dict]]: if not self._token: logger.warn(f"{self._name} 未获取到token,无法搜索") return True, [] diff --git a/app/modules/indexer/spider/torrentleech.py b/app/modules/indexer/spider/torrentleech.py index 56abcfd1..41098647 100644 --- a/app/modules/indexer/spider/torrentleech.py +++ b/app/modules/indexer/spider/torrentleech.py @@ -1,4 +1,4 @@ -from typing import List, Tuple +from typing import List, Tuple, Optional from urllib.parse import quote from app.core.config import settings @@ -23,7 +23,7 @@ class TorrentLeech: self._proxy = settings.PROXY self._timeout = indexer.get('timeout') or 15 - def search(self, keyword: str, page: int = 0) -> Tuple[bool, List[dict]]: + def search(self, keyword: str, page: Optional[int] = 0) -> Tuple[bool, List[dict]]: if StringUtils.is_chinese(keyword): # 不支持中文 diff --git a/app/modules/indexer/spider/yema.py b/app/modules/indexer/spider/yema.py index e71ce3bd..ae6266ff 100644 --- a/app/modules/indexer/spider/yema.py +++ b/app/modules/indexer/spider/yema.py @@ -1,4 +1,4 @@ -from typing import Tuple, List +from typing import Tuple, List, Optional from app.core.config import settings from app.db.systemconfig_oper import SystemConfigOper @@ -57,7 +57,7 @@ class YemaSpider: self._ua = indexer.get('ua') self._timeout = indexer.get('timeout') or 15 - def search(self, keyword: str, mtype: MediaType = None, page: int = 0) -> Tuple[bool, List[dict]]: + def search(self, keyword: str, mtype: MediaType = None, page: Optional[int] = 0) -> Tuple[bool, List[dict]]: """ 搜索 """ diff --git a/app/modules/jellyfin/__init__.py b/app/modules/jellyfin/__init__.py index 084b568c..d517eef1 100644 --- a/app/modules/jellyfin/__init__.py +++ b/app/modules/jellyfin/__init__.py @@ -136,8 +136,8 @@ class JellyfinModule(_ModuleBase, _MediaServerBase[Jellyfin]): return result return None - def media_exists(self, mediainfo: MediaInfo, itemid: str = None, - server: str = None) -> Optional[schemas.ExistMediaInfo]: + def media_exists(self, mediainfo: MediaInfo, itemid: Optional[str] = None, + server: Optional[str] = None) -> Optional[schemas.ExistMediaInfo]: """ 判断媒体文件是否存在 :param mediainfo: 识别的媒体信息 @@ -194,7 +194,7 @@ class JellyfinModule(_ModuleBase, _MediaServerBase[Jellyfin]): ) return None - def media_statistic(self, server: str = None) -> Optional[List[schemas.Statistic]]: + def media_statistic(self, server: Optional[str] = None) -> Optional[List[schemas.Statistic]]: """ 媒体数量统计 """ @@ -214,9 +214,9 @@ class JellyfinModule(_ModuleBase, _MediaServerBase[Jellyfin]): media_statistics.append(media_statistic) return media_statistics - def mediaserver_librarys(self, server: str = None, - username: str = None, - hidden: bool = False) -> Optional[List[schemas.MediaServerLibrary]]: + def mediaserver_librarys(self, server: Optional[str] = None, + username: Optional[str] = None, + hidden: Optional[bool] = False) -> Optional[List[schemas.MediaServerLibrary]]: """ 媒体库列表 """ @@ -225,7 +225,7 @@ class JellyfinModule(_ModuleBase, _MediaServerBase[Jellyfin]): return server_obj.get_librarys(username=username, hidden=hidden) return None - def mediaserver_items(self, server: str, library_id: Union[str, int], start_index: int = 0, + def mediaserver_items(self, server: str, library_id: Union[str, int], start_index: Optional[int] = 0, limit: Optional[int] = -1) -> Optional[Generator]: """ 获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据 @@ -268,7 +268,7 @@ class JellyfinModule(_ModuleBase, _MediaServerBase[Jellyfin]): ) for season, episodes in seasoninfo.items()] def mediaserver_playing(self, server: str, - count: int = 20, username: str = None) -> List[schemas.MediaServerPlayItem]: + count: Optional[int] = 20, username: Optional[str] = None) -> List[schemas.MediaServerPlayItem]: """ 获取媒体服务器正在播放信息 """ @@ -286,8 +286,8 @@ class JellyfinModule(_ModuleBase, _MediaServerBase[Jellyfin]): return None return server_obj.get_play_url(item_id) - def mediaserver_latest(self, server: str = None, count: int = 20, - username: str = None) -> List[schemas.MediaServerPlayItem]: + def mediaserver_latest(self, server: Optional[str] = None, count: Optional[int] = 20, + username: Optional[str] = None) -> List[schemas.MediaServerPlayItem]: """ 获取媒体服务器最新入库条目 """ @@ -297,10 +297,10 @@ class JellyfinModule(_ModuleBase, _MediaServerBase[Jellyfin]): return server_obj.get_latest(num=count, username=username) def mediaserver_latest_images(self, - server: str = None, - count: int = 20, - username: str = None, - remote: bool = False, + server: Optional[str] = None, + count: Optional[int] = 20, + username: Optional[str] = None, + remote: Optional[bool] = False, ) -> List[str]: """ 获取媒体服务器最新入库条目的图片 diff --git a/app/modules/jellyfin/jellyfin.py b/app/modules/jellyfin/jellyfin.py index 4d66cbe6..56b54504 100644 --- a/app/modules/jellyfin/jellyfin.py +++ b/app/modules/jellyfin/jellyfin.py @@ -14,13 +14,13 @@ from schemas import MediaServerItem class Jellyfin: - _host: str = None - _apikey: str = None - _playhost: str = None + _host: Optional[str] = None + _apikey: Optional[str] = None + _playhost: Optional[str] = None _sync_libraries: List[str] = [] user: Optional[Union[str, int]] = None - def __init__(self, host: str = None, apikey: str = None, play_host: str = None, + def __init__(self, host: Optional[str] = None, apikey: Optional[str] = None, play_host: Optional[str] = None, sync_libraries: list = None, **kwargs): if not host or not apikey: logger.error("Jellyfin服务器配置不完整!!") @@ -113,7 +113,7 @@ class Jellyfin: logger.error(f"连接Library/VirtualFolders 出错:" + str(e)) return [] - def __get_jellyfin_librarys(self, username: str = None) -> List[dict]: + def __get_jellyfin_librarys(self, username: Optional[str] = None) -> List[dict]: """ 获取Jellyfin媒体库的信息 """ @@ -136,7 +136,7 @@ class Jellyfin: logger.error(f"连接Users/Views 出错:" + str(e)) return [] - def get_librarys(self, username: str = None, hidden: bool = False) -> List[schemas.MediaServerLibrary]: + def get_librarys(self, username: Optional[str] = None, hidden: Optional[bool] = False) -> List[schemas.MediaServerLibrary]: """ 获取媒体服务器所有媒体库列表 """ @@ -193,7 +193,7 @@ class Jellyfin: logger.error(f"连接Users出错:" + str(e)) return 0 - def get_user(self, user_name: str = None) -> Optional[Union[str, int]]: + def get_user(self, user_name: Optional[str] = None) -> Optional[Union[str, int]]: """ 获得管理员用户 """ @@ -336,8 +336,8 @@ class Jellyfin: def get_movies(self, title: str, - year: str = None, - tmdb_id: int = None) -> Optional[List[schemas.MediaServerItem]]: + year: Optional[str] = None, + tmdb_id: Optional[int] = None) -> Optional[List[schemas.MediaServerItem]]: """ 根据标题和年份,检查电影是否在Jellyfin中存在,存在则返回列表 :param title: 标题 @@ -379,11 +379,11 @@ class Jellyfin: return [] def get_tv_episodes(self, - item_id: str = None, - title: str = None, - year: str = None, - tmdb_id: int = None, - season: int = None) -> Tuple[Optional[str], Optional[Dict[int, list]]]: + item_id: Optional[str] = None, + title: Optional[str] = None, + year: Optional[str] = None, + tmdb_id: Optional[int] = None, + season: Optional[int] = None) -> Tuple[Optional[str], Optional[Dict[int, list]]]: """ 根据标题和年份和季,返回Jellyfin中的剧集列表 :param item_id: Jellyfin中的Id @@ -761,7 +761,7 @@ class Jellyfin: logger.error(f"连接Users/{self.user}/Items/{itemid}:" + str(e)) return None - def get_items(self, parent: Union[str, int], start_index: int = 0, limit: Optional[int] = -1) \ + def get_items(self, parent: Union[str, int], start_index: Optional[int] = 0, limit: Optional[int] = -1) \ -> Generator[MediaServerItem | None | Any, Any, None]: """ 获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据 @@ -817,7 +817,7 @@ class Jellyfin: logger.error(f"连接Jellyfin出错:" + str(e)) return None - def post_data(self, url: str, data: str = None, headers: dict = None) -> Optional[Response]: + def post_data(self, url: str, data: Optional[str] = None, headers: dict = None) -> Optional[Response]: """ 自定义URL从媒体服务器获取数据,其中[HOST]、[APIKEY]、[USER]会被替换成实际的值 :param url: 请求地址 @@ -856,7 +856,7 @@ class Jellyfin: return "" return "%sItems/%s/Images/Primary" % (self._host, item_id) - def get_backdrop_url(self, item_id: str, image_tag: str, remote: bool = False) -> str: + def get_backdrop_url(self, item_id: str, image_tag: str, remote: Optional[bool] = False) -> str: """ 获取Backdrop图片地址 :param: item_id: 在Jellyfin中的ID @@ -874,7 +874,7 @@ class Jellyfin: return f"{host_url}Items/{item_id}/" \ f"Images/Backdrop?tag={image_tag}&api_key={self._apikey}" - def get_resume(self, num: int = 12, username: str = None) -> Optional[List[schemas.MediaServerPlayItem]]: + def get_resume(self, num: Optional[int] = 12, username: Optional[str] = None) -> Optional[List[schemas.MediaServerPlayItem]]: """ 获得继续观看 """ @@ -941,7 +941,7 @@ class Jellyfin: logger.error(f"连接Users/Items/Resume出错:" + str(e)) return [] - def get_latest(self, num=20, username: str = None) -> Optional[List[schemas.MediaServerPlayItem]]: + def get_latest(self, num=20, username: Optional[str] = None) -> Optional[List[schemas.MediaServerPlayItem]]: """ 获得最近更新 """ diff --git a/app/modules/plex/__init__.py b/app/modules/plex/__init__.py index c61c6c37..b786a42a 100644 --- a/app/modules/plex/__init__.py +++ b/app/modules/plex/__init__.py @@ -139,8 +139,8 @@ class PlexModule(_ModuleBase, _MediaServerBase[Plex]): return result return None - def media_exists(self, mediainfo: MediaInfo, itemid: str = None, - server: str = None) -> Optional[schemas.ExistMediaInfo]: + def media_exists(self, mediainfo: MediaInfo, itemid: Optional[str] = None, + server: Optional[str] = None) -> Optional[schemas.ExistMediaInfo]: """ 判断媒体文件是否存在 :param mediainfo: 识别的媒体信息 @@ -201,7 +201,7 @@ class PlexModule(_ModuleBase, _MediaServerBase[Plex]): ) return None - def media_statistic(self, server: str = None) -> Optional[List[schemas.Statistic]]: + def media_statistic(self, server: Optional[str] = None) -> Optional[List[schemas.Statistic]]: """ 媒体数量统计 """ @@ -221,7 +221,7 @@ class PlexModule(_ModuleBase, _MediaServerBase[Plex]): media_statistics.append(media_statistic) return media_statistics - def mediaserver_librarys(self, server: str = None, hidden: bool = False, + def mediaserver_librarys(self, server: Optional[str] = None, hidden: Optional[bool] = False, **kwargs) -> Optional[List[schemas.MediaServerLibrary]]: """ 媒体库列表 @@ -231,7 +231,7 @@ class PlexModule(_ModuleBase, _MediaServerBase[Plex]): return server_obj.get_librarys(hidden) return None - def mediaserver_items(self, server: str, library_id: Union[str, int], start_index: int = 0, + def mediaserver_items(self, server: str, library_id: Union[str, int], start_index: Optional[int] = 0, limit: Optional[int] = -1) -> Optional[Generator]: """ 获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据 @@ -273,7 +273,7 @@ class PlexModule(_ModuleBase, _MediaServerBase[Plex]): episodes=episodes ) for season, episodes in seasoninfo.items()] - def mediaserver_playing(self, server: str, count: int = 20, **kwargs) -> List[schemas.MediaServerPlayItem]: + def mediaserver_playing(self, server: str, count: Optional[int] = 20, **kwargs) -> List[schemas.MediaServerPlayItem]: """ 获取媒体服务器正在播放信息 """ @@ -282,7 +282,7 @@ class PlexModule(_ModuleBase, _MediaServerBase[Plex]): return [] return server_obj.get_resume(num=count) - def mediaserver_latest(self, server: str = None, count: int = 20, + def mediaserver_latest(self, server: Optional[str] = None, count: Optional[int] = 20, **kwargs) -> List[schemas.MediaServerPlayItem]: """ 获取媒体服务器最新入库条目 @@ -293,9 +293,9 @@ class PlexModule(_ModuleBase, _MediaServerBase[Plex]): return server_obj.get_latest(num=count) def mediaserver_latest_images(self, - server: str = None, - count: int = 20, - username: str = None, + server: Optional[str] = None, + count: Optional[int] = 20, + username: Optional[str] = None, **kwargs ) -> List[str]: """ diff --git a/app/modules/plex/plex.py b/app/modules/plex/plex.py index 86b50085..12e9f74a 100644 --- a/app/modules/plex/plex.py +++ b/app/modules/plex/plex.py @@ -22,7 +22,7 @@ class Plex: _session = None _sync_libraries: List[str] = [] - def __init__(self, host: str = None, token: str = None, play_host: str = None, + def __init__(self, host: Optional[str] = None, token: Optional[str] = None, play_host: Optional[str] = None, sync_libraries: list = None, **kwargs): if not host or not token: logger.error("Plex服务器配置不完整!") @@ -122,7 +122,7 @@ class Plex: return [f"{self._host.rstrip('/') + url}?X-Plex-Token={self._token}" for url in list(poster_urls.keys())[:total_size]] - def get_librarys(self, hidden: bool = False) -> List[schemas.MediaServerLibrary]: + def get_librarys(self, hidden: Optional[bool] = False) -> List[schemas.MediaServerLibrary]: """ 获取媒体服务器所有媒体库列表 """ @@ -186,9 +186,9 @@ class Plex: def get_movies(self, title: str, - original_title: str = None, - year: str = None, - tmdb_id: int = None) -> Optional[List[schemas.MediaServerItem]]: + original_title: Optional[str] = None, + year: Optional[str] = None, + tmdb_id: Optional[int] = None) -> Optional[List[schemas.MediaServerItem]]: """ 根据标题和年份,检查电影是否在Plex中存在,存在则返回列表 :param title: 标题 @@ -241,12 +241,12 @@ class Plex: return ret_movies def get_tv_episodes(self, - item_id: str = None, - title: str = None, - original_title: str = None, - year: str = None, - tmdb_id: int = None, - season: int = None) -> Tuple[Optional[str], Optional[Dict[int, list]]]: + item_id: Optional[str] = None, + title: Optional[str] = None, + original_title: Optional[str] = None, + year: Optional[str] = None, + tmdb_id: Optional[int] = None, + season: Optional[int] = None) -> Tuple[Optional[str], Optional[Dict[int, list]]]: """ 根据标题、年份、季查询电视剧所有集信息 :param item_id: 媒体ID @@ -296,8 +296,8 @@ class Plex: def get_remote_image_by_id(self, item_id: str, image_type: str, - depth: int = 0, - plex_url: bool = True) -> Optional[str]: + depth: Optional[int] = 0, + plex_url: Optional[bool] = True) -> Optional[str]: """ 根据ItemId从Plex查询图片地址 :param item_id: 在Plex中的ID @@ -511,7 +511,7 @@ class Plex: user_state=user_state, ) - def get_items(self, parent: Union[str, int], start_index: int = 0, limit: Optional[int] = -1) \ + def get_items(self, parent: Union[str, int], start_index: Optional[int] = 0, limit: Optional[int] = -1) \ -> Generator[MediaServerItem | None, Any, None]: """ 获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据 @@ -718,7 +718,7 @@ class Plex: """ return f'{self._playhost or self._host}web/index.html#!/server/{self._plex.machineIdentifier}/details?key={item_id}' - def get_resume(self, num: int = 12) -> Optional[List[schemas.MediaServerPlayItem]]: + def get_resume(self, num: Optional[int] = 12) -> Optional[List[schemas.MediaServerPlayItem]]: """ 获取继续观看的媒体 """ @@ -754,7 +754,7 @@ class Plex: )) return ret_resume[:num] - def get_latest(self, num: int = 20) -> Optional[List[schemas.MediaServerPlayItem]]: + def get_latest(self, num: Optional[int] = 20) -> Optional[List[schemas.MediaServerPlayItem]]: """ 获取最近添加媒体 """ diff --git a/app/modules/qbittorrent/__init__.py b/app/modules/qbittorrent/__init__.py index 32429deb..caf1693d 100644 --- a/app/modules/qbittorrent/__init__.py +++ b/app/modules/qbittorrent/__init__.py @@ -78,8 +78,8 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]): server.reconnect() def download(self, content: Union[Path, str], download_dir: Path, cookie: str, - episodes: Set[int] = None, category: str = None, label: str = None, - downloader: str = None) -> Optional[Tuple[Optional[str], Optional[str], Optional[str], str]]: + episodes: Set[int] = None, category: Optional[str] = None, label: Optional[str] = None, + downloader: Optional[str] = None) -> Optional[Tuple[Optional[str], Optional[str], Optional[str], str]]: """ 根据种子文件,选择并添加下载任务 :param content: 种子文件地址或者磁力链接 @@ -208,7 +208,7 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]): def list_torrents(self, status: TorrentStatus = None, hashs: Union[list, str] = None, - downloader: str = None + downloader: Optional[str] = None ) -> Optional[List[Union[TransferTorrent, DownloadingTorrent]]]: """ 获取下载器种子列表 @@ -293,7 +293,7 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]): return None return ret_torrents - def transfer_completed(self, hashs: str, downloader: str = None) -> None: + def transfer_completed(self, hashs: str, downloader: Optional[str] = None) -> None: """ 转移完成后的处理 :param hashs: 种子Hash @@ -304,8 +304,8 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]): return None server.set_torrents_tag(ids=hashs, tags=['已整理']) - def remove_torrents(self, hashs: Union[str, list], delete_file: bool = True, - downloader: str = None) -> Optional[bool]: + def remove_torrents(self, hashs: Union[str, list], delete_file: Optional[bool] = True, + downloader: Optional[str] = None) -> Optional[bool]: """ 删除下载器种子 :param hashs: 种子Hash @@ -319,7 +319,7 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]): return server.delete_torrents(delete_file=delete_file, ids=hashs) def start_torrents(self, hashs: Union[list, str], - downloader: str = None) -> Optional[bool]: + downloader: Optional[str] = None) -> Optional[bool]: """ 开始下载 :param hashs: 种子Hash @@ -331,7 +331,7 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]): return None return server.start_torrents(ids=hashs) - def stop_torrents(self, hashs: Union[list, str], downloader: str = None) -> Optional[bool]: + def stop_torrents(self, hashs: Union[list, str], downloader: Optional[str] = None) -> Optional[bool]: """ 停止下载 :param hashs: 种子Hash @@ -343,7 +343,7 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]): return None return server.stop_torrents(ids=hashs) - def torrent_files(self, tid: str, downloader: str = None) -> Optional[TorrentFilesList]: + def torrent_files(self, tid: str, downloader: Optional[str] = None) -> Optional[TorrentFilesList]: """ 获取种子文件列表 """ @@ -352,7 +352,7 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]): return None return server.get_files(tid=tid) - def downloader_info(self, downloader: str = None) -> Optional[List[schemas.DownloaderInfo]]: + def downloader_info(self, downloader: Optional[str] = None) -> Optional[List[schemas.DownloaderInfo]]: """ 下载器信息 """ diff --git a/app/modules/qbittorrent/qbittorrent.py b/app/modules/qbittorrent/qbittorrent.py index 0c764fbb..e05b9d1d 100644 --- a/app/modules/qbittorrent/qbittorrent.py +++ b/app/modules/qbittorrent/qbittorrent.py @@ -12,20 +12,20 @@ from app.utils.string import StringUtils class Qbittorrent: - _host: str = None + _host: Optional[str] = None _port: int = None - _username: str = None - _password: str = None - _category: bool = False - _sequentail: bool = False - _force_resume: bool = False + _username: Optional[str] = None + _password: Optional[str] = None + _category: Optional[bool] = False + _sequentail: Optional[bool] = False + _force_resume: Optional[bool] = False qbc: Client = None - def __init__(self, host: str = None, port: int = None, - username: str = None, password: str = None, - category: bool = False, sequentail: bool = False, - force_resume: bool = False, first_last_piece=False, + def __init__(self, host: Optional[str] = None, port: int = None, + username: Optional[str] = None, password: Optional[str] = None, + category: Optional[bool] = False, sequentail: Optional[bool] = False, + force_resume: Optional[bool] = False, first_last_piece=False, **kwargs): """ 若不设置参数,则创建配置文件设置的下载器 @@ -236,11 +236,11 @@ class Qbittorrent: def add_torrent(self, content: Union[str, bytes], - is_paused: bool = False, - download_dir: str = None, + is_paused: Optional[bool] = False, + download_dir: Optional[str] = None, tag: Union[str, list] = None, - category: str = None, - cookie=None, + category: Optional[str] = None, + cookie: Optional[str] = None, **kwargs ) -> bool: """ diff --git a/app/modules/slack/slack.py b/app/modules/slack/slack.py index d2a45d9a..f586714c 100644 --- a/app/modules/slack/slack.py +++ b/app/modules/slack/slack.py @@ -24,7 +24,8 @@ class Slack: _ds_url = f"http://127.0.0.1:{settings.PORT}/api/v1/message?token={settings.API_TOKEN}" _channel = "" - def __init__(self, SLACK_OAUTH_TOKEN: str = None, SLACK_APP_TOKEN: str = None, SLACK_CHANNEL: str = "", **kwargs): + def __init__(self, SLACK_OAUTH_TOKEN: Optional[str] = None, SLACK_APP_TOKEN: Optional[str] = None, + SLACK_CHANNEL: Optional[str] = None, **kwargs): if not SLACK_OAUTH_TOKEN or not SLACK_APP_TOKEN: logger.error("Slack 配置不完整!") @@ -100,7 +101,7 @@ class Slack: """ return True if self._client else False - def send_msg(self, title: str, text: str = "", image: str = "", link: str = "", userid: str = ""): + def send_msg(self, title: str, text: Optional[str] = None, image: Optional[str] = None, link: Optional[str] = None, userid: Optional[str] = None): """ 发送Telegram消息 :param title: 消息标题 @@ -168,7 +169,7 @@ class Slack: logger.error(f"Slack消息发送失败: {msg_e}") return False, str(msg_e) - def send_medias_msg(self, medias: List[MediaInfo], userid: str = "", title: str = "") -> Optional[bool]: + def send_medias_msg(self, medias: List[MediaInfo], userid: Optional[str] = None, title: Optional[str] = None) -> Optional[bool]: """ 发送列表类消息 """ @@ -252,7 +253,7 @@ class Slack: return False def send_torrents_msg(self, torrents: List[Context], - userid: str = "", title: str = "") -> Optional[bool]: + userid: Optional[str] = None, title: Optional[str] = None) -> Optional[bool]: """ 发送列表消息 """ diff --git a/app/modules/synologychat/synologychat.py b/app/modules/synologychat/synologychat.py index 280f77d0..dbb56e55 100644 --- a/app/modules/synologychat/synologychat.py +++ b/app/modules/synologychat/synologychat.py @@ -14,7 +14,7 @@ lock = Lock() class SynologyChat: - def __init__(self, SYNOLOGYCHAT_WEBHOOK: str = None, SYNOLOGYCHAT_TOKEN: str = None, **kwargs): + def __init__(self, SYNOLOGYCHAT_WEBHOOK: Optional[str] = None, SYNOLOGYCHAT_TOKEN: Optional[str] = None, **kwargs): if not SYNOLOGYCHAT_WEBHOOK or not SYNOLOGYCHAT_TOKEN: logger.error("SynologyChat配置不完整!") return @@ -38,8 +38,8 @@ class SynologyChat: return True return False - def send_msg(self, title: str, text: str = "", image: str = "", - userid: str = "", link: str = None) -> Optional[bool]: + def send_msg(self, title: str, text: Optional[str] = None, image: Optional[str] = None, + userid: Optional[str] = None, link: Optional[str] = None) -> Optional[bool]: """ 发送Telegram消息 :param title: 消息标题 @@ -90,7 +90,7 @@ class SynologyChat: logger.error(f"SynologyChat发送消息错误:{str(msg_e)}") return False - def send_medias_msg(self, medias: List[MediaInfo], userid: str = "", title: str = "") -> Optional[bool]: + def send_medias_msg(self, medias: List[MediaInfo], userid: Optional[str] = None, title: Optional[str] = None) -> Optional[bool]: """ 发送列表类消息 """ @@ -135,7 +135,7 @@ class SynologyChat: return False def send_torrents_msg(self, torrents: List[Context], - userid: str = "", title: str = "", link: str = None) -> Optional[bool]: + userid: Optional[str] = None, title: Optional[str] = None, link: Optional[str] = None) -> Optional[bool]: """ 发送列表消息 """ diff --git a/app/modules/telegram/telegram.py b/app/modules/telegram/telegram.py index 734eda34..3c33e071 100644 --- a/app/modules/telegram/telegram.py +++ b/app/modules/telegram/telegram.py @@ -25,7 +25,7 @@ class Telegram: _event = Event() _bot: telebot.TeleBot = None - def __init__(self, TELEGRAM_TOKEN: str = None, TELEGRAM_CHAT_ID: str = None, **kwargs): + def __init__(self, TELEGRAM_TOKEN: Optional[str] = None, TELEGRAM_CHAT_ID: Optional[str] = None, **kwargs): """ 初始化参数 """ @@ -74,8 +74,8 @@ class Telegram: """ return self._bot is not None - def send_msg(self, title: str, text: str = "", image: str = "", - userid: str = "", link: str = None) -> Optional[bool]: + def send_msg(self, title: str, text: Optional[str] = None, image: Optional[str] = None, + userid: Optional[str] = None, link: Optional[str] = None) -> Optional[bool]: """ 发送Telegram消息 :param title: 消息标题 @@ -114,8 +114,8 @@ class Telegram: logger.error(f"发送消息失败:{msg_e}") return False - def send_medias_msg(self, medias: List[MediaInfo], userid: str = "", - title: str = "", link: str = None) -> Optional[bool]: + def send_medias_msg(self, medias: List[MediaInfo], userid: Optional[str] = None, + title: Optional[str] = None, link: Optional[str] = None) -> Optional[bool]: """ 发送媒体列表消息 """ @@ -157,7 +157,7 @@ class Telegram: return False def send_torrents_msg(self, torrents: List[Context], - userid: str = "", title: str = "", link: str = None) -> Optional[bool]: + userid: Optional[str] = None, title: Optional[str] = None, link: Optional[str] = None) -> Optional[bool]: """ 发送列表消息 """ @@ -202,7 +202,7 @@ class Telegram: return False @retry(Exception, logger=logger) - def __send_request(self, userid: str = None, image="", caption="") -> bool: + def __send_request(self, userid: Optional[str] = None, image="", caption="") -> bool: """ 向Telegram发送报文 """ diff --git a/app/modules/themoviedb/__init__.py b/app/modules/themoviedb/__init__.py index 3c8c782c..00711acb 100644 --- a/app/modules/themoviedb/__init__.py +++ b/app/modules/themoviedb/__init__.py @@ -84,8 +84,8 @@ class TheMovieDbModule(_ModuleBase): def recognize_media(self, meta: MetaBase = None, mtype: MediaType = None, - tmdbid: int = None, - cache: bool = True, + tmdbid: Optional[int] = None, + cache: Optional[bool] = True, **kwargs) -> Optional[MediaInfo]: """ 识别媒体信息 @@ -219,7 +219,7 @@ class TheMovieDbModule(_ModuleBase): return None def match_tmdbinfo(self, name: str, mtype: MediaType = None, - year: str = None, season: int = None) -> dict: + year: Optional[str] = None, season: Optional[int] = None) -> dict: """ 搜索和匹配TMDB信息 :param name: 名称 @@ -239,7 +239,7 @@ class TheMovieDbModule(_ModuleBase): tmdbid=info.get("id")) return info - def tmdb_info(self, tmdbid: int, mtype: MediaType, season: int = None) -> Optional[dict]: + def tmdb_info(self, tmdbid: int, mtype: MediaType, season: Optional[int] = None) -> Optional[dict]: """ 获取TMDB信息 :param tmdbid: int @@ -334,7 +334,7 @@ class TheMovieDbModule(_ModuleBase): return [] def metadata_nfo(self, meta: MetaBase, mediainfo: MediaInfo, - season: int = None, episode: int = None) -> Optional[str]: + season: Optional[int] = None, episode: Optional[int] = None) -> Optional[str]: """ 获取NFO文件内容文本 :param meta: 元数据 @@ -346,7 +346,7 @@ class TheMovieDbModule(_ModuleBase): return None return self.scraper.get_metadata_nfo(meta=meta, mediainfo=mediainfo, season=season, episode=episode) - def metadata_img(self, mediainfo: MediaInfo, season: int = None, episode: int = None) -> Optional[dict]: + def metadata_img(self, mediainfo: MediaInfo, season: Optional[int] = None, episode: Optional[int] = None) -> Optional[dict]: """ 获取图片名称和url :param mediainfo: 媒体信息 @@ -365,7 +365,7 @@ class TheMovieDbModule(_ModuleBase): vote_average: float, vote_count: int, release_date: str, - page: int = 1) -> Optional[List[MediaInfo]]: + page: Optional[int] = 1) -> Optional[List[MediaInfo]]: """ :param mtype: 媒体类型 :param sort_by: 排序方式 @@ -409,7 +409,7 @@ class TheMovieDbModule(_ModuleBase): return [MediaInfo(tmdb_info=info) for info in infos] return [] - def tmdb_trending(self, page: int = 1) -> List[MediaInfo]: + def tmdb_trending(self, page: Optional[int] = 1) -> List[MediaInfo]: """ TMDB流行趋势 :param page: 第几页 @@ -493,8 +493,8 @@ class TheMovieDbModule(_ModuleBase): return mediainfo def obtain_specific_image(self, mediaid: Union[str, int], mtype: MediaType, - image_type: MediaImageType, image_prefix: str = "w500", - season: int = None, episode: int = None) -> Optional[str]: + image_type: MediaImageType, image_prefix: Optional[str] = "w500", + season: Optional[int] = None, episode: Optional[int] = None) -> Optional[str]: """ 获取指定媒体信息图片,返回图片地址 :param mediaid: 媒体ID @@ -566,7 +566,7 @@ class TheMovieDbModule(_ModuleBase): return [MediaInfo(tmdb_info=info) for info in recommend] return [] - def tmdb_movie_credits(self, tmdbid: int, page: int = 1) -> List[schemas.MediaPerson]: + def tmdb_movie_credits(self, tmdbid: int, page: Optional[int] = 1) -> List[schemas.MediaPerson]: """ 根据TMDBID查询电影演职员表 :param tmdbid: TMDBID @@ -577,7 +577,7 @@ class TheMovieDbModule(_ModuleBase): return [schemas.MediaPerson(source="themoviedb", **info) for info in credit_infos] return [] - def tmdb_tv_credits(self, tmdbid: int, page: int = 1) -> List[schemas.MediaPerson]: + def tmdb_tv_credits(self, tmdbid: int, page: Optional[int] = 1) -> List[schemas.MediaPerson]: """ 根据TMDBID查询电视剧演职员表 :param tmdbid: TMDBID @@ -598,7 +598,7 @@ class TheMovieDbModule(_ModuleBase): return schemas.MediaPerson(source="themoviedb", **detail) return schemas.MediaPerson() - def tmdb_person_credits(self, person_id: int, page: int = 1) -> List[MediaInfo]: + def tmdb_person_credits(self, person_id: int, page: Optional[int] = 1) -> List[MediaInfo]: """ 根据TMDBID查询人物参演作品 :param person_id: 人物ID diff --git a/app/modules/themoviedb/scraper.py b/app/modules/themoviedb/scraper.py index d0535375..afe82482 100644 --- a/app/modules/themoviedb/scraper.py +++ b/app/modules/themoviedb/scraper.py @@ -18,7 +18,7 @@ class TmdbScraper: self.tmdb = tmdb def get_metadata_nfo(self, meta: MetaBase, mediainfo: MediaInfo, - season: int = None, episode: int = None) -> Optional[str]: + season: Optional[int] = None, episode: Optional[int] = None) -> Optional[str]: """ 获取NFO文件内容文本 :param meta: 元数据 @@ -49,7 +49,7 @@ class TmdbScraper: return None - def get_metadata_img(self, mediainfo: MediaInfo, season: int = None, episode: int = None) -> dict: + def get_metadata_img(self, mediainfo: MediaInfo, season: Optional[int] = None, episode: Optional[int] = None) -> dict: """ 获取图片名称和url :param mediainfo: 媒体信息 diff --git a/app/modules/themoviedb/tmdbapi.py b/app/modules/themoviedb/tmdbapi.py index 7ecda58a..5ac62ae2 100644 --- a/app/modules/themoviedb/tmdbapi.py +++ b/app/modules/themoviedb/tmdbapi.py @@ -41,8 +41,8 @@ class TmdbApi: self.search = Search() self.movie = Movie() self.tv = TV() - self.season = Season() - self.episode = Episode() + self.season_obj = Season() + self.episode_obj = Episode() self.discover = Discover() self.trending = Trending() self.person = Person() @@ -185,9 +185,9 @@ class TmdbApi: def match(self, name: str, mtype: MediaType, - year: str = None, - season_year: str = None, - season_number: int = None) -> Optional[dict]: + year: Optional[str] = None, + season_year: Optional[str] = None, + season_number: Optional[int] = None) -> Optional[dict]: """ 搜索tmdb中的媒体信息,匹配返回一条尽可能正确的信息 :param name: 检索的名称 @@ -732,7 +732,7 @@ class TmdbApi: 更新TMDB信息中的其它语种名称 """ - def __get_tmdb_lang_title(tmdbinfo: dict, lang: str = "US") -> Optional[str]: + def __get_tmdb_lang_title(tmdbinfo: dict, lang: Optional[str] = "US") -> Optional[str]: """ 从译名中获取其它语种标题 """ @@ -767,7 +767,7 @@ class TmdbApi: def __get_movie_detail(self, tmdbid: int, - append_to_response: str = "images," + append_to_response: Optional[str] = "images," "credits," "alternative_titles," "translations," @@ -880,7 +880,7 @@ class TmdbApi: def __get_tv_detail(self, tmdbid: int, - append_to_response: str = "images," + append_to_response: Optional[str] = "images," "credits," "alternative_titles," "translations," @@ -1126,11 +1126,11 @@ class TmdbApi: "season_number": 1 } """ - if not self.season: + if not self.season_obj: return {} try: logger.debug("正在查询TMDB电视剧:%s,季:%s ..." % (tmdbid, season)) - tmdbinfo = self.season.details(tv_id=tmdbid, season_num=season) + tmdbinfo = self.season_obj.details(tv_id=tmdbid, season_num=season) return tmdbinfo or {} except Exception as e: logger.error(str(e)) @@ -1143,11 +1143,11 @@ class TmdbApi: :param season: 季,数字 :param episode: 集,数字 """ - if not self.episode: + if not self.episode_obj: return {} try: logger.debug("正在查询TMDB集详情:%s,季:%s,集:%s ..." % (tmdbid, season, episode)) - tmdbinfo = self.episode.details(tv_id=tmdbid, season_num=season, episode_num=episode) + tmdbinfo = self.episode_obj.details(tv_id=tmdbid, season_num=season, episode_num=episode) return tmdbinfo or {} except Exception as e: logger.error(str(e)) @@ -1191,7 +1191,7 @@ class TmdbApi: logger.error(str(e)) return [] - def discover_trending(self, page: int = 1) -> List[dict]: + def discover_trending(self, page: Optional[int] = 1) -> List[dict]: """ 流行趋势 """ @@ -1282,7 +1282,7 @@ class TmdbApi: logger.error(str(e)) return [] - def get_movie_credits(self, tmdbid: int, page: int = 1, count: int = 24) -> List[dict]: + def get_movie_credits(self, tmdbid: int, page: Optional[int] = 1, count: Optional[int] = 24) -> List[dict]: """ 获取电影的演职员列表 """ @@ -1299,7 +1299,7 @@ class TmdbApi: logger.error(str(e)) return [] - def get_tv_credits(self, tmdbid: int, page: int = 1, count: int = 24) -> List[dict]: + def get_tv_credits(self, tmdbid: int, page: Optional[int] = 1, count: Optional[int] = 24) -> List[dict]: """ 获取电视剧的演职员列表 """ @@ -1349,7 +1349,7 @@ class TmdbApi: logger.error(str(e)) return {} - def get_person_credits(self, person_id: int, page: int = 1, count: int = 24) -> List[dict]: + def get_person_credits(self, person_id: int, page: Optional[int] = 1, count: Optional[int] = 24) -> List[dict]: """ 获取人物参演作品 """ diff --git a/app/modules/transmission/__init__.py b/app/modules/transmission/__init__.py index 3d2ed3f4..47ae8d79 100644 --- a/app/modules/transmission/__init__.py +++ b/app/modules/transmission/__init__.py @@ -79,8 +79,8 @@ class TransmissionModule(_ModuleBase, _DownloaderBase[Transmission]): server.reconnect() def download(self, content: Union[Path, str], download_dir: Path, cookie: str, - episodes: Set[int] = None, category: str = None, label: str = None, - downloader: str = None) -> Optional[Tuple[Optional[str], Optional[str], Optional[str], str]]: + episodes: Set[int] = None, category: Optional[str] = None, label: Optional[str] = None, + downloader: Optional[str] = None) -> Optional[Tuple[Optional[str], Optional[str], Optional[str], str]]: """ 根据种子文件,选择并添加下载任务 :param content: 种子文件地址或者磁力链接 @@ -200,7 +200,7 @@ class TransmissionModule(_ModuleBase, _DownloaderBase[Transmission]): def list_torrents(self, status: TorrentStatus = None, hashs: Union[list, str] = None, - downloader: str = None + downloader: Optional[str] = None ) -> Optional[List[Union[TransferTorrent, DownloadingTorrent]]]: """ 获取下载器种子列表 @@ -280,7 +280,7 @@ class TransmissionModule(_ModuleBase, _DownloaderBase[Transmission]): return None return ret_torrents - def transfer_completed(self, hashs: str, downloader: str = None) -> None: + def transfer_completed(self, hashs: str, downloader: Optional[str] = None) -> None: """ 转移完成后的处理 :param hashs: 种子Hash @@ -299,8 +299,8 @@ class TransmissionModule(_ModuleBase, _DownloaderBase[Transmission]): tags = ['已整理'] server.set_torrent_tag(ids=hashs, tags=tags) - def remove_torrents(self, hashs: Union[str, list], delete_file: bool = True, - downloader: str = None) -> Optional[bool]: + def remove_torrents(self, hashs: Union[str, list], delete_file: Optional[bool] = True, + downloader: Optional[str] = None) -> Optional[bool]: """ 删除下载器种子 :param hashs: 种子Hash @@ -315,7 +315,7 @@ class TransmissionModule(_ModuleBase, _DownloaderBase[Transmission]): return server.delete_torrents(delete_file=delete_file, ids=hashs) def start_torrents(self, hashs: Union[list, str], - downloader: str = None) -> Optional[bool]: + downloader: Optional[str] = None) -> Optional[bool]: """ 开始下载 :param hashs: 种子Hash @@ -329,7 +329,7 @@ class TransmissionModule(_ModuleBase, _DownloaderBase[Transmission]): return server.start_torrents(ids=hashs) def stop_torrents(self, hashs: Union[list, str], - downloader: str = None) -> Optional[bool]: + downloader: Optional[str] = None) -> Optional[bool]: """ 停止下载 :param hashs: 种子Hash @@ -342,7 +342,7 @@ class TransmissionModule(_ModuleBase, _DownloaderBase[Transmission]): return None return server.start_torrents(ids=hashs) - def torrent_files(self, tid: str, downloader: str = None) -> Optional[List[File]]: + def torrent_files(self, tid: str, downloader: Optional[str] = None) -> Optional[List[File]]: """ 获取种子文件列表 """ @@ -352,7 +352,7 @@ class TransmissionModule(_ModuleBase, _DownloaderBase[Transmission]): return None return server.get_files(tid=tid) - def downloader_info(self, downloader: str = None) -> Optional[List[schemas.DownloaderInfo]]: + def downloader_info(self, downloader: Optional[str] = None) -> Optional[List[schemas.DownloaderInfo]]: """ 下载器信息 """ diff --git a/app/modules/transmission/transmission.py b/app/modules/transmission/transmission.py index a7075f6a..e9f059d6 100644 --- a/app/modules/transmission/transmission.py +++ b/app/modules/transmission/transmission.py @@ -10,10 +10,10 @@ from app.utils.url import UrlUtils class Transmission: _protocol: Literal["http", "https"] = "http" - _host: str = None - _port: int = None - _username: str = None - _password: str = None + _host: Optional[str] = None + _port: Optional[int] = None + _username: Optional[str] = None + _password: Optional[str] = None trc: Optional[Client] = None @@ -24,7 +24,8 @@ class Transmission: "peersGettingFromUs", "peersSendingToUs", "uploadRatio", "uploadedEver", "downloadedEver", "downloadDir", "error", "errorString", "doneDate", "queuePosition", "activityDate", "trackers"] - def __init__(self, host: str = None, port: int = None, username: str = None, password: str = None, **kwargs): + def __init__(self, host: Optional[str] = None, port: Optional[int] = None, + username: Optional[str] = None, password: Optional[str] = None, **kwargs): """ 若不设置参数,则创建配置文件设置的下载器 """ @@ -173,8 +174,8 @@ class Transmission: return [] def add_torrent(self, content: Union[str, bytes], - is_paused: bool = False, - download_dir: str = None, + is_paused: Optional[bool] = False, + download_dir: Optional[str] = None, labels=None, cookie=None) -> Optional[Torrent]: """ diff --git a/app/modules/vocechat/vocechat.py b/app/modules/vocechat/vocechat.py index 331b5c50..10594592 100644 --- a/app/modules/vocechat/vocechat.py +++ b/app/modules/vocechat/vocechat.py @@ -22,7 +22,7 @@ class VoceChat: # 请求对象 _client = None - def __init__(self, VOCECHAT_HOST: str = None, VOCECHAT_API_KEY: str = None, VOCECHAT_CHANNEL_ID: str = None, **kwargs): + def __init__(self, VOCECHAT_HOST: Optional[str] = None, VOCECHAT_API_KEY: Optional[str] = None, VOCECHAT_CHANNEL_ID: Optional[str] = None, **kwargs): """ 初始化 """ @@ -60,8 +60,8 @@ class VoceChat: if result and result.status_code == 200: return result.json() - def send_msg(self, title: str, text: str = "", - userid: str = None, link: str = None) -> Optional[bool]: + def send_msg(self, title: str, text: Optional[str] = None, + userid: Optional[str] = None, link: Optional[str] = None) -> Optional[bool]: """ 微信消息发送入口,支持文本、图片、链接跳转、指定发送对象 :param title: 消息标题 @@ -98,7 +98,7 @@ class VoceChat: return False def send_medias_msg(self, title: str, medias: List[MediaInfo], - userid: str = "", link: str = None) -> Optional[bool]: + userid: Optional[str] = None, link: Optional[str] = None) -> Optional[bool]: """ 发送列表类消息 """ @@ -138,7 +138,9 @@ class VoceChat: return False def send_torrents_msg(self, torrents: List[Context], - userid: str = "", title: str = "", link: str = None) -> Optional[bool]: + userid: Optional[str] = None, + title: Optional[str] = None, + link: Optional[str] = None) -> Optional[bool]: """ 发送列表消息 """ diff --git a/app/modules/wechat/wechat.py b/app/modules/wechat/wechat.py index f4b671aa..72ab8287 100644 --- a/app/modules/wechat/wechat.py +++ b/app/modules/wechat/wechat.py @@ -40,8 +40,8 @@ class WeChat: # 企业微信删除菜单URL _delete_menu_url = "cgi-bin/menu/delete?access_token={access_token}&agentid={agentid}" - def __init__(self, WECHAT_CORPID: str = None, WECHAT_APP_SECRET: str = None, - WECHAT_APP_ID: str = None, WECHAT_PROXY: str = None, **kwargs): + def __init__(self, WECHAT_CORPID: Optional[str] = None, WECHAT_APP_SECRET: Optional[str] = None, + WECHAT_APP_ID: Optional[str] = None, WECHAT_PROXY: Optional[str] = None, **kwargs): """ 初始化 """ @@ -159,8 +159,8 @@ class WeChat: return content_chunks - def __send_message(self, title: str, text: str = None, - userid: str = None, link: str = None) -> bool: + def __send_message(self, title: str, text: Optional[str] = None, + userid: Optional[str] = None, link: Optional[str] = None) -> bool: """ 发送文本消息 :param title: 消息标题 @@ -206,7 +206,7 @@ class WeChat: return True def __send_image_message(self, title: str, text: str, image_url: str, - userid: str = None, link: str = None) -> Optional[bool]: + userid: Optional[str] = None, link: Optional[str] = None) -> Optional[bool]: """ 发送图文消息 :param title: 消息标题 @@ -241,8 +241,8 @@ class WeChat: logger.error(f"发送图文消息失败:{e}") return False - def send_msg(self, title: str, text: str = "", image: str = "", - userid: str = None, link: str = None) -> Optional[bool]: + def send_msg(self, title: str, text: Optional[str] = None, image: Optional[str] = None, + userid: Optional[str] = None, link: Optional[str] = None) -> Optional[bool]: """ 微信消息发送入口,支持文本、图片、链接跳转、指定发送对象 :param title: 消息标题 @@ -267,7 +267,7 @@ class WeChat: logger.error(f"发送消息失败:{e}") return False - def send_medias_msg(self, medias: List[MediaInfo], userid: str = "") -> Optional[bool]: + def send_medias_msg(self, medias: List[MediaInfo], userid: Optional[str] = None) -> Optional[bool]: """ 发送列表类消息 """ @@ -307,7 +307,7 @@ class WeChat: return False def send_torrents_msg(self, torrents: List[Context], - userid: str = "", title: str = "", link: str = None) -> Optional[bool]: + userid: Optional[str] = None, title: Optional[str] = None, link: Optional[str] = None) -> Optional[bool]: """ 发送列表消息 """ @@ -416,7 +416,7 @@ class WeChat: { "type":"view", "name":"搜索", - "url":"http://www.soso.com/" + "url":"https://www.soso.com/" }, { "type":"click", diff --git a/app/plugins/__init__.py b/app/plugins/__init__.py index 973bafdc..b6caa7b9 100644 --- a/app/plugins/__init__.py +++ b/app/plugins/__init__.py @@ -29,11 +29,11 @@ class _PluginBase(metaclass=ABCMeta): - get_data_path() 获取插件数据保存目录 """ # 插件名称 - plugin_name: str = "" + plugin_name: Optional[str] = "" # 插件描述 - plugin_desc: str = "" + plugin_desc: Optional[str] = "" # 插件顺序 - plugin_order: int = 9999 + plugin_order: Optional[int] = 9999 def __init__(self): # 插件数据 @@ -162,7 +162,7 @@ class _PluginBase(metaclass=ABCMeta): """ pass - def update_config(self, config: dict, plugin_id: str = None) -> bool: + def update_config(self, config: dict, plugin_id: Optional[str] = None) -> bool: """ 更新配置信息 :param config: 配置信息字典 @@ -172,7 +172,7 @@ class _PluginBase(metaclass=ABCMeta): plugin_id = self.__class__.__name__ return self.systemconfig.set(f"plugin.{plugin_id}", config) - def get_config(self, plugin_id: str = None) -> Any: + def get_config(self, plugin_id: Optional[str] = None) -> Any: """ 获取配置信息 :param plugin_id: 插件ID @@ -181,7 +181,7 @@ class _PluginBase(metaclass=ABCMeta): plugin_id = self.__class__.__name__ return self.systemconfig.get(f"plugin.{plugin_id}") - def get_data_path(self, plugin_id: str = None) -> Path: + def get_data_path(self, plugin_id: Optional[str] = None) -> Path: """ 获取插件数据保存目录 """ @@ -192,7 +192,7 @@ class _PluginBase(metaclass=ABCMeta): data_path.mkdir(parents=True) return data_path - def save_data(self, key: str, value: Any, plugin_id: str = None): + def save_data(self, key: str, value: Any, plugin_id: Optional[str] = None): """ 保存插件数据 :param key: 数据key @@ -203,7 +203,7 @@ class _PluginBase(metaclass=ABCMeta): plugin_id = self.__class__.__name__ self.plugindata.save(plugin_id, key, value) - def get_data(self, key: str = None, plugin_id: str = None) -> Any: + def get_data(self, key: Optional[str] = None, plugin_id: Optional[str] = None) -> Any: """ 获取插件数据 :param key: 数据key @@ -213,7 +213,7 @@ class _PluginBase(metaclass=ABCMeta): plugin_id = self.__class__.__name__ return self.plugindata.get_data(plugin_id, key) - def del_data(self, key: str, plugin_id: str = None) -> Any: + def del_data(self, key: str, plugin_id: Optional[str] = None) -> Any: """ 删除插件数据 :param key: 数据key @@ -223,8 +223,9 @@ class _PluginBase(metaclass=ABCMeta): plugin_id = self.__class__.__name__ return self.plugindata.del_data(plugin_id, key) - def post_message(self, channel: MessageChannel = None, mtype: NotificationType = None, title: str = None, - text: str = None, image: str = None, link: str = None, userid: str = None, username: str = None, + def post_message(self, channel: MessageChannel = None, mtype: NotificationType = None, title: Optional[str] = None, + text: Optional[str] = None, image: Optional[str] = None, link: Optional[str] = None, + userid: Optional[str] = None, username: Optional[str] = None, **kwargs): """ 发送消息 diff --git a/app/scheduler.py b/app/scheduler.py index b87a6059..86523de2 100644 --- a/app/scheduler.py +++ b/app/scheduler.py @@ -1,7 +1,7 @@ import threading import traceback from datetime import datetime, timedelta -from typing import List +from typing import List, Optional import pytz from apscheduler.executors.pool import ThreadPoolExecutor @@ -449,7 +449,7 @@ class Scheduler(metaclass=Singleton): message=str(e), role="system") - def remove_plugin_job(self, pid: str, job_id: str = None): + def remove_plugin_job(self, pid: str, job_id: Optional[str] = None): """ 移除定时服务,可以是单个服务(包括默认服务)或整个插件的所有服务 :param pid: 插件 ID