mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-05-11 18:10:15 +08:00
fix plugins
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
import concurrent
|
||||
import concurrent.futures
|
||||
import importlib.util
|
||||
import inspect
|
||||
import os
|
||||
import time
|
||||
import traceback
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Type, Union
|
||||
from typing import Any, Dict, List, Optional, Type, Union, Callable, Tuple
|
||||
|
||||
from fastapi import HTTPException
|
||||
from starlette import status
|
||||
from watchdog.events import FileSystemEventHandler
|
||||
from watchdog.observers import Observer
|
||||
|
||||
@@ -526,7 +529,40 @@ class PluginManager(metaclass=Singleton):
|
||||
logger.error(f"获取插件 {plugin_id} 模块出错:{str(e)}")
|
||||
return ret_modules
|
||||
|
||||
def get_plugin_dashboard_meta(self):
|
||||
@staticmethod
|
||||
def get_plugin_remote_entry(plugin_id: str, dist_path: str) -> str:
|
||||
"""
|
||||
获取插件的远程入口地址
|
||||
:param plugin_id: 插件 ID
|
||||
:param dist_path: 插件的分发路径
|
||||
:return: 远程入口地址
|
||||
"""
|
||||
if dist_path.startswith("/"):
|
||||
dist_path = dist_path[1:]
|
||||
if dist_path.endswith("/"):
|
||||
dist_path = dist_path[:-1]
|
||||
return f"/plugin/file/{plugin_id.lower()}/{dist_path}/remoteEntry.js?token={settings.API_TOKEN}"
|
||||
|
||||
def get_plugin_remotes(self, pid: Optional[str] = None) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
获取插件联邦组件列表
|
||||
"""
|
||||
remotes = []
|
||||
for plugin_id, plugin in self._running_plugins.items():
|
||||
if pid and pid != plugin_id:
|
||||
continue
|
||||
if hasattr(plugin, "get_render_mode"):
|
||||
render_mode, dist_path = plugin.get_render_mode()
|
||||
if render_mode != "vue":
|
||||
continue
|
||||
remotes.append({
|
||||
"id": plugin_id,
|
||||
"url": self.get_plugin_remote_entry(plugin_id, dist_path),
|
||||
"name": plugin.plugin_name,
|
||||
})
|
||||
return remotes
|
||||
|
||||
def get_plugin_dashboard_meta(self) -> List[Dict[str, str]]:
|
||||
"""
|
||||
获取所有插件仪表盘元信息
|
||||
"""
|
||||
@@ -556,6 +592,49 @@ class PluginManager(metaclass=Singleton):
|
||||
logger.error(f"获取插件[{plugin_id}]仪表盘元数据出错:{str(e)}")
|
||||
return dashboard_meta
|
||||
|
||||
def get_plugin_dashboard(self, pid: str, key: str, user_agent: str = None) -> schemas.PluginDashboard:
|
||||
"""
|
||||
获取插件仪表盘
|
||||
"""
|
||||
|
||||
def __get_params_count(func: Callable):
|
||||
"""
|
||||
获取函数的参数信息
|
||||
"""
|
||||
signature = inspect.signature(func)
|
||||
return len(signature.parameters)
|
||||
|
||||
# 获取插件实例
|
||||
plugin_instance = self.running_plugins.get(pid)
|
||||
if not plugin_instance:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"插件 {pid} 不存在或未加载")
|
||||
|
||||
# 渲染模式
|
||||
render_mode, _ = plugin_instance.get_render_mode()
|
||||
# 获取插件仪表板
|
||||
try:
|
||||
# 检查方法的参数个数
|
||||
params_count = __get_params_count(plugin_instance.get_dashboard)
|
||||
if params_count > 1:
|
||||
dashboard: Tuple = plugin_instance.get_dashboard(key=key, user_agent=user_agent)
|
||||
elif params_count > 0:
|
||||
dashboard: Tuple = plugin_instance.get_dashboard(user_agent=user_agent)
|
||||
else:
|
||||
dashboard: Tuple = plugin_instance.get_dashboard()
|
||||
except Exception as e:
|
||||
logger.error(f"插件 {pid} 调用方法 get_dashboard 出错: {str(e)}")
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"插件 {pid} 调用方法 get_dashboard 出错: {str(e)}")
|
||||
cols, attrs, elements = dashboard
|
||||
return schemas.PluginDashboard(
|
||||
id=pid,
|
||||
name=plugin_instance.plugin_name,
|
||||
key=key,
|
||||
render_mode=render_mode,
|
||||
cols=cols or {},
|
||||
attrs=attrs or {},
|
||||
)
|
||||
|
||||
def get_plugin_attr(self, pid: str, attr: str) -> Any:
|
||||
"""
|
||||
获取插件属性
|
||||
|
||||
Reference in New Issue
Block a user