from threading import Thread import log from app.conf import SystemConfig from app.helper import SubmoduleHelper from app.plugins.event_manager import EventManager from app.utils.commons import singleton @singleton class PluginManager: """ 插件管理器 """ systemconfig = None eventmanager = None # 插件列表 _plugins = {} # 运行态插件列表 _running_plugins = {} # 配置Key _config_key = "plugin.%s" # 事件处理线程 _thread = None # 开关 _active = False def __init__(self): self.init_config() def init_config(self): self.systemconfig = SystemConfig() self.eventmanager = EventManager() # 启动事件处理进程 self.start_service() def __run(self): """ 事件处理线程 """ while self._active: event, handlers = self.eventmanager.get_event() if event: log.info(f"处理事件:{event.event_type} - {handlers}") for handler in handlers: try: names = handler.__qualname__.split(".") self.run_plugin(names[0], names[1], event) except Exception as e: log.error(f"事件处理出错:{str(e)}") def start_service(self): """ 启动 """ # 加载插件 self.__load_plugins() # 将事件管理器设为启动 self._active = True self._thread = Thread(target=self.__run) # 启动事件处理线程 self._thread.start() def stop_service(self): """ 停止 """ # 将事件管理器设为停止 self._active = False # 等待事件处理线程退出 self._thread.join() # 停止所有插件 self.__stop_plugins() def __load_plugins(self): """ 加载所有插件 """ plugins = SubmoduleHelper.import_submodules( "app.plugins.modules", filter_func=lambda _, obj: hasattr(obj, 'init_config') ) plugins.sort(key=lambda x: x.module_order if hasattr(x, "module_order") else 0) for plugin in plugins: module_id = plugin.__name__ self._plugins[module_id] = plugin self._running_plugins[module_id] = plugin() self.reload_plugin(module_id) log.info(f"加载插件:{plugin}") def run_plugin(self, pid, method, *args, **kwargs): """ 运行插件 """ if not self._running_plugins.get(pid): return None if not hasattr(self._running_plugins[pid], method): return return getattr(self._running_plugins[pid], method)(*args, **kwargs) def reload_plugin(self, pid): """ 生效插件配置 """ if not self._running_plugins.get(pid): return if hasattr(self._running_plugins[pid], "init_config"): self._running_plugins[pid].init_config(self.get_plugin_config(pid)) def __stop_plugins(self): """ 停止所有插件 """ for plugin in self._running_plugins.values(): if hasattr(plugin, "stop_service"): plugin.stop_service() def get_plugin_config(self, pid): """ 获取插件配置 """ if not self._plugins.get(pid): return {} return self.systemconfig.get_system_config(self._config_key % pid) or {} def save_plugin_config(self, pid, conf): """ 保存插件配置 """ if not self._plugins.get(pid): return False return self.systemconfig.set_system_config(self._config_key % pid, conf) def get_plugins_conf(self): """ 获取所有插件配置 """ all_confs = {} for pid, plugin in self._plugins.items(): # 基本属性 conf = {} if hasattr(plugin, "module_name"): conf.update({"name": plugin.module_name}) if hasattr(plugin, "module_desc"): conf.update({"desc": plugin.module_desc}) if hasattr(plugin, "module_version"): conf.update({"version": plugin.module_version}) if hasattr(plugin, "module_icon"): conf.update({"icon": plugin.module_icon}) if hasattr(plugin, "module_color"): conf.update({"color": plugin.module_color}) if hasattr(plugin, "module_author"): conf.update({"author": plugin.module_author}) if hasattr(plugin, "module_config_prefix"): conf.update({"prefix": plugin.module_config_prefix}) # 配置项 conf.update({"fields": plugin.get_fields() or {}}) # 配置值 conf.update({"config": self.get_plugin_config(pid)}) # 汇总 all_confs[pid] = conf return all_confs