diff --git a/astrbot/core/star/star.py b/astrbot/core/star/star.py index 862d8d03..eb940b40 100644 --- a/astrbot/core/star/star.py +++ b/astrbot/core/star/star.py @@ -2,7 +2,7 @@ from __future__ import annotations from types import ModuleType from typing import List, Dict -from dataclasses import dataclass +from dataclasses import dataclass, field from astrbot.core.config import AstrBotConfig star_registry: List[StarMetadata] = [] @@ -40,7 +40,7 @@ class StarMetadata: config: AstrBotConfig = None '''插件配置''' - star_handler_full_names: List[str] = None + star_handler_full_names: List[str] = field(default_factory=list) '''注册的 Handler 的全名列表''' def __str__(self) -> str: diff --git a/astrbot/core/star/star_handler.py b/astrbot/core/star/star_handler.py index 2d96ac8c..7fee47d2 100644 --- a/astrbot/core/star/star_handler.py +++ b/astrbot/core/star/star_handler.py @@ -57,7 +57,10 @@ class StarHandlerRegistry(Generic[T]): if h[1] == handler: self._handlers.pop(i) break - del self.star_handlers_map[handler.handler_full_name] + try: + del self.star_handlers_map[handler.handler_full_name] + except KeyError: + pass def __iter__(self): '''使 StarHandlerRegistry 支持迭代''' diff --git a/astrbot/core/star/star_manager.py b/astrbot/core/star/star_manager.py index 72e74f36..4d8b5e8a 100644 --- a/astrbot/core/star/star_manager.py +++ b/astrbot/core/star/star_manager.py @@ -40,6 +40,8 @@ class PluginManager: '''保留插件的路径。在 packages 目录下''' self.conf_schema_fname = "_conf_schema.json" '''插件配置 Schema 文件名''' + + self.failed_plugin_info = "" def _get_classes(self, arg: ModuleType): '''获取指定模块(可以理解为一个 python 文件)下所有的类''' @@ -263,7 +265,6 @@ class PluginManager: metadata.module_path = path star_map[path] = metadata star_registry.append(metadata) - logger.debug(f"插件 {root_dir_name} 载入成功。") # 禁用/启用插件 if metadata.module_path in inactivated_plugins: @@ -297,8 +298,12 @@ class PluginManager: await metadata.star_cls.initialize() except BaseException as e: - traceback.print_exc() - fail_rec += f"加载 {path} 插件时出现问题,原因 {str(e)}\n" + logger.error(f"----- 插件 {root_dir_name} 载入失败 -----") + errors = traceback.format_exc() + for line in errors.split('\n'): + logger.error(f"| {line}") + logger.error("----------------------------------") + fail_rec += f"加载 {root_dir_name} 插件时出现问题,原因 {str(e)}。\n" # 清除 pip.main 导致的多余的 logging handlers for handler in logging.root.handlers[:]: @@ -307,6 +312,7 @@ class PluginManager: if not fail_rec: return True, None else: + self.failed_plugin_info = fail_rec return False, fail_rec async def install_plugin(self, repo_url: str): diff --git a/astrbot/dashboard/routes/plugin.py b/astrbot/dashboard/routes/plugin.py index 63cb6ce1..de9f1a48 100644 --- a/astrbot/dashboard/routes/plugin.py +++ b/astrbot/dashboard/routes/plugin.py @@ -75,10 +75,10 @@ class PluginRoute(Route): "version": plugin.version, "reserved": plugin.reserved, "activated": plugin.activated, - "handlers": await self.get_plugin_handlers_info(plugin.star_handler_full_names) + "handlers": await self.get_plugin_handlers_info(plugin.star_handler_full_names), } _plugin_resp.append(_t) - return Response().ok(_plugin_resp).__dict__ + return Response().ok(_plugin_resp, message=self.plugin_manager.failed_plugin_info).__dict__ async def get_plugin_handlers_info(self, handler_full_names: list[str]): '''解析插件行为''' diff --git a/dashboard/src/views/ConfigPage.vue b/dashboard/src/views/ConfigPage.vue index 4f711278..f57bd823 100644 --- a/dashboard/src/views/ConfigPage.vue +++ b/dashboard/src/views/ConfigPage.vue @@ -68,7 +68,7 @@ import config from '@/config'; - + 删除这项 @@ -215,6 +215,20 @@ export default { // new_tmpl_cfg.id = "new_" + val + "_" + this.config_data[config_item_name].length; this.config_data[config_item_name].push(new_tmpl_cfg); this.config_template_tab = this.config_data[config_item_name].length - 1; + }, + deleteItem(config_item_name, index) { + console.log(config_item_name, index); + let new_list = []; + for (let i = 0; i < this.config_data[config_item_name].length; i++) { + if (i !== index) { + new_list.push(this.config_data[config_item_name][i]); + } + } + this.config_data[config_item_name] = new_list; + + if (this.config_template_tab > 0) { + this.config_template_tab -= 1; + } } }, } diff --git a/dashboard/src/views/ExtensionPage.vue b/dashboard/src/views/ExtensionPage.vue index 2550fcf9..2fe12c81 100644 --- a/dashboard/src/views/ExtensionPage.vue +++ b/dashboard/src/views/ExtensionPage.vue @@ -15,7 +15,30 @@ import { max } from 'date-fns';
-

🧩 已安装的插件

+
+

🧩 已安装的插件

+ + + + + 错误信息 + {{ extension_data.message }} +
+ 详情请检查控制台 +
+ + + + 关闭 + +
+
+
@@ -47,50 +70,50 @@ import { max } from 'date-fns'; -
-
-

🧩 插件市场

- 如无法显示,请打开 链接 复制想安装插件对应的 `repo` - 链接然后点击右下角 + 号安装,或打开链接下载压缩包安装。 - - {{ isListView ? 'mdi-view-grid' : 'mdi-view-list' }} - +
+
+

🧩 插件市场

+ 如无法显示,请打开 链接 复制想安装插件对应的 `repo` + 链接然后点击右下角 + 号安装,或打开链接下载压缩包安装。 + + {{ isListView ? 'mdi-view-grid' : 'mdi-view-list' }} + +
-
- - - - - - - - - + + + 插件开发文档 | @@ -209,11 +232,11 @@ import { max } from 'date-fns'; - {{selectedPlugin.name}} 插件行为 + {{ selectedPlugin.name }} 插件行为 + item-key="name"> @@ -262,7 +285,8 @@ export default { data() { return { extension_data: { - "data": [] + "data": [], + "message": "" }, extension_url: "", status: "", @@ -338,7 +362,8 @@ export default { }, getExtensions() { axios.get('/api/plugin/get').then((res) => { - this.extension_data.data = res.data.data; + this.extension_data = res.data; + this.checkAlreadyInstalled(); }); }, @@ -368,7 +393,7 @@ export default { this.onLoadingDialogResult(2, res.data.message, -1); return; } - this.extension_data.data = res.data.data; + this.extension_data = res.data; this.upload_file = ""; this.onLoadingDialogResult(1, res.data.message); this.dialog = false; @@ -389,8 +414,7 @@ export default { this.onLoadingDialogResult(2, res.data.message, -1); return; } - this.extension_data.data = res.data.data; - console.log(this.extension_data); + this.extension_data = res.data; this.extension_url = ""; this.onLoadingDialogResult(1, res.data.message); this.dialog = false; @@ -412,7 +436,7 @@ export default { this.toast(res.data.message, "error"); return; } - this.extension_data.data = res.data.data; + this.extension_data = res.data; this.toast(res.data.message, "success"); this.dialog = false; this.getExtensions(); @@ -430,7 +454,7 @@ export default { this.onLoadingDialogResult(2, res.data.message, -1); return; } - this.extension_data.data = res.data.data; + this.extension_data = res.data; console.log(this.extension_data); this.onLoadingDialogResult(1, res.data.message); this.dialog = false;