refactor: 重构部分插件管理逻辑

This commit is contained in:
Junyan Qin
2024-11-16 16:13:02 +08:00
parent bb219889e5
commit 658eb278c4
13 changed files with 219 additions and 158 deletions

View File

@@ -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)