diff --git a/.github/workflows/api_docs.yml b/.github/workflows/api_docs.yml
index ac01aa18..f4ee792b 100644
--- a/.github/workflows/api_docs.yml
+++ b/.github/workflows/api_docs.yml
@@ -1,7 +1,7 @@
name: Build API Doc
on:
- pull_request:
+ pull_request_target:
types: [ opened, synchronize, reopened ]
jobs:
@@ -12,6 +12,7 @@ jobs:
- uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
+ token: ${{ secrets.GH_TOKEN }}
- name: Set up Python
uses: actions/setup-python@v2
diff --git a/docs/.vuepress/components/Plugins.vue b/docs/.vuepress/components/Plugins.vue
new file mode 100644
index 00000000..a36b9d39
--- /dev/null
+++ b/docs/.vuepress/components/Plugins.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+ {{ plugin.name }}
+ {{ plugin.desc }}
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js
index 2713db96..f2656b4d 100644
--- a/docs/.vuepress/config.js
+++ b/docs/.vuepress/config.js
@@ -13,7 +13,8 @@ module.exports = context => ({
*/
head: [
["link", { rel: "icon", href: "/logo.png" }],
- ["meta", { name: "theme-color", content: "#d32f2f" }],
+ ["link", { rel: "manifest", href: "/manifest.json" }],
+ ["meta", { name: "theme-color", content: "#ea5252" }],
["meta", { name: "application-name", content: "NoneBot" }],
["meta", { name: "apple-mobile-web-app-title", content: "NoneBot" }],
["meta", { name: "apple-mobile-web-app-capable", content: "yes" }],
@@ -21,6 +22,26 @@ module.exports = context => ({
"meta",
{ name: "apple-mobile-web-app-status-bar-style", content: "black" }
],
+ [
+ "link",
+ { rel: "apple-touch-icon", href: "/icons/apple-touch-icon-180x180.png" }
+ ],
+ [
+ "link",
+ {
+ rel: "mask-icon",
+ href: "/icons/safari-pinned-tab.svg",
+ color: "#ea5252"
+ }
+ ],
+ [
+ "meta",
+ {
+ name: "msapplication-TileImage",
+ content: "/icons/mstile-150x150.png"
+ }
+ ],
+ ["meta", { name: "msapplication-TileColor", content: "#ea5252" }],
[
"link",
{
@@ -58,7 +79,8 @@ module.exports = context => ({
nav: [
{ text: "主页", link: "/" },
{ text: "指南", link: "/guide/" },
- { text: "API", link: "/api/" }
+ { text: "API", link: "/api/" },
+ { text: "插件广场", link: "/plugin-store" }
],
sidebarDepth: 2,
sidebar: {
@@ -155,6 +177,16 @@ module.exports = context => ({
plugins: [
"@vuepress/plugin-back-to-top",
"@vuepress/plugin-medium-zoom",
+ [
+ "@vuepress/pwa",
+ {
+ serviceWorker: true,
+ updatePopup: {
+ message: "发现新内容",
+ buttonText: "刷新"
+ }
+ }
+ ],
[
"versioning",
{
diff --git a/docs/.vuepress/public/icons/android-chrome-192x192.png b/docs/.vuepress/public/icons/android-chrome-192x192.png
new file mode 100644
index 00000000..a6d35412
Binary files /dev/null and b/docs/.vuepress/public/icons/android-chrome-192x192.png differ
diff --git a/docs/.vuepress/public/icons/android-chrome-384x384.png b/docs/.vuepress/public/icons/android-chrome-384x384.png
new file mode 100644
index 00000000..9d2db03b
Binary files /dev/null and b/docs/.vuepress/public/icons/android-chrome-384x384.png differ
diff --git a/docs/.vuepress/public/icons/apple-touch-icon-180x180.png b/docs/.vuepress/public/icons/apple-touch-icon-180x180.png
new file mode 100644
index 00000000..38b5ff25
Binary files /dev/null and b/docs/.vuepress/public/icons/apple-touch-icon-180x180.png differ
diff --git a/docs/.vuepress/public/icons/favicon-16x16.png b/docs/.vuepress/public/icons/favicon-16x16.png
new file mode 100644
index 00000000..271aca91
Binary files /dev/null and b/docs/.vuepress/public/icons/favicon-16x16.png differ
diff --git a/docs/.vuepress/public/icons/favicon-32x32.png b/docs/.vuepress/public/icons/favicon-32x32.png
new file mode 100644
index 00000000..e7e967a4
Binary files /dev/null and b/docs/.vuepress/public/icons/favicon-32x32.png differ
diff --git a/docs/.vuepress/public/icons/favicon.ico b/docs/.vuepress/public/icons/favicon.ico
new file mode 100644
index 00000000..b7fdcade
Binary files /dev/null and b/docs/.vuepress/public/icons/favicon.ico differ
diff --git a/docs/.vuepress/public/icons/mstile-150x150.png b/docs/.vuepress/public/icons/mstile-150x150.png
new file mode 100644
index 00000000..62563e36
Binary files /dev/null and b/docs/.vuepress/public/icons/mstile-150x150.png differ
diff --git a/docs/.vuepress/public/icons/safari-pinned-tab.svg b/docs/.vuepress/public/icons/safari-pinned-tab.svg
new file mode 100644
index 00000000..14efdabd
--- /dev/null
+++ b/docs/.vuepress/public/icons/safari-pinned-tab.svg
@@ -0,0 +1,29 @@
+
+
+
diff --git a/docs/.vuepress/public/manifest.json b/docs/.vuepress/public/manifest.json
new file mode 100644
index 00000000..dcb62739
--- /dev/null
+++ b/docs/.vuepress/public/manifest.json
@@ -0,0 +1,20 @@
+{
+ "name": "NoneBot",
+ "short_name": "NoneBot",
+ "background-color": "#ffffff",
+ "theme-color": "#ea5252",
+ "description": "An asynchronous python bot framework.",
+ "display": "standalone",
+ "icons": [
+ {
+ "src": "/icons/android-chrome-192x192.png",
+ "sizes": "192x192",
+ "type": "image/png"
+ },
+ {
+ "src": "/icons/android-chrome-384x384.png",
+ "sizes": "384x384",
+ "type": "image/png"
+ }
+ ]
+}
diff --git a/docs/.vuepress/public/plugins.json b/docs/.vuepress/public/plugins.json
new file mode 100644
index 00000000..b92dde26
--- /dev/null
+++ b/docs/.vuepress/public/plugins.json
@@ -0,0 +1,26 @@
+[
+ {
+ "name": "nonebot-plugin-status",
+ "desc": "通过戳一戳获取服务器状态",
+ "author": "nonebot",
+ "repo": "nonebot/nonebot2"
+ },
+ {
+ "name": "nonebot-plugin-status",
+ "desc": "通过戳一戳获取服务器状态",
+ "author": "nonebot",
+ "repo": "nonebot/nonebot2"
+ },
+ {
+ "name": "nonebot-plugin-status",
+ "desc": "通过戳一戳获取服务器状态",
+ "author": "nonebot",
+ "repo": "nonebot/nonebot2"
+ },
+ {
+ "name": "nonebot-plugin-status",
+ "desc": "通过戳一戳获取服务器状态",
+ "author": "nonebot",
+ "repo": "nonebot/nonebot2"
+ }
+]
diff --git a/docs/api/plugin.md b/docs/api/plugin.md
index 6ec390e3..7aeeabc9 100644
--- a/docs/api/plugin.md
+++ b/docs/api/plugin.md
@@ -394,9 +394,6 @@ sidebarDepth: 0
* `Type[Matcher]`
- * `MatcherGroup`
-
-
## `on_regex(pattern, flags=0, rule=None, **kwargs)`
@@ -510,9 +507,6 @@ sidebarDepth: 0
* `Type[Matcher]`
- * `MatcherGroup`
-
-
## `load_plugin(module_path)`
diff --git a/docs/api/rule.md b/docs/api/rule.md
index d3eac6ad..9142ce2e 100644
--- a/docs/api/rule.md
+++ b/docs/api/rule.md
@@ -139,19 +139,21 @@ Rule(async_function, run_sync(sync_function))
-## `command(command)`
+## `command(*cmds)`
* **说明**
命令形式匹配,根据配置里提供的 `command_start`, `command_sep` 判断消息是否为命令。
+ 可以通过 `state["_prefix"]["command"]` 获取匹配成功的命令(例:`("test",)`),通过 `state["_prefix"]["raw_command"]` 获取匹配成功的原始命令文本(例:`"/test"`)。
+
* **参数**
- * `command: Tuples[str, ...]`: 命令内容
+ * `*cmds: Union[str, Tuple[str, ...]]`: 命令内容
diff --git a/docs/guide/getting-started.md b/docs/guide/getting-started.md
index d52a9396..9c358ead 100644
--- a/docs/guide/getting-started.md
+++ b/docs/guide/getting-started.md
@@ -136,11 +136,11 @@ QQ 协议端举例:
现在,尝试向你的 QQ 机器人账号发送如下内容:
```default
-/say 你好,世界
+/echo 你好,世界
```
到这里如果一切 OK,你应该会收到机器人给你回复了 `你好,世界`。这一历史性的对话标志着你已经成功地运行了一个 NoneBot 的最小实例,开始了编写更强大的 QQ 机器人的创意之旅!
-
+
diff --git a/nonebot/__init__.py b/nonebot/__init__.py
index cbf14115..9e25268f 100644
--- a/nonebot/__init__.py
+++ b/nonebot/__init__.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
"""
快捷导入
========
diff --git a/nonebot/adapters/__init__.py b/nonebot/adapters/__init__.py
index ba9b712b..b7abd955 100644
--- a/nonebot/adapters/__init__.py
+++ b/nonebot/adapters/__init__.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
"""
协议适配基类
============
diff --git a/nonebot/adapters/cqhttp.py b/nonebot/adapters/cqhttp.py
index 33aee948..0f214e36 100644
--- a/nonebot/adapters/cqhttp.py
+++ b/nonebot/adapters/cqhttp.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
"""
CQHTTP (OneBot) v11 协议适配
============================
diff --git a/nonebot/config.py b/nonebot/config.py
index 70b8e3cb..252b39ad 100644
--- a/nonebot/config.py
+++ b/nonebot/config.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
"""
配置
====
diff --git a/nonebot/drivers/__init__.py b/nonebot/drivers/__init__.py
index 5100e130..09c182fe 100644
--- a/nonebot/drivers/__init__.py
+++ b/nonebot/drivers/__init__.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
"""
后端驱动适配基类
===============
diff --git a/nonebot/drivers/fastapi.py b/nonebot/drivers/fastapi.py
index e15beb26..bb0009b4 100644
--- a/nonebot/drivers/fastapi.py
+++ b/nonebot/drivers/fastapi.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
"""
FastAPI 驱动适配
================
@@ -32,7 +30,7 @@ def get_auth_bearer(access_token: Optional[str] = Header(
if not access_token:
return None
scheme, _, param = access_token.partition(" ")
- if scheme.lower() != "bearer":
+ if scheme.lower() not in ["bearer", "token"]:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,
detail="Not authenticated",
headers={"WWW-Authenticate": "Bearer"})
diff --git a/nonebot/exception.py b/nonebot/exception.py
index e129bd01..45062635 100644
--- a/nonebot/exception.py
+++ b/nonebot/exception.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
"""
异常
====
diff --git a/nonebot/log.py b/nonebot/log.py
index f088fc98..854b4b78 100644
--- a/nonebot/log.py
+++ b/nonebot/log.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
"""
日志
====
diff --git a/nonebot/matcher.py b/nonebot/matcher.py
index f0fe78f9..f4f67245 100644
--- a/nonebot/matcher.py
+++ b/nonebot/matcher.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
"""
事件响应器
==========
@@ -496,6 +494,7 @@ class MatcherGroup:
return matcher
def args_parser(self, func: ArgsParser) -> ArgsParser:
+ self._default_parser = func
for matcher in self.matchers:
matcher.args_parser(func)
return func
@@ -571,37 +570,38 @@ class MatcherGroup:
return _decorator
- async def send(self, message: Union[str, Message, MessageSegment]):
+ async def send(self, message: Union[str, Message, MessageSegment],
+ **kwargs):
bot = current_bot.get()
event = current_event.get()
- await bot.send(event=event, message=message)
+ await bot.send(event=event, message=message, **kwargs)
- async def finish(
- self,
- message: Optional[Union[str, Message,
- MessageSegment]] = None) -> NoReturn:
+ async def finish(self,
+ message: Optional[Union[str, Message,
+ MessageSegment]] = None,
+ **kwargs) -> NoReturn:
bot = current_bot.get()
event = current_event.get()
if message:
- await bot.send(event=event, message=message)
+ await bot.send(event=event, message=message, **kwargs)
raise FinishedException
- async def pause(
- self,
- prompt: Optional[Union[str, Message,
- MessageSegment]] = None) -> NoReturn:
+ async def pause(self,
+ prompt: Optional[Union[str, Message,
+ MessageSegment]] = None,
+ **kwargs) -> NoReturn:
bot = current_bot.get()
event = current_event.get()
if prompt:
- await bot.send(event=event, message=prompt)
+ await bot.send(event=event, message=prompt, **kwargs)
raise PausedException
- async def reject(
- self,
- prompt: Optional[Union[str, Message,
- MessageSegment]] = None) -> NoReturn:
+ async def reject(self,
+ prompt: Optional[Union[str, Message,
+ MessageSegment]] = None,
+ **kwargs) -> NoReturn:
bot = current_bot.get()
event = current_event.get()
if prompt:
- await bot.send(event=event, message=prompt)
+ await bot.send(event=event, message=prompt, **kwargs)
raise RejectedException
diff --git a/nonebot/message.py b/nonebot/message.py
index 9374d46a..d9e61c63 100644
--- a/nonebot/message.py
+++ b/nonebot/message.py
@@ -1,6 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
import asyncio
from datetime import datetime
@@ -57,6 +54,7 @@ async def _run_matcher(Matcher: Type[Matcher], bot: Bot, event: Event,
async def handle_event(bot: Bot, event: Event):
+ show_log = True
log_msg = f"{bot.type.upper()} | {event.self_id} [{event.name}]: "
if event.type == "message":
log_msg += f"Message {event.id} from "
@@ -74,8 +72,10 @@ async def handle_event(bot: Bot, event: Event):
elif event.type == "request":
log_msg += f"Request {event.raw_event}"
elif event.type == "meta_event":
- log_msg += f"MetaEvent {event.detail_type}"
- logger.opt(colors=True).info(log_msg)
+ # log_msg += f"MetaEvent {event.detail_type}"
+ show_log = False
+ if show_log:
+ logger.opt(colors=True).info(log_msg)
coros = []
state = {}
@@ -103,7 +103,8 @@ async def handle_event(bot: Bot, event: Event):
for matcher in matchers[priority]
]
- logger.debug(f"Checking for matchers in priority {priority}...")
+ if show_log:
+ logger.debug(f"Checking for matchers in priority {priority}...")
results = await asyncio.gather(*pending_tasks, return_exceptions=True)
i = 0
diff --git a/nonebot/permission.py b/nonebot/permission.py
index e194f453..df6c099b 100644
--- a/nonebot/permission.py
+++ b/nonebot/permission.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
"""
权限
====
diff --git a/nonebot/plugin.py b/nonebot/plugin.py
index c247b91a..b0196bd2 100644
--- a/nonebot/plugin.py
+++ b/nonebot/plugin.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
"""
插件
====
@@ -15,9 +13,9 @@ from dataclasses import dataclass
from importlib._bootstrap import _load
from nonebot.log import logger
+from nonebot.matcher import Matcher
from nonebot.permission import Permission
from nonebot.typing import Handler, RuleChecker
-from nonebot.matcher import Matcher, MatcherGroup
from nonebot.rule import Rule, startswith, endswith, command, regex
from nonebot.typing import Any, Set, List, Dict, Type, Tuple, Union, Optional, ModuleType
@@ -263,7 +261,7 @@ def on_endswith(msg: str,
def on_command(cmd: Union[str, Tuple[str, ...]],
rule: Optional[Union[Rule, RuleChecker]] = None,
aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = None,
- **kwargs) -> Union[Type[Matcher], MatcherGroup]:
+ **kwargs) -> Type[Matcher]:
"""
:说明:
注册一个消息事件响应器,并且当消息以指定命令开头时响应。
@@ -281,10 +279,7 @@ def on_command(cmd: Union[str, Tuple[str, ...]],
* ``state: Optional[dict]``: 默认的 state
:返回:
- ``Type[Matcher]``
- - ``MatcherGroup``
"""
- if isinstance(cmd, str):
- cmd = (cmd,)
async def _strip_cmd(bot, event, state: dict):
message = event.message
@@ -294,19 +289,10 @@ def on_command(cmd: Union[str, Tuple[str, ...]],
handlers = kwargs.pop("handlers", [])
handlers.insert(0, _strip_cmd)
- if aliases:
- aliases = set(map(lambda x: (x,) if isinstance(x, str) else x, aliases))
- group = MatcherGroup("message",
- Rule() & rule,
- handlers=handlers,
- **kwargs)
- for cmd_ in [cmd, *aliases]:
- _tmp_matchers.add(group.new(rule=command(cmd_)))
- return group
- else:
- return on_message(command(cmd) & rule, handlers=handlers, **
- kwargs) if rule else on_message(
- command(cmd), handlers=handlers, **kwargs)
+ commands = set([cmd]) | (aliases or set())
+ return on_message(command(*commands) & rule, handlers=handlers, **
+ kwargs) if rule else on_message(
+ command(*commands), handlers=handlers, **kwargs)
def on_regex(pattern: str,
@@ -359,7 +345,7 @@ class CommandGroup:
"""
def command(self, cmd: Union[str, Tuple[str, ...]],
- **kwargs) -> Union[Type[Matcher], MatcherGroup]:
+ **kwargs) -> Type[Matcher]:
"""
:说明:
注册一个新的命令。
@@ -368,7 +354,6 @@ class CommandGroup:
* ``**kwargs``: 其他传递给 ``on_command`` 的参数,将会覆盖命令组默认值
:返回:
- ``Type[Matcher]``
- - ``MatcherGroup``
"""
sub_cmd = (cmd,) if isinstance(cmd, str) else cmd
cmd = self.basecmd + sub_cmd
diff --git a/nonebot/plugin.pyi b/nonebot/plugin.pyi
index ccb8aed4..dbd96365 100644
--- a/nonebot/plugin.pyi
+++ b/nonebot/plugin.pyi
@@ -1,10 +1,6 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
import re
-from typing import overload
-from nonebot.typing import Rule, Matcher, Handler, Permission, RuleChecker, MatcherGroup
+from nonebot.typing import Rule, Matcher, Handler, Permission, RuleChecker
from nonebot.typing import Set, List, Dict, Type, Tuple, Union, Optional, ModuleType
plugins: Dict[str, "Plugin"] = ...
@@ -95,10 +91,9 @@ def on_endswith(msg: str,
...
-@overload
def on_command(cmd: Union[str, Tuple[str, ...]],
rule: Optional[Union[Rule, RuleChecker]] = ...,
- aliases: None = ...,
+ aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = ...,
permission: Optional[Permission] = ...,
*,
handlers: Optional[List[Handler]] = ...,
@@ -109,20 +104,6 @@ def on_command(cmd: Union[str, Tuple[str, ...]],
...
-@overload
-def on_command(cmd: Union[str, Tuple[str, ...]],
- rule: Optional[Union[Rule, RuleChecker]] = ...,
- aliases: Set[Union[str, Tuple[str, ...]]] = ...,
- permission: Optional[Permission] = ...,
- *,
- handlers: Optional[List[Handler]] = ...,
- temp: bool = ...,
- priority: int = ...,
- block: bool = ...,
- state: Optional[dict] = ...) -> MatcherGroup:
- ...
-
-
def on_regex(pattern: str,
flags: Union[int, re.RegexFlag] = 0,
rule: Optional[Rule] = ...,
@@ -166,16 +147,15 @@ class CommandGroup:
state: Optional[dict] = ...):
...
- def command(
- self,
- cmd: Union[str, Tuple[str, ...]],
- rule: Optional[Union[Rule, RuleChecker]] = ...,
- aliases: Set[Union[str, Tuple[str, ...]]] = ...,
- permission: Optional[Permission] = ...,
- *,
- handlers: Optional[List[Handler]] = ...,
- temp: bool = ...,
- priority: int = ...,
- block: bool = ...,
- state: Optional[dict] = ...) -> Union[Type[Matcher], MatcherGroup]:
+ def command(self,
+ cmd: Union[str, Tuple[str, ...]],
+ rule: Optional[Union[Rule, RuleChecker]] = ...,
+ aliases: Optional[Set[Union[str, Tuple[str, ...]]]] = ...,
+ permission: Optional[Permission] = ...,
+ *,
+ handlers: Optional[List[Handler]] = ...,
+ temp: bool = ...,
+ priority: int = ...,
+ block: bool = ...,
+ state: Optional[dict] = ...) -> Type[Matcher]:
...
diff --git a/nonebot/rule.py b/nonebot/rule.py
index b1927e59..c950c449 100644
--- a/nonebot/rule.py
+++ b/nonebot/rule.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
"""
规则
====
@@ -198,12 +196,14 @@ def keyword(msg: str) -> Rule:
return Rule(_keyword)
-def command(command: Tuple[str, ...]) -> Rule:
+def command(*cmds: Union[str, Tuple[str, ...]]) -> Rule:
"""
:说明:
命令形式匹配,根据配置里提供的 ``command_start``, ``command_sep`` 判断消息是否为命令。
+
+ 可以通过 ``state["_prefix"]["command"]`` 获取匹配成功的命令(例:``("test",)``),通过 ``state["_prefix"]["raw_command"]`` 获取匹配成功的原始命令文本(例:``"/test"``)。
:参数:
- * ``command: Tuples[str, ...]``: 命令内容
+ * ``*cmds: Union[str, Tuple[str, ...]]``: 命令内容
:示例:
使用默认 ``command_start``, ``command_sep`` 配置
@@ -218,15 +218,20 @@ def command(command: Tuple[str, ...]) -> Rule:
config = get_driver().config
command_start = config.command_start
command_sep = config.command_sep
- if len(command) == 1:
- for start in command_start:
- TrieRule.add_prefix(f"{start}{command[0]}", command)
- else:
- for start, sep in product(command_start, command_sep):
- TrieRule.add_prefix(f"{start}{sep.join(command)}", command)
+ commands = list(cmds)
+ for index, command in enumerate(commands):
+ if isinstance(command, str):
+ commands[index] = command = (command,)
+
+ if len(command) == 1:
+ for start in command_start:
+ TrieRule.add_prefix(f"{start}{command[0]}", command)
+ else:
+ for start, sep in product(command_start, command_sep):
+ TrieRule.add_prefix(f"{start}{sep.join(command)}", command)
async def _command(bot: Bot, event: Event, state: dict) -> bool:
- return command == state["_prefix"]["command"]
+ return state["_prefix"]["command"] in commands
return Rule(_command)
@@ -234,7 +239,9 @@ def command(command: Tuple[str, ...]) -> Rule:
def regex(regex: str, flags: Union[int, re.RegexFlag] = 0) -> Rule:
"""
:说明:
- 根据正则表达式进行匹配
+ 根据正则表达式进行匹配。
+
+ 可以通过 ``state["_matched"]`` 获取正则表达式匹配成功的文本。
:参数:
* ``regex: str``: 正则表达式
* ``flags: Union[int, re.RegexFlag]``: 正则标志
@@ -247,8 +254,13 @@ def regex(regex: str, flags: Union[int, re.RegexFlag] = 0) -> Rule:
pattern = re.compile(regex, flags)
async def _regex(bot: Bot, event: Event, state: dict) -> bool:
- return bool(pattern.search(str(event.message)))
-
+ matched = pattern.search(str(event.message))
+ if matched:
+ state["_matched"] = matched.group()
+ return True
+ else:
+ state["_matched"] = None
+ return False
return Rule(_regex)
diff --git a/nonebot/sched.py b/nonebot/sched.py
index 58447b67..e47d95b7 100644
--- a/nonebot/sched.py
+++ b/nonebot/sched.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
"""
计划任务
========
diff --git a/nonebot/typing.py b/nonebot/typing.py
index 5b722655..ec9a666b 100644
--- a/nonebot/typing.py
+++ b/nonebot/typing.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
"""
类型
====
diff --git a/nonebot/utils.py b/nonebot/utils.py
index 9efeb8ca..db447401 100644
--- a/nonebot/utils.py
+++ b/nonebot/utils.py
@@ -1,6 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
import re
import json
import asyncio
diff --git a/package-lock.json b/package-lock.json
index e59f17b2..efb2f7bf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1050,6 +1050,45 @@
"to-fast-properties": "^2.0.0"
}
},
+ "@hapi/address": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
+ "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==",
+ "dev": true
+ },
+ "@hapi/bourne": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz",
+ "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==",
+ "dev": true
+ },
+ "@hapi/hoek": {
+ "version": "8.5.1",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz",
+ "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==",
+ "dev": true
+ },
+ "@hapi/joi": {
+ "version": "15.1.1",
+ "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz",
+ "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==",
+ "dev": true,
+ "requires": {
+ "@hapi/address": "2.x.x",
+ "@hapi/bourne": "1.x.x",
+ "@hapi/hoek": "8.x.x",
+ "@hapi/topo": "3.x.x"
+ }
+ },
+ "@hapi/topo": {
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz",
+ "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==",
+ "dev": true,
+ "requires": {
+ "@hapi/hoek": "^8.3.0"
+ }
+ },
"@mrmlnc/readdir-enhanced": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
@@ -1454,6 +1493,17 @@
"nprogress": "^0.2.0"
}
},
+ "@vuepress/plugin-pwa": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/@vuepress/plugin-pwa/-/plugin-pwa-1.7.1.tgz",
+ "integrity": "sha512-c3oozxPPGpraU+UnY3gp3sWnKYO3mOLcexQWXaYABWnUC3yFbHx4e8wIF8LGqp7Z75bjQuUoI+LcHqpQXyYNag==",
+ "dev": true,
+ "requires": {
+ "@vuepress/shared-utils": "1.7.1",
+ "register-service-worker": "^1.7.0",
+ "workbox-build": "^4.3.1"
+ }
+ },
"@vuepress/plugin-register-components": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/@vuepress/plugin-register-components/-/plugin-register-components-1.7.1.tgz",
@@ -2076,6 +2126,15 @@
"integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==",
"dev": true
},
+ "babel-extract-comments": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz",
+ "integrity": "sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==",
+ "dev": true,
+ "requires": {
+ "babylon": "^6.18.0"
+ }
+ },
"babel-loader": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz",
@@ -2098,6 +2157,52 @@
"object.assign": "^4.1.0"
}
},
+ "babel-plugin-syntax-object-rest-spread": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
+ "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
+ "dev": true
+ },
+ "babel-plugin-transform-object-rest-spread": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz",
+ "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-syntax-object-rest-spread": "^6.8.0",
+ "babel-runtime": "^6.26.0"
+ }
+ },
+ "babel-runtime": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+ "dev": true,
+ "requires": {
+ "core-js": "^2.4.0",
+ "regenerator-runtime": "^0.11.0"
+ },
+ "dependencies": {
+ "core-js": {
+ "version": "2.6.11",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz",
+ "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==",
+ "dev": true
+ },
+ "regenerator-runtime": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+ "dev": true
+ }
+ }
+ },
+ "babylon": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+ "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+ "dev": true
+ },
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@@ -3011,6 +3116,12 @@
"integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
"dev": true
},
+ "common-tags": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz",
+ "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==",
+ "dev": true
+ },
"commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
@@ -4817,6 +4928,12 @@
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true
},
+ "get-own-enumerable-property-symbols": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
+ "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==",
+ "dev": true
+ },
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
@@ -5736,6 +5853,12 @@
"has-symbols": "^1.0.1"
}
},
+ "is-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
+ "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=",
+ "dev": true
+ },
"is-resolvable": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
@@ -7765,6 +7888,12 @@
"dev": true,
"optional": true
},
+ "pretty-bytes": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.4.1.tgz",
+ "integrity": "sha512-s1Iam6Gwz3JI5Hweaz4GoCD1WUNUIyzePFy5+Js2hjwGVt2Z79wNN+ZKOZ2vB6C+Xs6njyB84Z1IthQg8d9LxA==",
+ "dev": true
+ },
"pretty-error": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz",
@@ -8124,6 +8253,12 @@
"unicode-match-property-value-ecmascript": "^1.2.0"
}
},
+ "register-service-worker": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/register-service-worker/-/register-service-worker-1.7.1.tgz",
+ "integrity": "sha512-IdTfUZ4u8iJL8o1w8es8l6UMGPmkwHolUdT+UmM1UypC80IB4KbpuIlvwWVj8UDS7eJwkEYRcKRgfRX+oTmJsw==",
+ "dev": true
+ },
"registry-auth-token": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz",
@@ -9209,6 +9344,25 @@
"safe-buffer": "~5.1.0"
}
},
+ "stringify-object": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz",
+ "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==",
+ "dev": true,
+ "requires": {
+ "get-own-enumerable-property-symbols": "^3.0.0",
+ "is-obj": "^1.0.1",
+ "is-regexp": "^1.0.0"
+ },
+ "dependencies": {
+ "is-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+ "dev": true
+ }
+ }
+ },
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
@@ -9224,6 +9378,16 @@
"integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=",
"dev": true
},
+ "strip-comments": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-1.0.2.tgz",
+ "integrity": "sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==",
+ "dev": true,
+ "requires": {
+ "babel-extract-comments": "^1.0.0",
+ "babel-plugin-transform-object-rest-spread": "^6.26.0"
+ }
+ },
"strip-eof": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
@@ -10297,7 +10461,7 @@
}
},
"vuepress-theme-nonebot": {
- "version": "git+https://github.com/nonebot/vuepress-theme-nonebot.git#0325cd2403c210125907c4f7adcd64fb8754acae",
+ "version": "git+https://github.com/nonebot/vuepress-theme-nonebot.git#16c96d1cd12cbb72d0233875b0a671cada93ca2a",
"from": "git+https://github.com/nonebot/vuepress-theme-nonebot.git",
"dev": true,
"requires": {
@@ -10757,6 +10921,173 @@
}
}
},
+ "workbox-background-sync": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz",
+ "integrity": "sha512-1uFkvU8JXi7L7fCHVBEEnc3asPpiAL33kO495UMcD5+arew9IbKW2rV5lpzhoWcm/qhGB89YfO4PmB/0hQwPRg==",
+ "dev": true,
+ "requires": {
+ "workbox-core": "^4.3.1"
+ }
+ },
+ "workbox-broadcast-update": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-4.3.1.tgz",
+ "integrity": "sha512-MTSfgzIljpKLTBPROo4IpKjESD86pPFlZwlvVG32Kb70hW+aob4Jxpblud8EhNb1/L5m43DUM4q7C+W6eQMMbA==",
+ "dev": true,
+ "requires": {
+ "workbox-core": "^4.3.1"
+ }
+ },
+ "workbox-build": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-4.3.1.tgz",
+ "integrity": "sha512-UHdwrN3FrDvicM3AqJS/J07X0KXj67R8Cg0waq1MKEOqzo89ap6zh6LmaLnRAjpB+bDIz+7OlPye9iii9KBnxw==",
+ "dev": true,
+ "requires": {
+ "@babel/runtime": "^7.3.4",
+ "@hapi/joi": "^15.0.0",
+ "common-tags": "^1.8.0",
+ "fs-extra": "^4.0.2",
+ "glob": "^7.1.3",
+ "lodash.template": "^4.4.0",
+ "pretty-bytes": "^5.1.0",
+ "stringify-object": "^3.3.0",
+ "strip-comments": "^1.0.2",
+ "workbox-background-sync": "^4.3.1",
+ "workbox-broadcast-update": "^4.3.1",
+ "workbox-cacheable-response": "^4.3.1",
+ "workbox-core": "^4.3.1",
+ "workbox-expiration": "^4.3.1",
+ "workbox-google-analytics": "^4.3.1",
+ "workbox-navigation-preload": "^4.3.1",
+ "workbox-precaching": "^4.3.1",
+ "workbox-range-requests": "^4.3.1",
+ "workbox-routing": "^4.3.1",
+ "workbox-strategies": "^4.3.1",
+ "workbox-streams": "^4.3.1",
+ "workbox-sw": "^4.3.1",
+ "workbox-window": "^4.3.1"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
+ "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ }
+ }
+ },
+ "workbox-cacheable-response": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-4.3.1.tgz",
+ "integrity": "sha512-Rp5qlzm6z8IOvnQNkCdO9qrDgDpoPNguovs0H8C+wswLuPgSzSp9p2afb5maUt9R1uTIwOXrVQMmPfPypv+npw==",
+ "dev": true,
+ "requires": {
+ "workbox-core": "^4.3.1"
+ }
+ },
+ "workbox-core": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-4.3.1.tgz",
+ "integrity": "sha512-I3C9jlLmMKPxAC1t0ExCq+QoAMd0vAAHULEgRZ7kieCdUd919n53WC0AfvokHNwqRhGn+tIIj7vcb5duCjs2Kg==",
+ "dev": true
+ },
+ "workbox-expiration": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-4.3.1.tgz",
+ "integrity": "sha512-vsJLhgQsQouv9m0rpbXubT5jw0jMQdjpkum0uT+d9tTwhXcEZks7qLfQ9dGSaufTD2eimxbUOJfWLbNQpIDMPw==",
+ "dev": true,
+ "requires": {
+ "workbox-core": "^4.3.1"
+ }
+ },
+ "workbox-google-analytics": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-4.3.1.tgz",
+ "integrity": "sha512-xzCjAoKuOb55CBSwQrbyWBKqp35yg1vw9ohIlU2wTy06ZrYfJ8rKochb1MSGlnoBfXGWss3UPzxR5QL5guIFdg==",
+ "dev": true,
+ "requires": {
+ "workbox-background-sync": "^4.3.1",
+ "workbox-core": "^4.3.1",
+ "workbox-routing": "^4.3.1",
+ "workbox-strategies": "^4.3.1"
+ }
+ },
+ "workbox-navigation-preload": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-4.3.1.tgz",
+ "integrity": "sha512-K076n3oFHYp16/C+F8CwrRqD25GitA6Rkd6+qAmLmMv1QHPI2jfDwYqrytOfKfYq42bYtW8Pr21ejZX7GvALOw==",
+ "dev": true,
+ "requires": {
+ "workbox-core": "^4.3.1"
+ }
+ },
+ "workbox-precaching": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-4.3.1.tgz",
+ "integrity": "sha512-piSg/2csPoIi/vPpp48t1q5JLYjMkmg5gsXBQkh/QYapCdVwwmKlU9mHdmy52KsDGIjVaqEUMFvEzn2LRaigqQ==",
+ "dev": true,
+ "requires": {
+ "workbox-core": "^4.3.1"
+ }
+ },
+ "workbox-range-requests": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-4.3.1.tgz",
+ "integrity": "sha512-S+HhL9+iTFypJZ/yQSl/x2Bf5pWnbXdd3j57xnb0V60FW1LVn9LRZkPtneODklzYuFZv7qK6riZ5BNyc0R0jZA==",
+ "dev": true,
+ "requires": {
+ "workbox-core": "^4.3.1"
+ }
+ },
+ "workbox-routing": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-4.3.1.tgz",
+ "integrity": "sha512-FkbtrODA4Imsi0p7TW9u9MXuQ5P4pVs1sWHK4dJMMChVROsbEltuE79fBoIk/BCztvOJ7yUpErMKa4z3uQLX+g==",
+ "dev": true,
+ "requires": {
+ "workbox-core": "^4.3.1"
+ }
+ },
+ "workbox-strategies": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-4.3.1.tgz",
+ "integrity": "sha512-F/+E57BmVG8dX6dCCopBlkDvvhg/zj6VDs0PigYwSN23L8hseSRwljrceU2WzTvk/+BSYICsWmRq5qHS2UYzhw==",
+ "dev": true,
+ "requires": {
+ "workbox-core": "^4.3.1"
+ }
+ },
+ "workbox-streams": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-4.3.1.tgz",
+ "integrity": "sha512-4Kisis1f/y0ihf4l3u/+ndMkJkIT4/6UOacU3A4BwZSAC9pQ9vSvJpIi/WFGQRH/uPXvuVjF5c2RfIPQFSS2uA==",
+ "dev": true,
+ "requires": {
+ "workbox-core": "^4.3.1"
+ }
+ },
+ "workbox-sw": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-4.3.1.tgz",
+ "integrity": "sha512-0jXdusCL2uC5gM3yYFT6QMBzKfBr2XTk0g5TPAV4y8IZDyVNDyj1a8uSXy3/XrvkVTmQvLN4O5k3JawGReXr9w==",
+ "dev": true
+ },
+ "workbox-window": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-4.3.1.tgz",
+ "integrity": "sha512-C5gWKh6I58w3GeSc0wp2Ne+rqVw8qwcmZnQGpjiek8A2wpbxSJb1FdCoQVO+jDJs35bFgo/WETgl1fqgsxN0Hg==",
+ "dev": true,
+ "requires": {
+ "workbox-core": "^4.3.1"
+ }
+ },
"worker-farm": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
diff --git a/package.json b/package.json
index 5612d90b..0d01b7b2 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
"devDependencies": {
"@vuepress/plugin-back-to-top": "^1.7.1",
"@vuepress/plugin-medium-zoom": "^1.7.1",
+ "@vuepress/plugin-pwa": "^1.7.1",
"vuepress": "^1.7.1",
"vuepress-plugin-versioning": "git+https://github.com/nonebot/vuepress-plugin-versioning.git",
"vuepress-theme-nonebot": "git+https://github.com/nonebot/vuepress-theme-nonebot.git"
diff --git a/pages/plugin-store.md b/pages/plugin-store.md
new file mode 100644
index 00000000..28b142e2
--- /dev/null
+++ b/pages/plugin-store.md
@@ -0,0 +1,6 @@
+---
+---
+
+# 插件广场
+
+
diff --git a/tests/bot.py b/tests/bot.py
index e66875e9..7a294564 100644
--- a/tests/bot.py
+++ b/tests/bot.py
@@ -1,6 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
import os
import sys
diff --git a/tests/test_plugins/test_metaevent.py b/tests/test_plugins/test_metaevent.py
index f683716a..439513b1 100644
--- a/tests/test_plugins/test_metaevent.py
+++ b/tests/test_plugins/test_metaevent.py
@@ -1,6 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
from nonebot.typing import Bot, Event
from nonebot.plugin import on_metaevent
diff --git a/tests/test_plugins/test_package/__init__.py b/tests/test_plugins/test_package/__init__.py
index 60c5cee2..139447bf 100644
--- a/tests/test_plugins/test_package/__init__.py
+++ b/tests/test_plugins/test_package/__init__.py
@@ -1,4 +1 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
from . import test_command
diff --git a/tests/test_plugins/test_package/test_command.py b/tests/test_plugins/test_package/test_command.py
index af060fff..fd85b1d9 100644
--- a/tests/test_plugins/test_package/test_command.py
+++ b/tests/test_plugins/test_package/test_command.py
@@ -1,6 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
from nonebot.rule import to_me
from nonebot.typing import Event
from nonebot.plugin import on_command
diff --git a/tests/test_plugins/test_permission.py b/tests/test_plugins/test_permission.py
index a7f577a7..ed03b80f 100644
--- a/tests/test_plugins/test_permission.py
+++ b/tests/test_plugins/test_permission.py
@@ -1,6 +1,3 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
from nonebot.rule import to_me
from nonebot.typing import Event
from nonebot.plugin import on_startswith