Skip to content

Commit

Permalink
🔀 Merge pull request #202
Browse files Browse the repository at this point in the history
Pre Release 2.0.0a10
  • Loading branch information
yanyongyu authored Feb 7, 2021
2 parents 9a34647 + 27b9b41 commit 8821218
Show file tree
Hide file tree
Showing 25 changed files with 856 additions and 169 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build_docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Build API Doc

on:
pull_request:
types: [ opened, synchronize, reopened ]
types: [opened, synchronize, reopened]

jobs:
build:
Expand Down Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Set up dependencies
run: |
poetry install
poetry install -E all
- name: Build Doc
run: poetry run sphinx-build -M markdown ./docs_build ./build
Expand Down
4 changes: 4 additions & 0 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ module.exports = context => ({
title: "nonebot.drivers.fastapi 模块",
path: "drivers/fastapi"
},
{
title: "nonebot.drivers.quart 模块",
path: "drivers/quart"
},
{
title: "nonebot.adapters 模块",
path: "adapters/"
Expand Down
116 changes: 116 additions & 0 deletions docs/advanced/export-and-require.md
Original file line number Diff line number Diff line change
@@ -1 +1,117 @@
# 跨插件访问

由于 `nonebot2` 独特的插件加载机制,在使用 python 原有的 import 机制来进行插件之间的访问时,很可能会有奇怪的或者意料以外的情况发生。为了避免这种情况的发生,您可以有两种方法来实现跨插件访问:

1. 将插件间的要使用的公共代码剥离出来,作为公共文件或者文件夹,提供给插件加以调用。
2. 使用 `nonebot2` 提供的 `export``require` 机制,来实现插件间的互相调用。

第一种方法比较容易理解和实现,这里不再赘述,但需要注意的是,请不要将公共文件或者公共文件夹作为**插件**`nonebot2` 加载。

下面将介绍第二种方法—— `export``require` 机制:

## 使用 export and require

现在,假定有两个插件 `pluginA``pluginB`,需要在 `pluginB` 中调用 `pluginA` 中的一个变量 `varA` 和一个函数 `funcA`

在上面的条件中涉及到了两种操作:一种是在 `pluginA``导出对象` 操作;而另一种是在 `pluginB``导入对象` 操作。在 `nonebot2` 中,`导出对象` 的操作用 `export` 机制来实现,`导入对象` 的操作用 `require` 机制来实现。下面,我们将逐一进行介绍。

:::warning 警告

使用这个方法进行跨插件访问时,**需要先加载`导出对象`的插件,再加载`导入对象`的插件。**

:::

### 使用 export

`pluginA` 中,我们调用 `export` 机制 `导出对象`

`export` 机制调用前,我们需要保证导出的对象已经被定义,比如:

```python
varA = "varA"


def funcA():
return "funcA"
```

在确保定义之后,我们可以从 `nonebot.plugin` 导入 `export()` 方法, `export()` 方法会返回一个特殊的字典 `export`

```python
from nonebot.plugin import export

export=export()
```

这个字典可以用来装载导出的对象,它的 key 是对象导出后的命名,value 是对象本身,我们可以直接创建新的 `key` - `value` 对导出对象:

```python
export.vA = varA
export.fA = funcA
```

除此之外,也支持 `嵌套` 导出对象:

```python
export.sub.vA = varA
export.sub.fA = funcA
```

特别地,对于 `函数对象` 而言,`export` 支持用 `装饰器` 的方法来导出,因此,我们可以这样定义 `funcA`

```python
@export.sub
def funcA():
return "funcA"
```

或者:

```python
@export
def funcA():
return "funcA"
```

通过 `装饰器` 的方法导出函数时,命名固定为函数的命名,也就是说,上面的两个例子等同于:

```python
export.sub.funcA = funcA

export.funcA = funcA
```

这样,我们就成功导出 `varA``funcA` 对象了。

下面我们将介绍如何在 `pluginB` 中导入这些对象。

### 使用 require

`pluginB` 中,我们调用 `require` 机制 `导入对象`

:::warning 警告

在导入来自其他插件的对象时, 请确保导出该对象的插件在引用该对象的插件之前加载。如果该插件并未被加载,则会尝试加载,加载失败则会返回 `None`

:::

我们可以从 `nonebot.plugin` 中导入 `require()` 方法:

```python
from nonebot.plugin import require
```

`require()` 方法的参数是插件名, 它会返回在指定插件中,用 `export()` 方法创建的字典。

```python
require_A = require('pluginA')
```

在之前,这个字典已经存入了 `'vA'` - `varA`, `'fA'` - `funcA``'funcA'` - `funcA` 这样的 `key` - `value` 对。因此在这里我们直接用 `属性` 的方法来获取导入对象:

```python
varA = require_A.vA
funcA = require_A.fA or require_A.funcA
```

这样,我们就在 `pluginB` 中成功导入了 `varA``funcA` 对象了。
3 changes: 3 additions & 0 deletions docs/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
* [nonebot.drivers.fastapi](drivers/fastapi.html)


* [nonebot.drivers.quart](drivers/quart.html)


* [nonebot.adapters](adapters/)


Expand Down
41 changes: 26 additions & 15 deletions docs/api/adapters/mirai.md
Original file line number Diff line number Diff line change
Expand Up @@ -965,15 +965,40 @@ CQHTTP 协议 MessageSegment 适配。具体方法参考 [mirai-api-http 消息

基类:[`nonebot.adapters.Message`](README.md#nonebot.adapters.Message)

Mirai 协议 Messaqge 适配
Mirai 协议 Message 适配

由于Mirai协议的Message实现较为特殊, 故使用MessageChain命名


### `reduce()`


* **说明**

忽略为空的消息段, 合并相邻的纯文本消息段



### `export()`

导出为可以被正常json序列化的数组


### `extract_first(*type)`


* **说明**

弹出该消息链的第一个消息



* **参数**


* \*type: MessageType: 指定的消息类型, 当指定后如类型不匹配不弹出


# NoneBot.adapters.mirai.utils 模块


Expand Down Expand Up @@ -1070,20 +1095,6 @@ mirai-api-http 协议事件,字段与 mirai-api-http 一致。各事件字段
> * `MEMBER`: 普通群成员

## _class_ `MessageChain`

基类:[`nonebot.adapters.Message`](README.md#nonebot.adapters.Message)

Mirai 协议 Messaqge 适配

由于Mirai协议的Message实现较为特殊, 故使用MessageChain命名


### `export()`

导出为可以被正常json序列化的数组


## _class_ `MessageEvent`

基类:`nonebot.adapters.mirai.event.base.Event`
Expand Down
62 changes: 62 additions & 0 deletions docs/api/drivers/quart.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
contentSidebar: true
sidebarDepth: 0
---

# NoneBot.drivers.quart 模块

## Quart 驱动适配

后端使用方法请参考: [Quart 文档](https://pgjones.gitlab.io/quart/index.html)


## _class_ `Driver`

基类:[`nonebot.drivers.Driver`](README.md#nonebot.drivers.Driver)

Quart 驱动框架


* **上报地址**


* `/{adapter name}/http`: HTTP POST 上报


* `/{adapter name}/ws`: WebSocket 上报



### _property_ `type`

驱动名称: `quart`


### _property_ `server_app`

`Quart` 对象


### _property_ `asgi`

`Quart` 对象


### _property_ `logger`

fastapi 使用的 logger


### `on_startup(func)`

参考文档: [Startup and Shutdown](https://pgjones.gitlab.io/quart/how_to_guides/startup_shutdown.html)


### `on_shutdown(func)`

参考文档: [Startup and Shutdown](https://pgjones.gitlab.io/quart/how_to_guides/startup_shutdown.html)


### `run(host=None, port=None, *, app=None, **kwargs)`

使用 `uvicorn` 启动 Quart
2 changes: 1 addition & 1 deletion docs/guide/creating-a-matcher.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ async def async_checker(bot: Bot, event: Event, state: T_State) -> bool:
def sync_checker(bot: Bot, event: Event, state: T_State) -> bool:
return True

def check(arg1, args2):
def check(arg1, arg2):

async def _checker(bot: Bot, event: Event, state: T_State) -> bool:
return bool(arg1 + arg2)
Expand Down
15 changes: 12 additions & 3 deletions docs/guide/loading-a-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,28 @@

`bot.py` 文件中添加以下行:

```python{5}
```python{8}
import nonebot
from nonebot.adapters.cqhttp import Bot
nonebot.init()
# 加载 nonebot 内置插件
nonebot.load_builtin_plugins()
driver = nonebot.get_driver()
driver.register_adapter("cqhttp", Bot) # 注册 CQHTTP 的 Adapter
nonebot.load_builtin_plugins() # 加载 nonebot 内置插件
app = nonebot.get_asgi()
if __name__ == "__main__":
nonebot.run()
```

::: warning
目前, 内建插件仅支持 CQHTTP 的 Adapter

如果您使用的是其他 Adapter, 请移步该 Adapter 相应的文档
:::

这将会加载 nonebot 内置的插件,它包含:

- 命令 `say`:可由**superuser**使用,可以将消息内容由特殊纯文本转为富文本
Expand Down
33 changes: 33 additions & 0 deletions docs/guide/mirai-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,36 @@ Mirai-API-HTTP 的适配器以 [AGPLv3 许可](https://opensource.org/licenses/A
```
恭喜你, 你的配置已经成功!
现在, 我们可以写一个简单的插件来测试一下
```python
from nonebot.plugin import on_keyword, on_command
from nonebot.rule import to_me
from nonebot.adapters.mirai import Bot, MessageEvent
message_test = on_keyword({'reply'}, rule=to_me())
@message_test.handle()
async def _message(bot: Bot, event: MessageEvent):
text = event.get_plaintext()
await bot.send(event, text, at_sender=True)
command_test = on_command('miecho')
@command_test.handle()
async def _echo(bot: Bot, event: MessageEvent):
text = event.get_plaintext()
await bot.send(event, text, at_sender=True)
```
它具有两种行为
- 在指定机器人,即私聊、群聊内@机器人、群聊内称呼机器人昵称的情况下 (即 [Rule: to_me](../api/rule.md#to-me)), 如果消息内包含 `reply` 字段, 则该消息会被机器人重复一次
- 在执行指令`miecho xxx`时, 机器人会发送回参数`xxx`
至此, 你已经初步掌握了如何使用 Mirai Adapter
1 change: 1 addition & 0 deletions docs_build/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ NoneBot Api Reference
- `nonebot.exception <exception.html>`_
- `nonebot.drivers <drivers/>`_
- `nonebot.drivers.fastapi <drivers/fastapi.html>`_
- `nonebot.drivers.quart <drivers/quart.html>`_
- `nonebot.adapters <adapters/>`_
- `nonebot.adapters.cqhttp <adapters/cqhttp.html>`_
- `nonebot.adapters.ding <adapters/ding.html>`_
Expand Down
12 changes: 12 additions & 0 deletions docs_build/drivers/quart.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
contentSidebar: true
sidebarDepth: 0
---

NoneBot.drivers.quart 模块
==========================

.. automodule:: nonebot.drivers.quart
:members:
:private-members:
:show-inheritance:
3 changes: 2 additions & 1 deletion nonebot/adapters/cqhttp/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,8 @@ async def send(self,
- ``NetworkError``: 网络错误
- ``ActionFailed``: API 调用失败
"""
message = escape(message) if isinstance(message, str) else message
message = escape(message, escape_comma=False) if isinstance(
message, str) else message
msg = message if isinstance(message, Message) else Message(message)

at_sender = at_sender and getattr(event, "user_id", None)
Expand Down
Loading

0 comments on commit 8821218

Please sign in to comment.