mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 15:38:19 +08:00
refactor: 收口 V3 分层架构与插件兼容边界
This commit is contained in:
+52
-43
@@ -35,14 +35,18 @@ from app.application.commands import init_commands
|
||||
from app.application.scheduling import remove_plugin_job, update_plugin_job
|
||||
from app.runtime.cache import async_fresh
|
||||
from app.runtime.config import settings
|
||||
from app.runtime.extensions.plugin_manager import PluginManager
|
||||
from app.application.security.access import (
|
||||
from app.application.plugin.runtime import get_plugin_manager as PluginManager
|
||||
from app.runtime.extensions.plugin.contracts import (
|
||||
PluginDashboardError,
|
||||
PluginNotFoundError,
|
||||
)
|
||||
from app.adapters.web.security.access import (
|
||||
resource_token_cookie,
|
||||
verify_resource_token,
|
||||
verify_token,
|
||||
)
|
||||
from app.db.models import User
|
||||
from app.db.oper.systemconfig import SystemConfigOper
|
||||
from app.api.principal import ApiPrincipal
|
||||
from app.application.configuration import get_configured_system_config
|
||||
from app.api.deps import (
|
||||
get_current_active_superuser,
|
||||
get_current_active_superuser_async,
|
||||
@@ -240,7 +244,7 @@ async def _get_plugin_history_detail(
|
||||
|
||||
@router.get("/", summary="所有插件", response_model=List[_SchemaPlugin])
|
||||
async def all_plugins(
|
||||
_: User = Depends(get_current_active_superuser_async),
|
||||
_: ApiPrincipal = Depends(get_current_active_superuser_async),
|
||||
state: Optional[str] = "all",
|
||||
force: bool = False,
|
||||
) -> List[_SchemaPlugin]:
|
||||
@@ -298,17 +302,17 @@ async def all_plugins(
|
||||
|
||||
|
||||
@router.get("/installed", summary="已安装插件", response_model=List[str])
|
||||
async def installed(_: User = Depends(get_current_active_superuser_async)) -> Any:
|
||||
async def installed(_: ApiPrincipal = Depends(get_current_active_superuser_async)) -> Any:
|
||||
"""
|
||||
查询用户已安装插件清单
|
||||
"""
|
||||
return SystemConfigOper().get(SystemConfigKey.UserInstalledPlugins) or []
|
||||
return get_configured_system_config().get(SystemConfigKey.UserInstalledPlugins) or []
|
||||
|
||||
|
||||
@router.get("/history/{plugin_id}", summary="获取插件更新说明", response_model=_SchemaPlugin)
|
||||
async def plugin_history(
|
||||
plugin_id: str,
|
||||
_: User = Depends(get_current_active_superuser_async),
|
||||
_: ApiPrincipal = Depends(get_current_active_superuser_async),
|
||||
force: bool = True,
|
||||
) -> _SchemaPlugin:
|
||||
"""
|
||||
@@ -330,7 +334,7 @@ async def plugin_history(
|
||||
)
|
||||
async def plugin_releases(
|
||||
plugin_id: str,
|
||||
_: User = Depends(get_current_active_superuser_async),
|
||||
_: ApiPrincipal = Depends(get_current_active_superuser_async),
|
||||
repo_url: Optional[str] = "",
|
||||
force: bool = False,
|
||||
) -> dict:
|
||||
@@ -405,7 +409,7 @@ async def statistic(_: _SchemaTokenPayload = Depends(verify_token)) -> Any:
|
||||
)
|
||||
async def plugin_ratings(
|
||||
plugin_ids: Optional[str] = None,
|
||||
_: User = Depends(get_current_active_superuser_async),
|
||||
_: ApiPrincipal = Depends(get_current_active_superuser_async),
|
||||
) -> Dict[str, _SchemaPluginRating]:
|
||||
"""
|
||||
批量查询插件平均分、评分人数和当前安装实例评分。
|
||||
@@ -425,7 +429,7 @@ async def plugin_ratings(
|
||||
)
|
||||
async def plugin_rating(
|
||||
plugin_id: str,
|
||||
_: User = Depends(get_current_active_superuser_async),
|
||||
_: ApiPrincipal = Depends(get_current_active_superuser_async),
|
||||
) -> _SchemaPluginRating:
|
||||
"""
|
||||
查询单个插件平均分、评分人数和当前安装实例评分。
|
||||
@@ -442,12 +446,12 @@ async def plugin_rating(
|
||||
async def rate_plugin(
|
||||
plugin_id: str,
|
||||
payload: _SchemaPluginRatingRequest,
|
||||
_: User = Depends(get_current_active_superuser_async),
|
||||
_: ApiPrincipal = Depends(get_current_active_superuser_async),
|
||||
) -> _SchemaResponse:
|
||||
"""
|
||||
为已安装插件新增或更新当前安装实例评分。
|
||||
"""
|
||||
installed_plugins = SystemConfigOper().get(SystemConfigKey.UserInstalledPlugins) or []
|
||||
installed_plugins = get_configured_system_config().get(SystemConfigKey.UserInstalledPlugins) or []
|
||||
if plugin_id not in installed_plugins:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
@@ -467,7 +471,7 @@ async def rate_plugin(
|
||||
"/reload/{plugin_id}", summary="重新加载插件", response_model=_SchemaResponse[None]
|
||||
)
|
||||
def reload_plugin(
|
||||
plugin_id: str, _: User = Depends(get_current_active_superuser)
|
||||
plugin_id: str, _: ApiPrincipal = Depends(get_current_active_superuser)
|
||||
) -> Any:
|
||||
"""
|
||||
重新加载插件
|
||||
@@ -485,7 +489,7 @@ async def install(
|
||||
repo_url: Optional[str] = "",
|
||||
release_version: Optional[str] = None,
|
||||
force: Optional[bool] = False,
|
||||
_: User = Depends(get_current_active_superuser_async),
|
||||
_: ApiPrincipal = Depends(get_current_active_superuser_async),
|
||||
) -> Any:
|
||||
"""
|
||||
安装插件
|
||||
@@ -495,7 +499,7 @@ async def install(
|
||||
|
||||
async def save_installed_plugins(plugin_ids: List[str]) -> object:
|
||||
"""保存安装用例确认后的插件列表。"""
|
||||
return await SystemConfigOper().async_set(
|
||||
return await get_configured_system_config().async_set(
|
||||
SystemConfigKey.UserInstalledPlugins,
|
||||
plugin_ids,
|
||||
)
|
||||
@@ -523,7 +527,7 @@ async def install(
|
||||
return await run_in_threadpool(register_plugin, target_id)
|
||||
|
||||
command = PluginInstallCommand(
|
||||
installed_plugins_reader=lambda: SystemConfigOper().get(
|
||||
installed_plugins_reader=lambda: get_configured_system_config().get(
|
||||
SystemConfigKey.UserInstalledPlugins
|
||||
) or [],
|
||||
installed_plugins_writer=save_installed_plugins,
|
||||
@@ -585,7 +589,7 @@ def plugin_sidebar_nav(_: _SchemaTokenPayload = Depends(verify_token)) -> Any:
|
||||
response_model=_SchemaJsonObject,
|
||||
)
|
||||
def plugin_form(
|
||||
plugin_id: str, _: User = Depends(get_current_active_superuser)
|
||||
plugin_id: str, _: ApiPrincipal = Depends(get_current_active_superuser)
|
||||
) -> dict:
|
||||
"""
|
||||
根据插件ID获取插件配置表单或Vue组件URL
|
||||
@@ -621,7 +625,7 @@ def plugin_form(
|
||||
response_model=_SchemaJsonObject,
|
||||
)
|
||||
def plugin_page(
|
||||
plugin_id: str, _: User = Depends(get_current_active_superuser)
|
||||
plugin_id: str, _: ApiPrincipal = Depends(get_current_active_superuser)
|
||||
) -> dict:
|
||||
"""
|
||||
根据插件ID获取插件数据页面
|
||||
@@ -649,7 +653,7 @@ def plugin_page(
|
||||
response_model=List[_SchemaPluginDashboardMetaItem],
|
||||
)
|
||||
def plugin_dashboard_meta(
|
||||
_: User = Depends(get_current_active_superuser),
|
||||
_: ApiPrincipal = Depends(get_current_active_superuser),
|
||||
) -> List[dict]:
|
||||
"""
|
||||
获取所有插件仪表板元信息
|
||||
@@ -662,19 +666,24 @@ def plugin_dashboard_by_key(
|
||||
plugin_id: str,
|
||||
key: str,
|
||||
user_agent: Annotated[str | None, Header()] = None,
|
||||
_: User = Depends(get_current_active_superuser),
|
||||
_: ApiPrincipal = Depends(get_current_active_superuser),
|
||||
) -> Optional[_SchemaPluginDashboard]:
|
||||
"""
|
||||
根据插件ID获取插件仪表板
|
||||
"""
|
||||
return PluginManager().get_plugin_dashboard(plugin_id, key, user_agent)
|
||||
try:
|
||||
return PluginManager().get_plugin_dashboard(plugin_id, key, user_agent)
|
||||
except PluginNotFoundError as error:
|
||||
raise HTTPException(status_code=404, detail=str(error)) from error
|
||||
except PluginDashboardError as error:
|
||||
raise HTTPException(status_code=500, detail=str(error)) from error
|
||||
|
||||
|
||||
@router.get("/dashboard/{plugin_id}", summary="获取插件仪表板配置")
|
||||
def plugin_dashboard(
|
||||
plugin_id: str,
|
||||
user_agent: Annotated[str | None, Header()] = None,
|
||||
_: User = Depends(get_current_active_superuser),
|
||||
_: ApiPrincipal = Depends(get_current_active_superuser),
|
||||
) -> Optional[_SchemaPluginDashboard]:
|
||||
"""
|
||||
根据插件ID获取插件仪表板
|
||||
@@ -687,7 +696,7 @@ def plugin_dashboard(
|
||||
)
|
||||
def reset_plugin(
|
||||
plugin_id: str,
|
||||
_: User = Depends(get_current_active_superuser),
|
||||
_: ApiPrincipal = Depends(get_current_active_superuser),
|
||||
command: PluginConfigCommand = Depends(get_plugin_config_command),
|
||||
) -> Any:
|
||||
"""
|
||||
@@ -798,13 +807,13 @@ async def plugin_static_file(
|
||||
response_model=_SchemaPluginFoldersData,
|
||||
)
|
||||
async def get_plugin_folders(
|
||||
_: User = Depends(get_current_active_superuser_async),
|
||||
_: ApiPrincipal = Depends(get_current_active_superuser_async),
|
||||
) -> dict:
|
||||
"""
|
||||
获取插件文件夹分组配置
|
||||
"""
|
||||
try:
|
||||
result = SystemConfigOper().get(SystemConfigKey.PluginFolders) or {}
|
||||
result = get_configured_system_config().get(SystemConfigKey.PluginFolders) or {}
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error(f"[文件夹API] 获取文件夹配置失败: {str(e)}")
|
||||
@@ -813,13 +822,13 @@ async def get_plugin_folders(
|
||||
|
||||
@router.post("/folders", summary="保存插件文件夹配置", response_model=_SchemaResponse[None])
|
||||
async def save_plugin_folders(
|
||||
folders: dict, _: User = Depends(get_current_active_superuser_async)
|
||||
folders: dict, _: ApiPrincipal = Depends(get_current_active_superuser_async)
|
||||
) -> Any:
|
||||
"""
|
||||
保存插件文件夹分组配置
|
||||
"""
|
||||
try:
|
||||
SystemConfigOper().set(SystemConfigKey.PluginFolders, folders)
|
||||
get_configured_system_config().set(SystemConfigKey.PluginFolders, folders)
|
||||
return _SchemaResponse(success=True)
|
||||
except Exception as e:
|
||||
logger.error(f"[文件夹API] 保存文件夹配置失败: {str(e)}")
|
||||
@@ -830,15 +839,15 @@ async def save_plugin_folders(
|
||||
"/folders/{folder_name}", summary="创建插件文件夹", response_model=_SchemaResponse[None]
|
||||
)
|
||||
async def create_plugin_folder(
|
||||
folder_name: str, _: User = Depends(get_current_active_superuser_async)
|
||||
folder_name: str, _: ApiPrincipal = Depends(get_current_active_superuser_async)
|
||||
) -> Any:
|
||||
"""
|
||||
创建新的插件文件夹
|
||||
"""
|
||||
folders = SystemConfigOper().get(SystemConfigKey.PluginFolders) or {}
|
||||
folders = get_configured_system_config().get(SystemConfigKey.PluginFolders) or {}
|
||||
if folder_name not in folders:
|
||||
folders[folder_name] = []
|
||||
SystemConfigOper().set(SystemConfigKey.PluginFolders, folders)
|
||||
get_configured_system_config().set(SystemConfigKey.PluginFolders, folders)
|
||||
return _SchemaResponse(
|
||||
success=True, message=f"文件夹 '{folder_name}' 创建成功"
|
||||
)
|
||||
@@ -850,15 +859,15 @@ async def create_plugin_folder(
|
||||
"/folders/{folder_name}", summary="删除插件文件夹", response_model=_SchemaResponse[None]
|
||||
)
|
||||
async def delete_plugin_folder(
|
||||
folder_name: str, _: User = Depends(get_current_active_superuser_async)
|
||||
folder_name: str, _: ApiPrincipal = Depends(get_current_active_superuser_async)
|
||||
) -> Any:
|
||||
"""
|
||||
删除插件文件夹
|
||||
"""
|
||||
folders = SystemConfigOper().get(SystemConfigKey.PluginFolders) or {}
|
||||
folders = get_configured_system_config().get(SystemConfigKey.PluginFolders) or {}
|
||||
if folder_name in folders:
|
||||
del folders[folder_name]
|
||||
await SystemConfigOper().async_set(SystemConfigKey.PluginFolders, folders)
|
||||
await get_configured_system_config().async_set(SystemConfigKey.PluginFolders, folders)
|
||||
return _SchemaResponse(
|
||||
success=True, message=f"文件夹 '{folder_name}' 删除成功"
|
||||
)
|
||||
@@ -874,14 +883,14 @@ async def delete_plugin_folder(
|
||||
async def update_folder_plugins(
|
||||
folder_name: str,
|
||||
plugin_ids: List[str],
|
||||
_: User = Depends(get_current_active_superuser_async),
|
||||
_: ApiPrincipal = Depends(get_current_active_superuser_async),
|
||||
) -> Any:
|
||||
"""
|
||||
更新指定文件夹中的插件列表
|
||||
"""
|
||||
folders = SystemConfigOper().get(SystemConfigKey.PluginFolders) or {}
|
||||
folders = get_configured_system_config().get(SystemConfigKey.PluginFolders) or {}
|
||||
folders[folder_name] = plugin_ids
|
||||
await SystemConfigOper().async_set(SystemConfigKey.PluginFolders, folders)
|
||||
await get_configured_system_config().async_set(SystemConfigKey.PluginFolders, folders)
|
||||
return _SchemaResponse(
|
||||
success=True, message=f"文件夹 '{folder_name}' 中的插件已更新"
|
||||
)
|
||||
@@ -891,7 +900,7 @@ async def update_folder_plugins(
|
||||
"/clone/{plugin_id}", summary="创建插件分身", response_model=_SchemaResponse[None]
|
||||
)
|
||||
def clone_plugin(
|
||||
plugin_id: str, clone_data: dict, _: User = Depends(get_current_active_superuser)
|
||||
plugin_id: str, clone_data: dict, _: ApiPrincipal = Depends(get_current_active_superuser)
|
||||
) -> Any:
|
||||
"""
|
||||
创建插件分身
|
||||
@@ -925,7 +934,7 @@ def clone_plugin(
|
||||
response_model=_SchemaJsonObject,
|
||||
)
|
||||
async def plugin_config(
|
||||
plugin_id: str, _: User = Depends(get_current_active_superuser_async)
|
||||
plugin_id: str, _: ApiPrincipal = Depends(get_current_active_superuser_async)
|
||||
) -> dict:
|
||||
"""
|
||||
根据插件ID获取插件配置信息
|
||||
@@ -937,7 +946,7 @@ async def plugin_config(
|
||||
def set_plugin_config(
|
||||
plugin_id: str,
|
||||
conf: dict,
|
||||
_: User = Depends(get_current_active_superuser),
|
||||
_: ApiPrincipal = Depends(get_current_active_superuser),
|
||||
command: PluginConfigCommand = Depends(get_plugin_config_command),
|
||||
) -> Any:
|
||||
"""
|
||||
@@ -949,12 +958,12 @@ def set_plugin_config(
|
||||
|
||||
@router.delete("/{plugin_id}", summary="卸载插件", response_model=_SchemaResponse[None])
|
||||
def uninstall_plugin(
|
||||
plugin_id: str, _: User = Depends(get_current_active_superuser)
|
||||
plugin_id: str, _: ApiPrincipal = Depends(get_current_active_superuser)
|
||||
) -> Any:
|
||||
"""
|
||||
卸载插件
|
||||
"""
|
||||
config_oper = SystemConfigOper()
|
||||
config_oper = get_configured_system_config()
|
||||
# 删除已安装信息
|
||||
install_plugins = config_oper.get(SystemConfigKey.UserInstalledPlugins) or []
|
||||
for plugin in install_plugins:
|
||||
@@ -995,7 +1004,7 @@ def _add_clone_to_plugin_folder(original_plugin_id: str, clone_plugin_id: str):
|
||||
:param clone_plugin_id: 分身插件ID
|
||||
"""
|
||||
try:
|
||||
config_oper = SystemConfigOper()
|
||||
config_oper = get_configured_system_config()
|
||||
# 获取插件文件夹配置
|
||||
folders = config_oper.get(SystemConfigKey.PluginFolders) or {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user