Compare commits

...

110 Commits

Author SHA1 Message Date
github-actions[bot]
d83866f03b 🔖 Release 2.0.0rc2 2022-11-24 03:55:37 +00:00
Ju4tCode
cb83e76e16 📝 remove old doc version (#1417) 2022-11-24 11:50:20 +08:00
Ju4tCode
1644615462 🔖 bump version 2.0.0rc2 2022-11-24 03:35:31 +00:00
github-actions[bot]
89d8abf863 📝 Update changelog 2022-11-24 02:59:33 +00:00
p0ise
f8cf7c94ae 🍻 publish plugin 谁在窥屏 (#1415) 2022-11-24 10:58:29 +08:00
github-actions[bot]
bef494615f 📝 Update changelog 2022-11-24 02:58:06 +00:00
那个小白白白
6e110e725e 📝 Docs: 添加 ntchat 社区适配器 (#1414)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-24 10:56:53 +08:00
Ju4tCode
85390a14b6 ⬆️ upgrade dependencies (#1413) 2022-11-21 19:59:39 +08:00
github-actions[bot]
276041e314 📝 Update changelog 2022-11-21 10:46:01 +00:00
Ju4tCode
2922da7b2f Feature: 支持自定义 matchers 存储管理 (#1395) 2022-11-21 18:44:55 +08:00
github-actions[bot]
c783ab5e9b 📝 Update changelog 2022-11-20 09:42:50 +00:00
ZYKsslm
139190bff7 🍻 publish plugin 免费版NovelAI生图插件 (#1407) 2022-11-20 17:41:05 +08:00
github-actions[bot]
1524434444 📝 Update changelog 2022-11-19 16:05:11 +00:00
Ikaros
b6857d59b8 ✏️ 更新 nonebot_plugin_searchBiliInfo 插件标题和描述 (#1410) 2022-11-20 00:03:54 +08:00
github-actions[bot]
a7b0eb10a0 📝 Update changelog 2022-11-19 08:15:27 +00:00
synodriver
0eadb44e20 🐛 Fix: Bot __getattr__ 不再对 __xxx__ 方法返回 (#1398) 2022-11-19 16:14:03 +08:00
github-actions[bot]
6b43209d37 📝 Update changelog 2022-11-15 02:51:59 +00:00
Ju4tCode
a50990bef2 🐛 fix run pre/post hook not in context (#1391) 2022-11-15 10:50:52 +08:00
github-actions[bot]
f1525c1ecd 📝 Update changelog 2022-11-14 17:11:56 +00:00
Kaguya233qwq
7df9756205 🍻 publish plugin sky光遇 (#1393) 2022-11-15 01:10:50 +08:00
github-actions[bot]
376a720881 📝 Update changelog 2022-11-14 11:06:42 +00:00
Ju4tCode
c7377647fa Feature: 升级 devcontainer 配置 (#1392)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-14 19:05:34 +08:00
github-actions[bot]
cfbd6f1e4d 📝 Update changelog 2022-11-13 10:02:16 +00:00
EtherLeaF
cecc853f25 🍻 publish plugin Colab-NovelAI (#1389) 2022-11-13 18:01:08 +08:00
github-actions[bot]
fe5f85517e 📝 Update changelog 2022-11-13 09:38:21 +00:00
Ikaros-521
66040a7e44 🍻 publish plugin b站用户直播号、粉丝、舰团数查询 (#1384) 2022-11-13 17:37:22 +08:00
github-actions[bot]
81d2f017f6 📝 Update changelog 2022-11-12 10:23:32 +00:00
Akirami
4355025f87 Feature: 使用 importlib.metadata 替换 pkg_resources (#1388)
Co-authored-by: yanyongyu <42488585+yanyongyu@users.noreply.github.com>
2022-11-12 18:22:16 +08:00
github-actions[bot]
0bc8a39578 📝 Update changelog 2022-11-10 17:23:35 +00:00
Aziteee
7308f57776 🍻 publish plugin 投胎模拟器 (#1381) 2022-11-11 01:22:12 +08:00
github-actions[bot]
7de8912edb 📝 Update changelog 2022-11-09 15:55:14 +00:00
H-xiaoH
42a4edc3ee 🍻 publish plugin Apex API Query (#1374) 2022-11-09 23:54:00 +08:00
github-actions[bot]
4a12429a38 📝 Update changelog 2022-11-09 14:38:12 +00:00
Qianyiovo
092f6d05f5 🍻 publish bot Bread Dog Bot (#1379) 2022-11-09 22:37:07 +08:00
github-actions[bot]
2c0c05dca1 📝 Update changelog 2022-11-09 14:34:19 +00:00
Sena
31bafc832f 🍻 Plugin: Sena-nana项目拆分,地址更改 (#1378) 2022-11-09 22:33:08 +08:00
github-actions[bot]
e1720d8ea0 📝 Update changelog 2022-11-06 16:04:17 +00:00
jcjrobert
08be5724b9 🍻 publish plugin 随个人 (#1372) 2022-11-07 00:03:00 +08:00
github-actions[bot]
828714a4e3 📝 Update changelog 2022-11-06 06:58:29 +00:00
Melodyknit
a79eeb73a6 🍻 publish plugin 动漫资源获取 (#1370) 2022-11-06 14:57:18 +08:00
github-actions[bot]
c1aec637d5 📝 Update changelog 2022-11-04 07:19:58 +00:00
ssttkkl
12cc08efbd 🍻 publish plugin 日麻小工具 (#1364) 2022-11-04 15:18:35 +08:00
github-actions[bot]
f410af72dc 📝 Update changelog 2022-11-04 01:30:33 +00:00
StarHeart
113021cdf4 👷 CI: 测试环境添加 Python 3.11 (#1366)
Co-authored-by: yanyongyu <42488585+yanyongyu@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-04 09:29:13 +08:00
github-actions[bot]
fcc23f98f8 📝 Update changelog 2022-11-03 11:45:38 +00:00
gzy02
0b693c419e 🍻 publish bot hsbot (#1368) 2022-11-03 19:44:34 +08:00
github-actions[bot]
36e5b81510 📝 Update changelog 2022-11-02 17:05:59 +00:00
A-kirami
71f17bebaa 🍻 publish plugin 图像超分辨率增强 (#1361) 2022-11-03 01:04:38 +08:00
github-actions[bot]
2f45f25d13 📝 Update changelog 2022-11-02 16:57:54 +00:00
A-kirami
17d52446c3 🍻 publish plugin 二次元化图像 (#1359) 2022-11-03 00:56:36 +08:00
pre-commit-ci[bot]
2304aaf22b ⬆️ auto update by pre-commit hooks (#1358)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-01 14:12:53 +08:00
github-actions[bot]
a70c37de69 📝 Update changelog 2022-10-30 17:26:28 +00:00
ssttkkl
1cabc18277 🍻 publish plugin 日麻寄分器 (#1356) 2022-10-31 01:25:22 +08:00
github-actions[bot]
ed1235ed11 📝 Update changelog 2022-10-30 17:02:55 +00:00
MeetWq
9952b4e838 🍻 publish plugin 文本生成器 (#1354) 2022-10-31 01:01:33 +08:00
github-actions[bot]
e81390a104 📝 Update changelog 2022-10-30 16:16:02 +00:00
tkgs0
7bc22289b4 🍻 publish plugin 反嘴臭插件 (#1349) 2022-10-31 00:14:51 +08:00
github-actions[bot]
bfa4a079bf 📝 Update changelog 2022-10-28 07:06:09 +00:00
tkgs0
403850262b 🍻 publish plugin 用户&群聊黑名单 (#1347) 2022-10-28 15:05:08 +08:00
github-actions[bot]
ed25e7aa39 📝 Update changelog 2022-10-27 03:00:53 +00:00
ssttkkl
7ab480f044 🍻 publish plugin NoneBot SQLAlchemy封装 (#1344) 2022-10-27 10:59:36 +08:00
github-actions[bot]
d7d6152094 📝 Update changelog 2022-10-27 02:57:35 +00:00
bridgeL
2954e58c77 Plugin: 更新 ayaka 插件的主页链接 (#1346)
Co-authored-by: Su <wxlxy316@163.com>
2022-10-27 10:56:23 +08:00
github-actions[bot]
f684b96433 📝 Update changelog 2022-10-24 02:25:32 +00:00
jcjrobert
4388d1c9e6 🍻 publish plugin 通用抽图/语音 (#1340) 2022-10-24 10:24:15 +08:00
github-actions[bot]
876acf3e88 📝 Update changelog 2022-10-20 13:19:39 +00:00
Kaguya233qwq
963e73f517 🍻 publish plugin kfcrazy (#1338) 2022-10-20 21:18:27 +08:00
github-actions[bot]
bdc9e44142 📝 Update changelog 2022-10-20 03:14:13 +00:00
A-kirami
4f2efb7304 🍻 publish plugin 二次元图像鉴赏 (#1336) 2022-10-20 11:12:51 +08:00
github-actions[bot]
6ae891124f 📝 Update changelog 2022-10-19 11:27:42 +00:00
bridgeL
145bd4d4e1 🍻 publish plugin ayaka衍生插件 - 坏词撤回 (#1334) 2022-10-19 19:26:39 +08:00
github-actions[bot]
ab54049909 📝 Update changelog 2022-10-18 14:07:59 +00:00
Sena
7aa554f5a2 ✏️ Plugin: 补充 novelai 插件信息 (#1333) 2022-10-18 22:06:47 +08:00
github-actions[bot]
5566777374 📝 Update changelog 2022-10-18 09:57:33 +00:00
bridgeL
b2594f61de 🍻 publish plugin ayaka衍生插件 - 时区助手 (#1331) 2022-10-18 17:56:25 +08:00
github-actions[bot]
1ad1e0606c 📝 Update changelog 2022-10-18 07:07:05 +00:00
bridgeL
583d5060db 🍻 publish plugin ayaka衍生插件 - 谁是卧底 (#1329) 2022-10-18 15:05:45 +08:00
github-actions[bot]
eaa3dbdfa8 📝 Update changelog 2022-10-17 03:00:47 +00:00
bridgeL
03f378690a 🍻 publish plugin ayaka衍生插件 - 小游戏合集 (#1327) 2022-10-17 10:59:43 +08:00
github-actions[bot]
512c66ccc0 📝 Update changelog 2022-10-15 07:07:21 +00:00
lgc2333
9d20c7510a 🍻 publish plugin bnhhsh -「不能好好说话!」 (#1325) 2022-10-15 15:06:04 +08:00
github-actions[bot]
29ad8a6686 📝 Update changelog 2022-10-14 01:59:51 +00:00
Ju4tCode
db534b8824 Feature: 新增 dotenv 嵌套配置项支持 (#1324)
Co-authored-by: hemengyang <hmy0119@hotmail.com>
2022-10-14 09:58:44 +08:00
github-actions[bot]
67b96528af 📝 Update changelog 2022-10-13 04:47:18 +00:00
A-kirami
a5929f80f7 🍻 publish plugin AI绘图 (#1322) 2022-10-13 12:45:56 +08:00
github-actions[bot]
9619477a27 📝 Update changelog 2022-10-12 05:42:41 +00:00
Akirami
8377680fd7 Feature: 添加 State 响应器触发消息注入 (#1315) 2022-10-12 13:41:28 +08:00
github-actions[bot]
3e3d6f91a5 📝 Update changelog 2022-10-12 03:05:31 +00:00
sena-nana
1d3d886004 🍻 publish plugin novelai (#1318) 2022-10-12 11:04:34 +08:00
github-actions[bot]
ebc5a3cc9e 📝 Update changelog 2022-10-12 02:53:57 +00:00
Kaguyaya
1092767a51 🍻 publish plugin 游戏王小程序查价 (#1316) 2022-10-12 10:52:56 +08:00
github-actions[bot]
ab227ee64b 📝 Update changelog 2022-10-11 11:53:01 +00:00
cjladmin
00b37fb3d2 🍻 publish plugin 监测群事件 (#900) 2022-10-11 19:51:56 +08:00
github-actions[bot]
e6494dc98e 📝 Update changelog 2022-10-10 14:06:29 +00:00
JustUndertaker
c80869f952 🍻 publish adapter Ntchat (#1313) 2022-10-10 22:05:27 +08:00
github-actions[bot]
2be72eac5e 📝 Update changelog 2022-10-10 12:36:47 +00:00
HornCopper
830c4f8c6a 🍻 Bot: 修改 Inkar Suki 描述 (#1312) 2022-10-10 20:35:45 +08:00
github-actions[bot]
138fb458b7 📝 Update changelog 2022-10-08 08:18:40 +00:00
KarisAya
2c93f82ef3 🍻 publish plugin 轮盘禁言小游戏 (#1310) 2022-10-08 16:17:42 +08:00
github-actions[bot]
77aa16c2fc 📝 Update changelog 2022-10-07 02:33:18 +00:00
Ankhyty
945da7151e 🍻 publish plugin 真白萌自动签到 (#1307) 2022-10-07 10:32:15 +08:00
github-actions[bot]
41ea0df0a5 📝 Update changelog 2022-10-06 03:51:25 +00:00
Ju4tCode
cec45cf89c ⚰️ remove dead namespace (#1306) 2022-10-06 11:50:18 +08:00
Ju4tCode
2de8c66c70 ⬆️ upgrade pydantic dependency (#1305) 2022-10-05 15:13:54 +08:00
github-actions[bot]
0bcc4277e5 📝 Update changelog 2022-10-05 02:54:10 +00:00
Shadow403
d3dd93b36c 🍻 publish plugin BiliRequestAll (#1301) 2022-10-05 10:53:00 +08:00
github-actions[bot]
e9bd81d9bb 📝 Update changelog 2022-10-03 11:45:36 +00:00
17TheWord
997d4f5042 ✏️ 修改插件 MCQQ 主页地址 (#1303) 2022-10-03 19:44:21 +08:00
github-actions[bot]
3bb321c519 📝 Update changelog 2022-10-03 11:42:16 +00:00
AbCooly
fe92d29322 🍻 publish plugin 监听者 (#1298) 2022-10-03 19:41:11 +08:00
113 changed files with 2430 additions and 578 deletions

View File

@@ -1,15 +0,0 @@
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.238.1/containers/codespaces-linux/.devcontainer/base.Dockerfile
FROM mcr.microsoft.com/vscode/devcontainers/universal:2-focal
# ** [Optional] Uncomment this section to install additional packages. **
# USER root
#
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>
USER codespace
# [Required] Poetry
RUN curl -sSL https://install.python-poetry.org | python - -y
RUN poetry config virtualenvs.in-project true

View File

@@ -1,32 +1,13 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.238.1/containers/codespaces-linux
{
"name": "GitHub Codespaces (Default)",
"build": {
"dockerfile": "Dockerfile"
"name": "Default Linux Universal",
"image": "mcr.microsoft.com/devcontainers/universal:2-linux",
"features": {
"ghcr.io/devcontainers-contrib/features/poetry:1": {}
},
// Configure tool-specific properties.
"postCreateCommand": "poetry config virtualenvs.in-project true && poetry install -E all && poetry run pre-commit install && yarn install",
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
// Set *default* container specific settings.json values on container create.
"settings": {
"go.toolsManagement.checkForUpdates": "local",
"go.useLanguageServer": true,
"go.gopath": "/go",
"python.defaultInterpreterPath": "/opt/python/latest/bin/python",
"python.linting.enabled": true,
"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint",
"python.analysis.diagnosticMode": "workspace",
"python.analysis.typeCheckingMode": "basic",
"[python]": {
@@ -50,7 +31,6 @@
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"lldb.executable": "/usr/bin/lldb",
"files.exclude": {
"**/__pycache__": true
},
@@ -59,10 +39,7 @@
"**/__pycache__": true
}
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"GitHub.vscode-pull-request-github",
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.isort",
@@ -72,27 +49,5 @@
"bradlc.vscode-tailwindcss"
]
}
},
"remoteUser": "codespace",
"overrideCommand": false,
"mounts": [
"source=codespaces-linux-var-lib-docker,target=/var/lib/docker,type=volume"
],
"runArgs": [
"--cap-add=SYS_PTRACE",
"--security-opt",
"seccomp=unconfined",
"--privileged",
"--init"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// "oryx build" will automatically install your dependencies and attempt to build your project
"postCreateCommand": "poetry install && poetry run pre-commit install && yarn install"
}
}

View File

@@ -9,10 +9,10 @@ runs:
node-version: "16"
- id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
shell: bash
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}

View File

@@ -10,22 +10,15 @@ inputs:
runs:
using: "composite"
steps:
- id: python
uses: actions/setup-python@v2
- name: Install poetry
run: pipx install poetry
shell: bash
- uses: actions/setup-python@v4
with:
python-version: ${{ inputs.python-version }}
architecture: "x64"
- uses: Gr1N/setup-poetry@v7
- id: poetry-cache
run: echo "::set-output name=dir::$(poetry config virtualenvs.path)"
shell: bash
- uses: actions/cache@v2
with:
path: ${{ steps.poetry-cache.outputs.dir }}
key: ${{ runner.os }}-poetry-${{ steps.python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}
cache: "poetry"
- run: poetry install -E all
shell: bash

View File

@@ -15,7 +15,7 @@ jobs:
cancel-in-progress: true
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10"]
python-version: ["3.8", "3.9", "3.10", "3.11"]
os: [ubuntu-latest, windows-latest, macos-latest]
fail-fast: false
env:

View File

@@ -13,16 +13,16 @@ repos:
stages: [commit]
- repo: https://github.com/psf/black
rev: 22.8.0
rev: 22.10.0
hooks:
- id: black
stages: [commit]
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.0.0-alpha.0
rev: v3.0.0-alpha.4
hooks:
- id: prettier
types_or: [javascript, jsx, ts, tsx, markdown, yaml]
types_or: [javascript, jsx, ts, tsx, markdown, yaml, json]
stages: [commit]
- repo: https://github.com/nonebot/nonemoji

View File

@@ -33,7 +33,7 @@ pre-commit install
### 使用 GitHub CodespacesDev Container
使用 GitHub Codespaces 选择 `NoneBot2` 项目,然后选择 `.devcontainer/devcontainer.json` 配置即可。
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=master&repo=289605524)
### Commit 规范

View File

@@ -96,17 +96,18 @@ NoneBot2 是一个现代、跨平台、可扩展的 Python 聊天机器人框架
- 社区丰富:社区用户众多,直接和间接用户超过十万人,每天都有大量的活跃用户 ([社区资源](#社区资源))
- 海纳百川:一个框架,支持多个聊天软件平台,可自定义通信协议
| 协议名称 | 状态 | 注释 |
| :---------------------------------------------------: | :--: | :----------------------------------------------------------------: |
| [OneBot 协议](https://onebot.dev/) | ✅ | 支持 QQ、TG、微信公众号等[平台](https://onebot.dev/ecosystem.html) |
| [Telegram](https://core.telegram.org/bots/api) | ✅ | |
| [飞书](https://open.feishu.cn/document/home/index) | ✅ | |
| [GitHub](https://docs.github.com/en/developers/apps) | ✅ | GitHub APP & OAuth APP |
| [QQ 频道](https://bot.q.qq.com/wiki/) | ✅ | 官方接口调整较多 |
| [钉钉](https://open.dingtalk.com/document/) | 🤗 | 寻找 Maintainer |
| Console | ✅ | 控制台交互 |
| [开黑啦](https://developer.kookapp.cn/) | ↗️ | 由社区贡献 |
| [Mirai](https://docs.mirai.mamoe.net/mirai-api-http/) | ↗️ | 由社区贡献 |
| 协议名称 | 状态 | 注释 |
| :--------------------------------------------------------: | :--: | :----------------------------------------------------------------: |
| [OneBot 协议](https://onebot.dev/) | ✅ | 支持 QQ、TG、微信公众号等[平台](https://onebot.dev/ecosystem.html) |
| [Telegram](https://core.telegram.org/bots/api) | ✅ | |
| [飞书](https://open.feishu.cn/document/home/index) | ✅ | |
| [GitHub](https://docs.github.com/en/developers/apps) | ✅ | GitHub APP & OAuth APP |
| [QQ 频道](https://bot.q.qq.com/wiki/) | ✅ | 官方接口调整较多 |
| [钉钉](https://open.dingtalk.com/document/) | 🤗 | 寻找 Maintainer |
| Console | ✅ | 控制台交互 |
| [开黑啦](https://developer.kookapp.cn/) | ↗️ | 由社区贡献 |
| [Mirai](https://docs.mirai.mamoe.net/mirai-api-http/) | ↗️ | 由社区贡献 |
| [Ntchat](https://github.com/JustUndertaker/adapter-ntchat) | ↗️ | 由社区贡献 |
- 坚实后盾:支持多种 web 框架,可自定义替换、组合

View File

@@ -37,10 +37,13 @@ FrontMatter:
description: nonebot 模块
"""
import os
import importlib
from importlib.metadata import version
from typing import Any, Dict, Type, Optional
import loguru
from pydantic.env_settings import DotenvType
from nonebot.log import logger
from nonebot.adapters import Bot
@@ -49,14 +52,9 @@ from nonebot.config import Env, Config
from nonebot.drivers import Driver, ReverseDriver, combine_driver
try:
import pkg_resources
_dist: pkg_resources.Distribution = pkg_resources.get_distribution("nonebot2")
__version__ = _dist.version
VERSION = _dist.parsed_version
__version__ = version("nonebot2")
except Exception: # pragma: no cover
__version__ = None
VERSION = None
_driver: Optional[Driver] = None
@@ -217,7 +215,7 @@ def _log_patcher(record: "loguru.Record"):
)
def init(*, _env_file: Optional[str] = None, **kwargs: Any) -> None:
def init(*, _env_file: Optional[DotenvType] = None, **kwargs: Any) -> None:
"""初始化 NoneBot 以及 全局 {ref}`nonebot.drivers.Driver` 对象。
NoneBot 将会从 .env 文件中读取环境信息,并使用相应的 env 文件配置。
@@ -237,10 +235,12 @@ def init(*, _env_file: Optional[str] = None, **kwargs: Any) -> None:
if not _driver:
logger.success("NoneBot is initializing...")
env = Env()
_env_file = _env_file or f".env.{env.environment}"
config = Config(
**kwargs,
_common_config=env.dict(),
_env_file=_env_file or f".env.{env.environment}",
_env_file=(".env", _env_file)
if isinstance(_env_file, (str, os.PathLike))
else _env_file,
)
logger.configure(

View File

@@ -7,21 +7,6 @@ FrontMatter:
description: nonebot.adapters 模块
"""
from typing import Iterable
try:
import pkg_resources
pkg_resources.declare_namespace(__name__)
del pkg_resources
except ImportError:
import pkgutil
__path__: Iterable[str] = pkgutil.extend_path(__path__, __name__) # type: ignore
del pkgutil
except Exception:
pass
from nonebot.internal.adapter import Bot as Bot
from nonebot.internal.adapter import Event as Event
from nonebot.internal.adapter import Adapter as Adapter

View File

@@ -14,14 +14,14 @@ from datetime import timedelta
from ipaddress import IPv4Address
from typing import TYPE_CHECKING, Any, Set, Dict, Tuple, Union, Mapping, Optional
from pydantic import BaseSettings, IPvAnyAddress
from pydantic.utils import deep_update
from pydantic import Extra, BaseSettings, IPvAnyAddress
from pydantic.env_settings import (
DotenvType,
SettingsError,
EnvSettingsSource,
InitSettingsSource,
SettingsSourceCallable,
read_env_file,
env_file_sentinel,
)
from nonebot.log import logger
@@ -32,33 +32,15 @@ class CustomEnvSettings(EnvSettingsSource):
"""
Build environment variables suitable for passing to the Model.
"""
d: Dict[str, Optional[str]] = {}
d: Dict[str, Any] = {}
if settings.__config__.case_sensitive:
env_vars: Mapping[str, Optional[str]] = os.environ # pragma: no cover
else:
env_vars = {k.lower(): v for k, v in os.environ.items()}
env_file_vars: Dict[str, Optional[str]] = {}
env_file = (
self.env_file
if self.env_file != env_file_sentinel
else settings.__config__.env_file
)
env_file_encoding = (
self.env_file_encoding
if self.env_file_encoding is not None
else settings.__config__.env_file_encoding
)
if env_file is not None:
env_path = Path(env_file)
if env_path.is_file():
env_file_vars = read_env_file(
env_path,
encoding=env_file_encoding, # type: ignore
case_sensitive=settings.__config__.case_sensitive,
)
env_vars = {**env_file_vars, **env_vars}
env_file_vars = self._read_env_files(settings.__config__.case_sensitive)
env_vars = {**env_file_vars, **env_vars}
for field in settings.__fields__.values():
env_val: Optional[str] = None
@@ -69,31 +51,56 @@ class CustomEnvSettings(EnvSettingsSource):
if env_val is not None:
break
if env_val is None:
continue
if field.is_complex():
try:
env_val = settings.__config__.json_loads(env_val)
except ValueError as e: # pragma: no cover
raise SettingsError(
f'error parsing JSON for "{env_name}"' # type: ignore
) from e
d[field.alias] = env_val
if env_file_vars:
for env_name in env_file_vars.keys():
env_val = env_vars[env_name]
if env_val and (val_striped := env_val.strip()):
is_complex, allow_parse_failure = self.field_is_complex(field)
if is_complex:
if env_val is None:
if env_val_built := self.explode_env_vars(field, env_vars):
d[field.alias] = env_val_built
else:
# field is complex and there's a value, decode that as JSON, then add explode_env_vars
try:
env_val = settings.__config__.json_loads(val_striped)
env_val = settings.__config__.parse_env_var(field.name, env_val)
except ValueError as e:
logger.trace(
"Error while parsing JSON for "
f"{env_name!r}={val_striped!r}. "
"Assumed as string."
)
if not allow_parse_failure:
raise SettingsError(
f'error parsing env var "{env_name}"' # type: ignore
) from e
if isinstance(env_val, dict):
d[field.alias] = deep_update(
env_val, self.explode_env_vars(field, env_vars)
)
else:
d[field.alias] = env_val
elif env_val is not None:
# simplest case, field is not complex, we only need to add the value if it was found
d[field.alias] = env_val
# remain user custom config
for env_name in env_file_vars:
env_val = env_vars[env_name]
if env_val and (val_striped := env_val.strip()):
# there's a value, decode that as JSON
try:
env_val = settings.__config__.parse_env_var(env_name, val_striped)
except ValueError as e:
logger.trace(
"Error while parsing JSON for "
f"{env_name!r}={val_striped!r}. "
"Assumed as string."
)
# explode value when it's a nested dict
env_name, *nested_keys = env_name.split(self.env_nested_delimiter)
if nested_keys and (env_name not in d or isinstance(d[env_name], dict)):
result = {}
*keys, last_key = nested_keys
_tmp = result
for key in keys:
_tmp = _tmp.setdefault(key, {})
_tmp[last_key] = env_val
d[env_name] = deep_update(d.get(env_name, {}), result)
elif not nested_keys:
d[env_name] = env_val
return d
@@ -106,6 +113,9 @@ class BaseConfig(BaseSettings):
return self.__dict__.get(name)
class Config:
extra = Extra.allow
env_nested_delimiter = "__"
@classmethod
def customise_sources(
cls,
@@ -117,7 +127,10 @@ class BaseConfig(BaseSettings):
return (
init_settings,
CustomEnvSettings(
env_settings.env_file, env_settings.env_file_encoding
env_settings.env_file,
env_settings.env_file_encoding,
env_settings.env_nested_delimiter,
env_settings.env_prefix_len,
),
InitSettingsSource(common_config),
file_secret_settings,
@@ -137,7 +150,6 @@ class Env(BaseConfig):
"""
class Config:
extra = "allow"
env_file = ".env"
@@ -150,8 +162,7 @@ class Config(BaseConfig):
配置方法参考: [配置](https://v2.nonebot.dev/docs/tutorial/configuration)
"""
_env_file: str = ".env"
_common_config: Dict[str, Any] = {}
_env_file: DotenvType = ".env", ".env.prod"
# nonebot configs
driver: str = "~fastapi"
@@ -231,8 +242,7 @@ class Config(BaseConfig):
# or from env file using json loads
class Config:
extra = "allow"
env_file = ".env.prod"
env_file = ".env", ".env.prod"
__autodoc__ = {

View File

@@ -42,3 +42,11 @@ REGEX_GROUP: Literal["_matched_groups"] = "_matched_groups"
"""正则匹配 group 元组存储 key"""
REGEX_DICT: Literal["_matched_dict"] = "_matched_dict"
"""正则匹配 group 字典存储 key"""
STARTSWITH_KEY: Literal["_startswith"] = "_startswith"
"""响应触发前缀 key"""
ENDSWITH_KEY: Literal["_endswith"] = "_endswith"
"""响应触发后缀 key"""
FULLMATCH_KEY: Literal["_fullmatch"] = "_fullmatch"
"""响应触发完整消息 key"""
KEYWORD_KEY: Literal["_keyword"] = "_keyword"
"""响应触发关键字 key"""

View File

@@ -4,11 +4,11 @@ FrontMatter:
description: nonebot.dependencies.utils 模块
"""
import inspect
from typing import Any, Dict, TypeVar, Callable
from typing import Any, Dict, TypeVar, Callable, ForwardRef
from loguru import logger
from pydantic.fields import ModelField
from pydantic.typing import ForwardRef, evaluate_forwardref
from pydantic.typing import evaluate_forwardref
from nonebot.exception import TypeMisMatch

View File

@@ -262,7 +262,7 @@ class FastAPIWebSocket(BaseWebSocket):
async def close(
self, code: int = status.WS_1000_NORMAL_CLOSURE, reason: str = ""
) -> None:
await self.websocket.close(code)
await self.websocket.close(code, reason)
@overrides(BaseWebSocket)
async def receive(self) -> Union[str, bytes]:

View File

@@ -43,6 +43,10 @@ class Bot(abc.ABC):
return f"Bot(type={self.type!r}, self_id={self.self_id!r})"
def __getattr__(self, name: str) -> "_ApiCall":
if name.startswith("__") and name.endswith("__"):
raise AttributeError(
f"'{self.__class__.__name__}' object has no attribute '{name}'"
)
return partial(self.call_api, name)
@property

View File

@@ -0,0 +1,11 @@
from .manager import MatcherManager as MatcherManager
from .provider import MatcherProvider as MatcherProvider
from .provider import DEFAULT_PROVIDER_CLASS as DEFAULT_PROVIDER_CLASS
matchers = MatcherManager()
from .matcher import Matcher as Matcher
from .matcher import current_bot as current_bot
from .matcher import current_event as current_event
from .matcher import current_handler as current_handler
from .matcher import current_matcher as current_matcher

View File

@@ -0,0 +1,104 @@
from typing import (
TYPE_CHECKING,
Any,
List,
Type,
Tuple,
Union,
TypeVar,
Iterator,
KeysView,
Optional,
ItemsView,
ValuesView,
MutableMapping,
overload,
)
from .provider import DEFAULT_PROVIDER_CLASS, MatcherProvider
if TYPE_CHECKING:
from .matcher import Matcher
T = TypeVar("T")
class MatcherManager(MutableMapping[int, List[Type["Matcher"]]]):
"""事件响应器管理器
实现了常用字典操作,用于管理事件响应器。
"""
def __init__(self):
self.provider: MatcherProvider = DEFAULT_PROVIDER_CLASS({})
def __repr__(self) -> str:
return f"MatcherManager(provider={self.provider!r})"
def __contains__(self, o: object) -> bool:
return o in self.provider
def __iter__(self) -> Iterator[int]:
return iter(self.provider)
def __len__(self) -> int:
return len(self.provider)
def __getitem__(self, key: int) -> List[Type["Matcher"]]:
return self.provider[key]
def __setitem__(self, key: int, value: List[Type["Matcher"]]) -> None:
self.provider[key] = value
def __delitem__(self, key: int) -> None:
del self.provider[key]
def __eq__(self, other: Any) -> bool:
return isinstance(other, MatcherManager) and self.provider == other.provider
def keys(self) -> KeysView[int]:
return self.provider.keys()
def values(self) -> ValuesView[List[Type["Matcher"]]]:
return self.provider.values()
def items(self) -> ItemsView[int, List[Type["Matcher"]]]:
return self.provider.items()
@overload
def get(self, key: int) -> Optional[List[Type["Matcher"]]]:
...
@overload
def get(self, key: int, default: T) -> Union[List[Type["Matcher"]], T]:
...
def get(
self, key: int, default: Optional[T] = None
) -> Optional[Union[List[Type["Matcher"]], T]]:
return self.provider.get(key, default)
def pop(self, key: int) -> List[Type["Matcher"]]:
return self.provider.pop(key)
def popitem(self) -> Tuple[int, List[Type["Matcher"]]]:
return self.provider.popitem()
def clear(self) -> None:
self.provider.clear()
def update(self, __m: MutableMapping[int, List[Type["Matcher"]]]) -> None:
self.provider.update(__m)
def setdefault(
self, key: int, default: List[Type["Matcher"]]
) -> List[Type["Matcher"]]:
return self.provider.setdefault(key, default)
def set_provider(self, provider_class: Type[MatcherProvider]) -> None:
"""设置事件响应器存储器
参数:
provider_class: 事件响应器存储器类
"""
self.provider = provider_class(self.provider)

View File

@@ -1,12 +1,10 @@
from types import ModuleType
from contextvars import ContextVar
from collections import defaultdict
from contextlib import AsyncExitStack
from datetime import datetime, timedelta
from contextlib import AsyncExitStack, contextmanager
from typing import (
TYPE_CHECKING,
Any,
Dict,
List,
Type,
Union,
@@ -19,7 +17,16 @@ from typing import (
)
from nonebot.log import logger
from nonebot.internal.rule import Rule
from nonebot.dependencies import Dependent
from nonebot.internal.permission import USER, User, Permission
from nonebot.internal.adapter import (
Bot,
Event,
Message,
MessageSegment,
MessageTemplate,
)
from nonebot.consts import (
ARG_KEY,
RECEIVE_KEY,
@@ -42,11 +49,7 @@ from nonebot.exception import (
FinishedException,
RejectedException,
)
from .rule import Rule
from .permission import USER, User, Permission
from .adapter import Bot, Event, Message, MessageSegment, MessageTemplate
from .params import (
from nonebot.internal.params import (
Depends,
ArgParam,
BotParam,
@@ -57,13 +60,13 @@ from .params import (
MatcherParam,
)
from . import matchers
if TYPE_CHECKING:
from nonebot.plugin import Plugin
T = TypeVar("T")
matchers: Dict[int, List[Type["Matcher"]]] = defaultdict(list)
"""用于存储当前所有的事件响应器"""
current_bot: ContextVar[Bot] = ContextVar("current_bot")
current_event: ContextVar[Event] = ContextVar("current_event")
current_matcher: ContextVar["Matcher"] = ContextVar("current_matcher")
@@ -661,6 +664,18 @@ class Matcher(metaclass=MatcherMeta):
if REJECT_CACHE_TARGET in self.state:
self.state[REJECT_TARGET] = self.state[REJECT_CACHE_TARGET]
@contextmanager
def ensure_context(self, bot: Bot, event: Event):
b_t = current_bot.set(bot)
e_t = current_event.set(event)
m_t = current_matcher.set(self)
try:
yield
finally:
current_bot.reset(b_t)
current_event.reset(e_t)
current_matcher.reset(m_t)
async def simple_run(
self,
bot: Bot,
@@ -673,35 +688,31 @@ class Matcher(metaclass=MatcherMeta):
f"{self} run with incoming args: "
f"bot={bot}, event={event!r}, state={state!r}"
)
b_t = current_bot.set(bot)
e_t = current_event.set(event)
m_t = current_matcher.set(self)
try:
# Refresh preprocess state
self.state.update(state)
while self.handlers:
handler = self.handlers.pop(0)
current_handler.set(handler)
logger.debug(f"Running handler {handler}")
try:
await handler(
matcher=self,
bot=bot,
event=event,
state=self.state,
stack=stack,
dependency_cache=dependency_cache,
)
except SkippedException:
logger.debug(f"Handler {handler} skipped")
except StopPropagation:
self.block = True
finally:
logger.info(f"{self} running complete")
current_bot.reset(b_t)
current_event.reset(e_t)
current_matcher.reset(m_t)
with self.ensure_context(bot, event):
try:
# Refresh preprocess state
self.state.update(state)
while self.handlers:
handler = self.handlers.pop(0)
current_handler.set(handler)
logger.debug(f"Running handler {handler}")
try:
await handler(
matcher=self,
bot=bot,
event=event,
state=self.state,
stack=stack,
dependency_cache=dependency_cache,
)
except SkippedException:
logger.debug(f"Handler {handler} skipped")
except StopPropagation:
self.block = True
finally:
logger.info(f"{self} running complete")
# 运行handlers
async def run(
@@ -756,14 +767,3 @@ class Matcher(metaclass=MatcherMeta):
)
except FinishedException:
pass
__autodoc__ = {
"MatcherMeta": False,
"Matcher.get_target": False,
"Matcher.set_target": False,
"Matcher.update_type": False,
"Matcher.update_permission": False,
"Matcher.resolve_reject": False,
"Matcher.simple_run": False,
}

View File

@@ -0,0 +1,27 @@
import abc
from collections import defaultdict
from typing import TYPE_CHECKING, List, Type, Mapping, MutableMapping
if TYPE_CHECKING:
from .matcher import Matcher
class MatcherProvider(abc.ABC, MutableMapping[int, List[Type["Matcher"]]]):
"""事件响应器存储器基类
参数:
matchers: 当前存储器中已有的事件响应器
"""
@abc.abstractmethod
def __init__(self, matchers: Mapping[int, List[Type["Matcher"]]]):
raise NotImplementedError
class _DictProvider(defaultdict, MatcherProvider):
def __init__(self, matchers: Mapping[int, List[Type["Matcher"]]]):
super().__init__(list, matchers)
DEFAULT_PROVIDER_CLASS = _DictProvider
"""默认存储器类型"""

View File

@@ -9,10 +9,16 @@ from nonebot.internal.matcher import Matcher as Matcher
from nonebot.internal.matcher import matchers as matchers
from nonebot.internal.matcher import current_bot as current_bot
from nonebot.internal.matcher import current_event as current_event
from nonebot.internal.matcher import MatcherManager as MatcherManager
from nonebot.internal.matcher import MatcherProvider as MatcherProvider
from nonebot.internal.matcher import current_handler as current_handler
from nonebot.internal.matcher import current_matcher as current_matcher
from nonebot.internal.matcher import DEFAULT_PROVIDER_CLASS as DEFAULT_PROVIDER_CLASS
__autodoc__ = {
"Matcher": True,
"matchers": True,
"MatcherManager": True,
"MatcherProvider": True,
"DEFAULT_PROVIDER_CLASS": True,
}

View File

@@ -167,17 +167,19 @@ async def _run_matcher(
)
for proc in _run_preprocessors
]:
try:
await asyncio.gather(*coros)
except IgnoredException:
logger.opt(colors=True).info(f"{matcher} running is <b>cancelled</b>")
return
except Exception as e:
logger.opt(colors=True, exception=e).error(
"<r><bg #f8bbd0>Error when running RunPreProcessors. Running cancelled!</bg #f8bbd0></r>"
)
# ensure matcher function can be correctly called
with matcher.ensure_context(bot, event):
try:
await asyncio.gather(*coros)
except IgnoredException:
logger.opt(colors=True).info(f"{matcher} running is <b>cancelled</b>")
return
except Exception as e:
logger.opt(colors=True, exception=e).error(
"<r><bg #f8bbd0>Error when running RunPreProcessors. Running cancelled!</bg #f8bbd0></r>"
)
return
return
exception = None
@@ -205,12 +207,14 @@ async def _run_matcher(
)
for proc in _run_postprocessors
]:
try:
await asyncio.gather(*coros)
except Exception as e:
logger.opt(colors=True, exception=e).error(
"<r><bg #f8bbd0>Error when running RunPostProcessors</bg #f8bbd0></r>"
)
# ensure matcher function can be correctly called
with matcher.ensure_context(bot, event):
try:
await asyncio.gather(*coros)
except Exception as e:
logger.opt(colors=True, exception=e).error(
"<r><bg #f8bbd0>Error when running RunPostProcessors</bg #f8bbd0></r>"
)
if matcher.block:
raise StopPropagation

View File

@@ -29,10 +29,14 @@ from nonebot.consts import (
SHELL_ARGS,
SHELL_ARGV,
CMD_ARG_KEY,
KEYWORD_KEY,
RAW_CMD_KEY,
REGEX_GROUP,
ENDSWITH_KEY,
CMD_START_KEY,
FULLMATCH_KEY,
REGEX_MATCHED,
STARTSWITH_KEY,
)
@@ -153,6 +157,42 @@ def RegexDict() -> Dict[str, Any]:
return Depends(_regex_dict, use_cache=False)
def _startswith(state: T_State) -> str:
return state[STARTSWITH_KEY]
def Startswith() -> str:
"""响应触发前缀"""
return Depends(_startswith, use_cache=False)
def _endswith(state: T_State) -> str:
return state[ENDSWITH_KEY]
def Endswith() -> str:
"""响应触发后缀"""
return Depends(_endswith, use_cache=False)
def _fullmatch(state: T_State) -> str:
return state[FULLMATCH_KEY]
def Fullmatch() -> str:
"""响应触发完整消息"""
return Depends(_fullmatch, use_cache=False)
def _keyword(state: T_State) -> str:
return state[KEYWORD_KEY]
def Keyword() -> str:
"""响应触发关键字"""
return Depends(_keyword, use_cache=False)
def Received(id: Optional[str] = None, default: Any = None) -> Any:
"""`receive` 事件参数"""

View File

@@ -18,7 +18,6 @@ from argparse import ArgumentParser as ArgParser
from typing import (
IO,
TYPE_CHECKING,
Any,
List,
Type,
Tuple,
@@ -48,10 +47,14 @@ from nonebot.consts import (
SHELL_ARGS,
SHELL_ARGV,
CMD_ARG_KEY,
KEYWORD_KEY,
RAW_CMD_KEY,
REGEX_GROUP,
ENDSWITH_KEY,
CMD_START_KEY,
FULLMATCH_KEY,
REGEX_MATCHED,
STARTSWITH_KEY,
)
T = TypeVar("T")
@@ -136,20 +139,21 @@ class StartswithRule:
def __hash__(self) -> int:
return hash((frozenset(self.msg), self.ignorecase))
async def __call__(self, event: Event) -> bool:
async def __call__(self, event: Event, state: T_State) -> bool:
if event.get_type() != "message":
return False
try:
text = event.get_plaintext()
except Exception:
return False
return bool(
re.match(
f"^(?:{'|'.join(re.escape(prefix) for prefix in self.msg)})",
text,
re.IGNORECASE if self.ignorecase else 0,
)
)
if match := re.match(
f"^(?:{'|'.join(re.escape(prefix) for prefix in self.msg)})",
text,
re.IGNORECASE if self.ignorecase else 0,
):
state[STARTSWITH_KEY] = match.group()
return True
return False
def startswith(msg: Union[str, Tuple[str, ...]], ignorecase: bool = False) -> Rule:
@@ -192,20 +196,21 @@ class EndswithRule:
def __hash__(self) -> int:
return hash((frozenset(self.msg), self.ignorecase))
async def __call__(self, event: Event) -> bool:
async def __call__(self, event: Event, state: T_State) -> bool:
if event.get_type() != "message":
return False
try:
text = event.get_plaintext()
except Exception:
return False
return bool(
re.search(
f"(?:{'|'.join(re.escape(prefix) for prefix in self.msg)})$",
text,
re.IGNORECASE if self.ignorecase else 0,
)
)
if match := re.search(
f"(?:{'|'.join(re.escape(suffix) for suffix in self.msg)})$",
text,
re.IGNORECASE if self.ignorecase else 0,
):
state[ENDSWITH_KEY] = match.group()
return True
return False
def endswith(msg: Union[str, Tuple[str, ...]], ignorecase: bool = False) -> Rule:
@@ -248,14 +253,20 @@ class FullmatchRule:
def __hash__(self) -> int:
return hash((frozenset(self.msg), self.ignorecase))
async def __call__(self, event: Event) -> bool:
async def __call__(self, event: Event, state: T_State) -> bool:
if event.get_type() != "message":
return False
try:
text = event.get_plaintext()
except Exception:
return False
return (text.casefold() if self.ignorecase else text) in self.msg
if not text:
return False
text = text.casefold() if self.ignorecase else text
if text in self.msg:
state[FULLMATCH_KEY] = text
return True
return False
def fullmatch(msg: Union[str, Tuple[str, ...]], ignorecase: bool = False) -> Rule:
@@ -294,14 +305,19 @@ class KeywordsRule:
def __hash__(self) -> int:
return hash(frozenset(self.keywords))
async def __call__(self, event: Event) -> bool:
async def __call__(self, event: Event, state: T_State) -> bool:
if event.get_type() != "message":
return False
try:
text = event.get_plaintext()
except Exception:
return False
return bool(text and any(keyword in text for keyword in self.keywords))
if not text:
return False
if key := next((k for k in self.keywords if k in text), None):
state[KEYWORD_KEY] = key
return True
return False
def keyword(*keywords: str) -> Rule:

1104
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "nonebot2"
version = "2.0.0-rc.1"
version = "2.0.0rc2"
description = "An asynchronous python bot framework."
authors = ["yanyongyu <yyy@nonebot.dev>"]
license = "MIT"
@@ -26,25 +26,30 @@ python = "^3.8"
yarl = "^1.7.2"
loguru = "^0.6.0"
pygtrie = "^2.4.1"
fastapi = "^0.79.0"
fastapi = ">=0.87.0,<1.0.0"
tomlkit = ">=0.10.0,<1.0.0"
typing-extensions = ">=3.10.0,<5.0.0"
Quart = { version = "^0.17.0", optional = true }
websockets = { version="^10.0", optional = true }
pydantic = { version = "~1.9.0", extras = ["dotenv"] }
uvicorn = { version = "^0.18.0", extras = ["standard"] }
aiohttp = { version = "^3.7.4", extras = ["speedups"], optional = true }
httpx = { version = ">=0.20.0, <1.0.0", extras = ["http2"], optional = true }
pydantic = { version = "^1.10.0", extras = ["dotenv"] }
uvicorn = { version = ">=0.20.0,<1.0.0", extras = ["standard"] }
[tool.poetry.dev-dependencies]
websockets = { version="^10.0", optional = true }
Quart = { version = ">=0.18.0,<1.0.0", optional = true }
aiohttp = { version = "^3.7.4", extras = ["speedups"], optional = true }
httpx = { version = ">=0.20.0,<1.0.0", extras = ["http2"], optional = true }
[tool.poetry.group.dev.dependencies]
isort = "^5.10.1"
black = "^22.1.0"
nonemoji = "^0.1.2"
pytest-cov = "^3.0.0"
pre-commit = "^2.16.0"
pytest-xdist = "^2.5.0"
pytest-asyncio = "^0.19.0"
[tool.poetry.group.test.dependencies]
pytest-cov = "^4.0.0"
pytest-xdist = "^3.0.2"
pytest-asyncio = "^0.20.0"
nonebug = { git = "https://github.com/nonebot/nonebug.git" }
[tool.poetry.group.docs.dependencies]
nb-autodoc = { git = "https://github.com/nonebot/nb-autodoc.git" }
[tool.poetry.extras]
@@ -64,7 +69,7 @@ filterwarnings = [
[tool.black]
line-length = 88
target-version = ["py37", "py38", "py39", "py310"]
target-version = ["py38", "py39", "py310", "py311"]
include = '\.pyi?$'
extend-exclude = '''
'''

View File

@@ -1,2 +1,3 @@
ENVIRONMENT=test
COMMON_CONFIG=common
COMMON_OVERRIDE=old

View File

@@ -1,5 +1,13 @@
LOG_LEVEL=TRACE
NICKNAME=["test"]
SUPERUSERS=["test", "fake:faketest"]
COMMON_OVERRIDE=new
CONFIG_FROM_ENV=
CONFIG_OVERRIDE=old
NESTED_DICT={"a": 1}
NESTED_DICT__B=2
NESTED_DICT__C__D=3
NESTED_MISSING_DICT__A=1
NESTED_MISSING_DICT__B__C=2
NOT_NESTED=some string
NOT_NESTED__A=1

View File

@@ -4,10 +4,14 @@ from nonebot.typing import T_State
from nonebot.adapters import Message
from nonebot.params import (
Command,
Keyword,
Endswith,
Fullmatch,
RegexDict,
CommandArg,
RawCommand,
RegexGroup,
Startswith,
CommandStart,
RegexMatched,
ShellCommandArgs,
@@ -65,3 +69,19 @@ async def regex_group(regex_group: Tuple = RegexGroup()) -> Tuple:
async def regex_matched(regex_matched: str = RegexMatched()) -> str:
return regex_matched
async def startswith(startswith: str = Startswith()) -> str:
return startswith
async def endswith(endswith: str = Endswith()) -> str:
return endswith
async def fullmatch(fullmatch: str = Fullmatch()) -> str:
return fullmatch
async def keyword(keyword: str = Keyword()) -> str:
return keyword

View File

@@ -29,6 +29,10 @@ async def test_init(nonebug_init):
assert config.config_override == "new"
assert config.config_from_init == "init"
assert config.common_config == "common"
assert config.common_override == "new"
assert config.nested_dict == {"a": 1, "b": 2, "c": {"d": 3}}
assert config.nested_missing_dict == {"a": 1, "b": {"c": 2}}
assert config.not_nested == "some string"
@pytest.mark.asyncio

View File

@@ -0,0 +1,11 @@
import pytest
from nonebug import App
@pytest.mark.asyncio
async def test_manager(app: App, load_plugin):
from nonebot.matcher import DEFAULT_PROVIDER_CLASS, matchers
default_provider = matchers.provider
matchers.set_provider(DEFAULT_PROVIDER_CLASS)
assert matchers.provider == default_provider

View File

@@ -168,15 +168,23 @@ async def test_state(app: App, load_plugin):
SHELL_ARGS,
SHELL_ARGV,
CMD_ARG_KEY,
KEYWORD_KEY,
RAW_CMD_KEY,
REGEX_GROUP,
ENDSWITH_KEY,
CMD_START_KEY,
FULLMATCH_KEY,
REGEX_MATCHED,
STARTSWITH_KEY,
)
from plugins.param.param_state import (
state,
command,
keyword,
endswith,
fullmatch,
regex_dict,
startswith,
command_arg,
raw_command,
regex_group,
@@ -201,6 +209,10 @@ async def test_state(app: App, load_plugin):
REGEX_MATCHED: "[cq:test,arg=value]",
REGEX_GROUP: ("test", "arg=value"),
REGEX_DICT: {"type": "test", "arg": "value"},
STARTSWITH_KEY: "startswith",
ENDSWITH_KEY: "endswith",
FULLMATCH_KEY: "fullmatch",
KEYWORD_KEY: "keyword",
}
async with app.test_dependent(state, allow_types=[StateParam]) as ctx:
@@ -271,6 +283,30 @@ async def test_state(app: App, load_plugin):
ctx.pass_params(state=fake_state)
ctx.should_return(fake_state[REGEX_DICT])
async with app.test_dependent(
startswith, allow_types=[StateParam, DependParam]
) as ctx:
ctx.pass_params(state=fake_state)
ctx.should_return(fake_state[STARTSWITH_KEY])
async with app.test_dependent(
endswith, allow_types=[StateParam, DependParam]
) as ctx:
ctx.pass_params(state=fake_state)
ctx.should_return(fake_state[ENDSWITH_KEY])
async with app.test_dependent(
fullmatch, allow_types=[StateParam, DependParam]
) as ctx:
ctx.pass_params(state=fake_state)
ctx.should_return(fake_state[FULLMATCH_KEY])
async with app.test_dependent(
keyword, allow_types=[StateParam, DependParam]
) as ctx:
ctx.pass_params(state=fake_state)
ctx.should_return(fake_state[KEYWORD_KEY])
@pytest.mark.asyncio
async def test_matcher(app: App, load_plugin):

View File

@@ -65,19 +65,24 @@ async def test_startswith(
text: Optional[str],
expected: bool,
):
from nonebot.consts import STARTSWITH_KEY
from nonebot.rule import StartswithRule, startswith
test_startswith = startswith(msg, ignorecase)
dependent = list(test_startswith.checkers)[0]
checker = dependent.call
msg = (msg,) if isinstance(msg, str) else msg
assert isinstance(checker, StartswithRule)
assert checker.msg == (msg,) if isinstance(msg, str) else msg
assert checker.msg == msg
assert checker.ignorecase == ignorecase
message = text if text is None else make_fake_message()(text)
event = make_fake_event(_type=type, _message=message)()
assert await dependent(event=event) == expected
for prefix in msg:
state = {STARTSWITH_KEY: prefix}
assert await dependent(event=event, state=state) == expected
@pytest.mark.asyncio
@@ -103,19 +108,24 @@ async def test_endswith(
text: Optional[str],
expected: bool,
):
from nonebot.consts import ENDSWITH_KEY
from nonebot.rule import EndswithRule, endswith
test_endswith = endswith(msg, ignorecase)
dependent = list(test_endswith.checkers)[0]
checker = dependent.call
msg = (msg,) if isinstance(msg, str) else msg
assert isinstance(checker, EndswithRule)
assert checker.msg == (msg,) if isinstance(msg, str) else msg
assert checker.msg == msg
assert checker.ignorecase == ignorecase
message = text if text is None else make_fake_message()(text)
event = make_fake_event(_type=type, _message=message)()
assert await dependent(event=event) == expected
for suffix in msg:
state = {ENDSWITH_KEY: suffix}
assert await dependent(event=event, state=state) == expected
@pytest.mark.asyncio
@@ -141,19 +151,24 @@ async def test_fullmatch(
text: Optional[str],
expected: bool,
):
from nonebot.consts import FULLMATCH_KEY
from nonebot.rule import FullmatchRule, fullmatch
test_fullmatch = fullmatch(msg, ignorecase)
dependent = list(test_fullmatch.checkers)[0]
checker = dependent.call
msg = (msg,) if isinstance(msg, str) else msg
assert isinstance(checker, FullmatchRule)
assert checker.msg == ((msg,) if isinstance(msg, str) else msg)
assert checker.msg == msg
assert checker.ignorecase == ignorecase
message = text if text is None else make_fake_message()(text)
event = make_fake_event(_type=type, _message=message)()
assert await dependent(event=event) == expected
for full in msg:
state = {FULLMATCH_KEY: full}
assert await dependent(event=event, state=state) == expected
@pytest.mark.asyncio
@@ -164,6 +179,7 @@ async def test_fullmatch(
(("key", "foo"), "message", "_foo_", True),
(("key",), "message", None, False),
(("key",), "notice", "foo", False),
(("key",), "message", "foo", False),
],
)
async def test_keyword(
@@ -173,6 +189,7 @@ async def test_keyword(
text: Optional[str],
expected: bool,
):
from nonebot.consts import KEYWORD_KEY
from nonebot.rule import KeywordsRule, keyword
test_keyword = keyword(*kws)
@@ -184,7 +201,9 @@ async def test_keyword(
message = text if text is None else make_fake_message()(text)
event = make_fake_event(_type=type, _message=message)()
assert await dependent(event=event) == expected
for kw in kws:
state = {KEYWORD_KEY: kw}
assert await dependent(event=event, state=state) == expected
@pytest.mark.asyncio

View File

@@ -363,6 +363,62 @@ matcher = on_regex("regex")
async def _(foo: Dict[str, Any] = RegexDict()): ...
```
### Startswith
获取触发响应器的消息前缀字符串。
```python {7}
from nonebot import on_startswith
from nonebot.params import Startswith
matcher = on_startswith("prefix")
@matcher.handle()
async def _(foo: str = Startswith()): ...
```
### Endswith
获取触发响应器的消息后缀字符串。
```python {7}
from nonebot import on_endswith
from nonebot.params import Endswith
matcher = on_endswith("suffix")
@matcher.handle()
async def _(foo: str = Endswith()): ...
```
### Fullmatch
获取触发响应器的消息字符串。
```python {7}
from nonebot import on_fullmatch
from nonebot.params import Fullmatch
matcher = on_fullmatch("fullmatch")
@matcher.handle()
async def _(foo: str = Fullmatch()): ...
```
### Keyword
获取触发响应器的关键字字符串。
```python {7}
from nonebot import on_keyword
from nonebot.params import Keyword
matcher = on_keyword({"keyword"})
@matcher.handle()
async def _(foo: str = Keyword()): ...
```
### Matcher
获取当前事件响应器实例。

View File

@@ -5,6 +5,85 @@ toc_max_heading_level: 2
# 更新日志
## v2.0.0rc2
### 💥 破坏性变更
- Feature: 使用 `importlib.metadata` 替换 `pkg_resources` [@A-kirami](https://github.com/A-kirami) ([#1388](https://github.com/nonebot/nonebot2/pull/1388))
### 🚀 新功能
- Feature: 支持自定义 matchers 存储管理 [@yanyongyu](https://github.com/yanyongyu) ([#1395](https://github.com/nonebot/nonebot2/pull/1395))
- Feature: 升级 devcontainer 配置 [@yanyongyu](https://github.com/yanyongyu) ([#1392](https://github.com/nonebot/nonebot2/pull/1392))
- Feature: 使用 `importlib.metadata` 替换 `pkg_resources` [@A-kirami](https://github.com/A-kirami) ([#1388](https://github.com/nonebot/nonebot2/pull/1388))
- CI: 测试环境添加 Python 3.11 [@StarHeartHunt](https://github.com/StarHeartHunt) ([#1366](https://github.com/nonebot/nonebot2/pull/1366))
- Feature: 新增 dotenv 嵌套配置项支持 [@yanyongyu](https://github.com/yanyongyu) ([#1324](https://github.com/nonebot/nonebot2/pull/1324))
- Feature: 添加 State 响应器触发消息注入 [@A-kirami](https://github.com/A-kirami) ([#1315](https://github.com/nonebot/nonebot2/pull/1315))
- Remove: 移除无用的 namespace 声明 [@yanyongyu](https://github.com/yanyongyu) ([#1306](https://github.com/nonebot/nonebot2/pull/1306))
### 🐛 Bug 修复
- Fix: Bot `__getattr__` 不再对 `__xxx__` 方法返回 [@synodriver](https://github.com/synodriver) ([#1398](https://github.com/nonebot/nonebot2/pull/1398))
- Fix: 修复 run pre/post hook 没有在正确的上下文中运行 [@yanyongyu](https://github.com/yanyongyu) ([#1391](https://github.com/nonebot/nonebot2/pull/1391))
### 📝 文档
- Docs: 添加 ntchat 社区适配器 [@JustUndertaker](https://github.com/JustUndertaker) ([#1414](https://github.com/nonebot/nonebot2/pull/1414))
### 💫 杂项
- Plugin: b 站用户信息查询 [@Ikaros-521](https://github.com/Ikaros-521) ([#1410](https://github.com/nonebot/nonebot2/pull/1410))
- Plugin: 由于 Sena-nana 项目拆分,之前的插件地址更改 [@sena-nana](https://github.com/sena-nana) ([#1378](https://github.com/nonebot/nonebot2/pull/1378))
- Plugin: 更新 ayaka 插件的主页链接 [@bridgeL](https://github.com/bridgeL) ([#1346](https://github.com/nonebot/nonebot2/pull/1346))
- Plugin: 补充 novelai 插件信息 [@sena-nana](https://github.com/sena-nana) ([#1333](https://github.com/nonebot/nonebot2/pull/1333))
- Bot: 修改 Inkar Suki 描述 [@HornCopper](https://github.com/HornCopper) ([#1312](https://github.com/nonebot/nonebot2/pull/1312))
- Plugin: 修改插件 MCQQ MCRcon 主页地址 [@17TheWord](https://github.com/17TheWord) ([#1303](https://github.com/nonebot/nonebot2/pull/1303))
### 🍻 插件发布
- Plugin: 谁在窥屏 [@yanyongyu](https://github.com/yanyongyu) ([#1416](https://github.com/nonebot/nonebot2/pull/1416))
- Plugin: 免费版 NovelAI 生图插件 [@yanyongyu](https://github.com/yanyongyu) ([#1408](https://github.com/nonebot/nonebot2/pull/1408))
- Plugin: sky 光遇 [@yanyongyu](https://github.com/yanyongyu) ([#1394](https://github.com/nonebot/nonebot2/pull/1394))
- Plugin: Colab-NovelAI [@yanyongyu](https://github.com/yanyongyu) ([#1390](https://github.com/nonebot/nonebot2/pull/1390))
- Plugin: b 站用户直播号、粉丝、舰团数查询 [@yanyongyu](https://github.com/yanyongyu) ([#1385](https://github.com/nonebot/nonebot2/pull/1385))
- Plugin: 投胎模拟器 [@yanyongyu](https://github.com/yanyongyu) ([#1382](https://github.com/nonebot/nonebot2/pull/1382))
- Plugin: Apex API Query [@yanyongyu](https://github.com/yanyongyu) ([#1375](https://github.com/nonebot/nonebot2/pull/1375))
- Plugin: 随个人 [@yanyongyu](https://github.com/yanyongyu) ([#1373](https://github.com/nonebot/nonebot2/pull/1373))
- Plugin: 动漫资源获取 [@yanyongyu](https://github.com/yanyongyu) ([#1371](https://github.com/nonebot/nonebot2/pull/1371))
- Plugin: 日麻小工具 [@yanyongyu](https://github.com/yanyongyu) ([#1365](https://github.com/nonebot/nonebot2/pull/1365))
- Plugin: 图像超分辨率增强 [@yanyongyu](https://github.com/yanyongyu) ([#1362](https://github.com/nonebot/nonebot2/pull/1362))
- Plugin: 二次元化图像 [@yanyongyu](https://github.com/yanyongyu) ([#1360](https://github.com/nonebot/nonebot2/pull/1360))
- Plugin: 日麻寄分器 [@yanyongyu](https://github.com/yanyongyu) ([#1357](https://github.com/nonebot/nonebot2/pull/1357))
- Plugin: 文本生成器 [@yanyongyu](https://github.com/yanyongyu) ([#1355](https://github.com/nonebot/nonebot2/pull/1355))
- Plugin: 反嘴臭插件 [@yanyongyu](https://github.com/yanyongyu) ([#1350](https://github.com/nonebot/nonebot2/pull/1350))
- Plugin: 用户\&群聊黑名单 [@yanyongyu](https://github.com/yanyongyu) ([#1348](https://github.com/nonebot/nonebot2/pull/1348))
- Plugin: NoneBot SQLAlchemy 封装 [@yanyongyu](https://github.com/yanyongyu) ([#1345](https://github.com/nonebot/nonebot2/pull/1345))
- Plugin: 通用抽图/语音 [@yanyongyu](https://github.com/yanyongyu) ([#1341](https://github.com/nonebot/nonebot2/pull/1341))
- Plugin: kfcrazy [@yanyongyu](https://github.com/yanyongyu) ([#1339](https://github.com/nonebot/nonebot2/pull/1339))
- Plugin: 二次元图像鉴赏 [@yanyongyu](https://github.com/yanyongyu) ([#1337](https://github.com/nonebot/nonebot2/pull/1337))
- Plugin: ayaka 衍生插件 - 坏词撤回 [@yanyongyu](https://github.com/yanyongyu) ([#1335](https://github.com/nonebot/nonebot2/pull/1335))
- Plugin: ayaka 衍生插件 - 时区助手 [@yanyongyu](https://github.com/yanyongyu) ([#1332](https://github.com/nonebot/nonebot2/pull/1332))
- Plugin: ayaka 衍生插件 - 谁是卧底 [@yanyongyu](https://github.com/yanyongyu) ([#1330](https://github.com/nonebot/nonebot2/pull/1330))
- Plugin: ayaka 衍生插件 - 小游戏合集 [@yanyongyu](https://github.com/yanyongyu) ([#1328](https://github.com/nonebot/nonebot2/pull/1328))
- Plugin: bnhhsh -「不能好好说话!」 [@yanyongyu](https://github.com/yanyongyu) ([#1326](https://github.com/nonebot/nonebot2/pull/1326))
- Plugin: AI 绘图 [@yanyongyu](https://github.com/yanyongyu) ([#1323](https://github.com/nonebot/nonebot2/pull/1323))
- Plugin: novelai [@yanyongyu](https://github.com/yanyongyu) ([#1319](https://github.com/nonebot/nonebot2/pull/1319))
- Plugin: 游戏王小程序查价 [@yanyongyu](https://github.com/yanyongyu) ([#1317](https://github.com/nonebot/nonebot2/pull/1317))
- Plugin: 监测群事件 [@yanyongyu](https://github.com/yanyongyu) ([#1320](https://github.com/nonebot/nonebot2/pull/1320))
- Plugin: 轮盘禁言小游戏 [@yanyongyu](https://github.com/yanyongyu) ([#1311](https://github.com/nonebot/nonebot2/pull/1311))
- Plugin: 真白萌自动签到 [@yanyongyu](https://github.com/yanyongyu) ([#1308](https://github.com/nonebot/nonebot2/pull/1308))
- Plugin: BiliRequestAll [@yanyongyu](https://github.com/yanyongyu) ([#1302](https://github.com/nonebot/nonebot2/pull/1302))
- Plugin: 监听者 [@yanyongyu](https://github.com/yanyongyu) ([#1299](https://github.com/nonebot/nonebot2/pull/1299))
### 🍻 机器人发布
- Bot: Bread Dog Bot [@yanyongyu](https://github.com/yanyongyu) ([#1380](https://github.com/nonebot/nonebot2/pull/1380))
- Bot: hsbot [@yanyongyu](https://github.com/yanyongyu) ([#1369](https://github.com/nonebot/nonebot2/pull/1369))
### 🍻 适配器发布
- Adapter: Ntchat [@yanyongyu](https://github.com/yanyongyu) ([#1314](https://github.com/nonebot/nonebot2/pull/1314))
## v2.0.0-rc.1
### 💥 破坏性变更

View File

@@ -98,5 +98,20 @@
"homepage": "https://github.com/nonebot/adapter-github",
"tags": [],
"is_official": true
},
{
"module_name": "nonebot.adapters.ntchat",
"project_link": "nonebot-adapter-ntchat",
"name": "Ntchat",
"desc": "pc hook的微信客户端适配",
"author": "JustUndertaker",
"homepage": "https://github.com/JustUndertaker/adapter-ntchat",
"tags": [
{
"label": "微信",
"color": "#ea5252"
}
],
"is_official": false
}
]
]

View File

@@ -123,7 +123,7 @@
},
{
"name": "Inkar Suki",
"desc": "一个十分方便的Bot支持包括Webhook、群管、互动等一系列功能",
"desc": "一个十分方便的Bot支持包括Webhook、群管、剑网3等一系列功能,持续更新中……",
"author": "HornCopper",
"homepage": "https://github.com/HornCopper/Inkar-Suki",
"tags": [
@@ -136,8 +136,8 @@
"color": "#374fd0"
},
{
"label": "群管",
"color": "#4ede39"
"label": "剑网3",
"color": "#ff0033"
}
],
"is_official": false
@@ -276,5 +276,39 @@
}
],
"is_official": false
},
{
"name": "hsbot",
"desc": "服务于《炉石传说》玩家的机器人,上线至今已有加入十余个个炉石相关群聊,上千名用户使用,响应请求数万次。 数据使用HSreplay, Fbigame, Hearthstone API",
"author": "gzy02",
"homepage": "https://github.com/gzy02/hsbot",
"tags": [
{
"label": "炉石传说",
"color": "#526fea"
}
],
"is_official": false
},
{
"name": "Bread Dog Bot",
"desc": "Terraria TShock QQ 机器人",
"author": "Qianyiovo",
"homepage": "https://github.com/Qianyiovo/bread_dog_bot",
"tags": [
{
"label": "TShock",
"color": "#ea5252"
},
{
"label": "泰拉瑞亚",
"color": "#5dea52"
},
{
"label": "Terraria",
"color": "#5dea52"
}
],
"is_official": false
}
]
]

View File

@@ -2426,10 +2426,10 @@
"name": "MagiaDice骰娘及TRPGLOG",
"desc": "能够实时在网页围观的TRPG记录插件同时具有骰娘的功能",
"author": "sena-nana",
"homepage": "https://github.com/sena-nana/MutsukiBot/tree/main/nonebot-plugin-magiadice",
"homepage": "https://github.com/sena-nana/nonebot-plugin-magiadice",
"tags": [
{
"label": "TRPG",
"label": "t:TRPG",
"color": "#ea5252"
}
],
@@ -2439,20 +2439,20 @@
"module_name": "nonebot-plugin-send",
"project_link": "nonebot-plugin-send",
"name": "反馈及通知",
"desc": "用户通过bot向superuser发送反馈以及bot向群发送通知",
"desc": "用户通过bot向superuser发送反馈以及bot向所有群发送通知",
"author": "sena-nana",
"homepage": "https://github.com/sena-nana/MutsukiBot/tree/main/nonebot-plugin-send",
"homepage": "https://github.com/sena-nana/nonebot-plugin-send",
"tags": [
{
"label": "send",
"label": "t:send",
"color": "#ea5252"
},
{
"label": "notice",
"label": "t:notice",
"color": "#ea5252"
},
{
"label": "公告",
"label": "t:公告",
"color": "#ea5252"
}
],
@@ -2464,10 +2464,10 @@
"name": "雨课堂自动签到",
"desc": "使用playwright模拟浏览器签到雨课堂并将腾讯会议号发送给superuser",
"author": "sena-nana",
"homepage": "https://github.com/sena-nana/MutsukiBot/tree/main/nonebot-plugin-ykt",
"homepage": "https://github.com/sena-nana/nonebot-plugin-ykt",
"tags": [
{
"label": "playwright",
"label": "t:playwright",
"color": "#ea5252"
}
],
@@ -2553,7 +2553,7 @@
"name": "MC_QQ_MCRcon",
"desc": "基于NoneBot的QQ群聊与Minecraft Server消息互通插件",
"author": "17TheWord",
"homepage": "https://github.com/17TheWord/nonebot-plugin-mcqq/tree/mcqq_mcrcon",
"homepage": "https://github.com/17TheWord/nonebot-plugin-mcqq",
"tags": [
{
"label": "Minecraft",
@@ -2697,7 +2697,7 @@
"name": "ayaka - 文字游戏开发辅助插件",
"desc": "提供了状态机、命令隔离、缓存、固存、帮助指令等功能可以管理多个文字游戏避免命令冲突帮助开发者在nonebot2框架基础上快速开发qq文字游戏",
"author": "bridgeL",
"homepage": "https://github.com/bridgeL/nonebot-plugin-ayaka",
"homepage": "https://bridgel.github.io/ayaka_doc/",
"tags": [
{
"label": "a:cqhttp",
@@ -2877,5 +2877,532 @@
}
],
"is_official": false
},
{
"module_name": "nonebot_plugin_listener",
"project_link": "nonebot-plugin-listener",
"name": "监听者",
"desc": "监听指定消息并转发到指定群",
"author": "AbCooly",
"homepage": "https://github.com/AbCooly/nonebot_plugin_listener",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_BiliRequestAll",
"project_link": "nonebot-plugin-BiliRequestAll",
"name": "BiliRequestAll",
"desc": "通过B站UID审核入群",
"author": "Shadow403",
"homepage": "https://github.com/Shadow403/nonebot_plugin_BiliRequestAll",
"tags": [
{
"label": "bilibili",
"color": "#ea52e9"
},
{
"label": "request",
"color": "#5eea52"
}
],
"is_official": false
},
{
"module_name": "nonebot-plugin-masiro",
"project_link": "nonebot-plugin-masiro",
"name": "真白萌自动签到",
"desc": "帮你每天在真白萌签到,助力成为二次元婆罗门!",
"author": "Ankhyty",
"homepage": "https://github.com/Ankhyty/nonebot-plugin-masiro",
"tags": [
{
"label": "t:漫研",
"color": "#1435e4"
}
],
"is_official": false
},
{
"module_name": "nonebot_plugin_russian_ban",
"project_link": "nonebot-plugin-russian-ban",
"name": "轮盘禁言小游戏",
"desc": "轮盘禁言小游戏,附送快捷禁言/解禁",
"author": "KarisAya",
"homepage": "https://github.com/KarisAya/nonebot_plugin_russian_ban",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_monitor",
"project_link": "nonebot-plugin-monitor",
"name": "监测群事件",
"desc": "监测群成员变动、文件上传、红包运气王、管理员变动等等...",
"author": "cjladmin",
"homepage": "https://github.com/cjladmin/nonebot_plugin_monitor",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_ygo_trade",
"project_link": "nonebot-plugin-ygo-trade",
"name": "游戏王小程序查价",
"desc": "集换社游戏王的卡价查询",
"author": "Kaguyaya",
"homepage": "https://github.com/Kaguyaya/nonebot_plugin_ygo_trade",
"tags": [
{
"label": "游戏王",
"color": "#ea5252"
},
{
"label": "YGO",
"color": "#ea5252"
},
{
"label": "集换社",
"color": "#eada52"
}
],
"is_official": false
},
{
"module_name": "nonebot-plugin-novelai",
"project_link": "nonebot-plugin-novelai",
"name": "novelai",
"desc": "一个支持novelai、naifu、webui支持中文功能丰富的ai绘图插件",
"author": "sena-nana",
"homepage": "https://github.com/sena-nana/nonebot-plugin-novelai",
"tags": [
{
"label": "t:aidraw",
"color": "#ffc646"
},
{
"label": "t:naifu",
"color": "#ffc646"
},
{
"label": "t:webui",
"color": "#ffc646"
}
],
"is_official": false
},
{
"module_name": "nonebot_plugin_aidraw",
"project_link": "nonebot-plugin-aidraw",
"name": "AI绘图",
"desc": "使用第三方 API 的 NovelAI 绘图插件",
"author": "A-kirami",
"homepage": "https://github.com/A-kirami/nonebot-plugin-aidraw",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_bnhhsh",
"project_link": "nonebot-plugin-bnhhsh",
"name": "bnhhsh -「不能好好说话!」",
"desc": "不对劲的拼音首字母缩写翻译工具 | 基于 RimoChan/bnhhsh",
"author": "lgc2333",
"homepage": "https://github.com/lgc2333/nonebot-plugin-bnhhsh",
"tags": [
{
"label": "a:OB V11",
"color": "#000000"
},
{
"label": "t:涩涩!",
"color": "#ffc646"
}
],
"is_official": false
},
{
"module_name": "ayaka_games",
"project_link": "nonebot-plugin-ayaka-games",
"name": "ayaka衍生插件 - 小游戏合集",
"desc": "多功能聚合基于ayaka插件实现背包、 签到 、印加宝藏、生成糊文字截图、bingo、b站视频链接分析、原神接龙、成语接龙、缩写翻译",
"author": "bridgeL",
"homepage": "https://github.com/bridgeL/nonebot-plugin-ayaka-games",
"tags": [
{
"label": "a:cqhttp",
"color": "#0c0c0c"
},
{
"label": "a:onebot",
"color": "#0c0c0c"
},
{
"label": "t:文字游戏",
"color": "#e36306"
}
],
"is_official": false
},
{
"module_name": "ayaka_who_is_suspect",
"project_link": "nonebot-plugin-ayaka-who-is-suspect",
"name": "ayaka衍生插件 - 谁是卧底",
"desc": "至少4人游玩游玩前需要加bot好友否则无法通过私聊告知关键词",
"author": "bridgeL",
"homepage": "https://github.com/bridgeL/nonebot-plugin-ayaka-who-is-suspect",
"tags": [
{
"label": "a:cqhttp",
"color": "#000000"
},
{
"label": "a:onebot",
"color": "#000000"
},
{
"label": "t:文字游戏",
"color": "#e36306"
}
],
"is_official": false
},
{
"module_name": "ayaka_timezone",
"project_link": "nonebot-plugin-ayaka-timezone",
"name": "ayaka衍生插件 - 时区助手",
"desc": "提供不同时区时间询问服务",
"author": "bridgeL",
"homepage": "https://github.com/bridgeL/nonebot-plugin-ayaka-timezone",
"tags": [
{
"label": "a:cqhttp",
"color": "#000000"
},
{
"label": "a:onebot",
"color": "#000000"
},
{
"label": "t:timezone",
"color": "#e36306"
}
],
"is_official": false
},
{
"module_name": "ayaka_prevent_bad_words",
"project_link": "nonebot-plugin-ayaka-prevent-bad-words",
"name": "ayaka衍生插件 - 坏词撤回",
"desc": "撤回有问题的发言",
"author": "bridgeL",
"homepage": "https://github.com/bridgeL/nonebot-plugin-ayaka-prevent-bad-words",
"tags": [
{
"label": "a:cqhttp",
"color": "#000000"
},
{
"label": "a:onebot",
"color": "#000000"
},
{
"label": "t:撤回",
"color": "#e36306"
}
],
"is_official": false
},
{
"module_name": "nonebot_plugin_savor",
"project_link": "nonebot-plugin-savor",
"name": "二次元图像鉴赏",
"desc": "二次元图像分析",
"author": "A-kirami",
"homepage": "https://github.com/A-kirami/nonebot-plugin-savor",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_kfcrazy",
"project_link": "nonebot-plugin-kfcrazy",
"name": "kfcrazy",
"desc": "肯德基查询插件,输入地区即可查询全国店铺的数据,支持疯狂星期四",
"author": "Kaguya233qwq",
"homepage": "https://github.com/Kaguya233qwq/nonebot_plugin_kfcrazy",
"tags": [
{
"label": "肯德基",
"color": "#d93b3b"
},
{
"label": "疯狂星期四",
"color": "#e52124"
},
{
"label": "KFC",
"color": "#cb5c5e"
}
],
"is_official": false
},
{
"module_name": "nonebot-plugin-random",
"project_link": "nonebot-plugin-random",
"name": "通用抽图/语音",
"desc": "Nonebot2 通用抽图/语音插件",
"author": "jcjrobert",
"homepage": "https://github.com/jcjrobert/nonebot-plugin-random",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_sqlalchemy",
"project_link": "nonebot-plugin-sqlalchemy",
"name": "NoneBot SQLAlchemy封装",
"desc": "提供简单的sqlalchemy封装",
"author": "ssttkkl",
"homepage": "https://github.com/ssttkkl/nonebot-plugin-sqlalchemy",
"tags": [
{
"label": "t:sql",
"color": "#ad1717"
}
],
"is_official": false
},
{
"module_name": "nonebot_plugin_blacklist",
"project_link": "nonebot-plugin-blacklist",
"name": "用户&群聊黑名单",
"desc": "另一个黑名单插件, 可批量屏蔽用户和群聊",
"author": "tkgs0",
"homepage": "https://github.com/tkgs0/nonebot-plugin-blacklist",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_antiinsult",
"project_link": "nonebot-plugin-antiinsult",
"name": "反嘴臭插件",
"desc": "检测到有用户 @机器人 并嘴臭时将其临时屏蔽(bot重启后失效), 当bot为群管理时会请对方喝昏睡红茶(禁言), 可批量增删敏感词",
"author": "tkgs0",
"homepage": "https://github.com/tkgs0/nonebot-plugin-antiinsult",
"tags": [
{
"label": "a:onebot",
"color": "#000000"
},
{
"label": "t:被动",
"color": "#ea5252"
}
],
"is_official": false
},
{
"module_name": "nonebot_plugin_oddtext",
"project_link": "nonebot-plugin-oddtext",
"name": "文本生成器",
"desc": "抽象话、火星文等多种文本生成",
"author": "MeetWq",
"homepage": "https://github.com/noneplugin/nonebot-plugin-oddtext",
"tags": [
{
"label": "t:RCNB!",
"color": "#ea5252"
}
],
"is_official": false
},
{
"module_name": "nonebot_plugin_mahjong_scoreboard",
"project_link": "nonebot-plugin-mahjong-scoreboard",
"name": "日麻寄分器",
"desc": "为群友提供日麻对局分数记录。根据马点进行PT精算统计PT增减支持对局与榜单查询与导出。",
"author": "ssttkkl",
"homepage": "https://github.com/ssttkkl/nonebot-plugin-mahjong-scoreboard",
"tags": [
{
"label": "a:onebot",
"color": "#4684d3"
},
{
"label": "t:日麻",
"color": "#4684d3"
}
],
"is_official": false
},
{
"module_name": "nonebot_plugin_cartoon",
"project_link": "nonebot-plugin-cartoon",
"name": "二次元化图像",
"desc": "对三次元图像动漫化, 打开二次元的大门",
"author": "A-kirami",
"homepage": "https://github.com/A-kirami/nonebot-plugin-cartoon",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_super_resolution",
"project_link": "nonebot-plugin-super-resolution",
"name": "图像超分辨率增强",
"desc": "动漫图像超分辨率增强",
"author": "A-kirami",
"homepage": "https://github.com/A-kirami/nonebot-plugin-super-resolution",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_mahjong_utils",
"project_link": "nonebot-plugin-mahjong-utils",
"name": "日麻小工具",
"desc": "日麻小工具插件,支持手牌分析、番符点数查询",
"author": "ssttkkl",
"homepage": "https://github.com/ssttkkl/nonebot-plugin-mahjong-utils",
"tags": [
{
"label": "t:日麻",
"color": "#edad34"
}
],
"is_official": false
},
{
"module_name": "nonebot_plugin_animeres",
"project_link": "nonebot-plugin-animeres",
"name": "动漫资源获取",
"desc": "动漫资源获取",
"author": "Melodyknit",
"homepage": "https://github.com/Melodyknit/nonebot_plugin_animeres",
"tags": [
{
"label": "a:onebot",
"color": "#ec5252"
},
{
"label": "anime",
"color": "#ec5252"
}
],
"is_official": false
},
{
"module_name": "nonebot-plugin-person",
"project_link": "nonebot-plugin-person",
"name": "随个人",
"desc": "随个群友当幸运观众🤪",
"author": "jcjrobert",
"homepage": "https://github.com/jcjrobert/nonebot-plugin-person",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_apex_api_query",
"project_link": "nonebot-plugin-apex-api-query",
"name": "Apex API Query",
"desc": "Apex Legends API 查询插件",
"author": "H-xiaoH",
"homepage": "https://github.com/H-xiaoH/nonebot-plugin-apex-api-query",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_reborn",
"project_link": "nonebot-plugin-reborn",
"name": "投胎模拟器",
"desc": "重生后你会到哪里?",
"author": "Aziteee",
"homepage": "https://github.com/Aziteee/nonebot_plugin_reborn",
"tags": [],
"is_official": false
},
{
"module_name": "nonebot_plugin_searchBiliInfo",
"project_link": "nonebot-plugin-searchBiliInfo",
"name": "b站用户信息查询",
"desc": "查询b站用户粉丝数、舰团信息主播直播收益数据总收益、礼物、SC、上舰用户观看直播信息观看、弹幕记录通过关键词搜昵称、UID等",
"author": "Ikaros-521",
"homepage": "https://github.com/Ikaros-521/nonebot_plugin_searchBiliInfo",
"tags": [
{
"label": "bilibili",
"color": "#e55d80"
}
],
"is_official": false
},
{
"module_name": "nonebot_plugin_colab_novelai",
"project_link": "nonebot-plugin-colab-novelai",
"name": "Colab-NovelAI",
"desc": "解放你的双手让Colab持续给你提供算力生产色图",
"author": "EtherLeaF",
"homepage": "https://github.com/EtherLeaF/nonebot-plugin-colab-novelai",
"tags": [
{
"label": "a:onebot",
"color": "#ea5252"
},
{
"label": "t:NovelAI",
"color": "#eacd52"
}
],
"is_official": false
},
{
"module_name": "nonebot_plugin_sky",
"project_link": "nonebot-plugin-sky",
"name": "sky光遇",
"desc": "基于NoneBot2的光遇每日攻略插件",
"author": "Kaguya233qwq",
"homepage": "https://github.com/Kaguya233qwq/nonebot_plugin_sky",
"tags": [
{
"label": "光遇",
"color": "#7ebdf0"
},
{
"label": "攻略",
"color": "#2079c1"
}
],
"is_official": false
},
{
"module_name": "nonebot_plugin_zyk_novelai",
"project_link": "nonebot-plugin-zyk-novelai",
"name": "免费版NovelAI生图插件",
"desc": "一个用于nonebot2的简约AI绘图插件。没有繁琐的使用指令配置过程简单迅捷代码简洁易懂还有更多功能将会陆续加入。",
"author": "ZYKsslm",
"homepage": "https://github.com/ZYKsslm/nonebot_plugin_zyk_novelai",
"tags": [
{
"label": "Free",
"color": "#42e22f"
},
{
"label": "Simple",
"color": "#e2d92f"
},
{
"label": "Novelai",
"color": "#3e10e9"
}
],
"is_official": false
},
{
"module_name": "nonebot_plugin_repeep",
"project_link": "nonebot-plugin-repeep",
"name": "谁在窥屏",
"desc": "用于获取QQ中当前窥屏用户信息",
"author": "p0ise",
"homepage": "https://github.com/p0ise/nonebot-plugin-repeep",
"tags": [
{
"label": "a:onebot",
"color": "#ea5252"
}
],
"is_official": false
}
]
]

View File

@@ -21,7 +21,7 @@ NoneBot 使用 [`pydantic`](https://pydantic-docs.helpmanual.io/) 以及 [`pytho
- **参数**
- `_env_file` (str | os.PathLike | NoneType)
- `_env_file` (str | os.PathLike | list[str | os.PathLike] | tuple[str | os.PathLike, ...] | NoneType)
- `_env_file_encoding` (str | None)
@@ -56,7 +56,7 @@ NoneBot 使用 [`pydantic`](https://pydantic-docs.helpmanual.io/) 以及 [`pytho
- **参数**
- `_env_file` (str | os.PathLike | NoneType)
- `_env_file` (str | os.PathLike | list[str | os.PathLike] | tuple[str | os.PathLike, ...] | NoneType)
- `_env_file_encoding` (str | None)
@@ -72,7 +72,7 @@ NoneBot 使用 [`pydantic`](https://pydantic-docs.helpmanual.io/) 以及 [`pytho
- `log_level` (int | str)
- `api_timeout` (float)
- `api_timeout` (float | None)
- `superusers` (set[str])

View File

@@ -96,3 +96,27 @@ description: nonebot.consts 模块
- **类型:** Literal['_matched_dict']
- **说明:** 正则匹配 group 字典存储 key
## _var_ `STARTSWITH_KEY` {#STARTSWITH_KEY}
- **类型:** Literal['_startswith']
- **说明:** 响应触发前缀 key
## _var_ `ENDSWITH_KEY` {#ENDSWITH_KEY}
- **类型:** Literal['_endswith']
- **说明:** 响应触发后缀 key
## _var_ `FULLMATCH_KEY` {#FULLMATCH_KEY}
- **类型:** Literal['_fullmatch']
- **说明:** 响应触发完整消息 key
## _var_ `KEYWORD_KEY` {#KEYWORD_KEY}
- **类型:** Literal['_keyword']
- **说明:** 响应触发关键字 key

View File

@@ -19,7 +19,7 @@ description: nonebot.drivers.fastapi 模块
- **参数**
- `_env_file` (str | os.PathLike | NoneType)
- `_env_file` (str | os.PathLike | list[str | os.PathLike] | tuple[str | os.PathLike, ...] | NoneType)
- `_env_file_encoding` (str | None)
@@ -27,23 +27,23 @@ description: nonebot.drivers.fastapi 模块
- `_secrets_dir` (str | os.PathLike | NoneType)
- `fastapi_openapi_url` (str)
- `fastapi_openapi_url` (str | None)
- `fastapi_docs_url` (str)
- `fastapi_docs_url` (str | None)
- `fastapi_redoc_url` (str)
- `fastapi_redoc_url` (str | None)
- `fastapi_include_adapter_schema` (bool)
- `fastapi_reload` (bool)
- `fastapi_reload_dirs` (list[str])
- `fastapi_reload_dirs` (list[str] | None)
- `fastapi_reload_delay` (float)
- `fastapi_reload_includes` (list[str])
- `fastapi_reload_includes` (list[str] | None)
- `fastapi_reload_excludes` (list[str])
- `fastapi_reload_excludes` (list[str] | None)
### _class-var_ `fastapi_openapi_url` {#Config-fastapi_openapi_url}

View File

@@ -25,7 +25,7 @@ pip install nonebot2[quart]
- **参数**
- `_env_file` (str | os.PathLike | NoneType)
- `_env_file` (str | os.PathLike | list[str | os.PathLike] | tuple[str | os.PathLike, ...] | NoneType)
- `_env_file_encoding` (str | None)
@@ -35,13 +35,13 @@ pip install nonebot2[quart]
- `quart_reload` (bool)
- `quart_reload_dirs` (list[str])
- `quart_reload_dirs` (list[str] | None)
- `quart_reload_delay` (float)
- `quart_reload_includes` (list[str])
- `quart_reload_includes` (list[str] | None)
- `quart_reload_excludes` (list[str])
- `quart_reload_excludes` (list[str] | None)
### _class-var_ `quart_reload` {#Config-quart_reload}

View File

@@ -170,7 +170,7 @@ description: nonebot 模块
- **参数**
- `_env_file` (str | None): 配置文件名,默认从 `.env.{env_name}` 中读取配置
- `_env_file` (str | os.PathLike | list[str | os.PathLike] | tuple[str | os.PathLike, ...] | NoneType): 配置文件名,默认从 `.env.{env_name}` 中读取配置
- `**kwargs` (Any): 任意变量,将会存储到 {ref}`nonebot.drivers.Driver.config` 对象里

View File

@@ -67,6 +67,18 @@ description: nonebot.matcher 模块
- bool: 是否满足匹配规则
### _method_ `ensure_context(self, bot, event)` {#Matcher-ensure_context}
- **参数**
- `bot` (nonebot.internal.adapter.bot.Bot)
- `event` (nonebot.internal.adapter.event.Event)
- **返回**
- Unknown
### _async classmethod_ `finish(cls, message=None, **kwargs)` {#Matcher-finish}
- **说明**
@@ -479,3 +491,115 @@ description: nonebot.matcher 模块
- **返回**
- str
## _class_ `MatcherManager()` {#MatcherManager}
- **说明**
事件响应器管理器
实现了常用字典操作,用于管理事件响应器。
### _method_ `clear(self)` {#MatcherManager-clear}
- **返回**
- None
### _method_ `get(self, key, default=None)` {#MatcherManager-get}
- **参数**
- `key` (int)
- `default` ((~ T) | None)
- **返回**
- list[Type[Matcher]] | (~ T) | NoneType
### _method_ `items(self)` {#MatcherManager-items}
- **返回**
- ItemsView[int, list[Type[Matcher]]]
### _method_ `keys(self)` {#MatcherManager-keys}
- **返回**
- KeysView[int]
### _method_ `pop(self, key)` {#MatcherManager-pop}
- **参数**
- `key` (int)
- **返回**
- list[Type[Matcher]]
### _method_ `popitem(self)` {#MatcherManager-popitem}
- **返回**
- tuple[int, list[Type[Matcher]]]
### _method_ `set_provider(self, provider_class)` {#MatcherManager-set_provider}
- **说明**
设置事件响应器存储器
- **参数**
- `provider_class` (Type[nonebot.internal.matcher.provider.MatcherProvider]): 事件响应器存储器类
- **返回**
- None
### _method_ `setdefault(self, key, default)` {#MatcherManager-setdefault}
- **参数**
- `key` (int)
- `default` (list[Type[Matcher]])
- **返回**
- list[Type[Matcher]]
### _method_ `update(self, _MatcherManager__m)` {#MatcherManager-update}
- **参数**
- `_MatcherManager__m` (MutableMapping[int, list[Type[Matcher]]])
- **返回**
- None
### _method_ `values(self)` {#MatcherManager-values}
- **返回**
- ValuesView[list[Type[Matcher]]]
## _abstract class_ `MatcherProvider(matchers)` {#MatcherProvider}
- **说明**
事件响应器存储器基类
- **参数**
- `matchers` (Mapping[int, list[Type[Matcher]]]): 当前存储器中已有的事件响应器
## _class_ `DEFAULT_PROVIDER_CLASS(matchers)` {#DEFAULT_PROVIDER_CLASS}
- **参数**
- `matchers` (Mapping[int, list[Type[Matcher]]])

View File

@@ -307,6 +307,46 @@ description: nonebot.params 模块
- dict[str, Any]
## _def_ `Startswith()` {#Startswith}
- **说明**
响应触发前缀
- **返回**
- str
## _def_ `Endswith()` {#Endswith}
- **说明**
响应触发后缀
- **返回**
- str
## _def_ `Fullmatch()` {#Fullmatch}
- **说明**
响应触发完整消息
- **返回**
- str
## _def_ `Keyword()` {#Keyword}
- **说明**
响应触发关键字
- **返回**
- str
## _def_ `Received(id=None, default=None)` {#Received}
- **说明**

View File

@@ -35,7 +35,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
## _def_ `on_metaevent(rule=..., *, handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#on_metaevent}
@@ -61,7 +61,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
## _def_ `on_message(rule=..., permission=..., *, handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#on_message}
@@ -89,7 +89,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
## _def_ `on_notice(rule=..., *, handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#on_notice}
@@ -115,7 +115,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
## _def_ `on_request(rule=..., *, handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#on_request}
@@ -141,7 +141,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
## _def_ `on_startswith(msg, rule=..., ignorecase=..., *, permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#on_startswith}
@@ -173,7 +173,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
## _def_ `on_endswith(msg, rule=..., ignorecase=..., *, permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#on_endswith}
@@ -205,7 +205,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
## _def_ `on_fullmatch(msg, rule=..., ignorecase=..., *, permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#on_fullmatch}
@@ -237,7 +237,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
## _def_ `on_keyword(keywords, rule=..., *, permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#on_keyword}
@@ -267,7 +267,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
## _def_ `on_command(cmd, rule=..., aliases=..., *, permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#on_command}
@@ -301,7 +301,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
## _def_ `on_shell_command(cmd, rule=..., aliases=..., parser=..., *, permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#on_shell_command}
@@ -339,7 +339,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
## _def_ `on_regex(pattern, flags=..., rule=..., *, permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#on_regex}
@@ -373,7 +373,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
## _def_ `on_type(types, rule=..., *, permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#on_type}
@@ -403,7 +403,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
## _class_ `CommandGroup(cmd, *, rule=..., permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#CommandGroup}
@@ -457,7 +457,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
### _method_ `shell_command(self, cmd, *, rule=..., aliases=..., parser=..., permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#CommandGroup-shell_command}
@@ -491,7 +491,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
## _class_ `MatcherGroup(*, type=..., rule=..., permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#MatcherGroup}
@@ -543,7 +543,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
### _method_ `on_command(self, cmd, aliases=..., *, rule=..., permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#MatcherGroup-on_command}
@@ -577,7 +577,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
### _method_ `on_endswith(self, msg, *, ignorecase=..., rule=..., permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#MatcherGroup-on_endswith}
@@ -609,7 +609,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
### _method_ `on_fullmatch(self, msg, *, ignorecase=..., rule=..., permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#MatcherGroup-on_fullmatch}
@@ -641,7 +641,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
### _method_ `on_keyword(self, keywords, *, rule=..., permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#MatcherGroup-on_keyword}
@@ -671,7 +671,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
### _method_ `on_message(self, *, rule=..., permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#MatcherGroup-on_message}
@@ -699,7 +699,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
### _method_ `on_metaevent(self, *, rule=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#MatcherGroup-on_metaevent}
@@ -725,7 +725,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
### _method_ `on_notice(self, *, rule=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#MatcherGroup-on_notice}
@@ -751,7 +751,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
### _method_ `on_regex(self, pattern, flags=..., *, rule=..., permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#MatcherGroup-on_regex}
@@ -785,7 +785,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
### _method_ `on_request(self, *, rule=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#MatcherGroup-on_request}
@@ -811,7 +811,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
### _method_ `on_shell_command(self, cmd, aliases=..., parser=..., *, rule=..., permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#MatcherGroup-on_shell_command}
@@ -849,7 +849,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
### _method_ `on_startswith(self, msg, *, ignorecase=..., rule=..., permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#MatcherGroup-on_startswith}
@@ -881,7 +881,7 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]
### _method_ `on_type(self, types, *, rule=..., permission=..., handlers=..., temp=..., expire_time=..., priority=..., block=..., state=...)` {#MatcherGroup-on_type}
@@ -911,4 +911,4 @@ description: nonebot.plugin.on 模块
- **返回**
- Type[nonebot.internal.matcher.Matcher]
- Type[nonebot.internal.matcher.matcher.Matcher]

View File

@@ -65,7 +65,7 @@ description: nonebot.plugin.plugin 模块
- `manager` (PluginManager)
- `matcher` (set[Type[nonebot.internal.matcher.Matcher]])
- `matcher` (set[Type[nonebot.internal.matcher.matcher.Matcher]])
- `parent_plugin` (Plugin | None)
@@ -105,7 +105,7 @@ description: nonebot.plugin.plugin 模块
### _instance-var_ `matcher` {#Plugin-matcher}
- **类型:** set[Type[nonebot.internal.matcher.Matcher]]
- **类型:** set[Type[nonebot.internal.matcher.matcher.Matcher]]
- **说明:** 插件内定义的 `Matcher`

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