mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-08 23:06:03 +00:00
refactor: 重构部分插件管理逻辑
This commit is contained in:
@@ -22,7 +22,22 @@ class PluginManager:
|
||||
|
||||
api_host: context.APIHost
|
||||
|
||||
plugins: list[context.RuntimeContainer]
|
||||
def plugins(
|
||||
self,
|
||||
enabled: bool=None,
|
||||
status: context.RuntimeContainerStatus=None,
|
||||
) -> list[context.RuntimeContainer]:
|
||||
"""获取插件列表
|
||||
"""
|
||||
plugins = self.loader.plugins
|
||||
|
||||
if enabled is not None:
|
||||
plugins = [plugin for plugin in plugins if plugin.enabled == enabled]
|
||||
|
||||
if status is not None:
|
||||
plugins = [plugin for plugin in plugins if plugin.status == status]
|
||||
|
||||
return plugins
|
||||
|
||||
def __init__(self, ap: app.Application):
|
||||
self.ap = ap
|
||||
@@ -30,7 +45,6 @@ class PluginManager:
|
||||
self.installer = github.GitHubRepoInstaller(ap)
|
||||
self.setting = setting.SettingManager(ap)
|
||||
self.api_host = context.APIHost(ap)
|
||||
self.plugins = []
|
||||
|
||||
async def initialize(self):
|
||||
await self.loader.initialize()
|
||||
@@ -41,27 +55,57 @@ class PluginManager:
|
||||
setattr(models, 'require_ver', self.api_host.require_ver)
|
||||
|
||||
async def load_plugins(self):
|
||||
self.plugins = await self.loader.load_plugins()
|
||||
await self.loader.load_plugins()
|
||||
|
||||
await self.setting.sync_setting(self.plugins)
|
||||
await self.setting.sync_setting(self.loader.plugins)
|
||||
|
||||
# 按优先级倒序
|
||||
self.plugins.sort(key=lambda x: x.priority, reverse=True)
|
||||
self.loader.plugins.sort(key=lambda x: x.priority, reverse=True)
|
||||
|
||||
self.ap.logger.debug(f'优先级排序后的插件列表 {self.plugins}')
|
||||
self.ap.logger.debug(f'优先级排序后的插件列表 {self.loader.plugins}')
|
||||
|
||||
async def initialize_plugin(self, plugin: context.RuntimeContainer):
|
||||
self.ap.logger.debug(f'初始化插件 {plugin.plugin_name}')
|
||||
plugin.plugin_inst = plugin.plugin_class(self.api_host)
|
||||
plugin.plugin_inst.ap = self.ap
|
||||
plugin.plugin_inst.host = self.api_host
|
||||
await plugin.plugin_inst.initialize()
|
||||
plugin.status = context.RuntimeContainerStatus.INITIALIZED
|
||||
|
||||
async def initialize_plugins(self):
|
||||
for plugin in self.plugins:
|
||||
for plugin in self.plugins():
|
||||
if not plugin.enabled:
|
||||
self.ap.logger.debug(f'插件 {plugin.plugin_name} 未启用,跳过初始化')
|
||||
continue
|
||||
try:
|
||||
plugin.plugin_inst = plugin.plugin_class(self.api_host)
|
||||
plugin.plugin_inst.ap = self.ap
|
||||
plugin.plugin_inst.host = self.api_host
|
||||
await plugin.plugin_inst.initialize()
|
||||
await self.initialize_plugin(plugin)
|
||||
except Exception as e:
|
||||
self.ap.logger.error(f'插件 {plugin.plugin_name} 初始化失败: {e}')
|
||||
self.ap.logger.exception(e)
|
||||
continue
|
||||
|
||||
async def destroy_plugin(self, plugin: context.RuntimeContainer):
|
||||
if plugin.status != context.RuntimeContainerStatus.INITIALIZED:
|
||||
return
|
||||
|
||||
self.ap.logger.debug(f'释放插件 {plugin.plugin_name}')
|
||||
await plugin.plugin_inst.destroy()
|
||||
plugin.plugin_inst = None
|
||||
plugin.status = context.RuntimeContainerStatus.MOUNTED
|
||||
|
||||
async def destroy_plugins(self):
|
||||
for plugin in self.plugins():
|
||||
if plugin.status != context.RuntimeContainerStatus.INITIALIZED:
|
||||
self.ap.logger.debug(f'插件 {plugin.plugin_name} 未初始化,跳过释放')
|
||||
continue
|
||||
|
||||
try:
|
||||
await self.destroy_plugin(plugin)
|
||||
except Exception as e:
|
||||
self.ap.logger.error(f'插件 {plugin.plugin_name} 释放失败: {e}')
|
||||
self.ap.logger.exception(e)
|
||||
continue
|
||||
|
||||
async def install_plugin(
|
||||
self,
|
||||
plugin_source: str,
|
||||
@@ -127,7 +171,7 @@ class PluginManager:
|
||||
def get_plugin_by_name(self, plugin_name: str) -> context.RuntimeContainer:
|
||||
"""通过插件名获取插件
|
||||
"""
|
||||
for plugin in self.plugins:
|
||||
for plugin in self.plugins():
|
||||
if plugin.plugin_name == plugin_name:
|
||||
return plugin
|
||||
return None
|
||||
@@ -143,30 +187,32 @@ class PluginManager:
|
||||
|
||||
emitted_plugins: list[context.RuntimeContainer] = []
|
||||
|
||||
for plugin in self.plugins:
|
||||
if plugin.enabled:
|
||||
if event.__class__ in plugin.event_handlers:
|
||||
self.ap.logger.debug(f'插件 {plugin.plugin_name} 处理事件 {event.__class__.__name__}')
|
||||
|
||||
is_prevented_default_before_call = ctx.is_prevented_default()
|
||||
for plugin in self.plugins(
|
||||
enabled=True,
|
||||
status=context.RuntimeContainerStatus.INITIALIZED
|
||||
):
|
||||
if event.__class__ in plugin.event_handlers:
|
||||
self.ap.logger.debug(f'插件 {plugin.plugin_name} 处理事件 {event.__class__.__name__}')
|
||||
|
||||
is_prevented_default_before_call = ctx.is_prevented_default()
|
||||
|
||||
try:
|
||||
await plugin.event_handlers[event.__class__](
|
||||
plugin.plugin_inst,
|
||||
ctx
|
||||
)
|
||||
except Exception as e:
|
||||
self.ap.logger.error(f'插件 {plugin.plugin_name} 处理事件 {event.__class__.__name__} 时发生错误: {e}')
|
||||
self.ap.logger.debug(f"Traceback: {traceback.format_exc()}")
|
||||
|
||||
emitted_plugins.append(plugin)
|
||||
try:
|
||||
await plugin.event_handlers[event.__class__](
|
||||
plugin.plugin_inst,
|
||||
ctx
|
||||
)
|
||||
except Exception as e:
|
||||
self.ap.logger.error(f'插件 {plugin.plugin_name} 处理事件 {event.__class__.__name__} 时发生错误: {e}')
|
||||
self.ap.logger.debug(f"Traceback: {traceback.format_exc()}")
|
||||
|
||||
emitted_plugins.append(plugin)
|
||||
|
||||
if not is_prevented_default_before_call and ctx.is_prevented_default():
|
||||
self.ap.logger.debug(f'插件 {plugin.plugin_name} 阻止了默认行为执行')
|
||||
if not is_prevented_default_before_call and ctx.is_prevented_default():
|
||||
self.ap.logger.debug(f'插件 {plugin.plugin_name} 阻止了默认行为执行')
|
||||
|
||||
if ctx.is_prevented_postorder():
|
||||
self.ap.logger.debug(f'插件 {plugin.plugin_name} 阻止了后序插件的执行')
|
||||
break
|
||||
if ctx.is_prevented_postorder():
|
||||
self.ap.logger.debug(f'插件 {plugin.plugin_name} 阻止了后序插件的执行')
|
||||
break
|
||||
|
||||
for key in ctx.__return_value__.keys():
|
||||
if hasattr(ctx.event, key):
|
||||
@@ -191,16 +237,22 @@ class PluginManager:
|
||||
|
||||
return ctx
|
||||
|
||||
async def update_plugin_status(self, plugin_name: str, new_status: bool):
|
||||
async def update_plugin_switch(self, plugin_name: str, new_status: bool):
|
||||
if self.get_plugin_by_name(plugin_name) is not None:
|
||||
for plugin in self.plugins:
|
||||
for plugin in self.plugins():
|
||||
if plugin.plugin_name == plugin_name:
|
||||
plugin.enabled = new_status
|
||||
|
||||
for func in plugin.content_functions:
|
||||
func.enable = new_status
|
||||
if plugin.enabled == new_status:
|
||||
return False
|
||||
|
||||
await self.setting.dump_container_setting(self.plugins)
|
||||
# 初始化/释放插件
|
||||
if new_status:
|
||||
await self.initialize_plugin(plugin)
|
||||
else:
|
||||
await self.destroy_plugin(plugin)
|
||||
|
||||
plugin.enabled = new_status
|
||||
|
||||
await self.setting.dump_container_setting(self.loader.plugins)
|
||||
|
||||
break
|
||||
|
||||
@@ -214,11 +266,11 @@ class PluginManager:
|
||||
plugin_name = plugin.get('name')
|
||||
plugin_priority = plugin.get('priority')
|
||||
|
||||
for plugin in self.plugins:
|
||||
for plugin in self.loader.plugins:
|
||||
if plugin.plugin_name == plugin_name:
|
||||
plugin.priority = plugin_priority
|
||||
break
|
||||
|
||||
self.plugins.sort(key=lambda x: x.priority, reverse=True)
|
||||
self.loader.plugins.sort(key=lambda x: x.priority, reverse=True)
|
||||
|
||||
await self.setting.dump_container_setting(self.plugins)
|
||||
await self.setting.dump_container_setting(self.loader.plugins)
|
||||
|
||||
Reference in New Issue
Block a user