结构调整

视频解析多图/多媒体结构 消息体适配
This commit is contained in:
2026-09-08 14:25:32 +08:00
parent 30899688a7
commit 131b92b319
72 changed files with 433 additions and 186 deletions
+2
View File
@@ -3,6 +3,8 @@
> 依据 《插件结构标准》(docs/plugin-structure-standard.md) 与 《插件配置文件标准》(docs/plugin-config-standard.md),
> 并参照脚手架模板 `../plugin_template/nonebot_plugin_template`。
> 说明:初版为**审计报告**;后续按用户确认已开始落地改造(见下方「本轮已落地改动」)。
>
> **后续变动**:其中 `hexi_core` 与 `web_hub` 已从 `hexi/plugins/` 移出,改为机器人核心模块 `hexi/core`、`hexi/web_hub`(非插件),本报告中这两项的“插件”表述仅供参考。
---
+16 -12
View File
@@ -20,8 +20,12 @@
```text
hexi/
├── web_config.py # 配置标准核心:schema 注册 / 值库 / 保存热刷新
├── config_standard.py # pydantic Config 一键接入的辅助封装
├── web_hub/ # 统一 Web 管理台 / 鉴权 / 配置标准
│ ├── web_config.py # 配置标准核心:schema 注册 / 值库 / 保存热刷新
│ ├── config_standard.py # pydantic Config 一键接入的辅助封装
│ ├── web_auth.py # 统一 Web 鉴权(OAuth2 + SQLite)
│ ├── web_plugin_registry.py # 统一 Web 插件注册中心
│ └── web_hub_auth.py # 兼容 shim
├── config/
│ └── plugin_config.json # 统一值库:{ "<plugin_id>": { key: value, ... } }
└── web/ # /hub 前端(通用 schema 表单渲染器)
@@ -143,7 +147,7 @@ hexi/
```python
# 在插件 __init__.py 里
from hexi.config_standard import register_model_config
from hexi.web_hub.config_standard import register_model_config
from .config import config
register_model_config(
@@ -168,7 +172,7 @@ register_model_config(
### 方式 B:非 pydantic 插件手动注册
```python
from hexi.web_config import register_plugin_config
from hexi.web_hub.web_config import register_plugin_config
def _get(): # 返回当前生效值 dict
return {"field": get_my_cur_value("field")}
@@ -209,7 +213,7 @@ register_plugin_config(
2. **写值库** `plugin_config.json`(原子写)。
3. **写 .env**:非 list 字段写入 `os.environ` + `../../.env`(保证重启仍生效);list/path/object 跳过,避免 `str(list)` 破坏重启解析。
4. **调 `apply(values)`**:把值热应用到插件运行态对象(list/path/object 也在此生效)。
5. 若插件未提供 apply,则 `hot_reload(plugin_id)` 让插件重载。
5. 若插件未提供 apply,则 `hot_reload(plugin_id)` 让插件重载;**library/非 application 插件不受热重载**(见《插件类型分类》,热拔插会破坏依赖它的插件)。
**为什么 apply 与 env 都做**:NoneBot 的 `get_driver().config` 在启动时即固定,重载插件也读不到新 env;所以运行期必须 apply,重启靠 env。
@@ -220,7 +224,7 @@ register_plugin_config(
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | `/api/plugins` | 所有已注册 Web 插件 |
| GET | `/api/plugins/catalog` | 所有应用插件 + `has_config/has_web/web_path` |
| GET | `/api/plugins/catalog` | 所有 application/library 插件(含带配置项的 library)+ `type/has_config/has_web/web_path` |
| GET | `/api/plugins/{id}/config` | 读 `{schema, values, revision}`(登录);secret 值只返回 `****` |
| POST | `/api/plugins/{id}/config` | 保存 `{ "revision": n, "values": { key: value } }`;冲突 409,校验失败 422 |
| DELETE | `/api/plugins/{id}/config` | 清空该插件覆盖,恢复默认(可选) |
@@ -242,7 +246,7 @@ register_plugin_config(
## 9. 权限与安全
- 全部配置接口走 `hexi.web_auth.require_admin`(OAuth2 + SQLite)。
- 全部配置接口走 `hexi.web_hub.web_auth.require_admin`(OAuth2 + SQLite)。
- 配置 POST 必须携带 GET 返回的 `revision`;缺失返回 428,冲突返回 409。
- 只允许 `plugin_id` 存在于注册表,未注册返回 `ok:false`(防任意写入)。
- 部署时必须显式设置 Web 管理员凭据;禁止生产环境使用默认的 `admin/admin`。
@@ -277,7 +281,7 @@ register_plugin_config(
```python
# hexi/plugins/nonebot_plugin_helldivers_tools/__init__.py
from hexi.config_standard import register_model_config
from hexi.web_hub.config_standard import register_model_config
from .config import config as _hd2_config
register_model_config(
@@ -295,7 +299,7 @@ register_model_config(
## 12. 已接入与待接入
- **已接入**:`helldivers_tools`、`mc_server_status`、`video_analysis`、`steam_info`、`picstatus`、`galgame_card`。
- **未接入(建议后续)**:`learning_chat`、`group_daily_analysis`(已有独自 Web 配置,避免冲突)、`picfinder_take`、`bf_bot`、`group_tools`、`hexi_core`(模块级常量/SUPERUSERS,运行期热更复杂)。
- **未接入(建议后续)**:`learning_chat`、`group_daily_analysis`(已有独自 Web 配置,避免冲突)、`picfinder_take`、`bf_bot`、`group_tools`、`hexi/core`(模块级常量/SUPERUSERS,运行期热更复杂)。
---
@@ -316,7 +320,7 @@ register_model_config(
### 13.2 通用注册 API(任意来源)
```python
from hexi.config_standard import register_config_items
from hexi.web_hub.config_standard import register_config_items
register_config_items(
__name__, # = NoneBot 插件模块名
@@ -339,7 +343,7 @@ register_config_items(
Web 保存后 apply 会把新值写回来源(模块属性/dict/自定义),但若插件在别处是用 `from .config import X` **值拷贝**进来的量,不受影响。要真正运行期生效,插件在读配置处改用统一 API:
```python
from hexi.web_config import get_effective_value
from hexi.web_hub.web_config import get_effective_value
limit = get_effective_value("hexi.plugins.nonebot_plugin_picfinder_take", "DAILY_LIMIT", 50)
if not check_quota(limit): ...
@@ -395,7 +399,7 @@ if not check_quota(limit): ...
### 14.3 一键注册 API
```python
from hexi.config_standard import register_object_set
from hexi.web_hub.config_standard import register_object_set
register_object_set(
__name__, # NoneBot 插件模块名
+5 -4
View File
@@ -84,6 +84,7 @@ nonebot_plugin_xxx/
## 4. `__init__.py` 标准职责(固定顺序)
1. `__plugin_meta__ = PluginMetadata(name=..., description=..., usage=..., type="application")`。
> **type 取值(NoneBot 发布规范)**:`application`(向机器人用户提供功能,支持热插拔/热重载)或 `library`(为其他插件提供能力,不可热拔插)。新插件默认 `application`。本仓库的 `hexi/core`、`hexi/web_hub` 已从插件目录移出,作为机器人核心模块(**非插件**),直接不参与热拔插。
2. 声明依赖 `require("nonebot_plugin_alconna")` 等。
3. 显式导入子模块(`from . import handlers, services, utils`),注册 matcher/handler。
4. **配置注册**(在 config 就绪后):`register_model_config`(pydantic Config)或 `register_config_items` / `register_object_set`(来源无关)。
@@ -108,7 +109,7 @@ config = get_plugin_config(Config)
### 4.2 来源无关型(模块常量 / 配置文件 / DB)
```python
from hexi.config_standard import register_config_items, register_object_set
from hexi.web_hub.config_standard import register_config_items, register_object_set
register_object_set(__name__, "groups", [ {item_schema...} ], key_field="group_id",
getter=get_groups, setter=set_groups, nosave=True)
```
@@ -133,20 +134,20 @@ register_object_set(__name__, "groups", [ {item_schema...} ], key_field="group_i
- `services/`:业务编排,可依赖 repository / 外部 API;把「一个业务动作」收敛到一个方法。
- **禁止** `from x import *`、`except: pass`、`print()`;用 `logger`。
- async handler 内避免同步阻塞(`requests` / `time.sleep` / 同步爬虫);需要就 `asyncio.to_thread`。
- 命令触发:需要 @ 用 `rule=to_me()`;全局命令注意与其它插件冲突;高开销命令加冷却/限频(`hexi_core` 的 `cooldown/rate_limit`)。
- 命令触发:需要 @ 用 `rule=to_me()`;全局命令注意与其它插件冲突;高开销命令加冷却/限频(`hexi/core` 的 `cooldown/rate_limit`)。
- 外部 API:统一超时 + 重试 + 失败降级/用户提示。
## 8. Web 接入标准
- 需要独立 Web 页:`register_web_plugin(id, name, icon, lambda: build_app(), module_name=__name__)`,hub 启动自动挂载 `/api/<id>`。
- 需要 Web 配置:`register_plugin_config` / `register_model_config` / `register_config_items` / `register_object_set`(schema 驱动表单)。
- 鉴权统一用 `hexi.web_auth.require_admin`(OAuth2 + SQLite),不要自造一套。
- 鉴权统一用 `hexi.web_hub.web_auth.require_admin`(OAuth2 + SQLite),不要自造一套。
- 敏感字段 `secret=True`,前端掩码;写回允许明文。
## 9. 插件迁移检查清单
- [ ] 包名改为 `nonebot_plugin_*`,位置在 `../../hexi/plugins`。
- [ ] 有 `__plugin_meta__`,`type="application"`。
- [ ] 有 `__plugin_meta__`,`type="application"`(核心/框架插件标 `library`,不参与热拔插)。
- [ ] 配置已接入统一标准(Web 能读能改,运行期/重启生效)。
- [ ] 命令在 `handlers/`,业务在 `services/`,工具在 `utils/`。
- [ ] 数据访问集中(repository / services),原子写 / 事务。
+75
View File
@@ -0,0 +1,75 @@
# HeXi 插件类型分类(library / application)
> 依据 NoneBot 发布规范:`type` 是插件类别,发布必填。当前有效类别:
> - `library`:为其他插件编写提供功能(核心库/框架),**不参与热拔插/热重载**。
> - `application`:向机器人用户提供功能,**可热拔插/热重载**。
>
> 本仓库自定义插件统一在 `hexi/plugins/`(经 `nonebot.load_plugins("hexi")` 加载);
> pip 社区插件由其自带元数据决定类别,本仓库不改动,但热拔插管理器会按类别保护。
>
> **变动**:原 `nonebot_plugin_hexi_core` / `nonebot_plugin_web_hub` 已从 `hexi/plugins/` 移出,现为机器人核心模块 `hexi/core`、`hexi/web_hub`(**非插件**),不再参与插件类型分类与热拔插,故下表不列出。
---
## 自定义插件(`hexi/plugins/`)
| 插件(模块名) | type | 说明 |
|---|---|---|
| `hexi.plugins.nonebot_plugin_bf_bot` | `application` | 战地系列战绩查询(BF3/4/1/5/2042/6)。 |
| `hexi.plugins.nonebot_plugin_steam_info` | `application` | Steam 信息播报/查询。 |
| `hexi.plugins.nonebot_plugin_mc_server_status` | `application` | Minecraft 服务器状态查询。 |
| `hexi.plugins.nonebot_plugin_ncm_saying` | `application` | 网易云热评。 |
| `hexi.plugins.nonebot_plugin_helldivers_tools` | `application` | 绝地潜兵 2 前线战况/战备。 |
| `hexi.plugins.nonebot_plugin_learning_chat` | `application` | 马尔可夫链群聊学习/复读。 |
| `hexi.plugins.nonebot_plugin_galgame_card` | `application` | 群聊人设卡生成/展示。 |
| `hexi.plugins.nonebot_plugin_group_tools` | `application` | 群管理工具集。 |
| `hexi.plugins.nonebot_plugin_group_daily_analysis` | `application` | 群聊行为分析报告。 |
| `hexi.plugins.nonebot_plugin_dailywife` | `application` | 每日随机抽取群友。 |
| `hexi.plugins.nonebot_plugin_deer_pipe` | `application` | 每日打卡(鹿)。 |
| `hexi.plugins.nonebot_plugin_dice` | `application` | 掷骰子/结婚判定。 |
| `hexi.plugins.nonebot_plugin_makeaquote` | `application` | 名人/语录图生成。 |
| `hexi.plugins.nonebot_plugin_random_jm_code` | `application` | 随机 JM 码。 |
| `hexi.plugins.nonebot_plugin_video_analysis` | `application` | 视频链接解析。 |
| `hexi.plugins.nonebot_plugin_regif` | `application` | GIF 倒放/处理。 |
| `hexi.plugins.nonebot_plugin_picfinder_take` | `application` | 二次元搜图。 |
| `hexi.plugins.nonebot_plugin_picstatus` | `application` | 设备状态图。 |
| `hexi.plugins.nonebot_plugin_huoziyinshua` | `application` | otto 活字印刷(语音合成)。 |
| `hexi.plugins.memes_ops` | `application` | 给 `nonebot_plugin_memes` 追加裸词选项(用户侧语法)。 |
| `hexi.plugins.nonebot_plugin_deadlock` | - | **停用**:整文件被注释,不注册任何功能(历史遗留)。 |
| `hexi.plugins.nonebot_plugin_brash_general_supercredits_tools` | - | **空壳**:未完成占位,`__init__.py` 仅注释,无功能。 |
---
## pip 社区插件(`pyproject.toml` 声明)
这些插件由安装包自带的 `__plugin_meta__` 决定类别,本仓库不改动;其中的 library 型插件同样受热拔插保护。
| 插件 | 常见类别 | 说明 |
|---|---|---|
| `nonebot_plugin_apscheduler` | library | 定时任务框架。 |
| `nonebot_plugin_alconna` | library | 命令解析/消息框架。 |
| `nonebot_plugin_saa` | library | 跨平台发送辅助。 |
| `nonebot_plugin_session` | library | 会话/状态管理。 |
| `nonebot_plugin_userinfo` | library | 用户信息接口。 |
| `nonebot_plugin_user` | application | 用户数据接口(含绑定/查看命令)。 |
| `nonebot_plugin_datastore` | library | 数据存储底座。 |
| `nonebot_plugin_orm` | library | ORM 底座。 |
| `nonebot_plugin_fix_qq_img_ssl` | library | 图片 SSL 修复补丁。 |
| `nonebot_plugin_wordcloud` | application | 词云生成。 |
| `nonebot_plugin_memes` | application | 表情包。 |
| `nonebot_plugin_multincm` | application | 多源网抑云点歌。 |
| `nonebot_plugin_random_stereotypes` | application | 随机刻板印象。 |
| `nonebot_plugin_rollpig` | application | 滚猪。 |
> 说明:社区插件类别以其安装包 `PluginMetadata.type` 为准,若与本表不符请以包内元数据为准。
---
## 热拔插保护
`../../hexi/core/plugin_manager.py` 中的 `hot_load / hot_unload / hot_reload` 会先判断目标插件类别:
- 目标为 `application` → 正常热拔插。
- 其余(`library` / 未声明类别,含根包无 meta 但被依赖的核心/框架,如 alconna)→ **拒绝**并记录 warning(热拔插会使依赖它的插件运行混乱)。
`hexi/web_hub/web_config.py` 保存配置触发的 `hot_reload` 同样受此保护:非 application 插件若未提供 `apply` 回调,将不会执行热重载。