mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-08-15 11:04:12 +08:00
GET /plugin/folders 的响应模型 PluginFoldersData 只能校验旧版 数组格式,前端实际保存的是含展示配置的对象格式,导致建文件夹/ 移入插件后刷新时响应校验失败(500),文件夹恢复为空。改为同时 兼容新旧两种格式。
197 lines
6.0 KiB
Python
197 lines
6.0 KiB
Python
from typing import Optional, List, Dict, Union
|
||
|
||
from pydantic import BaseModel, Field, RootModel
|
||
|
||
from app.schemas.common import JsonData
|
||
|
||
|
||
class Plugin(BaseModel):
|
||
"""
|
||
插件信息
|
||
"""
|
||
id: str = None
|
||
# 插件名称
|
||
plugin_name: Optional[str] = None
|
||
# 插件描述
|
||
plugin_desc: Optional[str] = None
|
||
# 插件图标
|
||
plugin_icon: Optional[str] = None
|
||
# 插件版本
|
||
plugin_version: Optional[str] = None
|
||
# 插件标签
|
||
plugin_label: Optional[str] = None
|
||
# 插件作者
|
||
plugin_author: Optional[str] = None
|
||
# 作者主页
|
||
author_url: Optional[str] = None
|
||
# 插件配置项ID前缀
|
||
plugin_config_prefix: Optional[str] = None
|
||
# 加载顺序
|
||
plugin_order: Optional[int] = 0
|
||
# 可使用的用户级别
|
||
auth_level: Optional[int] = 0
|
||
# 是否已安装
|
||
installed: Optional[bool] = False
|
||
# 运行状态
|
||
state: Optional[bool] = False
|
||
# 是否有详情页面
|
||
has_page: Optional[bool] = False
|
||
# 是否有新版本
|
||
has_update: Optional[bool] = False
|
||
# 主系统版本是否兼容
|
||
system_version_compatible: Optional[bool] = True
|
||
# 主系统版本兼容提示
|
||
system_version_message: Optional[str] = None
|
||
# 主系统版本限定范围
|
||
system_version: Optional[str] = None
|
||
# 是否声明支持通过 GitHub Release 资产安装
|
||
release: Optional[bool] = False
|
||
# 是否本地
|
||
is_local: Optional[bool] = False
|
||
# 仓库地址
|
||
repo_url: Optional[str] = None
|
||
# 安装次数
|
||
install_count: Optional[int] = 0
|
||
# 更新记录
|
||
history: Optional[dict[str, str]] = Field(default_factory=dict)
|
||
# 添加时间,值越小表示越靠后发布
|
||
add_time: Optional[int] = 0
|
||
# 插件公钥
|
||
plugin_public_key: Optional[str] = None
|
||
|
||
|
||
class PluginDashboard(Plugin):
|
||
"""
|
||
插件仪表盘
|
||
"""
|
||
id: Optional[str] = None
|
||
# 名称
|
||
name: Optional[str] = None
|
||
# 仪表板key
|
||
key: Optional[str] = None
|
||
# 演染模式
|
||
render_mode: Optional[str] = Field(default="vuetify")
|
||
# 全局配置
|
||
attrs: Optional[dict[str, JsonData]] = Field(default_factory=dict)
|
||
# col列数
|
||
cols: Optional[dict[str, JsonData]] = Field(default_factory=dict)
|
||
# 页面元素
|
||
elements: Optional[List[dict[str, JsonData]]] = Field(default_factory=list)
|
||
|
||
|
||
class PluginSidebarNavItem(BaseModel):
|
||
"""
|
||
插件侧栏导航项(前端全页路由)
|
||
"""
|
||
plugin_id: str = Field(description="插件 ID")
|
||
nav_key: str = Field(description="导航键,对应 URL 段")
|
||
title: str = Field(description="侧栏标题")
|
||
icon: str = Field(default="mdi-puzzle", description="MDI 图标名")
|
||
section: str = Field(
|
||
description="分组:start / discovery / subscribe / organize / system",
|
||
)
|
||
permission: Optional[str] = Field(
|
||
default=None,
|
||
description="权限:subscribe / discovery / search / manage / admin",
|
||
)
|
||
order: int = Field(default=0, description="同组内排序,越小越靠前")
|
||
|
||
|
||
class PluginRatingRequest(BaseModel):
|
||
"""插件评分请求"""
|
||
|
||
rating: float = Field(
|
||
ge=0.1,
|
||
le=5.0,
|
||
multiple_of=0.1,
|
||
description="评分,范围 0.1 至 5.0,精确到 0.1",
|
||
)
|
||
|
||
|
||
class PluginRating(BaseModel):
|
||
"""插件评分结果"""
|
||
|
||
plugin_id: str = Field(description="插件 ID")
|
||
average_rating: float = Field(default=0.0, description="平均评分")
|
||
rating_count: int = Field(default=0, description="评分人数")
|
||
user_rating: Optional[float] = Field(default=None, description="当前安装实例评分")
|
||
|
||
|
||
class PluginRatingMap(RootModel[Dict[str, PluginRating]]):
|
||
"""插件 ID 与评分结果的映射。"""
|
||
|
||
|
||
class PluginMemoryInfo(BaseModel):
|
||
"""插件内存信息"""
|
||
plugin_id: str = Field(description="插件ID")
|
||
plugin_name: str = Field(description="插件名称")
|
||
plugin_version: str = Field(description="插件版本")
|
||
total_memory_bytes: int = Field(description="总内存使用量(字节)")
|
||
total_memory_mb: float = Field(description="总内存使用量(MB)")
|
||
object_count: int = Field(description="对象数量")
|
||
calculation_time_ms: float = Field(description="计算耗时(毫秒)")
|
||
timestamp: float = Field(description="统计时间戳")
|
||
error: Optional[str] = Field(default=None, description="错误信息")
|
||
object_details: Optional[List[Dict[str, JsonData]]] = Field(default=None, description="大对象详情")
|
||
|
||
|
||
class PluginRemoteInfo(BaseModel):
|
||
"""插件模块联邦远程入口。"""
|
||
|
||
id: str
|
||
url: str
|
||
name: str
|
||
|
||
|
||
class PluginReleaseItem(BaseModel):
|
||
"""可安装的插件 Release 版本。"""
|
||
|
||
version: str
|
||
tag_name: str
|
||
name: str
|
||
published_at: Optional[str] = None
|
||
body: str = ""
|
||
asset_name: str
|
||
is_latest: bool = False
|
||
is_current: bool = False
|
||
|
||
|
||
class PluginReleaseData(BaseModel):
|
||
"""插件 Release 能力与版本列表。"""
|
||
|
||
release_supported: bool = False
|
||
latest_version: Optional[str] = None
|
||
current_version: Optional[str] = None
|
||
items: List[PluginReleaseItem] = Field(default_factory=list)
|
||
|
||
|
||
class PluginFolderConfigData(BaseModel):
|
||
"""新版插件文件夹配置(对象格式,含展示配置与插件列表)。"""
|
||
|
||
# 文件夹内插件 ID 列表
|
||
plugins: List[str] = Field(default_factory=list)
|
||
# 文件夹排序值
|
||
order: Optional[int] = None
|
||
# 文件夹图标
|
||
icon: Optional[str] = None
|
||
# 文件夹颜色
|
||
color: Optional[str] = None
|
||
# 文件夹渐变
|
||
gradient: Optional[str] = None
|
||
# 文件夹背景
|
||
background: Optional[str] = None
|
||
# 是否显示图标(前端字段为驼峰命名)
|
||
show_icon: Optional[bool] = Field(default=None, alias="showIcon")
|
||
|
||
|
||
class PluginFoldersData(RootModel[Dict[str, Union[List[str], PluginFolderConfigData]]]):
|
||
"""插件文件夹与插件配置映射,兼容旧版数组格式与新版对象格式。"""
|
||
|
||
|
||
class PluginDashboardMetaItem(BaseModel):
|
||
"""插件仪表板入口摘要。"""
|
||
|
||
id: str
|
||
name: Optional[str] = None
|
||
key: Optional[str] = None
|