From 184b62b024e6f09af2f91c5e45de4537a97bbae3 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Tue, 13 May 2025 16:36:50 +0800 Subject: [PATCH] fix plugin apis --- app/api/endpoints/plugin.py | 54 ++++++++++++++++++++----------------- app/core/plugin.py | 17 +++++++----- app/helper/module.py | 8 +++--- 3 files changed, 44 insertions(+), 35 deletions(-) diff --git a/app/api/endpoints/plugin.py b/app/api/endpoints/plugin.py index 85f9850c..25666fa3 100644 --- a/app/api/endpoints/plugin.py +++ b/app/api/endpoints/plugin.py @@ -122,6 +122,18 @@ def _clean_protected_routes(existing_paths: dict): logger.error(f"Error removing protected route {protected_route}: {str(e)}") +def register_plugin(plugin_id: str): + """ + 注册一个插件相关的服务 + """ + # 注册插件服务 + Scheduler().update_plugin_job(plugin_id) + # 注册菜单命令 + Command().init_commands(plugin_id) + # 注册插件API + register_plugin_api(plugin_id) + + @router.get("/", summary="所有插件", response_model=List[schemas.Plugin]) def all_plugins(_: schemas.TokenPayload = Depends(get_current_active_superuser), state: Optional[str] = "all") -> List[schemas.Plugin]: @@ -185,6 +197,18 @@ def statistic(_: schemas.TokenPayload = Depends(verify_token)) -> Any: return PluginHelper().get_statistic() +@router.get("/reload/{plugin_id}", summary="重新加载插件", response_model=schemas.Response) +def reload_plugin(plugin_id: str, _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: + """ + 重新加载插件 + """ + # 重新加载插件 + PluginManager().reload_plugin(plugin_id) + # 注册插件服务 + register_plugin(plugin_id) + return schemas.Response(success=True) + + @router.get("/install/{plugin_id}", summary="安装插件", response_model=schemas.Response) def install(plugin_id: str, repo_url: Optional[str] = "", @@ -213,14 +237,8 @@ def install(plugin_id: str, install_plugins.append(plugin_id) # 保存设置 SystemConfigOper().set(SystemConfigKey.UserInstalledPlugins, install_plugins) - # 加载插件到内存 - PluginManager().reload_plugin(plugin_id) - # 注册插件服务 - Scheduler().update_plugin_job(plugin_id) - # 注册菜单命令 - Command().init_commands(plugin_id) - # 注册插件API - register_plugin_api(plugin_id) + # 重新加载插件 + reload_plugin(plugin_id) return schemas.Response(success=True) @@ -316,14 +334,8 @@ def reset_plugin(plugin_id: str, PluginManager().delete_plugin_config(plugin_id) # 删除插件所有数据 PluginManager().delete_plugin_data(plugin_id) - # 重新生效插件 - PluginManager().reload_plugin(plugin_id) - # 注册插件服务 - Scheduler().update_plugin_job(plugin_id) - # 注册菜单命令 - Command().init_commands(plugin_id) - # 注册插件API - register_plugin_api(plugin_id) + # 重新加载插件 + reload_plugin(plugin_id) return schemas.Response(success=True) @@ -382,11 +394,7 @@ def set_plugin_config(plugin_id: str, conf: dict, # 重新生效插件 PluginManager().init_plugin(plugin_id, conf) # 注册插件服务 - Scheduler().update_plugin_job(plugin_id) - # 注册菜单命令 - Command().init_commands(plugin_id) - # 注册插件API - register_plugin_api(plugin_id) + register_plugin(plugin_id) return schemas.Response(success=True) @@ -411,7 +419,3 @@ def uninstall_plugin(plugin_id: str, # 移除插件 PluginManager().remove_plugin(plugin_id) return schemas.Response(success=True) - - -# 注册全部插件API -register_plugin_api() diff --git a/app/core/plugin.py b/app/core/plugin.py index d0bd95eb..a03cb3c4 100644 --- a/app/core/plugin.py +++ b/app/core/plugin.py @@ -204,18 +204,21 @@ class PluginManager(metaclass=Singleton): # 停止插件 if pid: logger.info(f"正在停止插件 {pid}...") + plugin_obj = self._running_plugins.get(pid) + if not plugin_obj: + logger.warning(f"插件 {pid} 不存在或未加载") + return + plugins = {pid: plugin_obj} else: logger.info("正在停止所有插件...") - for plugin_id, plugin in self._running_plugins.items(): - if pid and plugin_id != pid: - continue + plugins = self._running_plugins + for plugin_id, plugin in plugins.items(): eventmanager.disable_event_handler(type(plugin)) self.__stop_plugin(plugin) # 清空对像 if pid: # 清空指定插件 - if pid in self._running_plugins: - self._running_plugins.pop(pid) + self._running_plugins.pop(pid, None) else: # 清空 self._plugins = {} @@ -833,8 +836,8 @@ class PluginManager(metaclass=Singleton): logger.debug(f"获取插件是否在本地包中存在失败,{e}") return False - def get_plugins_from_market(self, market: str, package_version: Optional[str] = None) -> Optional[ - List[schemas.Plugin]]: + def get_plugins_from_market(self, market: str, + package_version: Optional[str] = None) -> Optional[List[schemas.Plugin]]: """ 从指定的市场获取插件信息 :param market: 市场的 URL 或标识 diff --git a/app/helper/module.py b/app/helper/module.py index d9f5c1fc..2a7184be 100644 --- a/app/helper/module.py +++ b/app/helper/module.py @@ -7,14 +7,15 @@ from typing import List, Any, Callable from app.log import logger - FilterFuncType = Callable[[str, Any], bool] + def _default_filter(name: str, obj: Any) -> bool: """ 默认过滤器 """ - return True + return True if name and obj else False + class ModuleHelper: """ @@ -76,7 +77,8 @@ class ModuleHelper: def reload_sub_modules(parent_module, parent_module_name): """重新加载一级子模块""" - for sub_importer, sub_module_name, sub_is_pkg in pkgutil.walk_packages(parent_module.__path__, parent_module_name+'.'): + for sub_importer, sub_module_name, sub_is_pkg in pkgutil.walk_packages(parent_module.__path__, + parent_module_name + '.'): try: full_sub_module = importlib.import_module(sub_module_name) importlib.reload(full_sub_module)