164 lines
4.9 KiB
Python
164 lines
4.9 KiB
Python
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
|