mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-06-01 05:31:14 +08:00
fix: clean typing issues and refresh runtime dependencies
Align endpoint/module type hints and config reload handling while updating base Python image and package pins to improve build/runtime compatibility. Made-with: Cursor
This commit is contained in:
@@ -5,15 +5,13 @@ from fastapi import APIRouter, Depends, Body
|
||||
from app import schemas
|
||||
from app.chain.download import DownloadChain
|
||||
from app.chain.media import MediaChain
|
||||
from app.core.config import settings
|
||||
from app.core.context import MediaInfo, Context, TorrentInfo
|
||||
from app.core.event import eventmanager
|
||||
from app.core.metainfo import MetaInfo
|
||||
from app.core.security import verify_token
|
||||
from app.db.models.user import User
|
||||
from app.db.systemconfig_oper import SystemConfigOper
|
||||
from app.db.user_oper import get_current_active_user
|
||||
from app.schemas.types import ChainEventType, SystemConfigKey
|
||||
from app.schemas.types import SystemConfigKey
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ from app.db.models.user import User
|
||||
from app.db.user_oper import get_current_active_superuser_async, \
|
||||
get_current_active_user_async, get_current_active_user
|
||||
from app.db.userconfig_oper import UserConfigOper
|
||||
from app.utils.otp import OtpUtils
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@@ -253,7 +253,6 @@ class MediaChain(ChainBase, ConfigReloadMixin, metaclass=Singleton):
|
||||
"""
|
||||
流式下载图片并保存到文件
|
||||
|
||||
:param storagechain: StorageChain实例
|
||||
:param fileitem: 关联的媒体文件项
|
||||
:param path: 图片文件路径
|
||||
:param url: 图片下载URL
|
||||
|
||||
@@ -22,7 +22,6 @@ from webauthn.helpers.structs import (
|
||||
PublicKeyCredentialDescriptor,
|
||||
AuthenticatorTransport,
|
||||
UserVerificationRequirement,
|
||||
AuthenticatorAttachment,
|
||||
ResidentKeyRequirement,
|
||||
AuthenticatorSelectionCriteria
|
||||
)
|
||||
|
||||
@@ -714,7 +714,7 @@ class Emby:
|
||||
logger.error(f"连接Users/Items出错:" + str(e))
|
||||
return None
|
||||
|
||||
def get_webhook_message(self, form: any, args: dict) -> Optional[schemas.WebhookEventInfo]:
|
||||
def get_webhook_message(self, form: Any, args: dict) -> Optional[schemas.WebhookEventInfo]:
|
||||
"""
|
||||
解析Emby Webhook报文
|
||||
电影:
|
||||
|
||||
@@ -111,7 +111,7 @@ class BitptSiteUserInfo(SiteParserBase):
|
||||
def _parse_message_content(self, html_text) -> Tuple[Optional[str], Optional[str], Optional[str]]:
|
||||
pass
|
||||
|
||||
def _parse_user_torrent_seeding_info(self, html_text: str):
|
||||
def _parse_user_torrent_seeding_info(self, html_text: str, **kwargs):
|
||||
pass
|
||||
|
||||
def parse(self):
|
||||
|
||||
@@ -117,7 +117,7 @@ class ZhixingSiteUserInfo(SiteParserBase):
|
||||
def _parse_message_content(self, html_text) -> Tuple[Optional[str], Optional[str], Optional[str]]:
|
||||
pass
|
||||
|
||||
def _parse_user_torrent_seeding_info(self, html_text: str):
|
||||
def _parse_user_torrent_seeding_info(self, html_text: str, multi_page: bool = False):
|
||||
"""
|
||||
占位,避免抽象类报错
|
||||
"""
|
||||
|
||||
@@ -569,7 +569,7 @@ class Jellyfin:
|
||||
logger.error(f"连接Library/Refresh出错:" + str(e))
|
||||
return False
|
||||
|
||||
def get_webhook_message(self, body: any) -> Optional[schemas.WebhookEventInfo]:
|
||||
def get_webhook_message(self, body: Any) -> Optional[schemas.WebhookEventInfo]:
|
||||
"""
|
||||
解析Jellyfin报文
|
||||
{
|
||||
|
||||
@@ -549,7 +549,7 @@ class Plex:
|
||||
logger.error(f"获取媒体库列表出错:{str(err)}")
|
||||
return None
|
||||
|
||||
def get_webhook_message(self, form: any) -> Optional[schemas.WebhookEventInfo]:
|
||||
def get_webhook_message(self, form: Any) -> Optional[schemas.WebhookEventInfo]:
|
||||
"""
|
||||
解析Plex报文
|
||||
eventItem 字段的含义
|
||||
|
||||
@@ -409,7 +409,7 @@ class TrimeMedia:
|
||||
return lib
|
||||
return None
|
||||
|
||||
def get_webhook_message(self, body: any) -> Optional[schemas.WebhookEventInfo]:
|
||||
def get_webhook_message(self, body: Any) -> Optional[schemas.WebhookEventInfo]:
|
||||
pass
|
||||
|
||||
def get_iteminfo(self, itemid: str) -> Optional[schemas.MediaServerItem]:
|
||||
|
||||
@@ -17,34 +17,44 @@ class ConfigReloadMixin:
|
||||
def __init_subclass__(cls, **kwargs):
|
||||
super().__init_subclass__(**kwargs)
|
||||
|
||||
config_watch = getattr(cls, 'CONFIG_WATCH', None)
|
||||
config_watch = getattr(cls, "CONFIG_WATCH", None)
|
||||
if not config_watch:
|
||||
return
|
||||
|
||||
# 检查 on_config_changed 方法是否为异步
|
||||
is_async = inspect.iscoroutinefunction(cls.on_config_changed)
|
||||
|
||||
method_name = 'handle_config_changed'
|
||||
method_name = "handle_config_changed"
|
||||
|
||||
# 创建事件处理函数
|
||||
def create_handler(is_async):
|
||||
if is_async:
|
||||
|
||||
async def wrapper(self: ConfigReloadMixin, event: Event):
|
||||
if not event:
|
||||
return
|
||||
changed_keys = getattr(event.event_data, "key", set()) & config_watch
|
||||
changed_keys = (
|
||||
getattr(event.event_data, "key", set()) & config_watch
|
||||
)
|
||||
if not changed_keys:
|
||||
return
|
||||
logger.info(f"配置 {', '.join(changed_keys)} 变更,重载 {self.get_reload_name()}...")
|
||||
await self.on_config_changed()
|
||||
logger.info(
|
||||
f"配置 {', '.join(changed_keys)} 变更,重载 {self.get_reload_name()}..."
|
||||
)
|
||||
self.on_config_changed()
|
||||
else:
|
||||
|
||||
def wrapper(self: ConfigReloadMixin, event: Event):
|
||||
if not event:
|
||||
return
|
||||
changed_keys = getattr(event.event_data, "key", set()) & config_watch
|
||||
changed_keys = (
|
||||
getattr(event.event_data, "key", set()) & config_watch
|
||||
)
|
||||
if not changed_keys:
|
||||
return
|
||||
logger.info(f"配置 {', '.join(changed_keys)} 变更,重载 {self.get_reload_name()}...")
|
||||
logger.info(
|
||||
f"配置 {', '.join(changed_keys)} 变更,重载 {self.get_reload_name()}..."
|
||||
)
|
||||
self.on_config_changed()
|
||||
|
||||
return wrapper
|
||||
@@ -52,7 +62,7 @@ class ConfigReloadMixin:
|
||||
# 创建并设置处理函数
|
||||
handler = create_handler(is_async)
|
||||
handler.__module__ = cls.__module__
|
||||
handler.__qualname__ = f'{cls.__name__}.{method_name}'
|
||||
handler.__qualname__ = f"{cls.__name__}.{method_name}"
|
||||
setattr(cls, method_name, handler)
|
||||
# 添加为事件处理器
|
||||
eventmanager.add_event_listener(EventType.ConfigChanged, handler)
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
from typing import Tuple
|
||||
|
||||
import pyotp
|
||||
|
||||
|
||||
class OtpUtils:
|
||||
@staticmethod
|
||||
def generate_secret_key(username: str) -> (str, str):
|
||||
def generate_secret_key(username: str) -> Tuple[str, str]:
|
||||
try:
|
||||
secret = pyotp.random_base32()
|
||||
uri = pyotp.totp.TOTP(secret).provisioning_uri(name='MoviePilot',
|
||||
|
||||
Reference in New Issue
Block a user