mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-05-06 20:42:43 +08:00
fix ide warnings
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import threading
|
||||
from typing import List, Union, Optional, Generator
|
||||
from typing import List, Union, Optional, Generator, Any
|
||||
|
||||
from app.chain import ChainBase
|
||||
from app.core.cache import cached
|
||||
@@ -27,8 +27,8 @@ class MediaServerChain(ChainBase):
|
||||
"""
|
||||
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) \
|
||||
-> Optional[Generator]:
|
||||
def items(self, server: str, library_id: Union[str, int],
|
||||
start_index: int = 0, limit: Optional[int] = -1) -> Generator[Any, None, None]:
|
||||
"""
|
||||
获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据
|
||||
|
||||
|
||||
@@ -1262,7 +1262,7 @@ class SubscribeChain(ChainBase, metaclass=Singleton):
|
||||
订阅相关的下载和文件信息
|
||||
"""
|
||||
if not subscribe:
|
||||
return
|
||||
return None
|
||||
|
||||
# 返回订阅数据
|
||||
subscribe_info = schemas.SubscrbieInfo()
|
||||
|
||||
@@ -606,7 +606,7 @@ class TransferChain(ChainBase, metaclass=Singleton):
|
||||
logger.error(f"整理队列处理出现错误:{e} - {traceback.format_exc()}")
|
||||
|
||||
def __handle_transfer(self, task: TransferTask,
|
||||
callback: Optional[Callable] = None) -> Tuple[bool, str]:
|
||||
callback: Optional[Callable] = None) -> Optional[Tuple[bool, str]]:
|
||||
"""
|
||||
处理整理任务
|
||||
"""
|
||||
|
||||
@@ -121,7 +121,7 @@ class ModuleManager(metaclass=Singleton):
|
||||
获取实现了同一方法的模块列表
|
||||
"""
|
||||
if not self._running_modules:
|
||||
return []
|
||||
return
|
||||
for _, module in self._running_modules.items():
|
||||
if hasattr(module, method) \
|
||||
and ObjectUtils.check_method(getattr(module, method)):
|
||||
@@ -132,7 +132,7 @@ class ModuleManager(metaclass=Singleton):
|
||||
获取指定类型的模块列表
|
||||
"""
|
||||
if not self._running_modules:
|
||||
return []
|
||||
return
|
||||
for _, module in self._running_modules.items():
|
||||
if hasattr(module, 'get_type') \
|
||||
and module.get_type() == module_type:
|
||||
@@ -143,7 +143,7 @@ class ModuleManager(metaclass=Singleton):
|
||||
获取指定子类型的模块
|
||||
"""
|
||||
if not self._running_modules:
|
||||
return []
|
||||
return
|
||||
for _, module in self._running_modules.items():
|
||||
if hasattr(module, 'get_subtype') \
|
||||
and module.get_subtype() == module_subtype:
|
||||
|
||||
@@ -4,7 +4,8 @@ import hmac
|
||||
import json
|
||||
import os
|
||||
import traceback
|
||||
from datetime import datetime, timedelta
|
||||
import datetime
|
||||
from datetime import timedelta
|
||||
from typing import Any, Union, Annotated, Optional
|
||||
|
||||
import jwt
|
||||
@@ -69,13 +70,13 @@ def create_access_token(
|
||||
if expires_delta is not None:
|
||||
if expires_delta.total_seconds() <= 0:
|
||||
raise ValueError("过期时间必须为正数")
|
||||
expire = datetime.utcnow() + expires_delta
|
||||
expire = datetime.datetime.now(datetime.UTC) + expires_delta
|
||||
else:
|
||||
expire = datetime.utcnow() + default_expire
|
||||
expire = datetime.datetime.now(datetime.UTC) + default_expire
|
||||
|
||||
to_encode = {
|
||||
"exp": expire,
|
||||
"iat": datetime.utcnow(),
|
||||
"iat": datetime.datetime.now(datetime.UTC),
|
||||
"sub": str(userid),
|
||||
"username": username,
|
||||
"super_user": super_user,
|
||||
@@ -102,7 +103,7 @@ def __set_or_refresh_resource_token_cookie(request: Request, response: Response,
|
||||
decoded_token = jwt.decode(resource_token, settings.RESOURCE_SECRET_KEY, algorithms=[ALGORITHM])
|
||||
exp = decoded_token.get("exp")
|
||||
if exp:
|
||||
remaining_time = datetime.utcfromtimestamp(exp) - datetime.utcnow()
|
||||
remaining_time = datetime.datetime.fromtimestamp(exp) - datetime.datetime.now(datetime.UTC)
|
||||
# 根据剩余时长提前刷新令牌
|
||||
if remaining_time < timedelta(seconds=(settings.RESOURCE_ACCESS_TOKEN_EXPIRE_SECONDS / 3)):
|
||||
raise jwt.ExpiredSignatureError
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import Callable, Any
|
||||
from typing import Callable, Any, Optional
|
||||
|
||||
from playwright.sync_api import sync_playwright, Page
|
||||
from cf_clearance import sync_cf_retry, sync_stealth
|
||||
@@ -61,7 +61,7 @@ class PlaywrightHelper:
|
||||
ua: str = None,
|
||||
proxies: dict = None,
|
||||
headless: bool = False,
|
||||
timeout: int = 20) -> str:
|
||||
timeout: int = 20) -> Optional[str]:
|
||||
"""
|
||||
获取网页源码
|
||||
:param url: 网页地址
|
||||
|
||||
@@ -3,7 +3,7 @@ import re
|
||||
import traceback
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import List, Optional, Union, Dict, Generator, Tuple
|
||||
from typing import List, Optional, Union, Dict, Generator, Tuple, Any
|
||||
|
||||
from requests import Response
|
||||
|
||||
@@ -13,6 +13,7 @@ from app.log import logger
|
||||
from app.schemas.types import MediaType
|
||||
from app.utils.http import RequestUtils
|
||||
from app.utils.url import UrlUtils
|
||||
from schemas import MediaServerItem
|
||||
|
||||
|
||||
class Emby:
|
||||
@@ -545,7 +546,7 @@ class Emby:
|
||||
return False
|
||||
return False
|
||||
|
||||
def refresh_library_by_items(self, items: List[schemas.RefreshMediaItem]) -> bool:
|
||||
def refresh_library_by_items(self, items: List[schemas.RefreshMediaItem]) -> Optional[bool]:
|
||||
"""
|
||||
按类型、名称、年份来刷新媒体库
|
||||
:param items: 已识别的需要刷新媒体库的媒体信息列表
|
||||
@@ -668,8 +669,8 @@ 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, limit: Optional[int] = -1) \
|
||||
-> Optional[Generator]:
|
||||
def get_items(self, parent: Union[str, int], start_index: int = 0,
|
||||
limit: Optional[int] = -1) -> Generator[MediaServerItem | None | Any, Any, None]:
|
||||
"""
|
||||
获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据
|
||||
|
||||
|
||||
@@ -201,12 +201,12 @@ class Alist(StorageBase, metaclass=Singleton):
|
||||
|
||||
if resp is None:
|
||||
logging.warning(f"请求获取目录 {fileitem.path} 的文件列表失败,无法连接alist服务")
|
||||
return
|
||||
return None
|
||||
if resp.status_code != 200:
|
||||
logging.warning(
|
||||
f"请求获取目录 {fileitem.path} 的文件列表失败,状态码:{resp.status_code}"
|
||||
)
|
||||
return
|
||||
return None
|
||||
|
||||
result = resp.json()
|
||||
|
||||
@@ -214,7 +214,7 @@ class Alist(StorageBase, metaclass=Singleton):
|
||||
logging.warning(
|
||||
f'获取目录 {fileitem.path} 的文件列表失败,错误信息:{result["message"]}'
|
||||
)
|
||||
return
|
||||
return None
|
||||
|
||||
return [
|
||||
schemas.FileItem(
|
||||
@@ -259,15 +259,15 @@ class Alist(StorageBase, metaclass=Singleton):
|
||||
"""
|
||||
if resp is None:
|
||||
logging.warning(f"请求创建目录 {path} 失败,无法连接alist服务")
|
||||
return
|
||||
return None
|
||||
if resp.status_code != 200:
|
||||
logging.warning(f"请求创建目录 {path} 失败,状态码:{resp.status_code}")
|
||||
return
|
||||
return None
|
||||
|
||||
result = resp.json()
|
||||
if result["code"] != 200:
|
||||
logging.warning(f'创建目录 {path} 失败,错误信息:{result["message"]}')
|
||||
return
|
||||
return None
|
||||
|
||||
return self.get_item(path)
|
||||
|
||||
@@ -349,15 +349,15 @@ class Alist(StorageBase, metaclass=Singleton):
|
||||
"""
|
||||
if resp is None:
|
||||
logging.warning(f"请求获取文件 {path} 失败,无法连接alist服务")
|
||||
return
|
||||
return None
|
||||
if resp.status_code != 200:
|
||||
logging.warning(f"请求获取文件 {path} 失败,状态码:{resp.status_code}")
|
||||
return
|
||||
return None
|
||||
|
||||
result = resp.json()
|
||||
if result["code"] != 200:
|
||||
logging.debug(f'获取文件 {path} 失败,错误信息:{result["message"]}')
|
||||
return
|
||||
return None
|
||||
|
||||
return schemas.FileItem(
|
||||
storage=self.schema.value,
|
||||
@@ -513,15 +513,15 @@ class Alist(StorageBase, metaclass=Singleton):
|
||||
"""
|
||||
if not resp:
|
||||
logging.warning(f"请求获取文件 {path} 失败,无法连接alist服务")
|
||||
return
|
||||
return None
|
||||
if resp.status_code != 200:
|
||||
logging.warning(f"请求获取文件 {path} 失败,状态码:{resp.status_code}")
|
||||
return
|
||||
return None
|
||||
|
||||
result = resp.json()
|
||||
if result["code"] != 200:
|
||||
logging.warning(f'获取文件 {path} 失败,错误信息:{result["message"]}')
|
||||
return
|
||||
return None
|
||||
|
||||
if result["data"]["raw_url"]:
|
||||
download_url = result["data"]["raw_url"]
|
||||
@@ -569,7 +569,7 @@ class Alist(StorageBase, metaclass=Singleton):
|
||||
|
||||
if resp.status_code != 200:
|
||||
logging.warning(f"请求上传文件 {path} 失败,状态码:{resp.status_code}")
|
||||
return
|
||||
return None
|
||||
|
||||
new_item = self.get_item(Path(fileitem.path) / path.name)
|
||||
if new_item and new_name and new_name != path.name:
|
||||
|
||||
@@ -259,7 +259,7 @@ class FilterModule(_ModuleBase):
|
||||
|
||||
return None if not matched else torrent
|
||||
|
||||
def __match_group(self, torrent: TorrentInfo, rule_group: Union[list, str]) -> bool:
|
||||
def __match_group(self, torrent: TorrentInfo, rule_group: Union[list, str]) -> Optional[bool]:
|
||||
"""
|
||||
判断种子是否匹配规则组
|
||||
"""
|
||||
|
||||
@@ -54,7 +54,7 @@ class IptSiteUserInfo(SiteParserBase):
|
||||
def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: bool = False) -> Optional[str]:
|
||||
html = etree.HTML(html_text)
|
||||
if not StringUtils.is_valid_html_element(html):
|
||||
return
|
||||
return None
|
||||
# seeding start
|
||||
seeding_end_pos = 3
|
||||
if html.xpath('//tr/td[text() = "Leechers"]'):
|
||||
|
||||
@@ -65,7 +65,7 @@ class TNodeSiteUserInfo(SiteParserBase):
|
||||
"""
|
||||
seeding_info = json.loads(html_text)
|
||||
if seeding_info.get("status") != 200:
|
||||
return
|
||||
return None
|
||||
|
||||
torrents = seeding_info.get("data", {}).get("torrents", [])
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
from typing import List, Union, Optional, Dict, Generator, Tuple
|
||||
from typing import List, Union, Optional, Dict, Generator, Tuple, Any
|
||||
|
||||
from requests import Response
|
||||
|
||||
@@ -10,6 +10,7 @@ from app.log import logger
|
||||
from app.schemas import MediaType
|
||||
from app.utils.http import RequestUtils
|
||||
from app.utils.url import UrlUtils
|
||||
from schemas import MediaServerItem
|
||||
|
||||
|
||||
class Jellyfin:
|
||||
@@ -548,7 +549,7 @@ class Jellyfin:
|
||||
logger.error(f"连接Items/Id/Ancestors出错:" + str(e))
|
||||
return None
|
||||
|
||||
def refresh_root_library(self) -> bool:
|
||||
def refresh_root_library(self) -> Optional[bool]:
|
||||
"""
|
||||
通知Jellyfin刷新整个媒体库
|
||||
"""
|
||||
@@ -762,7 +763,7 @@ class Jellyfin:
|
||||
return None
|
||||
|
||||
def get_items(self, parent: Union[str, int], start_index: int = 0, limit: Optional[int] = -1) \
|
||||
-> Optional[Generator]:
|
||||
-> Generator[MediaServerItem | None | Any, Any, None]:
|
||||
"""
|
||||
获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ from app.log import logger
|
||||
from app.schemas import MediaType
|
||||
from app.utils.http import RequestUtils
|
||||
from app.utils.url import UrlUtils
|
||||
from schemas import MediaServerItem
|
||||
|
||||
|
||||
class Plex:
|
||||
@@ -367,7 +368,7 @@ class Plex:
|
||||
return False
|
||||
return self._plex.library.update()
|
||||
|
||||
def refresh_library_by_items(self, items: List[schemas.RefreshMediaItem]) -> bool:
|
||||
def refresh_library_by_items(self, items: List[schemas.RefreshMediaItem]) -> Optional[bool]:
|
||||
"""
|
||||
按路径刷新媒体库 item: target_path
|
||||
"""
|
||||
@@ -512,7 +513,7 @@ class Plex:
|
||||
)
|
||||
|
||||
def get_items(self, parent: Union[str, int], start_index: int = 0, limit: Optional[int] = -1) \
|
||||
-> Optional[Generator]:
|
||||
-> Generator[MediaServerItem | None, Any, None]:
|
||||
"""
|
||||
获取媒体服务器项目列表,支持分页和不分页逻辑,默认不分页获取所有数据
|
||||
|
||||
@@ -855,7 +856,7 @@ class Plex:
|
||||
:param kwargs: 其他请求参数,如headers, cookies, proxies等
|
||||
"""
|
||||
if not self._session:
|
||||
return
|
||||
return None
|
||||
try:
|
||||
url = UrlUtils.adapt_request_url(host=self._host, endpoint=endpoint)
|
||||
kwargs.setdefault("headers", self.__get_request_headers())
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import Optional, Dict, List, Union
|
||||
from typing import Optional, Dict, List, Union, Any
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
@@ -235,9 +235,9 @@ class Context(BaseModel):
|
||||
上下文
|
||||
"""
|
||||
# 元数据
|
||||
meta_info: Optional[MetaInfo] = None
|
||||
meta_info: Optional[Union[MetaInfo, Any]] = None
|
||||
# 媒体信息
|
||||
media_info: Optional[MediaInfo] = None
|
||||
media_info: Optional[Union[MediaInfo, Any]] = None
|
||||
# 种子信息
|
||||
torrent_info: Optional[TorrentInfo] = None
|
||||
|
||||
|
||||
@@ -42,43 +42,43 @@ class Action(BaseModel):
|
||||
"""
|
||||
动作信息
|
||||
"""
|
||||
id: Optional[str] = Field(None, description="动作ID")
|
||||
type: Optional[str] = Field(None, description="动作类型 (类名)")
|
||||
name: Optional[str] = Field(None, description="动作名称")
|
||||
description: Optional[str] = Field(None, description="动作描述")
|
||||
position: Optional[dict] = Field({}, description="位置")
|
||||
data: Optional[dict] = Field({}, description="参数")
|
||||
id: Optional[str] = Field(default=None, description="动作ID")
|
||||
type: Optional[str] = Field(default=None, description="动作类型 (类名)")
|
||||
name: Optional[str] = Field(default=None, description="动作名称")
|
||||
description: Optional[str] = Field(default=None, description="动作描述")
|
||||
position: Optional[dict] = Field(default={}, description="位置")
|
||||
data: Optional[dict] = Field(default={}, description="参数")
|
||||
|
||||
|
||||
class ActionExecution(BaseModel):
|
||||
"""
|
||||
动作执行情况
|
||||
"""
|
||||
action: Optional[str] = Field(None, description="当前动作(名称)")
|
||||
result: Optional[bool] = Field(None, description="执行结果")
|
||||
message: Optional[str] = Field(None, description="执行消息")
|
||||
action: Optional[str] = Field(default=None, description="当前动作(名称)")
|
||||
result: Optional[bool] = Field(default=None, description="执行结果")
|
||||
message: Optional[str] = Field(default=None, description="执行消息")
|
||||
|
||||
|
||||
class ActionContext(BaseModel):
|
||||
"""
|
||||
动作基础上下文,各动作通用数据
|
||||
"""
|
||||
content: Optional[str] = Field(None, description="文本类内容")
|
||||
torrents: Optional[List[Context]] = Field([], description="资源列表")
|
||||
medias: Optional[List[MediaInfo]] = Field([], description="媒体列表")
|
||||
fileitems: Optional[List[FileItem]] = Field([], description="文件列表")
|
||||
downloads: Optional[List[DownloadTask]] = Field([], description="下载任务列表")
|
||||
sites: Optional[List[Site]] = Field([], description="站点列表")
|
||||
subscribes: Optional[List[Subscribe]] = Field([], description="订阅列表")
|
||||
execute_history: Optional[List[ActionExecution]] = Field([], description="执行历史")
|
||||
progress: Optional[int] = Field(0, description="执行进度(%)")
|
||||
content: Optional[str] = Field(default=None, description="文本类内容")
|
||||
torrents: Optional[List[Context]] = Field(default=[], description="资源列表")
|
||||
medias: Optional[List[MediaInfo]] = Field(default=[], description="媒体列表")
|
||||
fileitems: Optional[List[FileItem]] = Field(default=[], description="文件列表")
|
||||
downloads: Optional[List[DownloadTask]] = Field(default=[], description="下载任务列表")
|
||||
sites: Optional[List[Site]] = Field(default=[], description="站点列表")
|
||||
subscribes: Optional[List[Subscribe]] = Field(default=[], description="订阅列表")
|
||||
execute_history: Optional[List[ActionExecution]] = Field(default=[], description="执行历史")
|
||||
progress: Optional[int] = Field(default=0, description="执行进度(%)")
|
||||
|
||||
|
||||
class ActionFlow(BaseModel):
|
||||
"""
|
||||
工作流流程
|
||||
"""
|
||||
id: Optional[str] = Field(None, description="流程ID")
|
||||
source: Optional[str] = Field(None, description="源动作")
|
||||
target: Optional[str] = Field(None, description="目标动作")
|
||||
animated: Optional[bool] = Field(True, description="是否动画流程")
|
||||
id: Optional[str] = Field(default=None, description="流程ID")
|
||||
source: Optional[str] = Field(default=None, description="源动作")
|
||||
target: Optional[str] = Field(default=None, description="目标动作")
|
||||
animated: Optional[bool] = Field(default=True, description="是否动画流程")
|
||||
|
||||
Reference in New Issue
Block a user