Compare commits

...

203 Commits

Author SHA1 Message Date
github-actions[bot]
eceef1ebec 🔖 Release 2.0.0rc3 2023-01-22 08:17:26 +00:00
Ju4tCode
50aa8c53e0 🔖 bump version 2.0.0rc3 (#1620) 2023-01-22 16:10:57 +08:00
github-actions[bot]
558f740c13 📝 Update changelog 2023-01-22 07:31:16 +00:00
wwweww
8bffba7efd 🍻 publish adapter BilibiliLive (#1616) 2023-01-22 15:29:55 +08:00
github-actions[bot]
ce93ea13e7 📝 Update changelog 2023-01-22 07:26:24 +00:00
Limnium
174182d62a 🍻 publish plugin 反向词典 (#1618) 2023-01-22 15:25:20 +08:00
github-actions[bot]
36f047be7f 📝 Update changelog 2023-01-22 07:21:13 +00:00
lgc2333
9d73af0513 🍻 publish plugin PicMCStat (#1613) 2023-01-22 15:20:03 +08:00
github-actions[bot]
ecb0d78011 📝 Update changelog 2023-01-22 07:19:32 +00:00
Ju4tCode
5920efb6c5 📝 Docs: 修改更新部分文档 (#1615) 2023-01-22 15:18:26 +08:00
github-actions[bot]
5893fbe57d 📝 Update changelog 2023-01-22 03:41:58 +00:00
17TheWord
27557af636 🍻 publish adapter Spigot (#1611) 2023-01-22 11:40:49 +08:00
github-actions[bot]
b37c7995cb 📝 Update changelog 2023-01-22 03:32:38 +00:00
StarHeart
f46addbb85 Docs: 商店搜索大小写不敏感 (#1609) 2023-01-22 11:31:32 +08:00
github-actions[bot]
6f57a290d7 📝 Update changelog 2023-01-21 06:12:32 +00:00
bridgeL
ae66e45287 🍻 publish plugin 犯人在跳舞 (#1607) 2023-01-21 14:11:18 +08:00
github-actions[bot]
03cf7f290a 📝 Update changelog 2023-01-20 04:02:45 +00:00
Jigsaw
f203aaf4ca ✏️ Plugin: 移除 nonebot-plugin-puppet (#1605) 2023-01-20 12:01:35 +08:00
github-actions[bot]
9a2edbbeb1 📝 Update changelog 2023-01-18 07:26:26 +00:00
Rinfair-CSP-A016
bd9ca99f63 🍻 publish bot SuzunoBot (#1600) 2023-01-18 15:25:12 +08:00
github-actions[bot]
8be262d305 📝 Update changelog 2023-01-17 02:30:56 +00:00
nikissXI
b92d47b362 🍻 publish plugin 喵喵自记菜谱 (#1598) 2023-01-17 10:29:45 +08:00
github-actions[bot]
bdf8cb0d57 📝 Update changelog 2023-01-16 07:06:21 +00:00
itsevin
0cb65214c6 🍻 publish plugin 语音功能 (#1596) 2023-01-16 15:05:12 +08:00
github-actions[bot]
ccc2c5676a 📝 Update changelog 2023-01-16 06:54:42 +00:00
BigOrangeQWQ
6daec67ebd 🍻 publish plugin OrangeDice! (#1594) 2023-01-16 14:53:41 +08:00
github-actions[bot]
051851faed 📝 Update changelog 2023-01-16 06:43:25 +00:00
nikissXI
8d2fca3e12 🍻 publish plugin 简易谷歌翻译插件 (#1592) 2023-01-16 14:42:17 +08:00
github-actions[bot]
76f37c485c 📝 Update changelog 2023-01-16 03:54:28 +00:00
mengxinyuan638
0c7af0873f 🍻 publish plugin 哔哩哔哩q群登录 (#1590) 2023-01-16 11:53:03 +08:00
github-actions[bot]
31fa4ec5f4 📝 Update changelog 2023-01-16 03:06:47 +00:00
nikissXI
fda490d252 ✏️ Plugin: 更新 MC 的插件信息 (#1589) 2023-01-16 11:05:43 +08:00
github-actions[bot]
40e443fd1a 📝 Update changelog 2023-01-16 03:04:37 +00:00
Akirami
4a17e581d2 🔥 移除 nonebot-plugin-aidraw (#1588) 2023-01-16 11:03:24 +08:00
github-actions[bot]
081d212487 📝 Update changelog 2023-01-13 09:11:38 +00:00
mengxinyuan638
3d6774136f 🍻 publish plugin 原神实时公告 (#1584) 2023-01-13 17:10:28 +08:00
github-actions[bot]
fa934a156a 📝 Update changelog 2023-01-12 09:09:47 +00:00
bridgeL
bac5356a90 ✏️ Plugins: 更新 ayaka_games 插件名和描述 (#1586)
Co-authored-by: Su <wxlxy316@163.com>
2023-01-12 17:08:28 +08:00
github-actions[bot]
b289065f71 📝 Update changelog 2023-01-12 02:38:13 +00:00
dpm12345
09cf0f29ba ✏️ Plugin: 更新 tts_gal 插件名和描述 (#1581) 2023-01-12 10:36:58 +08:00
github-actions[bot]
244837dd7c 📝 Update changelog 2023-01-12 02:35:30 +00:00
mengxinyuan638
a0bc113912 🍻 publish bot 辞辞(cici)Bot (#1582) 2023-01-12 10:34:19 +08:00
github-actions[bot]
6f6a296105 📝 Update changelog 2023-01-12 02:29:19 +00:00
Monarchdos
a0d316127f 🍻 publish plugin 心灵鸡汤 (#1579) 2023-01-12 10:27:57 +08:00
github-actions[bot]
f0c0d7788f 📝 Update changelog 2023-01-11 08:52:35 +00:00
Akirami
3f7e2604f1 🔊 Feature: 添加事件响应器检查完成日志 (#1578)
Co-authored-by: Ju4tCode <42488585+yanyongyu@users.noreply.github.com>
2023-01-11 16:51:20 +08:00
github-actions[bot]
f43c0087f7 📝 Update changelog 2023-01-10 08:47:48 +00:00
ericzhang-debug
e71d841045 🍻 publish plugin Bing每日图片获取 (#1576) 2023-01-10 16:46:32 +08:00
github-actions[bot]
a3af8da331 📝 Update changelog 2023-01-09 06:25:42 +00:00
Ju4tCode
8bdfdaef91 ⬆️ Fix: 屏蔽 fastapi 0.89.0 (#1574) 2023-01-09 14:24:30 +08:00
github-actions[bot]
afd13ed65d 📝 Update changelog 2023-01-09 02:39:02 +00:00
mengxinyuan638
d83751d0ca 🍻 publish plugin 星座运势 (#1571) 2023-01-09 10:37:45 +08:00
github-actions[bot]
63dd3b8fa7 📝 Update changelog 2023-01-09 02:32:39 +00:00
hmzz804
ae689605a5 🍻 publish plugin 回声洞 (#1570) 2023-01-09 10:31:25 +08:00
github-actions[bot]
bbaba1c955 📝 Update changelog 2023-01-08 08:51:53 +00:00
Cvandia
f1ee54e5c9 🍻 publish plugin 整点报时 (#1568) 2023-01-08 16:50:38 +08:00
github-actions[bot]
6f8e532afe 📝 Update changelog 2023-01-08 07:22:21 +00:00
Akirami
6f68ff61e5 🔥 移除 nonebot_plugin_super_resolution (#1561) 2023-01-08 15:21:05 +08:00
github-actions[bot]
a930fc0997 📝 Update changelog 2023-01-07 09:54:17 +00:00
Jigsaw
65da0947fe ✏️ update OlivOS.nb2's module_name (#1560) 2023-01-07 17:52:56 +08:00
github-actions[bot]
1b64a54421 📝 Update changelog 2023-01-07 08:03:05 +00:00
Akirami
d4e1bb7bf3 🐛 修复子插件加载失败时没有从父插件中移除的问题 (#1559) 2023-01-07 16:01:56 +08:00
github-actions[bot]
d737679ccd 📝 Update changelog 2023-01-07 07:59:53 +00:00
SkyDynamic
4cef5512ee 🍻 publish plugin Hypixel数据查询 (#1555) 2023-01-07 15:58:47 +08:00
github-actions[bot]
1d5d1602f0 📝 Update changelog 2023-01-06 12:08:47 +00:00
Ju4tCode
87e767fa25 remove default fastapi installation (#1557) 2023-01-06 20:07:28 +08:00
github-actions[bot]
c38437a22f 📝 Update changelog 2023-01-06 04:43:30 +00:00
Ju4tCode
cafb7bedb4 add pyright config (#1554) 2023-01-06 12:42:20 +08:00
github-actions[bot]
ace053f387 📝 Update changelog 2023-01-06 03:51:04 +00:00
cpuopt
d6e176d03b 🍻 publish plugin 查找图片出处 (#1552) 2023-01-06 11:49:51 +08:00
github-actions[bot]
2fca5b9664 📝 Update changelog 2023-01-06 03:44:58 +00:00
Monarchdos
cd93ace0dd 🍻 publish plugin 云签到 (#1549) 2023-01-06 11:43:47 +08:00
github-actions[bot]
b118cb6f22 📝 Update changelog 2023-01-06 03:00:44 +00:00
istrashguy
a69ccb4e6c 🍻 publish plugin 图像标注 (#1546) 2023-01-06 10:59:15 +08:00
github-actions[bot]
d5ec31d0a0 📝 Update changelog 2023-01-04 06:55:42 +00:00
CMHopeSunshine
62560635b2 🍻 publish plugin 对对联 (#1541) 2023-01-04 14:54:29 +08:00
github-actions[bot]
c00430c53f 📝 Update changelog 2023-01-04 06:34:51 +00:00
CMHopeSunshine
1dcda4bd77 🍻 publish plugin 群聊学习 (#1539) 2023-01-04 14:33:25 +08:00
github-actions[bot]
b60035f0e6 📝 Update changelog 2023-01-04 05:51:54 +00:00
Umamusume-Agnes-Digital
8551b13eab 🍻 publish plugin 求生之路2——服务器操作 (#1531) 2023-01-04 13:50:41 +08:00
github-actions[bot]
b448a6e083 📝 Update changelog 2023-01-04 05:10:19 +00:00
nikissXI
956b202087 🍻 publish plugin setu_customization (#1533) 2023-01-04 13:08:54 +08:00
github-actions[bot]
b95d49cd9c 📝 Update changelog 2023-01-04 04:59:45 +00:00
Akirami
006b9dd816 Feature: 支持给 FastAPIQuart 传递额外的参数 (#1543) 2023-01-04 12:58:26 +08:00
github-actions[bot]
a9125cd696 📝 Update changelog 2023-01-04 04:49:29 +00:00
uy/sun
ee5dcf0d42 👷 CI: 优化触发条件减少无效运行 (#1545)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-01-04 12:48:10 +08:00
github-actions[bot]
f13c1cc980 📝 Update changelog 2023-01-03 16:23:05 +00:00
ssttkkl
16c0a87929 🍻 publish plugin 主动消息撤回 (#1535) 2023-01-04 00:21:51 +08:00
github-actions[bot]
39d1554905 📝 Update changelog 2023-01-03 16:14:15 +00:00
ANGJustinl
37067229b0 🍻 publish plugin HttpCat🐱猫猫http状态码 (#1528) 2023-01-04 00:13:05 +08:00
pre-commit-ci[bot]
5ca708d3f4 ⬆️ auto update by pre-commit hooks (#1530)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-01-03 13:54:27 +08:00
github-actions[bot]
53dded52a7 📝 Update changelog 2023-01-01 07:23:20 +00:00
Akirami
f8cee790e7 Feature: 添加 logger 重导出 (#1526)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-01-01 15:22:07 +08:00
bridgeL
10447ff3c4 🍻 publish plugin 命令探查 (#1523) 2023-01-01 15:20:53 +08:00
github-actions[bot]
f08aec7894 📝 Update changelog 2023-01-01 07:09:08 +00:00
uy/sun
69edb98835 Feature: 将 block driver 转正为 none 驱动器 (#1522) 2023-01-01 15:08:00 +08:00
github-actions[bot]
c73ca2b43f 📝 Update changelog 2023-01-01 07:05:09 +00:00
bridgeL
848c6c5061 ✏️ Plugin: 删除 ayaka_who_is_suspect 插件 (#1525)
Co-authored-by: Su <wxlxy316@163.com>
2023-01-01 15:03:41 +08:00
github-actions[bot]
58f82bf881 📝 Update changelog 2022-12-31 12:43:05 +00:00
uy/sun
9b3e670cee 🐛 修复异常在 traceback 中无法正常显示信息 (#1521) 2022-12-31 20:41:53 +08:00
github-actions[bot]
f0bebb65b4 📝 Update changelog 2022-12-30 15:09:51 +00:00
ANGJustinl
bc845c94e2 🍻 publish plugin AnimalVoice_Convert (#1517) 2022-12-30 23:08:41 +08:00
github-actions[bot]
f4668bf0bc 📝 Update changelog 2022-12-30 03:32:03 +00:00
uy/sun
3493d69fcd 👷 CI: 添加插件加载测试 (#1519)
* 👷 添加插件加载测试

* 调整命名格式

* 添加 issue_comment 的触发条件
2022-12-30 11:30:47 +08:00
github-actions[bot]
125bcb943f 📝 Update changelog 2022-12-29 12:27:17 +00:00
OREOCODEDEV
e65eb3fb18 🍻 publish plugin 服务状态查询 (#1512) 2022-12-29 20:26:12 +08:00
github-actions[bot]
8045420f97 📝 Update changelog 2022-12-29 11:28:33 +00:00
ANGJustinl
03a90006e5 🍻 publish plugin 腾讯云图像变换 (#1514) 2022-12-29 19:27:09 +08:00
github-actions[bot]
adbe341076 📝 Update changelog 2022-12-27 10:54:55 +00:00
Johnny Hsieh
2a623b1c81 🔥 Plugin: 移除停止维护的 nonebot-plugin-filehost (#1516) 2022-12-27 18:53:46 +08:00
github-actions[bot]
c91926aea6 📝 Update changelog 2022-12-27 03:08:47 +00:00
IAXRetailer
63329257de 🍻 publish bot RanBot (#1510) 2022-12-27 11:07:31 +08:00
github-actions[bot]
c9dc6e648e 📝 Update changelog 2022-12-26 03:13:47 +00:00
Ikaros
78a818547e ✏️ Plugin: 更新 abstain_diary 插件名和描述 (#1509) 2022-12-26 11:12:40 +08:00
github-actions[bot]
41eed9d0e9 📝 Update changelog 2022-12-26 02:57:23 +00:00
StarHeart
e32019f15d 📝 Docs: 更新测试文档中的连接方式&细化插件发布描述 (#1504) 2022-12-26 10:56:16 +08:00
github-actions[bot]
59c033e2dd 📝 Update changelog 2022-12-26 02:55:30 +00:00
zhulinyv
49cf1ec5d3 🍻 publish plugin Ping (#1507) 2022-12-26 10:54:07 +08:00
github-actions[bot]
e5ad15d6d6 📝 Update changelog 2022-12-25 16:18:00 +00:00
zhulinyv
4cf9790a95 🍻 publish plugin 群友召唤术 (#1502) 2022-12-26 00:16:32 +08:00
github-actions[bot]
7467e66dab 📝 Update changelog 2022-12-25 16:06:28 +00:00
050644zf
516c1c220c 🍻 publish plugin 战地群聊天插件 (#1505) 2022-12-26 00:05:05 +08:00
github-actions[bot]
136778ae5b 📝 Update changelog 2022-12-24 02:58:56 +00:00
chrisyy2003
17538f7a66 ✏️ Plugin: 更新 gpt3 插件模块名 (#1501) 2022-12-24 10:57:34 +08:00
github-actions[bot]
d1da0be0da 📝 Update changelog 2022-12-23 15:07:19 +00:00
bridgeL
e92bc24631 🍻 publish plugin 不要复读 (#1499) 2022-12-23 23:06:04 +08:00
github-actions[bot]
73d1e5dd88 📝 Update changelog 2022-12-21 06:53:36 +00:00
nikissXI
ea83ba78ec 🍻 publish plugin JAVA MC服务器信息查询 (#1496) 2022-12-21 14:52:23 +08:00
github-actions[bot]
712f80a307 📝 Update changelog 2022-12-21 06:40:17 +00:00
Ju4tCode
5c4ef8fc00 🐛 Fix: 修复客户端请求未处理 cookies (#1491) 2022-12-21 14:39:05 +08:00
github-actions[bot]
2b0973c9f5 📝 Update changelog 2022-12-21 05:59:28 +00:00
Ikaros
767a8ecb08 ✏️ Plugin: 更新 随机禁言 插件功能描述 (#1495) 2022-12-21 13:58:11 +08:00
github-actions[bot]
b342940b69 📝 Update changelog 2022-12-21 04:46:10 +00:00
Jerry080801
7880f07db4 🍻 publish plugin 防撤回 (#1488) 2022-12-21 12:44:42 +08:00
github-actions[bot]
ac702d7eb7 📝 Update changelog 2022-12-21 03:32:39 +00:00
chrisyy2003
9f3b3b2c32 ✏️ Plugin: 更新 multi chatgpt 插件仓库地址 (#1487) 2022-12-21 11:31:35 +08:00
Ju4tCode
2d08465426 add cookies support for forward driver 2022-12-20 10:13:45 +00:00
github-actions[bot]
827d8fbc0e 📝 Update changelog 2022-12-20 07:22:48 +00:00
Ikaros-521
0320be1947 🍻 publish plugin 随机禁言 (#1485) 2022-12-20 15:21:42 +08:00
github-actions[bot]
aca65954bd 📝 Update changelog 2022-12-20 07:04:06 +00:00
RShock
1da9376fc8 🍻 publish plugin 只因进化录 (#1483) 2022-12-20 15:02:47 +08:00
github-actions[bot]
909b811f68 📝 Update changelog 2022-12-18 07:54:38 +00:00
Ju4tCode
ceecf9c692 🐛 fix on_type typing error (#1482) 2022-12-18 15:53:25 +08:00
github-actions[bot]
3de2922773 📝 Update changelog 2022-12-17 09:05:55 +00:00
Ju4tCode
a5d26b7747 add pycln to auto remove unused imports (#1481) 2022-12-17 17:04:38 +08:00
github-actions[bot]
932f50d1fb 📝 Update changelog 2022-12-17 06:25:10 +00:00
chrisyy2003
c69619f142 🍻 publish plugin GPT3 (#1479) 2022-12-17 14:24:08 +08:00
github-actions[bot]
5a49d1e0e2 📝 Update changelog 2022-12-16 05:17:35 +00:00
ReiiNoki
4f9f3f449c 🍻 publish plugin 熊老板 (#1471) 2022-12-16 13:16:23 +08:00
github-actions[bot]
60733c97be 📝 Update changelog 2022-12-15 05:39:28 +00:00
Yuelioi
7a1aa0c204 🍻 publish plugin QQ群文件备份 (#1477) 2022-12-15 13:38:27 +08:00
github-actions[bot]
6d1383a10c 📝 Update changelog 2022-12-15 05:31:38 +00:00
Ikaros-521
86006fafdc 🍻 publish plugin 戒色打卡日记 (#1474) 2022-12-15 13:30:24 +08:00
github-actions[bot]
44ca4f729a 📝 Update changelog 2022-12-14 05:01:36 +00:00
wsdtl
cf29209a55 🍻 publish plugin nonebot_plugin_idiom (#1468) 2022-12-14 13:00:22 +08:00
github-actions[bot]
5e78e2bb5d 📝 Update changelog 2022-12-13 09:49:05 +00:00
幼稚园园长
440e15e204 📝 Docs: 修复文档中部分超链接跳转到 /store.html 的问题 (#1470) 2022-12-13 17:47:45 +08:00
github-actions[bot]
6711a84cab 📝 Update changelog 2022-12-12 14:39:08 +00:00
Ikaros-521
5c2d2141e3 🍻 publish plugin 随机配色方案 (#1465) 2022-12-12 22:37:49 +08:00
github-actions[bot]
8ec1552fd6 📝 Update changelog 2022-12-11 17:09:38 +00:00
chrisyy2003
c1dca723ae 🍻 publish plugin multi-ChatGPT (#1461) 2022-12-12 01:08:28 +08:00
github-actions[bot]
b6cd0424fa 📝 Update changelog 2022-12-10 09:28:58 +00:00
ssttkkl
1beee94c1d 🍻 publish plugin 权限控制 (#1463) 2022-12-10 17:27:48 +08:00
github-actions[bot]
f2a618f663 📝 Update changelog 2022-12-09 16:13:43 +00:00
Akirami
c4286f1f39 💡 补充 params 模块的类型注解 (#1458) 2022-12-10 00:12:28 +08:00
github-actions[bot]
cd9e30bd52 📝 Update changelog 2022-12-09 06:49:49 +00:00
A-kirami
24ae0dfa15 🍻 publish plugin 汇率换算 (#1451) 2022-12-09 14:48:44 +08:00
github-actions[bot]
19a20a3407 📝 Update changelog 2022-12-09 06:44:08 +00:00
Akirami
36d7b44741 Feature: 添加正则匹配文本注入 (#1457)
Co-authored-by: Ju4tCode <42488585+yanyongyu@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-09 14:42:54 +08:00
dependabot[bot]
8176cd189c ⬆️ Bump nwtgck/actions-netlify from 1 to 2 (#1456)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-09 12:19:22 +08:00
github-actions[bot]
b25de93eb1 📝 Update changelog 2022-12-07 17:06:48 +00:00
A-kirami
79e636ad89 🍻 publish plugin 全群广播 (#1449) 2022-12-08 01:05:31 +08:00
github-actions[bot]
9c9973d8d8 📝 Update changelog 2022-12-07 15:49:53 +00:00
Akirami
04d4954d50 📝 Docs: 移除文档 自定义日志 中多余的符号 (#1448) 2022-12-07 23:48:48 +08:00
github-actions[bot]
2c81dc1975 📝 Update changelog 2022-12-07 13:44:39 +00:00
Akirami
850096ceaa 📝 Docs: 完善 调用平台 API 部分 (#1447)
Co-authored-by: StarHeart <starheart233@gmail.com>
2022-12-07 21:43:27 +08:00
github-actions[bot]
6bb15f6533 📝 Update changelog 2022-12-06 15:12:57 +00:00
Ikaros-521
92c6a8dd6e 🍻 publish plugin 图片背景消除 (#1445) 2022-12-06 23:11:44 +08:00
github-actions[bot]
723eef10bb 📝 Update changelog 2022-12-06 06:20:53 +00:00
Akirami
06c33ad6ea Feature: 支持主动销毁事件响应器 (#1444)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-06 14:19:48 +08:00
github-actions[bot]
9826bc29ca 📝 Update changelog 2022-12-05 15:22:06 +00:00
ssttkkl
f35b5b57b7 🍻 publish plugin 雀魂信息查询 (#1442) 2022-12-05 23:20:54 +08:00
github-actions[bot]
433b50c79c 📝 Update changelog 2022-12-05 08:44:04 +00:00
A-kirami
89f3496a2a 🍻 publish plugin ChatGPT (#1438) 2022-12-05 16:42:59 +08:00
github-actions[bot]
df7e8f6d83 📝 Update changelog 2022-12-04 05:23:34 +00:00
ZYKsslm
b57f17d447 🍻 publish plugin 免费快捷点歌插件 (#1435) 2022-12-04 13:22:09 +08:00
github-actions[bot]
665de1da3e 📝 Update changelog 2022-12-04 02:44:19 +00:00
Ikaros-521
091232e996 🍻 publish plugin 动画截图追溯来源 (#1433) 2022-12-04 10:43:09 +08:00
github-actions[bot]
9ee2d94f3c 📝 Update changelog 2022-12-03 06:35:43 +00:00
MingxuanGame
78bdfe65ba ✏️ Docs: 修正文档中部分配置文件示例的符号误用 (#1432)
* :typo: 使用方括号替换大括号

* ✏️ 修改 2.0.0rc2 的文档
2022-12-03 14:34:25 +08:00
github-actions[bot]
5006cf7be6 📝 Update changelog 2022-12-02 06:42:02 +00:00
jcjrobert
a818e0056e 🍻 publish plugin b站图片下载 (#1429) 2022-12-02 14:40:59 +08:00
github-actions[bot]
3efae8bfbc 📝 Update changelog 2022-12-02 05:57:28 +00:00
bridgeL
024d97b997 🍻 Plugin: 更新 ayaka_games 介绍 (#1431)
Co-authored-by: Su <wxlxy316@163.com>
2022-12-02 13:56:15 +08:00
github-actions[bot]
c90ab949d2 📝 Update changelog 2022-11-29 04:01:31 +00:00
Ju4tCode
e8ffa63b78 🐛 fix argument parser message (#1426) 2022-11-29 12:00:09 +08:00
github-actions[bot]
6c27ec7357 📝 Update changelog 2022-11-27 11:38:28 +00:00
Sena
9bf08593d7 ✏️ Plugin: 修改 novelai send magiadice 插件模块名 (#1423) 2022-11-27 19:37:15 +08:00
github-actions[bot]
b016a59a38 📝 Update changelog 2022-11-27 11:22:19 +00:00
Passerby-D
794395e737 🍻 publish plugin 记事本 (#1419) 2022-11-27 19:21:17 +08:00
github-actions[bot]
a758e6f06e 📝 Update changelog 2022-11-26 02:33:35 +00:00
monsterxcn
11feb2c0d0 🍻 publish plugin 原神前瞻直播兑换码查询 (#1421) 2022-11-26 10:32:16 +08:00
Ju4tCode
59a2ed7c2e 🎨 format code 2022-11-25 16:12:23 +00:00
131 changed files with 3451 additions and 1930 deletions

View File

@@ -5,6 +5,10 @@ on:
branches: branches:
- master - master
pull_request: pull_request:
paths:
- "nonebot/**"
- "packages/**"
- "tests/**"
jobs: jobs:
test: test:

View File

@@ -5,17 +5,45 @@ on:
types: [opened, reopened, edited] types: [opened, reopened, edited]
pull_request_target: pull_request_target:
types: [closed] types: [closed]
issue_comment:
types: [created]
concurrency:
group: ${{ github.workflow }}-${{ github.event.issue.number || github.run_id }}
cancel-in-progress: true
jobs: jobs:
plugin_test:
runs-on: ubuntu-latest
name: nonebot2 plugin test
if: github.event_name != 'issue_comment' || !github.event.issue.pull_request
permissions:
issues: read
outputs:
result: ${{ steps.plugin-test.outputs.RESULT }}
output: ${{ steps.plugin-test.outputs.OUTPUT }}
steps:
- name: Install Poetry
if: ${{ !startsWith(github.event_name, 'pull_request') }}
run: pipx install poetry
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Test Plugin
id: plugin-test
run: |
curl -sSL https://raw.githubusercontent.com/nonebot/nonebot2-publish-bot/main/plugin_test.py -o plugin_test.py
python plugin_test.py
publish_bot: publish_bot:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: nonebot2 publish bot name: nonebot2 publish bot
needs: plugin_test
steps: steps:
- name: Checkout code - name: Checkout Code
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
token: ${{ secrets.GH_TOKEN }} token: ${{ secrets.GH_TOKEN }}
- name: NoneBot2 Publish Bot - name: NoneBot2 Publish Bot
uses: docker://ghcr.io/nonebot/nonebot2-publish-bot:main uses: docker://ghcr.io/nonebot/nonebot2-publish-bot:main
with: with:
@@ -27,3 +55,6 @@ jobs:
"bot_path": "website/static/bots.json", "bot_path": "website/static/bots.json",
"adapter_path": "website/static/adapters.json" "adapter_path": "website/static/adapters.json"
} }
env:
PLUGIN_TEST_RESULT: ${{ needs.plugin_test.outputs.result }}
PLUGIN_TEST_OUTPUT: ${{ needs.plugin_test.outputs.output }}

View File

@@ -31,7 +31,7 @@ jobs:
run: echo "BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/})" >> $GITHUB_ENV run: echo "BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/})" >> $GITHUB_ENV
- name: Deploy to Netlify - name: Deploy to Netlify
uses: nwtgck/actions-netlify@v1 uses: nwtgck/actions-netlify@v2
with: with:
publish-dir: "./website/build" publish-dir: "./website/build"
production-deploy: true production-deploy: true

View File

@@ -32,7 +32,7 @@ jobs:
echo "DEPLOY_NAME=deploy-preview-${{ github.event.number }}" >> $GITHUB_ENV echo "DEPLOY_NAME=deploy-preview-${{ github.event.number }}" >> $GITHUB_ENV
- name: Deploy to Netlify - name: Deploy to Netlify
uses: nwtgck/actions-netlify@v1 uses: nwtgck/actions-netlify@v2
with: with:
publish-dir: "./website/build" publish-dir: "./website/build"
production-deploy: false production-deploy: false

View File

@@ -6,14 +6,20 @@ ci:
autoupdate_schedule: monthly autoupdate_schedule: monthly
autoupdate_commit_msg: ":arrow_up: auto update by pre-commit hooks" autoupdate_commit_msg: ":arrow_up: auto update by pre-commit hooks"
repos: repos:
- repo: https://github.com/hadialqattan/pycln
rev: v2.1.2
hooks:
- id: pycln
args: [--config, pyproject.toml]
- repo: https://github.com/pycqa/isort - repo: https://github.com/pycqa/isort
rev: 5.10.1 rev: 5.11.4
hooks: hooks:
- id: isort - id: isort
stages: [commit] stages: [commit]
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 22.10.0 rev: 22.12.0
hooks: hooks:
- id: black - id: black
stages: [commit] stages: [commit]

View File

@@ -97,7 +97,7 @@ NoneBot2 是一个现代、跨平台、可扩展的 Python 聊天机器人框架
- 海纳百川:一个框架,支持多个聊天软件平台,可自定义通信协议 - 海纳百川:一个框架,支持多个聊天软件平台,可自定义通信协议
| 协议名称 | 状态 | 注释 | | 协议名称 | 状态 | 注释 |
| :--------------------------------------------------------: | :--: | :----------------------------------------------------------------: | | :-----------------------------------------------------------------------: | :--: | :----------------------------------------------------------------: |
| [OneBot 协议](https://onebot.dev/) | ✅ | 支持 QQ、TG、微信公众号等[平台](https://onebot.dev/ecosystem.html) | | [OneBot 协议](https://onebot.dev/) | ✅ | 支持 QQ、TG、微信公众号等[平台](https://onebot.dev/ecosystem.html) |
| [Telegram](https://core.telegram.org/bots/api) | ✅ | | | [Telegram](https://core.telegram.org/bots/api) | ✅ | |
| [飞书](https://open.feishu.cn/document/home/index) | ✅ | | | [飞书](https://open.feishu.cn/document/home/index) | ✅ | |
@@ -108,6 +108,8 @@ NoneBot2 是一个现代、跨平台、可扩展的 Python 聊天机器人框架
| [开黑啦](https://developer.kookapp.cn/) | ↗️ | 由社区贡献 | | [开黑啦](https://developer.kookapp.cn/) | ↗️ | 由社区贡献 |
| [Mirai](https://docs.mirai.mamoe.net/mirai-api-http/) | ↗️ | 由社区贡献 | | [Mirai](https://docs.mirai.mamoe.net/mirai-api-http/) | ↗️ | 由社区贡献 |
| [Ntchat](https://github.com/JustUndertaker/adapter-ntchat) | ↗️ | 由社区贡献 | | [Ntchat](https://github.com/JustUndertaker/adapter-ntchat) | ↗️ | 由社区贡献 |
| [MineCraft (Spigot)](https://github.com/17TheWord/nonebot-adapter-spigot) | ↗️ | 由社区贡献 |
| [BiliBili Live](https://github.com/wwweww/adapter-bilibili) | ↗️ | 由社区贡献 |
- 坚实后盾:支持多种 web 框架,可自定义替换、组合 - 坚实后盾:支持多种 web 框架,可自定义替换、组合
@@ -135,12 +137,17 @@ NoneBot2 不是 NoneBot1 的替代品。事实上,它们都在被积极的维
懒得看文档?下面是快速安装指南: 懒得看文档?下面是快速安装指南:
1. (**强烈建议**)使用你喜欢的 Python 环境管理工具创建新的虚拟环境。 1. 安装 [pipx](https://pypa.github.io/pipx/)
2. 使用 `pip` (或其他) 安装 NoneBot 脚手架。
```bash ```bash
pip install nb-cli python -m pip install --user pipx
python -m pipx ensurepath
```
2. 安装脚手架
```bash
pipx install nb-cli
``` ```
3. 使用脚手架创建项目 3. 使用脚手架创建项目
@@ -149,6 +156,12 @@ NoneBot2 不是 NoneBot1 的替代品。事实上,它们都在被积极的维
nb create nb create
``` ```
4. 运行项目
```bash
nb run
```
## 社区资源 ## 社区资源
### 常见问题 ### 常见问题

View File

@@ -45,10 +45,10 @@ from typing import Any, Dict, Type, Optional
import loguru import loguru
from pydantic.env_settings import DotenvType from pydantic.env_settings import DotenvType
from nonebot.log import logger
from nonebot.adapters import Bot from nonebot.adapters import Bot
from nonebot.utils import escape_tag from nonebot.utils import escape_tag
from nonebot.config import Env, Config from nonebot.config import Env, Config
from nonebot.log import logger as logger
from nonebot.drivers import Driver, ReverseDriver, combine_driver from nonebot.drivers import Driver, ReverseDriver, combine_driver
try: try:

View File

@@ -9,7 +9,6 @@ FrontMatter:
description: nonebot.config 模块 description: nonebot.config 模块
""" """
import os import os
from pathlib import Path
from datetime import timedelta from datetime import timedelta
from ipaddress import IPv4Address from ipaddress import IPv4Address
from typing import TYPE_CHECKING, Any, Set, Dict, Tuple, Union, Mapping, Optional from typing import TYPE_CHECKING, Any, Set, Dict, Tuple, Union, Mapping, Optional

View File

@@ -38,6 +38,8 @@ SHELL_ARGV: Literal["_argv"] = "_argv"
REGEX_MATCHED: Literal["_matched"] = "_matched" REGEX_MATCHED: Literal["_matched"] = "_matched"
"""正则匹配结果存储 key""" """正则匹配结果存储 key"""
REGEX_STR: Literal["_matched_str"] = "_matched_str"
"""正则匹配文本存储 key"""
REGEX_GROUP: Literal["_matched_groups"] = "_matched_groups" REGEX_GROUP: Literal["_matched_groups"] = "_matched_groups"
"""正则匹配 group 元组存储 key""" """正则匹配 group 元组存储 key"""
REGEX_DICT: Literal["_matched_dict"] = "_matched_dict" REGEX_DICT: Literal["_matched_dict"] = "_matched_dict"

View File

@@ -21,7 +21,7 @@ from contextlib import asynccontextmanager
from nonebot.typing import overrides from nonebot.typing import overrides
from nonebot.drivers import Request, Response from nonebot.drivers import Request, Response
from nonebot.exception import WebSocketClosed from nonebot.exception import WebSocketClosed
from nonebot.drivers._block_driver import BlockDriver from nonebot.drivers.none import Driver as NoneDriver
from nonebot.drivers import WebSocket as BaseWebSocket from nonebot.drivers import WebSocket as BaseWebSocket
from nonebot.drivers import HTTPVersion, ForwardMixin, ForwardDriver, combine_driver from nonebot.drivers import HTTPVersion, ForwardMixin, ForwardDriver, combine_driver
@@ -56,7 +56,13 @@ class Mixin(ForwardMixin):
files = aiohttp.FormData() files = aiohttp.FormData()
for name, file in setup.files: for name, file in setup.files:
files.add_field(name, file[1], content_type=file[2], filename=file[0]) files.add_field(name, file[1], content_type=file[2], filename=file[0])
async with aiohttp.ClientSession(version=version, trust_env=True) as session:
cookies = {
cookie.name: cookie.value for cookie in setup.cookies if cookie.value
}
async with aiohttp.ClientSession(
cookies=cookies, version=version, trust_env=True
) as session:
async with session.request( async with session.request(
setup.method, setup.method,
setup.url, setup.url,
@@ -66,13 +72,12 @@ class Mixin(ForwardMixin):
timeout=timeout, timeout=timeout,
proxy=setup.proxy, proxy=setup.proxy,
) as response: ) as response:
res = Response( return Response(
response.status, response.status,
headers=response.headers.copy(), headers=response.headers.copy(),
content=await response.read(), content=await response.read(),
request=setup, request=setup,
) )
return res
@overrides(ForwardMixin) @overrides(ForwardMixin)
@asynccontextmanager @asynccontextmanager
@@ -92,8 +97,7 @@ class Mixin(ForwardMixin):
headers=setup.headers, headers=setup.headers,
proxy=setup.proxy, proxy=setup.proxy,
) as ws: ) as ws:
websocket = WebSocket(request=setup, session=session, websocket=ws) yield WebSocket(request=setup, session=session, websocket=ws)
yield websocket
class WebSocket(BaseWebSocket): class WebSocket(BaseWebSocket):
@@ -166,5 +170,5 @@ class WebSocket(BaseWebSocket):
await self.websocket.send_bytes(data) await self.websocket.send_bytes(data)
Driver: Type[ForwardDriver] = combine_driver(BlockDriver, Mixin) # type: ignore Driver: Type[ForwardDriver] = combine_driver(NoneDriver, Mixin) # type: ignore
"""AIOHTTP Driver""" """AIOHTTP Driver"""

View File

@@ -1,5 +1,11 @@
"""[FastAPI](https://fastapi.tiangolo.com/) 驱动适配 """[FastAPI](https://fastapi.tiangolo.com/) 驱动适配
```bash
nb driver install fastapi
# 或者
pip install nonebot2[fastapi]
```
:::tip 提示 :::tip 提示
本驱动仅支持服务端连接 本驱动仅支持服务端连接
::: :::
@@ -13,13 +19,9 @@ FrontMatter:
import logging import logging
import contextlib import contextlib
from functools import wraps from functools import wraps
from typing import Any, List, Tuple, Union, Callable, Optional from typing import Any, Dict, List, Tuple, Union, Callable, Optional
import uvicorn
from pydantic import BaseSettings from pydantic import BaseSettings
from fastapi.responses import Response
from fastapi import FastAPI, Request, UploadFile, status
from starlette.websockets import WebSocket, WebSocketState, WebSocketDisconnect
from nonebot.config import Env from nonebot.config import Env
from nonebot.typing import overrides from nonebot.typing import overrides
@@ -30,6 +32,16 @@ from nonebot.drivers import Request as BaseRequest
from nonebot.drivers import WebSocket as BaseWebSocket from nonebot.drivers import WebSocket as BaseWebSocket
from nonebot.drivers import ReverseDriver, HTTPServerSetup, WebSocketServerSetup from nonebot.drivers import ReverseDriver, HTTPServerSetup, WebSocketServerSetup
try:
import uvicorn
from fastapi.responses import Response
from fastapi import FastAPI, Request, UploadFile, status
from starlette.websockets import WebSocket, WebSocketState, WebSocketDisconnect
except ImportError: # pragma: no cover
raise ImportError(
"Please install FastAPI by using `pip install nonebot2[fastapi]`"
) from None
def catch_closed(func): def catch_closed(func):
@wraps(func) @wraps(func)
@@ -65,6 +77,8 @@ class Config(BaseSettings):
"""要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值""" """要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值"""
fastapi_reload_excludes: Optional[List[str]] = None fastapi_reload_excludes: Optional[List[str]] = None
"""不要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值""" """不要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值"""
fastapi_extra: Dict[str, Any] = {}
"""传递给 `FastAPI` 的其他参数。"""
class Config: class Config:
extra = "ignore" extra = "ignore"
@@ -82,6 +96,7 @@ class Driver(ReverseDriver):
openapi_url=self.fastapi_config.fastapi_openapi_url, openapi_url=self.fastapi_config.fastapi_openapi_url,
docs_url=self.fastapi_config.fastapi_docs_url, docs_url=self.fastapi_config.fastapi_docs_url,
redoc_url=self.fastapi_config.fastapi_redoc_url, redoc_url=self.fastapi_config.fastapi_redoc_url,
**self.fastapi_config.fastapi_extra,
) )
@property @property

View File

@@ -18,7 +18,7 @@ from typing import Type, AsyncGenerator
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from nonebot.typing import overrides from nonebot.typing import overrides
from nonebot.drivers._block_driver import BlockDriver from nonebot.drivers.none import Driver as NoneDriver
from nonebot.drivers import ( from nonebot.drivers import (
Request, Request,
Response, Response,
@@ -48,17 +48,18 @@ class Mixin(ForwardMixin):
@overrides(ForwardMixin) @overrides(ForwardMixin)
async def request(self, setup: Request) -> Response: async def request(self, setup: Request) -> Response:
async with httpx.AsyncClient( async with httpx.AsyncClient(
cookies=setup.cookies.jar,
http2=setup.version == HTTPVersion.H2, http2=setup.version == HTTPVersion.H2,
proxies=setup.proxy, # type: ignore proxies=setup.proxy,
follow_redirects=True, follow_redirects=True,
) as client: ) as client:
response = await client.request( response = await client.request(
setup.method, setup.method,
str(setup.url), str(setup.url),
content=setup.content, # type: ignore content=setup.content,
data=setup.data, # type: ignore data=setup.data,
json=setup.json, json=setup.json,
files=setup.files, # type: ignore files=setup.files,
headers=tuple(setup.headers.items()), headers=tuple(setup.headers.items()),
timeout=setup.timeout, timeout=setup.timeout,
) )
@@ -76,5 +77,5 @@ class Mixin(ForwardMixin):
yield ws yield ws
Driver: Type[ForwardDriver] = combine_driver(BlockDriver, Mixin) # type: ignore Driver: Type[ForwardDriver] = combine_driver(NoneDriver, Mixin) # type: ignore
"""HTTPX Driver""" """HTTPX Driver"""

View File

@@ -1,12 +1,24 @@
"""None 驱动适配
:::tip 提示
本驱动不支持任何服务器或客户端连接
:::
FrontMatter:
sidebar_position: 6
description: nonebot.drivers.none 模块
"""
import signal import signal
import asyncio import asyncio
import threading import threading
from typing import Set, Union, Callable, Awaitable, cast from typing import Set, Union, Callable, Awaitable, cast
from nonebot.log import logger from nonebot.log import logger
from nonebot.drivers import Driver
from nonebot.typing import overrides from nonebot.typing import overrides
from nonebot.config import Env, Config from nonebot.config import Env, Config
from nonebot.drivers import Driver as BaseDriver
from nonebot.utils import run_sync, is_coroutine_callable from nonebot.utils import run_sync, is_coroutine_callable
HOOK_FUNC = Union[Callable[[], None], Callable[[], Awaitable[None]]] HOOK_FUNC = Union[Callable[[], None], Callable[[], Awaitable[None]]]
@@ -16,7 +28,9 @@ HANDLED_SIGNALS = (
) )
class BlockDriver(Driver): class Driver(BaseDriver):
"""None 驱动框架"""
def __init__(self, env: Env, config: Config): def __init__(self, env: Env, config: Config):
super().__init__(env, config) super().__init__(env, config)
self.startup_funcs: Set[HOOK_FUNC] = set() self.startup_funcs: Set[HOOK_FUNC] = set()
@@ -25,18 +39,18 @@ class BlockDriver(Driver):
self.force_exit: bool = False self.force_exit: bool = False
@property @property
@overrides(Driver) @overrides(BaseDriver)
def type(self) -> str: def type(self) -> str:
"""驱动名称: `block_driver`""" """驱动名称: `none`"""
return "block_driver" return "none"
@property @property
@overrides(Driver) @overrides(BaseDriver)
def logger(self): def logger(self):
"""block driver 使用的 logger""" """none driver 使用的 logger"""
return logger return logger
@overrides(Driver) @overrides(BaseDriver)
def on_startup(self, func: HOOK_FUNC) -> HOOK_FUNC: def on_startup(self, func: HOOK_FUNC) -> HOOK_FUNC:
""" """
注册一个启动时执行的函数 注册一个启动时执行的函数
@@ -44,7 +58,7 @@ class BlockDriver(Driver):
self.startup_funcs.add(func) self.startup_funcs.add(func)
return func return func
@overrides(Driver) @overrides(BaseDriver)
def on_shutdown(self, func: HOOK_FUNC) -> HOOK_FUNC: def on_shutdown(self, func: HOOK_FUNC) -> HOOK_FUNC:
""" """
注册一个停止时执行的函数 注册一个停止时执行的函数
@@ -52,22 +66,22 @@ class BlockDriver(Driver):
self.shutdown_funcs.add(func) self.shutdown_funcs.add(func)
return func return func
@overrides(Driver) @overrides(BaseDriver)
def run(self, *args, **kwargs): def run(self, *args, **kwargs):
"""启动 block driver""" """启动 none driver"""
super().run(*args, **kwargs) super().run(*args, **kwargs)
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
loop.run_until_complete(self.serve()) loop.run_until_complete(self._serve())
async def serve(self): async def _serve(self):
self.install_signal_handlers() self._install_signal_handlers()
await self.startup() await self._startup()
if self.should_exit.is_set(): if self.should_exit.is_set():
return return
await self.main_loop() await self._main_loop()
await self.shutdown() await self._shutdown()
async def startup(self): async def _startup(self):
# run startup # run startup
cors = [ cors = [
cast(Callable[..., Awaitable[None]], startup)() cast(Callable[..., Awaitable[None]], startup)()
@@ -86,10 +100,10 @@ class BlockDriver(Driver):
logger.info("Application startup completed.") logger.info("Application startup completed.")
async def main_loop(self): async def _main_loop(self):
await self.should_exit.wait() await self.should_exit.wait()
async def shutdown(self): async def _shutdown(self):
logger.info("Shutting down") logger.info("Shutting down")
logger.info("Waiting for application shutdown.") logger.info("Waiting for application shutdown.")
@@ -130,7 +144,7 @@ class BlockDriver(Driver):
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
loop.stop() loop.stop()
def install_signal_handlers(self) -> None: def _install_signal_handlers(self) -> None:
if threading.current_thread() is not threading.main_thread(): if threading.current_thread() is not threading.main_thread():
# Signals can only be listened to from the main thread. # Signals can only be listened to from the main thread.
return return
@@ -139,13 +153,13 @@ class BlockDriver(Driver):
try: try:
for sig in HANDLED_SIGNALS: for sig in HANDLED_SIGNALS:
loop.add_signal_handler(sig, self.handle_exit, sig, None) loop.add_signal_handler(sig, self._handle_exit, sig, None)
except NotImplementedError: except NotImplementedError:
# Windows # Windows
for sig in HANDLED_SIGNALS: for sig in HANDLED_SIGNALS:
signal.signal(sig, self.handle_exit) signal.signal(sig, self._handle_exit)
def handle_exit(self, sig, frame): def _handle_exit(self, sig, frame):
if self.should_exit.is_set(): if self.should_exit.is_set():
self.force_exit = True self.force_exit = True
else: else:

View File

@@ -17,9 +17,8 @@ FrontMatter:
import asyncio import asyncio
from functools import wraps from functools import wraps
from typing import List, Tuple, Union, TypeVar, Callable, Optional, Coroutine from typing import Any, Dict, List, Tuple, Union, TypeVar, Callable, Optional, Coroutine
import uvicorn
from pydantic import BaseSettings from pydantic import BaseSettings
from nonebot.config import Env from nonebot.config import Env
@@ -32,6 +31,7 @@ from nonebot.drivers import WebSocket as BaseWebSocket
from nonebot.drivers import ReverseDriver, HTTPServerSetup, WebSocketServerSetup from nonebot.drivers import ReverseDriver, HTTPServerSetup, WebSocketServerSetup
try: try:
import uvicorn
from quart import request as _request from quart import request as _request
from quart import websocket as _websocket from quart import websocket as _websocket
from quart import Quart, Request, Response from quart import Quart, Request, Response
@@ -69,6 +69,8 @@ class Config(BaseSettings):
"""要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值""" """要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值"""
quart_reload_excludes: Optional[List[str]] = None quart_reload_excludes: Optional[List[str]] = None
"""不要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值""" """不要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值"""
quart_extra: Dict[str, Any] = {}
"""传递给 `Quart` 的其他参数。"""
class Config: class Config:
extra = "ignore" extra = "ignore"
@@ -82,7 +84,9 @@ class Driver(ReverseDriver):
self.quart_config = Config(**config.dict()) self.quart_config = Config(**config.dict())
self._server_app = Quart(self.__class__.__qualname__) self._server_app = Quart(
self.__class__.__qualname__, **self.quart_config.quart_extra
)
@property @property
@overrides(ReverseDriver) @overrides(ReverseDriver)

View File

@@ -23,7 +23,7 @@ from nonebot.typing import overrides
from nonebot.log import LoguruHandler from nonebot.log import LoguruHandler
from nonebot.drivers import Request, Response from nonebot.drivers import Request, Response
from nonebot.exception import WebSocketClosed from nonebot.exception import WebSocketClosed
from nonebot.drivers._block_driver import BlockDriver from nonebot.drivers.none import Driver as NoneDriver
from nonebot.drivers import WebSocket as BaseWebSocket from nonebot.drivers import WebSocket as BaseWebSocket
from nonebot.drivers import ForwardMixin, ForwardDriver, combine_driver from nonebot.drivers import ForwardMixin, ForwardDriver, combine_driver
@@ -70,7 +70,7 @@ class Mixin(ForwardMixin):
async def websocket(self, setup: Request) -> AsyncGenerator["WebSocket", None]: async def websocket(self, setup: Request) -> AsyncGenerator["WebSocket", None]:
connection = Connect( connection = Connect(
str(setup.url), str(setup.url),
extra_headers=setup.headers.items(), extra_headers={**setup.headers, **setup.cookies.as_header(setup)},
open_timeout=setup.timeout, open_timeout=setup.timeout,
) )
async with connection as ws: async with connection as ws:
@@ -101,8 +101,7 @@ class WebSocket(BaseWebSocket):
@overrides(BaseWebSocket) @overrides(BaseWebSocket)
@catch_closed @catch_closed
async def receive(self) -> Union[str, bytes]: async def receive(self) -> Union[str, bytes]:
msg = await self.websocket.recv() return await self.websocket.recv()
return msg
@overrides(BaseWebSocket) @overrides(BaseWebSocket)
@catch_closed @catch_closed
@@ -129,5 +128,5 @@ class WebSocket(BaseWebSocket):
await self.websocket.send(data) await self.websocket.send(data)
Driver: Type[ForwardDriver] = combine_driver(BlockDriver, Mixin) # type: ignore Driver: Type[ForwardDriver] = combine_driver(NoneDriver, Mixin) # type: ignore
"""Websockets Driver""" """Websockets Driver"""

View File

@@ -37,6 +37,9 @@ from pydantic.fields import ModelField
class NoneBotException(Exception): class NoneBotException(Exception):
"""所有 NoneBot 发生的异常基类。""" """所有 NoneBot 发生的异常基类。"""
def __str__(self) -> str:
return self.__repr__()
# Rule Exception # Rule Exception
class ParserExit(NoneBotException): class ParserExit(NoneBotException):
@@ -53,9 +56,6 @@ class ParserExit(NoneBotException):
+ ")" + ")"
) )
def __str__(self) -> str:
return self.__repr__()
# Processor Exception # Processor Exception
class ProcessException(NoneBotException): class ProcessException(NoneBotException):
@@ -75,9 +75,6 @@ class IgnoredException(ProcessException):
def __repr__(self) -> str: def __repr__(self) -> str:
return f"IgnoredException(reason={self.reason!r})" return f"IgnoredException(reason={self.reason!r})"
def __str__(self) -> str:
return self.__repr__()
class SkippedException(ProcessException): class SkippedException(ProcessException):
"""指示 NoneBot 立即结束当前 `Dependent` 的运行。 """指示 NoneBot 立即结束当前 `Dependent` 的运行。
@@ -109,9 +106,6 @@ class TypeMisMatch(SkippedException):
f"type={self.param._type_display()}, value={self.value!r}>" f"type={self.param._type_display()}, value={self.value!r}>"
) )
def __str__(self) -> str:
return self.__repr__()
class MockApiException(ProcessException): class MockApiException(ProcessException):
"""指示 NoneBot 阻止本次 API 调用或修改本次调用返回值,并返回自定义内容。可由 api hook 抛出。 """指示 NoneBot 阻止本次 API 调用或修改本次调用返回值,并返回自定义内容。可由 api hook 抛出。
@@ -126,9 +120,6 @@ class MockApiException(ProcessException):
def __repr__(self) -> str: def __repr__(self) -> str:
return f"MockApiException(result={self.result!r})" return f"MockApiException(result={self.result!r})"
def __str__(self) -> str:
return self.__repr__()
class StopPropagation(ProcessException): class StopPropagation(ProcessException):
"""指示 NoneBot 终止事件向下层传播。 """指示 NoneBot 终止事件向下层传播。
@@ -244,6 +235,3 @@ class WebSocketClosed(DriverException):
+ (f", reason={self.reason!r}" if self.reason else "") + (f", reason={self.reason!r}" if self.reason else "")
+ ")" + ")"
) )
def __str__(self) -> str:
return self.__repr__()

View File

@@ -49,11 +49,11 @@ class MessageTemplate(Formatter, Generic[TF]):
) -> None: ) -> None:
... ...
def __init__( # type:ignore def __init__(
self, template, factory=str self, template: Union[str, TM], factory: Union[Type[str], Type[TM]] = str
) -> None: # TODO: fix type hint here ) -> None:
self.template: TF = template self.template: TF = template # type: ignore
self.factory: Type[TF] = factory self.factory: Type[TF] = factory # type: ignore
self.format_specs: Dict[str, FormatSpecFunc] = {} self.format_specs: Dict[str, FormatSpecFunc] = {}
def __repr__(self) -> str: def __repr__(self) -> str:
@@ -98,7 +98,7 @@ class MessageTemplate(Formatter, Generic[TF]):
else: else:
raise TypeError("template must be a string or instance of Message!") raise TypeError("template must be a string or instance of Message!")
self.check_unused_args(list(used_args), args, kwargs) self.check_unused_args(used_args, args, kwargs)
return cast(TF, full_message) return cast(TF, full_message)
def vformat( def vformat(

View File

@@ -1,4 +1,5 @@
import abc import abc
import urllib.request
from enum import Enum from enum import Enum
from dataclasses import dataclass from dataclasses import dataclass
from http.cookiejar import Cookie, CookieJar from http.cookiejar import Cookie, CookieJar
@@ -105,12 +106,9 @@ class Request:
self.url: URL = url self.url: URL = url
# headers # headers
self.headers: CIMultiDict[str] self.headers: CIMultiDict[str] = (
if headers is not None: CIMultiDict(headers) if headers is not None else CIMultiDict()
self.headers = CIMultiDict(headers) )
else:
self.headers = CIMultiDict()
# cookies # cookies
self.cookies = Cookies(cookies) self.cookies = Cookies(cookies)
@@ -147,12 +145,9 @@ class Response:
self.status_code: int = status_code self.status_code: int = status_code
# headers # headers
self.headers: CIMultiDict[str] self.headers: CIMultiDict[str] = (
if headers is not None: CIMultiDict(headers) if headers is not None else CIMultiDict()
self.headers = CIMultiDict(headers) )
else:
self.headers = CIMultiDict()
# body # body
self.content: ContentTypes = content self.content: ContentTypes = content
@@ -308,6 +303,11 @@ class Cookies(MutableMapping):
for cookie in cookies.jar: for cookie in cookies.jar:
self.jar.set_cookie(cookie) self.jar.set_cookie(cookie)
def as_header(self, request: Request) -> Dict[str, str]:
urllib_request = self._CookieCompatRequest(request)
self.jar.add_cookie_header(urllib_request)
return urllib_request.added_headers
def __setitem__(self, name: str, value: str) -> None: def __setitem__(self, name: str, value: str) -> None:
return self.set(name, value) return self.set(name, value)
@@ -333,6 +333,20 @@ class Cookies(MutableMapping):
) )
return f"{self.__class__.__name__}({cookies_repr})" return f"{self.__class__.__name__}({cookies_repr})"
class _CookieCompatRequest(urllib.request.Request):
def __init__(self, request: Request) -> None:
super().__init__(
url=str(request.url),
headers=dict(request.headers),
method=request.method,
)
self.request = request
self.added_headers: Dict[str, str] = {}
def add_unredirected_header(self, key: str, value: str) -> None:
super().add_unredirected_header(key, value)
self.added_headers[key] = value
@dataclass @dataclass
class HTTPServerSetup: class HTTPServerSetup:

View File

@@ -247,6 +247,11 @@ class Matcher(metaclass=MatcherMeta):
return NewMatcher return NewMatcher
@classmethod
def destroy(cls) -> None:
"""销毁当前的事件响应器"""
matchers[cls.priority].remove(cls)
@classmethod @classmethod
async def check_perm( async def check_perm(
cls, cls,

View File

@@ -112,7 +112,6 @@ def run_postprocessor(func: T_RunPostProcessor) -> T_RunPostProcessor:
async def _check_matcher( async def _check_matcher(
priority: int,
Matcher: Type[Matcher], Matcher: Type[Matcher],
bot: "Bot", bot: "Bot",
event: "Event", event: "Event",
@@ -122,7 +121,7 @@ async def _check_matcher(
) -> None: ) -> None:
if Matcher.expire_time and datetime.now() > Matcher.expire_time: if Matcher.expire_time and datetime.now() > Matcher.expire_time:
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
matchers[priority].remove(Matcher) Matcher.destroy()
return return
try: try:
@@ -138,7 +137,7 @@ async def _check_matcher(
if Matcher.temp: if Matcher.temp:
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
matchers[priority].remove(Matcher) Matcher.destroy()
await _run_matcher(Matcher, bot, event, state, stack, dependency_cache) await _run_matcher(Matcher, bot, event, state, stack, dependency_cache)
@@ -294,7 +293,7 @@ async def handle_event(bot: "Bot", event: "Event") -> None:
pending_tasks = [ pending_tasks = [
_check_matcher( _check_matcher(
priority, matcher, bot, event, state.copy(), stack, dependency_cache matcher, bot, event, state.copy(), stack, dependency_cache
) )
for matcher in matchers[priority] for matcher in matchers[priority]
] ]
@@ -312,6 +311,9 @@ async def handle_event(bot: "Bot", event: "Event") -> None:
"<r><bg #f8bbd0>Error when checking Matcher.</bg #f8bbd0></r>" "<r><bg #f8bbd0>Error when checking Matcher.</bg #f8bbd0></r>"
) )
if show_log:
logger.debug("Checking for matchers completed")
if coros := [ if coros := [
run_coro_with_catch( run_coro_with_catch(
proc( proc(

View File

@@ -5,6 +5,7 @@ FrontMatter:
description: nonebot.params 模块 description: nonebot.params 模块
""" """
import warnings
from typing import Any, Dict, List, Tuple, Union, Optional from typing import Any, Dict, List, Tuple, Union, Optional
from nonebot.typing import T_State from nonebot.typing import T_State
@@ -24,6 +25,7 @@ from nonebot.internal.params import MatcherParam as MatcherParam
from nonebot.internal.params import ExceptionParam as ExceptionParam from nonebot.internal.params import ExceptionParam as ExceptionParam
from nonebot.consts import ( from nonebot.consts import (
CMD_KEY, CMD_KEY,
REGEX_STR,
PREFIX_KEY, PREFIX_KEY,
REGEX_DICT, REGEX_DICT,
SHELL_ARGS, SHELL_ARGS,
@@ -136,10 +138,25 @@ def _regex_matched(state: T_State) -> str:
def RegexMatched() -> str: def RegexMatched() -> str:
"""正则匹配结果""" """正则匹配结果"""
warnings.warn(
'"RegexMatched()" will be changed to "re.Match" object, '
'use "RegexStr()" instead. '
"See https://github.com/nonebot/nonebot2/pull/1453 .",
DeprecationWarning,
)
return Depends(_regex_matched, use_cache=False) return Depends(_regex_matched, use_cache=False)
def _regex_group(state: T_State): def _regex_str(state: T_State) -> str:
return state[REGEX_STR]
def RegexStr() -> str:
"""正则匹配结果文本"""
return Depends(_regex_str, use_cache=False)
def _regex_group(state: T_State) -> Tuple[Any, ...]:
return state[REGEX_GROUP] return state[REGEX_GROUP]
@@ -148,7 +165,7 @@ def RegexGroup() -> Tuple[Any, ...]:
return Depends(_regex_group, use_cache=False) return Depends(_regex_group, use_cache=False)
def _regex_dict(state: T_State): def _regex_dict(state: T_State) -> Dict[str, Any]:
return state[REGEX_DICT] return state[REGEX_DICT]
@@ -196,7 +213,7 @@ def Keyword() -> str:
def Received(id: Optional[str] = None, default: Any = None) -> Any: def Received(id: Optional[str] = None, default: Any = None) -> Any:
"""`receive` 事件参数""" """`receive` 事件参数"""
def _received(matcher: "Matcher"): def _received(matcher: "Matcher") -> Any:
return matcher.get_receive(id or "", default) return matcher.get_receive(id or "", default)
return Depends(_received, use_cache=False) return Depends(_received, use_cache=False)

View File

@@ -65,6 +65,8 @@ def _revert_plugin(plugin: "Plugin") -> None:
if plugin.name not in _plugins: if plugin.name not in _plugins:
raise RuntimeError("Plugin not found!") raise RuntimeError("Plugin not found!")
del _plugins[plugin.name] del _plugins[plugin.name]
if parent_plugin := plugin.parent_plugin:
parent_plugin.sub_plugins.remove(plugin)
def get_plugin(name: str) -> Optional["Plugin"]: def get_plugin(name: str) -> Optional["Plugin"]:

View File

@@ -14,7 +14,7 @@ from itertools import chain
from types import ModuleType from types import ModuleType
from importlib.abc import MetaPathFinder from importlib.abc import MetaPathFinder
from importlib.machinery import PathFinder, SourceFileLoader from importlib.machinery import PathFinder, SourceFileLoader
from typing import Set, Dict, List, Union, Iterable, Optional, Sequence from typing import Set, Dict, List, Iterable, Optional, Sequence
from nonebot.log import logger from nonebot.log import logger
from nonebot.utils import escape_tag, path_to_module_name from nonebot.utils import escape_tag, path_to_module_name
@@ -174,7 +174,7 @@ class PluginFinder(MetaPathFinder):
def find_spec( def find_spec(
self, self,
fullname: str, fullname: str,
path: Optional[Sequence[Union[bytes, str]]], path: Optional[Sequence[str]],
target: Optional[ModuleType] = None, target: Optional[ModuleType] = None,
): ):
if _managers: if _managers:

View File

@@ -439,7 +439,7 @@ def on_regex(
def on_type( def on_type(
types: Union[Type[Event], Tuple[Type[Event]]], types: Union[Type[Event], Tuple[Type[Event], ...]],
rule: Optional[Union[Rule, T_RuleChecker]] = None, rule: Optional[Union[Rule, T_RuleChecker]] = None,
*, *,
_depth: int = 0, _depth: int = 0,

View File

@@ -154,7 +154,7 @@ def on_regex(
state: Optional[T_State] = ..., state: Optional[T_State] = ...,
) -> Type[Matcher]: ... ) -> Type[Matcher]: ...
def on_type( def on_type(
types: Union[Type[Event], Tuple[Type[Event]]], types: Union[Type[Event], Tuple[Type[Event], ...]],
rule: Optional[Union[Rule, T_RuleChecker]] = ..., rule: Optional[Union[Rule, T_RuleChecker]] = ...,
*, *,
permission: Optional[Union[Permission, T_PermissionChecker]] = ..., permission: Optional[Union[Permission, T_PermissionChecker]] = ...,

View File

@@ -12,7 +12,8 @@ from pydantic import BaseModel
from nonebot.matcher import Matcher from nonebot.matcher import Matcher
from . import _plugins as plugins # FIXME: backport for nonebug # FIXME: backport for nonebug
from . import _plugins as plugins # nopycln: import
if TYPE_CHECKING: if TYPE_CHECKING:
from .manager import PluginManager from .manager import PluginManager

View File

@@ -12,6 +12,7 @@ import re
import shlex import shlex
from argparse import Action from argparse import Action
from argparse import ArgumentError from argparse import ArgumentError
from contextvars import ContextVar
from itertools import chain, product from itertools import chain, product
from argparse import Namespace as Namespace from argparse import Namespace as Namespace
from argparse import ArgumentParser as ArgParser from argparse import ArgumentParser as ArgParser
@@ -42,6 +43,7 @@ from nonebot.params import Command, EventToMe, CommandArg
from nonebot.adapters import Bot, Event, Message, MessageSegment from nonebot.adapters import Bot, Event, Message, MessageSegment
from nonebot.consts import ( from nonebot.consts import (
CMD_KEY, CMD_KEY,
REGEX_STR,
PREFIX_KEY, PREFIX_KEY,
REGEX_DICT, REGEX_DICT,
SHELL_ARGS, SHELL_ARGS,
@@ -73,6 +75,8 @@ TRIE_VALUE = NamedTuple(
"TRIE_VALUE", [("command_start", str), ("command", Tuple[str, ...])] "TRIE_VALUE", [("command_start", str), ("command", Tuple[str, ...])]
) )
parser_message: ContextVar[str] = ContextVar("parser_message")
class TrieRule: class TrieRule:
prefix: CharTrie = CharTrie() prefix: CharTrie = CharTrie()
@@ -446,13 +450,15 @@ class ArgumentParser(ArgParser):
) )
def _print_message(self, message: str, file: Optional[IO[str]] = None): def _print_message(self, message: str, file: Optional[IO[str]] = None):
if message: if (msg := parser_message.get(None)) is not None:
setattr(self, "_message", getattr(self, "_message", "") + message) parser_message.set(msg + message)
else:
super()._print_message(message, file)
def exit(self, status: int = 0, message: Optional[str] = None): def exit(self, status: int = 0, message: Optional[str] = None):
if message: if message:
self._print_message(message) self._print_message(message)
raise ParserExit(status=status, message=getattr(self, "_message", None)) raise ParserExit(status=status, message=parser_message.get(None))
class ShellCommandRule: class ShellCommandRule:
@@ -499,6 +505,7 @@ class ShellCommandRule:
) )
if self.parser: if self.parser:
t = parser_message.set("")
try: try:
args = self.parser.parse_args(state[SHELL_ARGV]) args = self.parser.parse_args(state[SHELL_ARGV])
state[SHELL_ARGS] = args state[SHELL_ARGS] = args
@@ -506,6 +513,8 @@ class ShellCommandRule:
state[SHELL_ARGS] = ParserExit(status=2, message=str(e)) state[SHELL_ARGS] = ParserExit(status=2, message=str(e))
except ParserExit as e: except ParserExit as e:
state[SHELL_ARGS] = e state[SHELL_ARGS] = e
finally:
parser_message.reset(t)
return True return True
@@ -608,6 +617,7 @@ class RegexRule:
return False return False
if matched := re.search(self.regex, str(msg), self.flags): if matched := re.search(self.regex, str(msg), self.flags):
state[REGEX_MATCHED] = matched.group() state[REGEX_MATCHED] = matched.group()
state[REGEX_STR] = matched.group()
state[REGEX_GROUP] = matched.groups() state[REGEX_GROUP] = matched.groups()
state[REGEX_DICT] = matched.groupdict() state[REGEX_DICT] = matched.groupdict()
return True return True
@@ -618,7 +628,7 @@ class RegexRule:
def regex(regex: str, flags: Union[int, re.RegexFlag] = 0) -> Rule: def regex(regex: str, flags: Union[int, re.RegexFlag] = 0) -> Rule:
"""匹配符合正则表达式的消息字符串。 """匹配符合正则表达式的消息字符串。
可以通过 {ref}`nonebot.params.RegexMatched` 获取匹配成功的字符串, 可以通过 {ref}`nonebot.params.RegexStr` 获取匹配成功的字符串,
通过 {ref}`nonebot.params.RegexGroup` 获取匹配成功的 group 元组, 通过 {ref}`nonebot.params.RegexGroup` 获取匹配成功的 group 元组,
通过 {ref}`nonebot.params.RegexDict` 获取匹配成功的 group 字典。 通过 {ref}`nonebot.params.RegexDict` 获取匹配成功的 group 字典。

View File

@@ -11,7 +11,7 @@
"start": "yarn workspace nonebot start", "start": "yarn workspace nonebot start",
"serve": "yarn workspace nonebot serve", "serve": "yarn workspace nonebot serve",
"clear": "yarn workspace nonebot clear", "clear": "yarn workspace nonebot clear",
"prettier": "prettier --config ./.prettierrc --write \"./website/**/*.md\"" "prettier": "prettier --config ./.prettierrc --write \"./website/\""
}, },
"devDependencies": { "devDependencies": {
"cross-env": "^7.0.3", "cross-env": "^7.0.3",

3242
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "nonebot2" name = "nonebot2"
version = "2.0.0rc2" version = "2.0.0rc3"
description = "An asynchronous python bot framework." description = "An asynchronous python bot framework."
authors = ["yanyongyu <yyy@nonebot.dev>"] authors = ["yanyongyu <yyy@nonebot.dev>"]
license = "MIT" license = "MIT"
@@ -26,18 +26,19 @@ python = "^3.8"
yarl = "^1.7.2" yarl = "^1.7.2"
loguru = "^0.6.0" loguru = "^0.6.0"
pygtrie = "^2.4.1" pygtrie = "^2.4.1"
fastapi = ">=0.87.0,<1.0.0"
tomlkit = ">=0.10.0,<1.0.0" tomlkit = ">=0.10.0,<1.0.0"
typing-extensions = ">=3.10.0,<5.0.0" typing-extensions = ">=3.10.0,<5.0.0"
pydantic = { version = "^1.10.0", extras = ["dotenv"] } pydantic = { version = "^1.10.0", extras = ["dotenv"] }
uvicorn = { version = ">=0.20.0,<1.0.0", extras = ["standard"] }
websockets = { version="^10.0", optional = true } websockets = { version = "^10.0", optional = true }
Quart = { version = ">=0.18.0,<1.0.0", optional = true } Quart = { version = ">=0.18.0,<1.0.0", optional = true }
fastapi = { version = ">=0.87.0,!=0.89.0,<1.0.0", optional = true }
aiohttp = { version = "^3.7.4", extras = ["speedups"], optional = true } aiohttp = { version = "^3.7.4", extras = ["speedups"], optional = true }
httpx = { version = ">=0.20.0,<1.0.0", extras = ["http2"], optional = true } httpx = { version = ">=0.20.0,<1.0.0", extras = ["http2"], optional = true }
uvicorn = { version = ">=0.20.0,<1.0.0", extras = ["standard"], optional = true }
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
pycln = "^2.1.2"
isort = "^5.10.1" isort = "^5.10.1"
black = "^22.1.0" black = "^22.1.0"
nonemoji = "^0.1.2" nonemoji = "^0.1.2"
@@ -53,11 +54,12 @@ nonebug = { git = "https://github.com/nonebot/nonebug.git" }
nb-autodoc = { git = "https://github.com/nonebot/nb-autodoc.git" } nb-autodoc = { git = "https://github.com/nonebot/nb-autodoc.git" }
[tool.poetry.extras] [tool.poetry.extras]
quart = ["quart"]
httpx = ["httpx"] httpx = ["httpx"]
aiohttp = ["aiohttp"] aiohttp = ["aiohttp"]
websockets = ["websockets"] websockets = ["websockets"]
all = ["quart", "aiohttp", "httpx", "websockets"] quart = ["quart", "uvicorn"]
fastapi = ["fastapi", "uvicorn"]
all = ["fastapi", "quart", "aiohttp", "httpx", "websockets", "uvicorn"]
[tool.pytest.ini_options] [tool.pytest.ini_options]
asyncio_mode = "auto" asyncio_mode = "auto"
@@ -83,6 +85,20 @@ force_sort_within_sections = true
src_paths = ["nonebot", "tests"] src_paths = ["nonebot", "tests"]
extra_standard_library = ["typing_extensions"] extra_standard_library = ["typing_extensions"]
[tool.pycln]
path = "."
all = false
[tool.pyright]
reportShadowedImports = false
pythonVersion = "3.8"
pythonPlatform = "All"
executionEnvironments = [
{ root = "./tests", extraPaths = ["./"] },
{ root = "./" },
]
[build-system] [build-system]
requires = ["poetry_core>=1.0.0"] requires = ["poetry_core>=1.0.0"]
build-backend = "poetry.core.masonry.api" build-backend = "poetry.core.masonry.api"

View File

@@ -1 +1 @@
from .nested_subplugin2 import a from .nested_subplugin2 import a # nopycln: import

View File

@@ -6,6 +6,7 @@ from nonebot.params import (
Command, Command,
Keyword, Keyword,
Endswith, Endswith,
RegexStr,
Fullmatch, Fullmatch,
RegexDict, RegexDict,
CommandArg, CommandArg,
@@ -71,6 +72,10 @@ async def regex_matched(regex_matched: str = RegexMatched()) -> str:
return regex_matched return regex_matched
async def regex_str(regex_matched: str = RegexStr()) -> str:
return regex_matched
async def startswith(startswith: str = Startswith()) -> str: async def startswith(startswith: str = Startswith()) -> str:
return startswith return startswith

View File

@@ -1,3 +1,5 @@
import json
import asyncio
from typing import cast from typing import cast
import pytest import pytest
@@ -79,6 +81,62 @@ async def test_reverse_driver(app: App):
await ws.close() await ws.close()
await asyncio.sleep(1)
@pytest.mark.asyncio
@pytest.mark.parametrize(
"nonebug_init",
[
pytest.param({"driver": "nonebot.drivers.httpx:Driver"}, id="httpx"),
pytest.param({"driver": "nonebot.drivers.aiohttp:Driver"}, id="aiohttp"),
],
indirect=True,
)
async def test_http_driver(app: App):
import nonebot
from nonebot.drivers import Request, ForwardDriver
driver = cast(ForwardDriver, nonebot.get_driver())
request = Request(
"POST",
"https://httpbin.org/post",
params={"param": "test"},
headers={"X-Test": "test"},
cookies={"session": "test"},
content="test",
)
response = await driver.request(request)
assert response.status_code == 200 and response.content
data = json.loads(response.content)
assert data["args"] == {"param": "test"}
assert data["headers"].get("X-Test") == "test"
assert data["headers"].get("Cookie") == "session=test"
assert data["data"] == "test"
request = Request("POST", "https://httpbin.org/post", data={"form": "test"})
response = await driver.request(request)
assert response.status_code == 200 and response.content
data = json.loads(response.content)
assert data["form"] == {"form": "test"}
request = Request("POST", "https://httpbin.org/post", json={"json": "test"})
response = await driver.request(request)
assert response.status_code == 200 and response.content
data = json.loads(response.content)
assert data["json"] == {"json": "test"}
request = Request(
"POST", "https://httpbin.org/post", files={"test": ("test.txt", b"test")}
)
response = await driver.request(request)
assert response.status_code == 200 and response.content
data = json.loads(response.content)
assert data["files"] == {"test": "test"}
await asyncio.sleep(1)
@pytest.mark.asyncio @pytest.mark.asyncio
@pytest.mark.parametrize( @pytest.mark.parametrize(
@@ -91,7 +149,7 @@ async def test_reverse_driver(app: App):
), ),
pytest.param( pytest.param(
{"driver": "~httpx:Driver+~websockets"}, {"driver": "~httpx:Driver+~websockets"},
"block_driver+httpx+websockets", "none+httpx+websockets",
id="httpx+websockets", id="httpx+websockets",
), ),
], ],

View File

@@ -187,25 +187,19 @@ async def test_expire(app: App, load_plugin):
async with app.test_api() as ctx: async with app.test_api() as ctx:
bot = ctx.create_bot() bot = ctx.create_bot()
assert test_temp_matcher in matchers[test_temp_matcher.priority] assert test_temp_matcher in matchers[test_temp_matcher.priority]
await _check_matcher( await _check_matcher(test_temp_matcher, bot, event, {})
test_temp_matcher.priority, test_temp_matcher, bot, event, {}
)
assert test_temp_matcher not in matchers[test_temp_matcher.priority] assert test_temp_matcher not in matchers[test_temp_matcher.priority]
event = make_fake_event()() event = make_fake_event()()
async with app.test_api() as ctx: async with app.test_api() as ctx:
bot = ctx.create_bot() bot = ctx.create_bot()
assert test_datetime_matcher in matchers[test_datetime_matcher.priority] assert test_datetime_matcher in matchers[test_datetime_matcher.priority]
await _check_matcher( await _check_matcher(test_datetime_matcher, bot, event, {})
test_datetime_matcher.priority, test_datetime_matcher, bot, event, {}
)
assert test_datetime_matcher not in matchers[test_datetime_matcher.priority] assert test_datetime_matcher not in matchers[test_datetime_matcher.priority]
event = make_fake_event()() event = make_fake_event()()
async with app.test_api() as ctx: async with app.test_api() as ctx:
bot = ctx.create_bot() bot = ctx.create_bot()
assert test_timedelta_matcher in matchers[test_timedelta_matcher.priority] assert test_timedelta_matcher in matchers[test_timedelta_matcher.priority]
await _check_matcher( await _check_matcher(test_timedelta_matcher, bot, event, {})
test_timedelta_matcher.priority, test_timedelta_matcher, bot, event, {}
)
assert test_timedelta_matcher not in matchers[test_timedelta_matcher.priority] assert test_timedelta_matcher not in matchers[test_timedelta_matcher.priority]

View File

@@ -163,6 +163,7 @@ async def test_state(app: App, load_plugin):
from nonebot.params import StateParam, DependParam from nonebot.params import StateParam, DependParam
from nonebot.consts import ( from nonebot.consts import (
CMD_KEY, CMD_KEY,
REGEX_STR,
PREFIX_KEY, PREFIX_KEY,
REGEX_DICT, REGEX_DICT,
SHELL_ARGS, SHELL_ARGS,
@@ -183,6 +184,7 @@ async def test_state(app: App, load_plugin):
keyword, keyword,
endswith, endswith,
fullmatch, fullmatch,
regex_str,
regex_dict, regex_dict,
startswith, startswith,
command_arg, command_arg,
@@ -207,6 +209,7 @@ async def test_state(app: App, load_plugin):
SHELL_ARGV: ["-h"], SHELL_ARGV: ["-h"],
SHELL_ARGS: {"help": True}, SHELL_ARGS: {"help": True},
REGEX_MATCHED: "[cq:test,arg=value]", REGEX_MATCHED: "[cq:test,arg=value]",
REGEX_STR: "[cq:test,arg=value]",
REGEX_GROUP: ("test", "arg=value"), REGEX_GROUP: ("test", "arg=value"),
REGEX_DICT: {"type": "test", "arg": "value"}, REGEX_DICT: {"type": "test", "arg": "value"},
STARTSWITH_KEY: "startswith", STARTSWITH_KEY: "startswith",
@@ -271,6 +274,12 @@ async def test_state(app: App, load_plugin):
ctx.pass_params(state=fake_state) ctx.pass_params(state=fake_state)
ctx.should_return(fake_state[REGEX_MATCHED]) ctx.should_return(fake_state[REGEX_MATCHED])
async with app.test_dependent(
regex_str, allow_types=[StateParam, DependParam]
) as ctx:
ctx.pass_params(state=fake_state)
ctx.should_return(fake_state[REGEX_STR])
async with app.test_dependent( async with app.test_dependent(
regex_group, allow_types=[StateParam, DependParam] regex_group, allow_types=[StateParam, DependParam]
) as ctx: ) as ctx:

View File

@@ -296,6 +296,7 @@ async def test_shell_command(app: App):
assert state[SHELL_ARGV] == [] assert state[SHELL_ARGV] == []
assert isinstance(state[SHELL_ARGS], ParserExit) assert isinstance(state[SHELL_ARGS], ParserExit)
assert state[SHELL_ARGS].status != 0 assert state[SHELL_ARGS].status != 0
assert state[SHELL_ARGS].message.startswith(parser.format_usage() + "test: error:")
test_message_parser = shell_command(CMD, parser=parser) test_message_parser = shell_command(CMD, parser=parser)
dependent = list(test_message_parser.checkers)[0] dependent = list(test_message_parser.checkers)[0]
@@ -327,7 +328,7 @@ async def test_shell_command(app: App):
@pytest.mark.asyncio @pytest.mark.asyncio
@pytest.mark.parametrize( @pytest.mark.parametrize(
"pattern,type,text,expected,matched,group,dict", "pattern,type,text,expected,matched,string,group,dict",
[ [
( (
r"(?P<key>key\d)", r"(?P<key>key\d)",
@@ -335,11 +336,12 @@ async def test_shell_command(app: App):
"_key1_", "_key1_",
True, True,
"key1", "key1",
"key1",
("key1",), ("key1",),
{"key": "key1"}, {"key": "key1"},
), ),
(r"foo", "message", None, False, None, None, None), (r"foo", "message", None, False, None, None, None, None),
(r"foo", "notice", "foo", False, None, None, None), (r"foo", "notice", "foo", False, None, None, None, None),
], ],
) )
async def test_regex( async def test_regex(
@@ -349,12 +351,13 @@ async def test_regex(
text: Optional[str], text: Optional[str],
expected: bool, expected: bool,
matched: Optional[str], matched: Optional[str],
string: Optional[str],
group: Optional[Tuple[str, ...]], group: Optional[Tuple[str, ...]],
dict: Optional[Dict[str, str]], dict: Optional[Dict[str, str]],
): ):
from nonebot.typing import T_State from nonebot.typing import T_State
from nonebot.rule import RegexRule, regex from nonebot.rule import RegexRule, regex
from nonebot.consts import REGEX_DICT, REGEX_GROUP, REGEX_MATCHED from nonebot.consts import REGEX_STR, REGEX_DICT, REGEX_GROUP, REGEX_MATCHED
test_regex = regex(pattern) test_regex = regex(pattern)
dependent = list(test_regex.checkers)[0] dependent = list(test_regex.checkers)[0]
@@ -368,6 +371,7 @@ async def test_regex(
state = {} state = {}
assert await dependent(event=event, state=state) == expected assert await dependent(event=event, state=state) == expected
assert state.get(REGEX_MATCHED) == matched assert state.get(REGEX_MATCHED) == matched
assert state.get(REGEX_STR) == string
assert state.get(REGEX_GROUP) == group assert state.get(REGEX_GROUP) == group
assert state.get(REGEX_DICT) == dict assert state.get(REGEX_DICT) == dict

View File

@@ -20,7 +20,11 @@ options:
您可以选择自己喜欢的方式将插件发布到 [**PyPI**](https://pypi.org/),如使用 [**setuptools**](https://pypi.org/project/setuptools/) 或 [**Poetry**](https://pypi.org/project/poetry/)。 您可以选择自己喜欢的方式将插件发布到 [**PyPI**](https://pypi.org/),如使用 [**setuptools**](https://pypi.org/project/setuptools/) 或 [**Poetry**](https://pypi.org/project/poetry/)。
发布时,请您为自己的插件取一个清晰易懂的名字。通常而言,一款 NoneBot2 插件名称使用 `nonebot-plugin-` 作为前缀(如`nonebot-plugin-foo`),以 `nonebot_plugin_` 作为包名的前缀(如`nonebot_plugin_foo`),这并非强制规范,而是为了防止与其他 PyPI 包产生冲突,所以我们推荐您在没有特殊需求的情况下这样做。 发布时,请您为自己的插件取一个清晰易懂的名字。通常而言,一款 NoneBot2 插件名称使用 `nonebot-plugin-` 作为 PyPI 项目名前缀(如`nonebot-plugin-foo`),以 `nonebot_plugin_` 作为 Python 包名的前缀(如`nonebot_plugin_foo`),这并非强制规范,而是为了防止与其他 PyPI 包产生冲突,所以我们推荐您在没有特殊需求的情况下这样做。
:::warning
虽然在 NoneBot 2 载入插件时,插件的 Python 包名中可以使用 `-`,但是在 Python 的 import 语句中,`-` 不会被解析为包名的一部分。如果插件需要向外界提供 import 语法导入的支持,应在 Python 包名中使用 `_` 代替 `-`
:::
发布后,请确保您的插件已能公开的从 PyPI 访问到,试着检查您的插件在 PyPI 的地址,如 `https://pypi.org/project/<您的 NoneBot2 插件项目名>` 发布后,请确保您的插件已能公开的从 PyPI 访问到,试着检查您的插件在 PyPI 的地址,如 `https://pypi.org/project/<您的 NoneBot2 插件项目名>`
@@ -32,7 +36,7 @@ options:
### 申请发布到 NoneBot2 插件商店 ### 申请发布到 NoneBot2 插件商店
完成在 PyPI 的插件发布流程与源代码托管流程后,请您前往 [**NoneBot2 商店**](https://v2.nonebot.dev/store.html)页面,切换到**插件**页签,点击**发布插件**按钮。 完成在 PyPI 的插件发布流程与源代码托管流程后,请您前往 [**NoneBot2 商店**](https://v2.nonebot.dev/store)页面,切换到**插件**页签,点击**发布插件**按钮。
![插件发布界面](./images/plugin_store_publish.png) ![插件发布界面](./images/plugin_store_publish.png)
@@ -61,12 +65,12 @@ import 包名:您的插件通过 Python 导入时使用的包名,如 nonebot
之后NoneBot2 的维护者们将会对插件进行进一步的检查,以确保用户能够正常安装并使用该插件。 之后NoneBot2 的维护者们将会对插件进行进一步的检查,以确保用户能够正常安装并使用该插件。
完成这些步骤后,您的插件将会被合并到 [**NoneBot2 商店**](https://v2.nonebot.dev/store.html),而您也将成为 [**NoneBot2 贡献者**](https://github.com/nonebot/nonebot2/graphs/contributors)中的一员。 完成这些步骤后,您的插件将会被合并到 [**NoneBot2 商店**](https://v2.nonebot.dev/store),而您也将成为 [**NoneBot2 贡献者**](https://github.com/nonebot/nonebot2/graphs/contributors)中的一员。
## 完成 ## 完成
恭喜您,经过上述的发布流程,您的插件已经成功发布到 NoneBot2 商店了。 恭喜您,经过上述的发布流程,您的插件已经成功发布到 NoneBot2 商店了。
此时,您可以在 [**NoneBot2 商店**](https://v2.nonebot.dev/store.html)的插件页签查找到您的插件。同时,欢迎您成为 [**NoneBot2 贡献者**](https://github.com/nonebot/nonebot2/graphs/contributors) 此时,您可以在 [**NoneBot2 商店**](https://v2.nonebot.dev/store)的插件页签查找到您的插件。同时,欢迎您成为 [**NoneBot2 贡献者**](https://github.com/nonebot/nonebot2/graphs/contributors)
**Congratulations!** **Congratulations!**

View File

@@ -49,8 +49,8 @@ async def init_adapter(app: App, import_hook):
1. 反向 HTTPWebHook 1. 反向 HTTPWebHook
2. 反向 WebSocket 2. 反向 WebSocket
3. ~~正向 HTTP(尚未实现)~~ 3. 正向 HTTP
4. ~~正向 WebSocket(尚未实现)~~ 4. 正向 WebSocket
NoneBug 的 `test_server` 方法可以供我们测试反向连接方式。 NoneBug 的 `test_server` 方法可以供我们测试反向连接方式。

View File

@@ -24,7 +24,7 @@ nb adapter list
或者自行输入命令安装: 或者自行输入命令安装:
```bash ```bash
nb adapter install <adapter-name> nb adapter install <adapter-package>
``` ```
或者使用交互模式安装: 或者使用交互模式安装:
@@ -36,7 +36,7 @@ nb adapter install
也可以使用 pip 安装 也可以使用 pip 安装
```bash ```bash
pip install <adapter-name> pip install <adapter-package>
``` ```
<Asciinema <Asciinema

View File

@@ -7,7 +7,7 @@ import Asciinema from "@site/src/components/Asciinema";
# 安装驱动器 # 安装驱动器
NoneBot 在默认安装情况下内置了 `fastapi` 服务端驱动器,其他驱动器如 `httpx`、`aiohttp` 则需要额外安装。 NoneBot 在默认安装情况下内置了 `none` 驱动器,其他驱动器如 `fastapi`、`httpx`、`aiohttp` 则需要额外安装。
## 查看 ## 查看
@@ -38,7 +38,7 @@ nb driver install
也可以使用 pip 安装 也可以使用 pip 安装
```bash ```bash
pip install <driver-name> pip install <driver-package>
``` ```
<Asciinema <Asciinema

View File

@@ -24,7 +24,7 @@ nb plugin list
或者自行输入命令安装: 或者自行输入命令安装:
```bash ```bash
nb plugin install <plugin-name> nb plugin install <plugin-package>
``` ```
或者使用交互模式安装: 或者使用交互模式安装:
@@ -36,7 +36,7 @@ nb plugin install
也可以使用 pip 安装 也可以使用 pip 安装
```bash ```bash
pip install <plugin-name> pip install <plugin-package>
``` ```
<Asciinema <Asciinema

View File

@@ -27,13 +27,21 @@ pip uninstall nonebot
## 通过脚手架安装(推荐) ## 通过脚手架安装(推荐)
1. (可选)使用你喜欢的 Python 环境管理工具(如 Poetry、venv、Conda 等)创建新的虚拟环境 1. 安装 [pipx](https://pypa.github.io/pipx/)
2. 使用 pip 或其他包管理工具安装 nb-cliNoneBot2 会作为其依赖被一起安装
```bash ```bash
pip install nb-cli python -m pip install --user pipx
python -m pipx ensurepath
``` ```
2. 安装脚手架
```bash
pipx install nb-cli
```
安装完成后,你可以在命令行使用 `nb` 命令来使用脚手架。如果出现无法找到命令的情况(例如:`Command not found`),请参考 [pipx 文档](https://pypa.github.io/pipx/) 检查你的环境变量。
<Asciinema <Asciinema
url="https://asciinema.org/a/464654.cast" url="https://asciinema.org/a/464654.cast"
options={{ theme: "monokai", poster: "npt:2.8" }} options={{ theme: "monokai", poster: "npt:2.8" }}
@@ -48,9 +56,9 @@ nb-cli 的使用方法详见[使用脚手架](./nb-cli.md)
如果你不想使用脚手架,可以直接安装 NoneBot2并自行完成开发配置。 如果你不想使用脚手架,可以直接安装 NoneBot2并自行完成开发配置。
```bash ```bash
pip install nonebot2 pip install nonebot2[fastapi]
# 也可以通过 Poetry 安装 # 也可以通过 Poetry 安装
poetry add nonebot2 poetry add nonebot2[fastapi]
``` ```
## 从 GitHub 安装 ## 从 GitHub 安装

View File

@@ -10,10 +10,12 @@ options:
# 使用脚手架 # 使用脚手架
`nb-cli` 详细参考文档已移至 <https://cli.nonebot.dev>
## 安装 ## 安装
```bash ```bash
pip install nb-cli pipx install nb-cli
``` ```
## 初次使用 ## 初次使用
@@ -21,14 +23,11 @@ pip install nb-cli
在安装完成之后,即可在命令行使用 nb-cli 的命令 `nb` 进行开发: 在安装完成之后,即可在命令行使用 nb-cli 的命令 `nb` 进行开发:
```bash ```bash
# 直接使用 nb 命令
nb nb
# 或使用 Python 执行 module
python -m nb_cli
``` ```
:::warning 注意 :::warning 注意
通常情况下,你可以直接在命令行使用 `nb` 命令,但如果命令行出现 `Command not found` 错误,这是由于环境变量 `PATH` 没有正确配置或未配置导致的,可以使用第二种方式代替 通常情况下,你可以直接在命令行使用 `nb` 命令。如果出现无法找到命令的情况(例如:`Command not found`),请参考 [pipx 文档](https://pypa.github.io/pipx/) 检查你的环境变量
::: :::
## 使用方式 ## 使用方式

View File

@@ -14,16 +14,36 @@ options:
NoneBot 提供了两种方式来调用机器人平台 API两种方式都需要首先获得 Bot 实例,然后调用相应的方法。 NoneBot 提供了两种方式来调用机器人平台 API两种方式都需要首先获得 Bot 实例,然后调用相应的方法。
例如,如果需要调用机器人平台的 `get_user_info` API可以这样做 ## 获取 Bot 实例
```python ```python
from nonebot import get_bot from nonebot import get_bot
bot = get_bot("bot_id") bot = get_bot() # 获取第一个已连接的 bot 实例
bot = get_bot("bot_id") # 获取指定 bot_id 的 bot 实例
```
在事件处理依赖中,我们可以使用更为简便的办法来获取 bot 实例,详情可以参考 [获取上下文信息-Bot](https://v2.nonebot.dev/docs/tutorial/plugin/create-handler#bot)
```python
from nonebot.adapters import Bot
async def handle_func(bot: Bot): # 通过依赖注入获取 bot 实例
...
```
## 调用 API
如果需要调用某个机器人平台的 `get_user_info` API我们可以使用以下任意一种方式
```python
# 通过 bot 实例上的魔术方法直接使用.操作符调用 API
result = await bot.get_user_info(user_id=12345678) result = await bot.get_user_info(user_id=12345678)
await bot.call_api("get_user_info", user_id=12345678)
# 通过 bot 实例上的 call_api 方法调用 API
result = await bot.call_api("get_user_info", user_id=12345678)
``` ```
:::tip 提示 :::tip 提示
API 由平台提供,请参考平台文档。 实际可用的 API 由平台提供,请参考平台文档。
::: :::

View File

@@ -146,6 +146,12 @@ nonebot.run(app="bot:app")
默认值:`None` 默认值:`None`
说明:不要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值 说明:不要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值
##### `fastapi_extra`
类型:`Dist[str, Any]`
默认值:`{}`
说明:传递给 `FastAPI` 的其他参数
### Quart ### Quart
类型:`ReverseDriver` 类型:`ReverseDriver`
@@ -199,6 +205,12 @@ nonebot.run(app="bot:app")
默认值:`None` 默认值:`None`
说明:不要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值 说明:不要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值
##### `quart_extra`
类型:`Dist[str, Any]`
默认值:`{}`
说明:传递给 `Quart` 的其他参数
### HTTPX ### HTTPX
类型:`ForwardDriver` 类型:`ForwardDriver`

View File

@@ -224,8 +224,8 @@ NICKNAME=["bot"]
命令消息的起始符和分隔符。用于 [`command`](../api/rule.md#command) 规则。 命令消息的起始符和分隔符。用于 [`command`](../api/rule.md#command) 规则。
```env ```env
COMMAND_START={"/", "!"} COMMAND_START=["/", "!"]
COMMAND_SEP={".", "/"} COMMAND_SEP=[".", "/"]
``` ```
### Session Expire Timeout ### Session Expire Timeout

View File

@@ -11,7 +11,7 @@ NoneBot 使用 [Loguru](https://loguru.readthedocs.io/) 进行日志记录,并
NoneBot 启动时会添加一个默认的日志 handler。此 handler 将会将日志输出到 **stdout**,并且根据配置的日志级别进行过滤。 NoneBot 启动时会添加一个默认的日志 handler。此 handler 将会将日志输出到 **stdout**,并且根据配置的日志级别进行过滤。
[默认格式](../api/log.md#default_format)): [默认格式](../api/log.md#default_format):
```python ```python
default_format: str = ( default_format: str = (

View File

@@ -321,18 +321,18 @@ matcher = on_shell_command("cmd")
async def _(foo: List[Union[str, MessageSegment]] = ShellCommandArgv()): ... async def _(foo: List[Union[str, MessageSegment]] = ShellCommandArgv()): ...
``` ```
### RegexMatched ### RegexStr
获取正则匹配结果。 获取正则匹配结果的文本
```python {7} ```python {7}
from nonebot import on_regex from nonebot import on_regex
from nonebot.params import RegexMatched from nonebot.params import RegexStr
matcher = on_regex("regex") matcher = on_regex("regex")
@matcher.handle() @matcher.handle()
async def _(foo: str = RegexMatched()): ... async def _(foo: str = RegexStr()): ...
``` ```
### RegexGroup ### RegexGroup

View File

@@ -17,14 +17,16 @@ export type Obj = {
}; };
export function filterObjs(filter: string, objs: Obj[]): Obj[] { export function filterObjs(filter: string, objs: Obj[]): Obj[] {
let filterLower = filter.toLowerCase();
return objs.filter((o) => { return objs.filter((o) => {
return ( return (
o.module_name?.includes(filter) || o.module_name?.toLowerCase().includes(filterLower) ||
o.project_link?.includes(filter) || o.project_link?.toLowerCase().includes(filterLower) ||
o.name.includes(filter) || o.name.toLowerCase().includes(filterLower) ||
o.desc.includes(filter) || o.desc.toLowerCase().includes(filterLower) ||
o.author.includes(filter) || o.author.toLowerCase().includes(filterLower) ||
o.tags.filter((t) => t.label.includes(filter)).length > 0 o.tags.filter((t) => t.label.toLowerCase().includes(filterLower)).length >
0
); );
}); });
} }

View File

@@ -5,6 +5,128 @@ toc_max_heading_level: 2
# 更新日志 # 更新日志
## v2.0.0rc3
### 🚀 新功能
- Feature: 添加事件响应器检查完成日志 [@A-kirami](https://github.com/A-kirami) ([#1578](https://github.com/nonebot/nonebot2/pull/1578))
- Remove: 移除默认安装 FastAPI [@yanyongyu](https://github.com/yanyongyu) ([#1557](https://github.com/nonebot/nonebot2/pull/1557))
- Feature: 支持给 `FastAPI``Quart` 传递额外的参数 [@A-kirami](https://github.com/A-kirami) ([#1543](https://github.com/nonebot/nonebot2/pull/1543))
- Feature: 添加 `logger` 重导出 [@A-kirami](https://github.com/A-kirami) ([#1526](https://github.com/nonebot/nonebot2/pull/1526))
- Feature: 将 block driver 转正为 none 驱动器 [@he0119](https://github.com/he0119) ([#1522](https://github.com/nonebot/nonebot2/pull/1522))
- Develop: 使用 pycln 自动移除未使用的 import [@yanyongyu](https://github.com/yanyongyu) ([#1481](https://github.com/nonebot/nonebot2/pull/1481))
- Feature: 添加正则匹配文本注入 [@A-kirami](https://github.com/A-kirami) ([#1457](https://github.com/nonebot/nonebot2/pull/1457))
- Feature: 支持主动销毁事件响应器 [@A-kirami](https://github.com/A-kirami) ([#1444](https://github.com/nonebot/nonebot2/pull/1444))
### 🐛 Bug 修复
- Fix: 屏蔽 fastapi 0.89.0 [@yanyongyu](https://github.com/yanyongyu) ([#1574](https://github.com/nonebot/nonebot2/pull/1574))
- Fix: 修复子插件加载失败时没有从父插件中移除的问题 [@A-kirami](https://github.com/A-kirami) ([#1559](https://github.com/nonebot/nonebot2/pull/1559))
- Fix: 修复客户端请求未处理 cookies [@yanyongyu](https://github.com/yanyongyu) ([#1491](https://github.com/nonebot/nonebot2/pull/1491))
- Fix: `on_type` typing error [@yanyongyu](https://github.com/yanyongyu) ([#1482](https://github.com/nonebot/nonebot2/pull/1482))
- Fix: 修复 ArgumentParser 错误信息叠加问题 [@yanyongyu](https://github.com/yanyongyu) ([#1426](https://github.com/nonebot/nonebot2/pull/1426))
### 📝 文档
- Docs: 修改更新部分文档 [@yanyongyu](https://github.com/yanyongyu) ([#1615](https://github.com/nonebot/nonebot2/pull/1615))
- Docs: 商店搜索大小写不敏感 [@StarHeartHunt](https://github.com/StarHeartHunt) ([#1609](https://github.com/nonebot/nonebot2/pull/1609))
- Docs: 更新测试文档中的连接方式\&细化插件发布描述 [@StarHeartHunt](https://github.com/StarHeartHunt) ([#1504](https://github.com/nonebot/nonebot2/pull/1504))
- Docs: 修复文档中部分超链接跳转到 `/store.html` 的问题 [@yzyyz1387](https://github.com/yzyyz1387) ([#1470](https://github.com/nonebot/nonebot2/pull/1470))
- Fix: 补充 `params` 模块的类型注解 [@A-kirami](https://github.com/A-kirami) ([#1458](https://github.com/nonebot/nonebot2/pull/1458))
- Docs: 移除文档 `自定义日志` 中多余的符号 [@A-kirami](https://github.com/A-kirami) ([#1448](https://github.com/nonebot/nonebot2/pull/1448))
- Docs: 完善 `调用平台 API` 部分 [@A-kirami](https://github.com/A-kirami) ([#1447](https://github.com/nonebot/nonebot2/pull/1447))
- Docs: 修正文档中部分配置文件示例的符号误用 [@MingxuanGame](https://github.com/MingxuanGame) ([#1432](https://github.com/nonebot/nonebot2/pull/1432))
### 💫 杂项
- Plugin: 移除 nonebot-plugin-puppet [@j1g5awi](https://github.com/j1g5awi) ([#1605](https://github.com/nonebot/nonebot2/pull/1605))
- Plugin: 更新 MC 的插件信息 [@nikissXI](https://github.com/nikissXI) ([#1589](https://github.com/nonebot/nonebot2/pull/1589))
- Plugin: 移除 `nonebot-plugin-aidraw` [@A-kirami](https://github.com/A-kirami) ([#1588](https://github.com/nonebot/nonebot2/pull/1588))
- Plugins: 更新 ayaka_games 插件名和描述 [@bridgeL](https://github.com/bridgeL) ([#1586](https://github.com/nonebot/nonebot2/pull/1586))
- Plugin: 更新 tts_gal 插件名和描述 [@dpm12345](https://github.com/dpm12345) ([#1581](https://github.com/nonebot/nonebot2/pull/1581))
- Plugin: 移除 `nonebot_plugin_super_resolution` [@A-kirami](https://github.com/A-kirami) ([#1561](https://github.com/nonebot/nonebot2/pull/1561))
- Plugin: 更新 OlivOS.nb2 import 包名 [@j1g5awi](https://github.com/j1g5awi) ([#1560](https://github.com/nonebot/nonebot2/pull/1560))
- Develop: 添加 pyright 环境配置 [@yanyongyu](https://github.com/yanyongyu) ([#1554](https://github.com/nonebot/nonebot2/pull/1554))
- CI: 优化触发条件减少无效运行 [@he0119](https://github.com/he0119) ([#1545](https://github.com/nonebot/nonebot2/pull/1545))
- Plugin: 删除 ayaka_who_is_suspect 插件 [@bridgeL](https://github.com/bridgeL) ([#1525](https://github.com/nonebot/nonebot2/pull/1525))
- Fix: 修复异常在 traceback 中无法正常显示信息 [@he0119](https://github.com/he0119) ([#1521](https://github.com/nonebot/nonebot2/pull/1521))
- CI: 添加插件加载测试 [@he0119](https://github.com/he0119) ([#1519](https://github.com/nonebot/nonebot2/pull/1519))
- Plugin: 移除 `nonebot-plugin-filehost` [@mnixry](https://github.com/mnixry) ([#1516](https://github.com/nonebot/nonebot2/pull/1516))
- Plugin: 更新 `abstain_diary` 插件名和描述 [@Ikaros-521](https://github.com/Ikaros-521) ([#1509](https://github.com/nonebot/nonebot2/pull/1509))
- Plugin: 更新 gpt3 插件模块名 [@chrisyy2003](https://github.com/chrisyy2003) ([#1501](https://github.com/nonebot/nonebot2/pull/1501))
- Plugin: 更新 随机禁言 插件功能描述 [@Ikaros-521](https://github.com/Ikaros-521) ([#1495](https://github.com/nonebot/nonebot2/pull/1495))
- Plugin: 更新 multi chatgpt 插件仓库地址 [@chrisyy2003](https://github.com/chrisyy2003) ([#1487](https://github.com/nonebot/nonebot2/pull/1487))
- Plugin: 更新 ayaka_games 介绍 [@bridgeL](https://github.com/bridgeL) ([#1431](https://github.com/nonebot/nonebot2/pull/1431))
- Plugin: 修改 novelai send magiadice 插件模块名 [@sena-nana](https://github.com/sena-nana) ([#1423](https://github.com/nonebot/nonebot2/pull/1423))
### 🍻 插件发布
- Plugin: 反向词典 [@yanyongyu](https://github.com/yanyongyu) ([#1619](https://github.com/nonebot/nonebot2/pull/1619))
- Plugin: PicMCStat [@yanyongyu](https://github.com/yanyongyu) ([#1614](https://github.com/nonebot/nonebot2/pull/1614))
- Plugin: 犯人在跳舞 [@yanyongyu](https://github.com/yanyongyu) ([#1608](https://github.com/nonebot/nonebot2/pull/1608))
- Plugin: 喵喵自记菜谱 [@yanyongyu](https://github.com/yanyongyu) ([#1599](https://github.com/nonebot/nonebot2/pull/1599))
- Plugin: 语音功能 [@yanyongyu](https://github.com/yanyongyu) ([#1597](https://github.com/nonebot/nonebot2/pull/1597))
- Plugin: OrangeDice! [@yanyongyu](https://github.com/yanyongyu) ([#1595](https://github.com/nonebot/nonebot2/pull/1595))
- Plugin: 简易谷歌翻译插件 [@yanyongyu](https://github.com/yanyongyu) ([#1593](https://github.com/nonebot/nonebot2/pull/1593))
- Plugin: 哔哩哔哩 q 群登录 [@yanyongyu](https://github.com/yanyongyu) ([#1591](https://github.com/nonebot/nonebot2/pull/1591))
- Plugin: 原神实时公告 [@yanyongyu](https://github.com/yanyongyu) ([#1585](https://github.com/nonebot/nonebot2/pull/1585))
- Plugin: 心灵鸡汤 [@yanyongyu](https://github.com/yanyongyu) ([#1580](https://github.com/nonebot/nonebot2/pull/1580))
- Plugin: Bing 每日图片获取 [@yanyongyu](https://github.com/yanyongyu) ([#1577](https://github.com/nonebot/nonebot2/pull/1577))
- Plugin: 星座运势 [@yanyongyu](https://github.com/yanyongyu) ([#1572](https://github.com/nonebot/nonebot2/pull/1572))
- Plugin: 回声洞 [@yanyongyu](https://github.com/yanyongyu) ([#1573](https://github.com/nonebot/nonebot2/pull/1573))
- Plugin: 整点报时 [@yanyongyu](https://github.com/yanyongyu) ([#1569](https://github.com/nonebot/nonebot2/pull/1569))
- Plugin: Hypixel 数据查询 [@yanyongyu](https://github.com/yanyongyu) ([#1556](https://github.com/nonebot/nonebot2/pull/1556))
- Plugin: 查找图片出处 [@yanyongyu](https://github.com/yanyongyu) ([#1553](https://github.com/nonebot/nonebot2/pull/1553))
- Plugin: 云签到 [@yanyongyu](https://github.com/yanyongyu) ([#1551](https://github.com/nonebot/nonebot2/pull/1551))
- Plugin: 图像标注 [@yanyongyu](https://github.com/yanyongyu) ([#1550](https://github.com/nonebot/nonebot2/pull/1550))
- Plugin: 对对联 [@yanyongyu](https://github.com/yanyongyu) ([#1542](https://github.com/nonebot/nonebot2/pull/1542))
- Plugin: 群聊学习 [@yanyongyu](https://github.com/yanyongyu) ([#1540](https://github.com/nonebot/nonebot2/pull/1540))
- Plugin: 求生之路 2——服务器操作 [@yanyongyu](https://github.com/yanyongyu) ([#1538](https://github.com/nonebot/nonebot2/pull/1538))
- Plugin: setu_customization [@yanyongyu](https://github.com/yanyongyu) ([#1537](https://github.com/nonebot/nonebot2/pull/1537))
- Plugin: 主动消息撤回 [@yanyongyu](https://github.com/yanyongyu) ([#1536](https://github.com/nonebot/nonebot2/pull/1536))
- Plugin: HttpCat🐱 猫猫 http 状态码 [@yanyongyu](https://github.com/yanyongyu) ([#1529](https://github.com/nonebot/nonebot2/pull/1529))
- Plugin: 命令探查 [@yanyongyu](https://github.com/yanyongyu) ([#1524](https://github.com/nonebot/nonebot2/pull/1524))
- Plugin: AnimalVoice_Convert [@yanyongyu](https://github.com/yanyongyu) ([#1518](https://github.com/nonebot/nonebot2/pull/1518))
- Plugin: 服务状态查询 [@yanyongyu](https://github.com/yanyongyu) ([#1513](https://github.com/nonebot/nonebot2/pull/1513))
- Plugin: 腾讯云图像变换 [@yanyongyu](https://github.com/yanyongyu) ([#1515](https://github.com/nonebot/nonebot2/pull/1515))
- Plugin: Ping [@yanyongyu](https://github.com/yanyongyu) ([#1508](https://github.com/nonebot/nonebot2/pull/1508))
- Plugin: 群友召唤术 [@yanyongyu](https://github.com/yanyongyu) ([#1503](https://github.com/nonebot/nonebot2/pull/1503))
- Plugin: 战地群聊天插件 [@yanyongyu](https://github.com/yanyongyu) ([#1506](https://github.com/nonebot/nonebot2/pull/1506))
- Plugin: 不要复读 [@yanyongyu](https://github.com/yanyongyu) ([#1500](https://github.com/nonebot/nonebot2/pull/1500))
- Plugin: JAVA MC 服务器信息查询 [@yanyongyu](https://github.com/yanyongyu) ([#1497](https://github.com/nonebot/nonebot2/pull/1497))
- Plugin: 防撤回 [@yanyongyu](https://github.com/yanyongyu) ([#1489](https://github.com/nonebot/nonebot2/pull/1489))
- Plugin: 随机禁言 [@yanyongyu](https://github.com/yanyongyu) ([#1486](https://github.com/nonebot/nonebot2/pull/1486))
- Plugin: 只因进化录 [@yanyongyu](https://github.com/yanyongyu) ([#1484](https://github.com/nonebot/nonebot2/pull/1484))
- Plugin: GPT3 [@yanyongyu](https://github.com/yanyongyu) ([#1480](https://github.com/nonebot/nonebot2/pull/1480))
- Plugin: 熊老板 [@yanyongyu](https://github.com/yanyongyu) ([#1472](https://github.com/nonebot/nonebot2/pull/1472))
- Plugin: QQ 群文件备份 [@yanyongyu](https://github.com/yanyongyu) ([#1478](https://github.com/nonebot/nonebot2/pull/1478))
- Plugin: 戒色打卡日记 [@yanyongyu](https://github.com/yanyongyu) ([#1475](https://github.com/nonebot/nonebot2/pull/1475))
- Plugin: nonebot_plugin_idiom [@yanyongyu](https://github.com/yanyongyu) ([#1469](https://github.com/nonebot/nonebot2/pull/1469))
- Plugin: 随机配色方案 [@yanyongyu](https://github.com/yanyongyu) ([#1466](https://github.com/nonebot/nonebot2/pull/1466))
- Plugin: multi-ChatGPT [@yanyongyu](https://github.com/yanyongyu) ([#1462](https://github.com/nonebot/nonebot2/pull/1462))
- Plugin: 权限控制 [@yanyongyu](https://github.com/yanyongyu) ([#1464](https://github.com/nonebot/nonebot2/pull/1464))
- Plugin: 汇率换算 [@yanyongyu](https://github.com/yanyongyu) ([#1452](https://github.com/nonebot/nonebot2/pull/1452))
- Plugin: 全群广播 [@yanyongyu](https://github.com/yanyongyu) ([#1450](https://github.com/nonebot/nonebot2/pull/1450))
- Plugin: 图片背景消除 [@yanyongyu](https://github.com/yanyongyu) ([#1446](https://github.com/nonebot/nonebot2/pull/1446))
- Plugin: 雀魂信息查询 [@yanyongyu](https://github.com/yanyongyu) ([#1443](https://github.com/nonebot/nonebot2/pull/1443))
- Plugin: ChatGPT [@yanyongyu](https://github.com/yanyongyu) ([#1439](https://github.com/nonebot/nonebot2/pull/1439))
- Plugin: 免费快捷点歌插件 [@yanyongyu](https://github.com/yanyongyu) ([#1436](https://github.com/nonebot/nonebot2/pull/1436))
- Plugin: 动画截图追溯来源 [@yanyongyu](https://github.com/yanyongyu) ([#1434](https://github.com/nonebot/nonebot2/pull/1434))
- Plugin: b 站图片下载 [@yanyongyu](https://github.com/yanyongyu) ([#1430](https://github.com/nonebot/nonebot2/pull/1430))
- Plugin: 记事本 [@yanyongyu](https://github.com/yanyongyu) ([#1420](https://github.com/nonebot/nonebot2/pull/1420))
- Plugin: 原神前瞻直播兑换码查询 [@yanyongyu](https://github.com/yanyongyu) ([#1422](https://github.com/nonebot/nonebot2/pull/1422))
### 🍻 机器人发布
- Bot: SuzunoBot [@yanyongyu](https://github.com/yanyongyu) ([#1601](https://github.com/nonebot/nonebot2/pull/1601))
- Bot: 辞辞(cici)Bot [@yanyongyu](https://github.com/yanyongyu) ([#1583](https://github.com/nonebot/nonebot2/pull/1583))
- Bot: RanBot [@yanyongyu](https://github.com/yanyongyu) ([#1511](https://github.com/nonebot/nonebot2/pull/1511))
### 🍻 适配器发布
- Adapter: BilibiliLive [@yanyongyu](https://github.com/yanyongyu) ([#1617](https://github.com/nonebot/nonebot2/pull/1617))
- Adapter: Spigot [@yanyongyu](https://github.com/yanyongyu) ([#1612](https://github.com/nonebot/nonebot2/pull/1612))
## v2.0.0rc2 ## v2.0.0rc2
### 💥 破坏性变更 ### 💥 破坏性变更

View File

@@ -113,5 +113,30 @@
} }
], ],
"is_official": false "is_official": false
},
{
"module_name": "nonebot.adapters.spigot",
"project_link": "nonebot-adapter-spigot",
"name": "Spigot",
"desc": "MineCraft通信适配",
"author": "17TheWord",
"homepage": "https://github.com/17TheWord/nonebot-adapter-spigot",
"tags": [
{
"label": "Minecraft",
"color": "#4ef0ea"
}
],
"is_official": false
},
{
"module_name": "nonebot.adapter.bilibili",
"project_link": "nonebot-adapter-bilibili",
"name": "BilibiliLive",
"desc": "b站直播间ws协议",
"author": "wwweww",
"homepage": "https://github.com/wwweww/adapter-bilibili",
"tags": [],
"is_official": false
} }
] ]

View File

@@ -310,5 +310,55 @@
} }
], ],
"is_official": false "is_official": false
},
{
"name": "RanBot",
"desc": "不@会很安静的Bot",
"author": "IAXRetailer",
"homepage": "https://github.com/Hecatia-Hell-Workshop/RanBot",
"tags": [],
"is_official": false
},
{
"name": "辞辞(cici)Bot",
"desc": "一个集成娱乐和群管为一体的机器人",
"author": "mengxinyuan638",
"homepage": "https://github.com/mengxinyuan638/cici-bot",
"tags": [
{
"label": "辞辞Bot",
"color": "#04de4d"
},
{
"label": "萌新源",
"color": "#fd1c06"
},
{
"label": "群管",
"color": "#06b8fd"
}
],
"is_official": false
},
{
"name": "SuzunoBot",
"desc": "多功能音游bot主要服务maimaiDX、Arcaea",
"author": "Rinfair-CSP-A016",
"homepage": "https://github.com/Rinfair-CSP-A016/SuzunoBot-AGLAS",
"tags": [
{
"label": "t:maimaiDX",
"color": "#189ede"
},
{
"label": "t:Arcaea",
"color": "#d551ef"
},
{
"label": "t:coc",
"color": "#7fe4d0"
}
],
"is_official": false
} }
] ]

View File

@@ -1,7 +1,17 @@
[ [
{ {
"module_name": "nonebot.drivers.fastapi", "module_name": "~none",
"project_link": "", "project_link": "",
"name": "None",
"desc": "None 驱动器",
"author": "yanyongyu",
"homepage": "/docs/tutorial/choose-driver",
"tags": [],
"is_official": true
},
{
"module_name": "~fastapi",
"project_link": "nonebot2[fastapi]",
"name": "FastAPI", "name": "FastAPI",
"desc": "FastAPI 驱动器", "desc": "FastAPI 驱动器",
"author": "yanyongyu", "author": "yanyongyu",
@@ -10,8 +20,8 @@
"is_official": true "is_official": true
}, },
{ {
"module_name": "nonebot.drivers.quart", "module_name": "~quart",
"project_link": "quart", "project_link": "nonebot2[quart]",
"name": "Quart", "name": "Quart",
"desc": "Quart 驱动器", "desc": "Quart 驱动器",
"author": "yanyongyu", "author": "yanyongyu",
@@ -20,8 +30,8 @@
"is_official": true "is_official": true
}, },
{ {
"module_name": "nonebot.drivers.httpx", "module_name": "~httpx",
"project_link": "httpx", "project_link": "nonebot2[httpx]",
"name": "HTTPX", "name": "HTTPX",
"desc": "HTTPX 驱动器", "desc": "HTTPX 驱动器",
"author": "yanyongyu", "author": "yanyongyu",
@@ -30,8 +40,8 @@
"is_official": true "is_official": true
}, },
{ {
"module_name": "nonebot.drivers.websockets", "module_name": "~websockets",
"project_link": "websockets", "project_link": "nonebot2[websockets]",
"name": "websockets", "name": "websockets",
"desc": "websockets 驱动器", "desc": "websockets 驱动器",
"author": "yanyongyu", "author": "yanyongyu",
@@ -40,8 +50,8 @@
"is_official": true "is_official": true
}, },
{ {
"module_name": "nonebot.drivers.aiohttp", "module_name": "~aiohttp",
"project_link": "aiohttp", "project_link": "nonebot2[aiohttp]",
"name": "AIOHTTP", "name": "AIOHTTP",
"desc": "AIOHTTP 驱动器", "desc": "AIOHTTP 驱动器",
"author": "yanyongyu", "author": "yanyongyu",

File diff suppressed because it is too large Load Diff

View File

@@ -1,29 +0,0 @@
---
sidebar_position: 8
description: 调用机器人平台 API完成更多的功能
options:
menu:
weight: 29
category: guide
---
# 调用平台 API
在使用机器人功能时,除了发送消息以外,还可能需要调用机器人平台的 API 来完成更多的功能。
NoneBot 提供了两种方式来调用机器人平台 API两种方式都需要首先获得 Bot 实例,然后调用相应的方法。
例如,如果需要调用机器人平台的 `get_user_info` API可以这样做
```python
from nonebot import get_bot
bot = get_bot("bot_id")
result = await bot.get_user_info(user_id=12345678)
await bot.call_api("get_user_info", user_id=12345678)
```
:::tip 提示
API 由平台提供,请参考平台文档。
:::

View File

@@ -20,7 +20,11 @@ options:
您可以选择自己喜欢的方式将插件发布到 [**PyPI**](https://pypi.org/),如使用 [**setuptools**](https://pypi.org/project/setuptools/) 或 [**Poetry**](https://pypi.org/project/poetry/)。 您可以选择自己喜欢的方式将插件发布到 [**PyPI**](https://pypi.org/),如使用 [**setuptools**](https://pypi.org/project/setuptools/) 或 [**Poetry**](https://pypi.org/project/poetry/)。
发布时,请您为自己的插件取一个清晰易懂的名字。通常而言,一款 NoneBot2 插件名称使用 `nonebot-plugin-` 作为前缀(如`nonebot-plugin-foo`),以 `nonebot_plugin_` 作为包名的前缀(如`nonebot_plugin_foo`),这并非强制规范,而是为了防止与其他 PyPI 包产生冲突,所以我们推荐您在没有特殊需求的情况下这样做。 发布时,请您为自己的插件取一个清晰易懂的名字。通常而言,一款 NoneBot2 插件名称使用 `nonebot-plugin-` 作为 PyPI 项目名前缀(如`nonebot-plugin-foo`),以 `nonebot_plugin_` 作为 Python 包名的前缀(如`nonebot_plugin_foo`),这并非强制规范,而是为了防止与其他 PyPI 包产生冲突,所以我们推荐您在没有特殊需求的情况下这样做。
:::warning
虽然在 NoneBot 2 载入插件时,插件的 Python 包名中可以使用 `-`,但是在 Python 的 import 语句中,`-` 不会被解析为包名的一部分。如果插件需要向外界提供 import 语法导入的支持,应在 Python 包名中使用 `_` 代替 `-`
:::
发布后,请确保您的插件已能公开的从 PyPI 访问到,试着检查您的插件在 PyPI 的地址,如 `https://pypi.org/project/<您的 NoneBot2 插件项目名>` 发布后,请确保您的插件已能公开的从 PyPI 访问到,试着检查您的插件在 PyPI 的地址,如 `https://pypi.org/project/<您的 NoneBot2 插件项目名>`
@@ -32,7 +36,7 @@ options:
### 申请发布到 NoneBot2 插件商店 ### 申请发布到 NoneBot2 插件商店
完成在 PyPI 的插件发布流程与源代码托管流程后,请您前往 [**NoneBot2 商店**](https://v2.nonebot.dev/store.html)页面,切换到**插件**页签,点击**发布插件**按钮。 完成在 PyPI 的插件发布流程与源代码托管流程后,请您前往 [**NoneBot2 商店**](https://v2.nonebot.dev/store)页面,切换到**插件**页签,点击**发布插件**按钮。
![插件发布界面](./images/plugin_store_publish.png) ![插件发布界面](./images/plugin_store_publish.png)
@@ -61,12 +65,12 @@ import 包名:您的插件通过 Python 导入时使用的包名,如 nonebot
之后NoneBot2 的维护者们将会对插件进行进一步的检查,以确保用户能够正常安装并使用该插件。 之后NoneBot2 的维护者们将会对插件进行进一步的检查,以确保用户能够正常安装并使用该插件。
完成这些步骤后,您的插件将会被合并到 [**NoneBot2 商店**](https://v2.nonebot.dev/store.html),而您也将成为 [**NoneBot2 贡献者**](https://github.com/nonebot/nonebot2/graphs/contributors)中的一员。 完成这些步骤后,您的插件将会被合并到 [**NoneBot2 商店**](https://v2.nonebot.dev/store),而您也将成为 [**NoneBot2 贡献者**](https://github.com/nonebot/nonebot2/graphs/contributors)中的一员。
## 完成 ## 完成
恭喜您,经过上述的发布流程,您的插件已经成功发布到 NoneBot2 商店了。 恭喜您,经过上述的发布流程,您的插件已经成功发布到 NoneBot2 商店了。
此时,您可以在 [**NoneBot2 商店**](https://v2.nonebot.dev/store.html)的插件页签查找到您的插件。同时,欢迎您成为 [**NoneBot2 贡献者**](https://github.com/nonebot/nonebot2/graphs/contributors) 此时,您可以在 [**NoneBot2 商店**](https://v2.nonebot.dev/store)的插件页签查找到您的插件。同时,欢迎您成为 [**NoneBot2 贡献者**](https://github.com/nonebot/nonebot2/graphs/contributors)
**Congratulations!** **Congratulations!**

View File

@@ -49,8 +49,8 @@ async def init_adapter(app: App, import_hook):
1. 反向 HTTPWebHook 1. 反向 HTTPWebHook
2. 反向 WebSocket 2. 反向 WebSocket
3. ~~正向 HTTP(尚未实现)~~ 3. 正向 HTTP
4. ~~正向 WebSocket(尚未实现)~~ 4. 正向 WebSocket
NoneBug 的 `test_server` 方法可以供我们测试反向连接方式。 NoneBug 的 `test_server` 方法可以供我们测试反向连接方式。

View File

@@ -546,9 +546,9 @@ description: nonebot.adapters 模块
- **参数** - **参数**
- `template`: 模板 - `template` (str | (~ TM)): 模板
- `factory`: 消息类型工厂,默认为 `str` - `factory` (Type[str] | Type[(~ TM)]): 消息类型工厂,默认为 `str`
### _method_ `add_format_spec(self, spec, name=None)` {#MessageTemplate-add_format_spec} ### _method_ `add_format_spec(self, spec, name=None)` {#MessageTemplate-add_format_spec}

View File

@@ -85,6 +85,12 @@ description: nonebot.consts 模块
- **说明:** 正则匹配结果存储 key - **说明:** 正则匹配结果存储 key
## _var_ `REGEX_STR` {#REGEX_STR}
- **类型:** Literal['_matched_str']
- **说明:** 正则匹配文本存储 key
## _var_ `REGEX_GROUP` {#REGEX_GROUP} ## _var_ `REGEX_GROUP` {#REGEX_GROUP}
- **类型:** Literal['_matched_groups'] - **类型:** Literal['_matched_groups']

View File

@@ -7,11 +7,17 @@ description: nonebot.drivers.fastapi 模块
[FastAPI](https://fastapi.tiangolo.com/) 驱动适配 [FastAPI](https://fastapi.tiangolo.com/) 驱动适配
```bash
nb driver install fastapi
# 或者
pip install nonebot2[fastapi]
```
:::tip 提示 :::tip 提示
本驱动仅支持服务端连接 本驱动仅支持服务端连接
::: :::
## _class_ `Config(_env_file='<object object>', _env_file_encoding=None, _env_nested_delimiter=None, _secrets_dir=None, *, fastapi_openapi_url=None, fastapi_docs_url=None, fastapi_redoc_url=None, fastapi_include_adapter_schema=True, fastapi_reload=False, fastapi_reload_dirs=None, fastapi_reload_delay=0.25, fastapi_reload_includes=None, fastapi_reload_excludes=None)` {#Config} ## _class_ `Config(_env_file='<object object>', _env_file_encoding=None, _env_nested_delimiter=None, _secrets_dir=None, *, fastapi_openapi_url=None, fastapi_docs_url=None, fastapi_redoc_url=None, fastapi_include_adapter_schema=True, fastapi_reload=False, fastapi_reload_dirs=None, fastapi_reload_delay=0.25, fastapi_reload_includes=None, fastapi_reload_excludes=None, fastapi_extra={})` {#Config}
- **说明** - **说明**
@@ -45,6 +51,8 @@ description: nonebot.drivers.fastapi 模块
- `fastapi_reload_excludes` (list[str] | None) - `fastapi_reload_excludes` (list[str] | None)
- `fastapi_extra` (dict[str, Any])
### _class-var_ `fastapi_openapi_url` {#Config-fastapi_openapi_url} ### _class-var_ `fastapi_openapi_url` {#Config-fastapi_openapi_url}
- **类型:** str | None - **类型:** str | None
@@ -99,6 +107,12 @@ description: nonebot.drivers.fastapi 模块
- **说明:** 不要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值 - **说明:** 不要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值
### _class-var_ `fastapi_extra` {#Config-fastapi_extra}
- **类型:** dict[str, Any]
- **说明:** 传递给 `FastAPI` 的其他参数。
## _class_ `Driver(env, config)` {#Driver} ## _class_ `Driver(env, config)` {#Driver}
- **说明** - **说明**

View File

@@ -141,6 +141,16 @@ description: nonebot.drivers 模块
- `cookies` (NoneType | Cookies | http.cookiejar.CookieJar | dict[str, str] | list[tuple[str, str]]) - `cookies` (NoneType | Cookies | http.cookiejar.CookieJar | dict[str, str] | list[tuple[str, str]])
### _method_ `as_header(self, request)` {#Cookies-as_header}
- **参数**
- `request` (nonebot.internal.driver.model.Request)
- **返回**
- dict[str, str]
### _method_ `clear(self, domain=None, path=None)` {#Cookies-clear} ### _method_ `clear(self, domain=None, path=None)` {#Cookies-clear}
- **参数** - **参数**

View File

@@ -0,0 +1,80 @@
---
sidebar_position: 6
description: nonebot.drivers.none 模块
---
# nonebot.drivers.none
None 驱动适配
:::tip 提示
本驱动不支持任何服务器或客户端连接
:::
## _class_ `Driver(env, config)` {#Driver}
- **说明**
None 驱动框架
- **参数**
- `env` ([Env](../config.md#Env))
- `config` ([Config](../config.md#Config))
### _property_ `logger` {#Driver-logger}
- **类型:**
- **说明:** none driver 使用的 logger
### _property_ `type` {#Driver-type}
- **类型:** str
- **说明:** 驱动名称: `none`
### _method_ `on_shutdown(self, func)` {#Driver-on_shutdown}
- **说明**
注册一个停止时执行的函数
- **参数**
- `func` (() -> NoneType | () -> Awaitable[NoneType])
- **返回**
- () -> NoneType | () -> Awaitable[NoneType]
### _method_ `on_startup(self, func)` {#Driver-on_startup}
- **说明**
注册一个启动时执行的函数
- **参数**
- `func` (() -> NoneType | () -> Awaitable[NoneType])
- **返回**
- () -> NoneType | () -> Awaitable[NoneType]
### _method_ `run(self, *args, **kwargs)` {#Driver-run}
- **说明**
启动 none driver
- **参数**
- `*args`
- `**kwargs`
- **返回**
- Unknown

View File

@@ -17,7 +17,7 @@ pip install nonebot2[quart]
本驱动仅支持服务端连接 本驱动仅支持服务端连接
::: :::
## _class_ `Config(_env_file='<object object>', _env_file_encoding=None, _env_nested_delimiter=None, _secrets_dir=None, *, quart_reload=False, quart_reload_dirs=None, quart_reload_delay=0.25, quart_reload_includes=None, quart_reload_excludes=None)` {#Config} ## _class_ `Config(_env_file='<object object>', _env_file_encoding=None, _env_nested_delimiter=None, _secrets_dir=None, *, quart_reload=False, quart_reload_dirs=None, quart_reload_delay=0.25, quart_reload_includes=None, quart_reload_excludes=None, quart_extra={})` {#Config}
- **说明** - **说明**
@@ -43,6 +43,8 @@ pip install nonebot2[quart]
- `quart_reload_excludes` (list[str] | None) - `quart_reload_excludes` (list[str] | None)
- `quart_extra` (dict[str, Any])
### _class-var_ `quart_reload` {#Config-quart_reload} ### _class-var_ `quart_reload` {#Config-quart_reload}
- **类型:** bool - **类型:** bool
@@ -73,6 +75,12 @@ pip install nonebot2[quart]
- **说明:** 不要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值 - **说明:** 不要监听的文件列表,支持 glob pattern默认为 uvicorn 默认值
### _class-var_ `quart_extra` {#Config-quart_extra}
- **类型:** dict[str, Any]
- **说明:** 传递给 `Quart` 的其他参数。
## _class_ `Driver(env, config)` {#Driver} ## _class_ `Driver(env, config)` {#Driver}
- **说明** - **说明**

View File

@@ -67,6 +67,16 @@ description: nonebot.matcher 模块
- bool: 是否满足匹配规则 - bool: 是否满足匹配规则
### _classmethod_ `destroy(cls)` {#Matcher-destroy}
- **说明**
销毁当前的事件响应器
- **返回**
- None
### _method_ `ensure_context(self, bot, event)` {#Matcher-ensure_context} ### _method_ `ensure_context(self, bot, event)` {#Matcher-ensure_context}
- **参数** - **参数**

View File

@@ -287,6 +287,16 @@ description: nonebot.params 模块
- str - str
## _def_ `RegexStr()` {#RegexStr}
- **说明**
正则匹配结果文本
- **返回**
- str
## _def_ `RegexGroup()` {#RegexGroup} ## _def_ `RegexGroup()` {#RegexGroup}
- **说明** - **说明**

View File

@@ -83,7 +83,7 @@ description: nonebot.plugin.manager 模块
- `fullname` (str) - `fullname` (str)
- `path` (Sequence[bytes | str] | None) - `path` (Sequence[str] | None)
- `target` (module | None) - `target` (module | None)

Some files were not shown because too many files have changed in this diff Show More