diff --git a/plugin_common/plugin_manager.py b/plugin_common/plugin_manager.py index c085b4e..f408520 100644 --- a/plugin_common/plugin_manager.py +++ b/plugin_common/plugin_manager.py @@ -57,15 +57,35 @@ class PluginManager: # 遍历插件目录 for item in os.listdir(self.plugin_dir): if os.path.isdir(os.path.join(self.plugin_dir, item)) and not item.startswith("__"): - # 检查是否有__init__.py文件 - if os.path.exists(os.path.join(self.plugin_dir, item, "__init__.py")): + # 检查是否有main.py文件 + if os.path.exists(os.path.join(self.plugin_dir, item, "main.py")): plugin_modules.append(item) elif item.endswith(".py") and not item.startswith("__"): # 单文件插件 plugin_modules.append(item[:-3]) - self.LOG.info(f"plugin_modules:{plugin_modules}") + self.LOG.info(f"发现插件模块: {plugin_modules}") return plugin_modules + def load_all_plugins(self) -> Dict[str, PluginInterface]: + """ + 加载所有插件 + + Returns: + 插件实例字典 + """ + plugin_modules = self.discover_plugins() + loaded_plugins = [] + + for plugin_name in plugin_modules: + try: + if self.load_plugin(plugin_name): + loaded_plugins.append(plugin_name) + except Exception as e: + self.LOG.error(f"加载插件 {plugin_name} 时发生错误: {str(e)}", exc_info=True) + + self.LOG.info(f"成功加载插件: {loaded_plugins}") + return self.plugins + def load_plugin(self, plugin_name: str) -> Optional[PluginInterface]: """ 加载插件 @@ -80,40 +100,42 @@ class PluginManager: # 如果插件已加载,直接返回 if plugin_name in self.plugins: return self.plugins[plugin_name] - - # 确定插件路径 - if os.path.isdir(os.path.join(self.plugin_dir, plugin_name)): - plugin_path = os.path.join(self.plugin_dir, plugin_name) - - # 直接从main.py加载插件,不再尝试从__init__.py加载 - main_module_path = f"{plugin_name}.main" - if os.path.exists(os.path.join(plugin_path, "main.py")): - try: - module = importlib.import_module(main_module_path) - self.plugin_modules[plugin_name] = module - except ImportError as e: - self.LOG.error(f"导入插件模块 {main_module_path} 失败: {e}") - return None - else: - self.LOG.error(f"插件 {plugin_name} 缺少 main.py 文件") + + # 确定插件路径和模块路径 + plugin_path = os.path.join(self.plugin_dir, plugin_name) + + # 加载模块 + if os.path.isdir(plugin_path) and os.path.exists(os.path.join(plugin_path, "main.py")): + # 目录插件,从main.py加载 + module_path = f"plugins.{plugin_name}.main" + try: + module = importlib.import_module(module_path) + self.plugin_modules[plugin_name] = module + except ImportError as e: + self.LOG.error(f"导入插件模块 {module_path} 失败: {e}") return None else: # 单文件插件 plugin_path = self.plugin_dir - module = importlib.import_module(plugin_name) - self.plugin_modules[plugin_name] = module - + try: + module = importlib.import_module(plugin_name) + self.plugin_modules[plugin_name] = module + except ImportError as e: + self.LOG.error(f"导入单文件插件 {plugin_name} 失败: {e}") + return None + # 查找插件类 plugin_class = None for name, obj in inspect.getmembers(module): - if (inspect.isclass(obj) and - (issubclass(obj, PluginInterface) or issubclass(obj, MessagePluginInterface)) and - obj != PluginInterface and - obj != MessagePluginInterface): + if (inspect.isclass(obj) and + issubclass(obj, PluginInterface) and + obj != PluginInterface and + obj != MessagePluginInterface and + obj != ScheduledPluginInterface): plugin_class = obj break - - # 如果插件类为空,尝试查找get_plugin函数 + + # 如果没有找到插件类,尝试查找get_plugin函数 if plugin_class is None: get_plugin_func = getattr(module, "get_plugin", None) if callable(get_plugin_func): @@ -147,53 +169,39 @@ class PluginManager: else: self.LOG.error(f"插件 {plugin_name} 中未找到有效的插件类或 get_plugin 函数") return None - + # 实例化插件 plugin = plugin_class() plugin.status = PluginStatus.LOADED - + # 设置插件路径 plugin.set_plugin_path(plugin_path) - + # 加载插件配置 if not plugin.load_config(): self.LOG.error(f"插件 {plugin_name} 加载配置失败") return None - + # 初始化插件 if not plugin.initialize(self.system_context): self.LOG.error(f"插件 {plugin_name} 初始化失败") return None - + # 注册插件 PluginRegistry().register(plugin) - + # 存储插件实例 self.plugins[plugin.name] = plugin - + # 发布插件加载事件 EventSystem().publish(EventType.PLUGIN_LOADED, {"plugin": plugin}) - + return plugin - + except Exception as e: - self.LOG.error(f"加载插件 {plugin_name} 失败: {e}") + self.LOG.error(f"加载插件 {plugin_name} 失败: {e}", exc_info=True) return None - def load_all_plugins(self) -> Dict[str, PluginInterface]: - """ - 加载所有插件 - - Returns: - 插件实例字典 - """ - plugin_modules = self.discover_plugins() - - for module_name in plugin_modules: - self.load_plugin(module_name) - - return self.plugins - def unload_plugin(self, plugin_name: str) -> bool: """ 卸载插件