nonebot-plugin-uninfo 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nonebot_plugin_uninfo-0.1.0/LICENSE +21 -0
- nonebot_plugin_uninfo-0.1.0/PKG-INFO +177 -0
- nonebot_plugin_uninfo-0.1.0/README.md +166 -0
- nonebot_plugin_uninfo-0.1.0/pyproject.toml +131 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/__init__.py +34 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/__init__.py +56 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/console/__init__.py +13 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/console/main.py +57 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/discord/__init__.py +13 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/discord/main.py +478 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/dodo/__init__.py +13 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/dodo/main.py +211 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/feishu/__init__.py +13 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/feishu/main.py +221 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/kook/__init__.py +13 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/kook/main.py +216 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/kritor/__init__.py +13 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/kritor/main.py +414 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/minecraft/__init__.py +13 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/minecraft/main.py +56 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/mirai/__init__.py +13 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/mirai/main.py +538 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/onebot11/__init__.py +13 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/onebot11/main.py +360 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/onebot12/__init__.py +13 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/onebot12/main.py +333 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/qq/__init__.py +13 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/qq/main.py +389 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/satori/__init__.py +13 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/satori/main.py +240 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/telegram/__init__.py +13 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/adapters/telegram/main.py +199 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/constraint.py +110 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/fetch.py +96 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/loader.py +12 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/model.py +135 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/params.py +86 -0
- nonebot_plugin_uninfo-0.1.0/src/nonebot_plugin_uninfo/permission.py +152 -0
- nonebot_plugin_uninfo-0.1.0/tests/__init__.py +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 RF-Tar-Railt
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: nonebot-plugin-uninfo
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Universal Information Model for Nonebot2
|
|
5
|
+
Author-Email: RF-Tar-Railt <rf_tar_railt@qq.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Requires-Dist: nonebot2>=2.3.0
|
|
9
|
+
Requires-Dist: importlib-metadata>=4.13.0
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
<div align="center">
|
|
13
|
+
|
|
14
|
+
<a href="https://nonebot.dev/">
|
|
15
|
+
<img src="https://nonebot.dev/logo.png" width="200" height="200" alt="nonebot">
|
|
16
|
+
</a>
|
|
17
|
+
|
|
18
|
+
# nonebot-plugin-uninfo
|
|
19
|
+
|
|
20
|
+
_✨ [Nonebot2](https://github.com/nonebot/nonebot2) 多平台的会话信息(用户、群组、频道)获取插件 ✨_
|
|
21
|
+
|
|
22
|
+
<p align="center">
|
|
23
|
+
<img src="https://img.shields.io/github/license/RF-Tar-Railt/nonebot-plugin-uninfo" alt="license">
|
|
24
|
+
<img src="https://img.shields.io/badge/python-3.9+-blue.svg" alt="Python">
|
|
25
|
+
<img src="https://img.shields.io/badge/nonebot-2.3.0+-red.svg" alt="NoneBot">
|
|
26
|
+
<a href="https://pypi.org/project/nonebot-plugin-uninfo">
|
|
27
|
+
<img src="https://badgen.net/pypi/v/nonebot-plugin-uninfo" alt="pypi">
|
|
28
|
+
</a>
|
|
29
|
+
</p>
|
|
30
|
+
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
本插件提供了多个模型,可以从不同适配器的 `Bot` 和 `Event` 中提取与会话相关的属性
|
|
34
|
+
|
|
35
|
+
## 安装
|
|
36
|
+
|
|
37
|
+
- 使用 nb-cli
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
nb plugin install nonebot-plugin-uninfo
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
- 使用 pip
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
pip install nonebot-plugin-uninfo
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 使用
|
|
50
|
+
|
|
51
|
+
### 获取 `Session`:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from nonebot_plugin_uninfo import get_session
|
|
55
|
+
|
|
56
|
+
@matcher.handle()
|
|
57
|
+
async def handle(bot: Bot, event: Event):
|
|
58
|
+
session = await get_session(bot, event)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
或使用依赖注入的形式:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from nonebot_plugin_uninfo import Uninfo, UniSession, Session
|
|
65
|
+
|
|
66
|
+
@matcher.handle()
|
|
67
|
+
async def handle(session: Session = UniSession()):
|
|
68
|
+
...
|
|
69
|
+
|
|
70
|
+
@matcher.handle()
|
|
71
|
+
async def handle1(session: Uninfo):
|
|
72
|
+
...
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 拉取用户/群组/频道列表:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from nonebot_plugin_uninfo import get_interface
|
|
79
|
+
|
|
80
|
+
@matcher.handle()
|
|
81
|
+
async def handle(bot: Bot):
|
|
82
|
+
interface = await get_interface(bot)
|
|
83
|
+
if interface:
|
|
84
|
+
users = await interface.get_users()
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 模型定义
|
|
88
|
+
|
|
89
|
+
### `User`
|
|
90
|
+
|
|
91
|
+
| 属性 | 类型 | 含义 | 备注 |
|
|
92
|
+
|----------|-------------|-------|------|
|
|
93
|
+
| `id` | str | 用户 id | |
|
|
94
|
+
| `name` | str \| None | 用户名称 | |
|
|
95
|
+
| `nick` | str \| None | 用户昵称 | 好友备注 |
|
|
96
|
+
| `avatar` | str \| None | 用户头像 | |
|
|
97
|
+
| `gender` | str | 用户性别 | |
|
|
98
|
+
|
|
99
|
+
### `Scene`
|
|
100
|
+
|
|
101
|
+
| 属性 | 类型 | 含义 | 备注 |
|
|
102
|
+
|----------|---------------|-------|-------------------------------------------------|
|
|
103
|
+
| `id` | str | 场景 id | |
|
|
104
|
+
| `type` | SceneType | 场景类型 | 可分为 `Private`, `Group`, `Guild` 和 `Channel_XXX` |
|
|
105
|
+
| `name` | str \| None | 场景名称 | |
|
|
106
|
+
| `avatar` | str \| None | 场景图标 | |
|
|
107
|
+
| `parent` | Scene \| None | 父级场景 | 适用于频道的二级群组场景, 或针对临时会话的来源群组 |
|
|
108
|
+
|
|
109
|
+
### `Member`
|
|
110
|
+
|
|
111
|
+
| 属性 | 类型 | 含义 | 备注 |
|
|
112
|
+
|-------------|------------------|---------|-------------------------------|
|
|
113
|
+
| `user` | User | 成员的用户信息 | |
|
|
114
|
+
| `nick` | str \| None | 成员昵称 | |
|
|
115
|
+
| `role` | str \| None | 成员角色组 | 当可能存在多个角色组时,此处会使用 level 最高的那个 |
|
|
116
|
+
| `mute` | MuteInfo \| None | 成员禁言信息 | |
|
|
117
|
+
| `joined_at` | datetime \| None | 成员加入时间 | |
|
|
118
|
+
|
|
119
|
+
### `Session`
|
|
120
|
+
|
|
121
|
+
| 属性 | 类型 | 含义 | 备注 |
|
|
122
|
+
|------------|----------------|--------|--------------------|
|
|
123
|
+
| `self_id` | str | 机器人 id | |
|
|
124
|
+
| `adapter` | str | 适配器名称 | |
|
|
125
|
+
| `scope` | str | 适配器范围 | 相比 adapter 更指向实际平台 |
|
|
126
|
+
| `scene` | Scene | 事件场景 | |
|
|
127
|
+
| `user` | User | 用户信息 | |
|
|
128
|
+
| `member` | Member \| None | 成员信息 | 仅适用于群组,频道场景 |
|
|
129
|
+
| `operator` | Member \| None | 操作者信息 | 仅适用于群组,频道场景 |
|
|
130
|
+
|
|
131
|
+
## 示例
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from nonebot_plugin_uninfo import Uninfo
|
|
135
|
+
from nonebot import on_command
|
|
136
|
+
|
|
137
|
+
matcher = on_command("inspect", aliases={"查看"}, priority=1)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
@matcher.handle()
|
|
141
|
+
async def inspect(session: Uninfo):
|
|
142
|
+
texts = [
|
|
143
|
+
f"平台名: {session.adapter} | {session.scope}",
|
|
144
|
+
f"用户ID: {session.user.name + ' | ' if session.user.name else ''}{session.user.id}",
|
|
145
|
+
f"自身ID: {session.self_id}",
|
|
146
|
+
f"事件场景: {session.scene.type.name}",
|
|
147
|
+
f"频道 ID: {session.scene.name + ' | ' if session.scene.name else ''}{session.scene.id}"
|
|
148
|
+
]
|
|
149
|
+
if session.scene.parent:
|
|
150
|
+
texts.append(f"群组 ID: {session.scene.parent.name + ' | ' if session.scene.parent.name else ''}{session.scene.parent.id}")
|
|
151
|
+
if session.member:
|
|
152
|
+
texts.append(f"成员 ID: {session.member.nick + ' | ' if session.member.nick else ''}{session.member.id}")
|
|
153
|
+
await matcher.send("\n".join(texts))
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## 支持的 adapter
|
|
157
|
+
|
|
158
|
+
- [x] OneBot v11
|
|
159
|
+
- [x] OneBot v12
|
|
160
|
+
- [x] Console
|
|
161
|
+
- [x] Kook (Kaiheila)
|
|
162
|
+
- [x] Telegram
|
|
163
|
+
- [x] Feishu
|
|
164
|
+
- [x] Discord
|
|
165
|
+
- [x] QQ
|
|
166
|
+
- [x] Satori
|
|
167
|
+
- [x] DoDo
|
|
168
|
+
- [x] Kritor
|
|
169
|
+
- [x] Mirai
|
|
170
|
+
- [ ] Tailchat
|
|
171
|
+
|
|
172
|
+
## 相关插件
|
|
173
|
+
|
|
174
|
+
- [nonebot-plugin-alconna](https://github.com/nonebot/plugin-alconna) 强大的 Nonebot2 命令匹配拓展,支持富文本/多媒体解析,跨平台消息收发
|
|
175
|
+
## 鸣谢
|
|
176
|
+
|
|
177
|
+
- [nonebot-plugin-session](https://github.com/noneplugin/nonebot-plugin-session) 与 [nonebot-plugin-userinfo](https://github.com/noneplugin/nonebot-plugin-userinfo) 项目的灵感来源以及部分实现的参考
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<a href="https://nonebot.dev/">
|
|
4
|
+
<img src="https://nonebot.dev/logo.png" width="200" height="200" alt="nonebot">
|
|
5
|
+
</a>
|
|
6
|
+
|
|
7
|
+
# nonebot-plugin-uninfo
|
|
8
|
+
|
|
9
|
+
_✨ [Nonebot2](https://github.com/nonebot/nonebot2) 多平台的会话信息(用户、群组、频道)获取插件 ✨_
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<img src="https://img.shields.io/github/license/RF-Tar-Railt/nonebot-plugin-uninfo" alt="license">
|
|
13
|
+
<img src="https://img.shields.io/badge/python-3.9+-blue.svg" alt="Python">
|
|
14
|
+
<img src="https://img.shields.io/badge/nonebot-2.3.0+-red.svg" alt="NoneBot">
|
|
15
|
+
<a href="https://pypi.org/project/nonebot-plugin-uninfo">
|
|
16
|
+
<img src="https://badgen.net/pypi/v/nonebot-plugin-uninfo" alt="pypi">
|
|
17
|
+
</a>
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
本插件提供了多个模型,可以从不同适配器的 `Bot` 和 `Event` 中提取与会话相关的属性
|
|
23
|
+
|
|
24
|
+
## 安装
|
|
25
|
+
|
|
26
|
+
- 使用 nb-cli
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
nb plugin install nonebot-plugin-uninfo
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
- 使用 pip
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
pip install nonebot-plugin-uninfo
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 使用
|
|
39
|
+
|
|
40
|
+
### 获取 `Session`:
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from nonebot_plugin_uninfo import get_session
|
|
44
|
+
|
|
45
|
+
@matcher.handle()
|
|
46
|
+
async def handle(bot: Bot, event: Event):
|
|
47
|
+
session = await get_session(bot, event)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
或使用依赖注入的形式:
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from nonebot_plugin_uninfo import Uninfo, UniSession, Session
|
|
54
|
+
|
|
55
|
+
@matcher.handle()
|
|
56
|
+
async def handle(session: Session = UniSession()):
|
|
57
|
+
...
|
|
58
|
+
|
|
59
|
+
@matcher.handle()
|
|
60
|
+
async def handle1(session: Uninfo):
|
|
61
|
+
...
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 拉取用户/群组/频道列表:
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from nonebot_plugin_uninfo import get_interface
|
|
68
|
+
|
|
69
|
+
@matcher.handle()
|
|
70
|
+
async def handle(bot: Bot):
|
|
71
|
+
interface = await get_interface(bot)
|
|
72
|
+
if interface:
|
|
73
|
+
users = await interface.get_users()
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## 模型定义
|
|
77
|
+
|
|
78
|
+
### `User`
|
|
79
|
+
|
|
80
|
+
| 属性 | 类型 | 含义 | 备注 |
|
|
81
|
+
|----------|-------------|-------|------|
|
|
82
|
+
| `id` | str | 用户 id | |
|
|
83
|
+
| `name` | str \| None | 用户名称 | |
|
|
84
|
+
| `nick` | str \| None | 用户昵称 | 好友备注 |
|
|
85
|
+
| `avatar` | str \| None | 用户头像 | |
|
|
86
|
+
| `gender` | str | 用户性别 | |
|
|
87
|
+
|
|
88
|
+
### `Scene`
|
|
89
|
+
|
|
90
|
+
| 属性 | 类型 | 含义 | 备注 |
|
|
91
|
+
|----------|---------------|-------|-------------------------------------------------|
|
|
92
|
+
| `id` | str | 场景 id | |
|
|
93
|
+
| `type` | SceneType | 场景类型 | 可分为 `Private`, `Group`, `Guild` 和 `Channel_XXX` |
|
|
94
|
+
| `name` | str \| None | 场景名称 | |
|
|
95
|
+
| `avatar` | str \| None | 场景图标 | |
|
|
96
|
+
| `parent` | Scene \| None | 父级场景 | 适用于频道的二级群组场景, 或针对临时会话的来源群组 |
|
|
97
|
+
|
|
98
|
+
### `Member`
|
|
99
|
+
|
|
100
|
+
| 属性 | 类型 | 含义 | 备注 |
|
|
101
|
+
|-------------|------------------|---------|-------------------------------|
|
|
102
|
+
| `user` | User | 成员的用户信息 | |
|
|
103
|
+
| `nick` | str \| None | 成员昵称 | |
|
|
104
|
+
| `role` | str \| None | 成员角色组 | 当可能存在多个角色组时,此处会使用 level 最高的那个 |
|
|
105
|
+
| `mute` | MuteInfo \| None | 成员禁言信息 | |
|
|
106
|
+
| `joined_at` | datetime \| None | 成员加入时间 | |
|
|
107
|
+
|
|
108
|
+
### `Session`
|
|
109
|
+
|
|
110
|
+
| 属性 | 类型 | 含义 | 备注 |
|
|
111
|
+
|------------|----------------|--------|--------------------|
|
|
112
|
+
| `self_id` | str | 机器人 id | |
|
|
113
|
+
| `adapter` | str | 适配器名称 | |
|
|
114
|
+
| `scope` | str | 适配器范围 | 相比 adapter 更指向实际平台 |
|
|
115
|
+
| `scene` | Scene | 事件场景 | |
|
|
116
|
+
| `user` | User | 用户信息 | |
|
|
117
|
+
| `member` | Member \| None | 成员信息 | 仅适用于群组,频道场景 |
|
|
118
|
+
| `operator` | Member \| None | 操作者信息 | 仅适用于群组,频道场景 |
|
|
119
|
+
|
|
120
|
+
## 示例
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
from nonebot_plugin_uninfo import Uninfo
|
|
124
|
+
from nonebot import on_command
|
|
125
|
+
|
|
126
|
+
matcher = on_command("inspect", aliases={"查看"}, priority=1)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@matcher.handle()
|
|
130
|
+
async def inspect(session: Uninfo):
|
|
131
|
+
texts = [
|
|
132
|
+
f"平台名: {session.adapter} | {session.scope}",
|
|
133
|
+
f"用户ID: {session.user.name + ' | ' if session.user.name else ''}{session.user.id}",
|
|
134
|
+
f"自身ID: {session.self_id}",
|
|
135
|
+
f"事件场景: {session.scene.type.name}",
|
|
136
|
+
f"频道 ID: {session.scene.name + ' | ' if session.scene.name else ''}{session.scene.id}"
|
|
137
|
+
]
|
|
138
|
+
if session.scene.parent:
|
|
139
|
+
texts.append(f"群组 ID: {session.scene.parent.name + ' | ' if session.scene.parent.name else ''}{session.scene.parent.id}")
|
|
140
|
+
if session.member:
|
|
141
|
+
texts.append(f"成员 ID: {session.member.nick + ' | ' if session.member.nick else ''}{session.member.id}")
|
|
142
|
+
await matcher.send("\n".join(texts))
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## 支持的 adapter
|
|
146
|
+
|
|
147
|
+
- [x] OneBot v11
|
|
148
|
+
- [x] OneBot v12
|
|
149
|
+
- [x] Console
|
|
150
|
+
- [x] Kook (Kaiheila)
|
|
151
|
+
- [x] Telegram
|
|
152
|
+
- [x] Feishu
|
|
153
|
+
- [x] Discord
|
|
154
|
+
- [x] QQ
|
|
155
|
+
- [x] Satori
|
|
156
|
+
- [x] DoDo
|
|
157
|
+
- [x] Kritor
|
|
158
|
+
- [x] Mirai
|
|
159
|
+
- [ ] Tailchat
|
|
160
|
+
|
|
161
|
+
## 相关插件
|
|
162
|
+
|
|
163
|
+
- [nonebot-plugin-alconna](https://github.com/nonebot/plugin-alconna) 强大的 Nonebot2 命令匹配拓展,支持富文本/多媒体解析,跨平台消息收发
|
|
164
|
+
## 鸣谢
|
|
165
|
+
|
|
166
|
+
- [nonebot-plugin-session](https://github.com/noneplugin/nonebot-plugin-session) 与 [nonebot-plugin-userinfo](https://github.com/noneplugin/nonebot-plugin-userinfo) 项目的灵感来源以及部分实现的参考
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "nonebot-plugin-uninfo"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Universal Information Model for Nonebot2"
|
|
5
|
+
authors = [
|
|
6
|
+
{ name = "RF-Tar-Railt", email = "rf_tar_railt@qq.com" },
|
|
7
|
+
]
|
|
8
|
+
dependencies = [
|
|
9
|
+
"nonebot2>=2.3.0",
|
|
10
|
+
"importlib-metadata>=4.13.0",
|
|
11
|
+
]
|
|
12
|
+
requires-python = ">=3.9"
|
|
13
|
+
readme = "README.md"
|
|
14
|
+
|
|
15
|
+
[project.license]
|
|
16
|
+
text = "MIT"
|
|
17
|
+
|
|
18
|
+
[build-system]
|
|
19
|
+
requires = [
|
|
20
|
+
"pdm-backend",
|
|
21
|
+
]
|
|
22
|
+
build-backend = "pdm.backend"
|
|
23
|
+
|
|
24
|
+
[tool.pdm]
|
|
25
|
+
distribution = true
|
|
26
|
+
|
|
27
|
+
[tool.pdm.dev-dependencies]
|
|
28
|
+
dev = [
|
|
29
|
+
"isort>=5.13.2",
|
|
30
|
+
"black>=24.4.2",
|
|
31
|
+
"loguru>=0.7.2",
|
|
32
|
+
"ruff>=0.4.2",
|
|
33
|
+
"fastapi>=0.110.2",
|
|
34
|
+
"uvicorn[standard]>=0.28.1",
|
|
35
|
+
"pydantic>=2.7.0",
|
|
36
|
+
"nonebot2[httpx,websockets]>=2.3.0",
|
|
37
|
+
"nonebot-adapter-console>=0.5.0",
|
|
38
|
+
"nonebot-adapter-ding>=2.0.0a16",
|
|
39
|
+
"nonebot-adapter-discord>=0.1.8",
|
|
40
|
+
"nonebot-adapter-dodo>=0.2.1",
|
|
41
|
+
"nonebot-adapter-feishu>=2.6.0",
|
|
42
|
+
"nonebot-adapter-kaiheila>=0.3.4",
|
|
43
|
+
"nonebot-adapter-mirai>=2.3.3",
|
|
44
|
+
"nonebot-adapter-mirai2>=0.0.22",
|
|
45
|
+
"nonebot-adapter-minecraft>=1.3.2",
|
|
46
|
+
"nonebot-adapter-onebot>=2.4.3",
|
|
47
|
+
"nonebot-adapter-qq>=1.5.1",
|
|
48
|
+
"nonebot-adapter-red>=0.9.0",
|
|
49
|
+
"nonebot-adapter-satori>=0.12.5",
|
|
50
|
+
"nonebot-adapter-telegram>=0.1.0b17",
|
|
51
|
+
"nonebot-adapter-kritor>=0.3.0",
|
|
52
|
+
"nonebot-adapter-tailchat>=0.1.0b7",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[tool.pdm.build]
|
|
56
|
+
includes = [
|
|
57
|
+
"src/nonebot_plugin_uninfo",
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
[tool.pdm.scripts.format]
|
|
61
|
+
composite = [
|
|
62
|
+
"isort ./src/ ",
|
|
63
|
+
"black ./src/ ",
|
|
64
|
+
"ruff check ./src/",
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
[tool.black]
|
|
68
|
+
line-length = 120
|
|
69
|
+
target-version = [
|
|
70
|
+
"py39",
|
|
71
|
+
"py310",
|
|
72
|
+
"py311",
|
|
73
|
+
"py312",
|
|
74
|
+
]
|
|
75
|
+
include = "\\.pyi?$"
|
|
76
|
+
extend-exclude = ""
|
|
77
|
+
|
|
78
|
+
[tool.isort]
|
|
79
|
+
profile = "black"
|
|
80
|
+
line_length = 120
|
|
81
|
+
length_sort = false
|
|
82
|
+
skip_gitignore = true
|
|
83
|
+
force_sort_within_sections = true
|
|
84
|
+
extra_standard_library = [
|
|
85
|
+
"typing_extensions",
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
[tool.ruff]
|
|
89
|
+
line-length = 120
|
|
90
|
+
target-version = "py39"
|
|
91
|
+
|
|
92
|
+
[tool.ruff.lint]
|
|
93
|
+
select = [
|
|
94
|
+
"E",
|
|
95
|
+
"W",
|
|
96
|
+
"F",
|
|
97
|
+
"UP",
|
|
98
|
+
"C",
|
|
99
|
+
"T",
|
|
100
|
+
"PYI",
|
|
101
|
+
"PT",
|
|
102
|
+
"Q",
|
|
103
|
+
]
|
|
104
|
+
ignore = [
|
|
105
|
+
"C901",
|
|
106
|
+
"T201",
|
|
107
|
+
"E731",
|
|
108
|
+
"E402",
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
[tool.pyright]
|
|
112
|
+
pythonVersion = "3.9"
|
|
113
|
+
pythonPlatform = "All"
|
|
114
|
+
typeCheckingMode = "basic"
|
|
115
|
+
reportShadowedImports = false
|
|
116
|
+
disableBytesTypePromotions = true
|
|
117
|
+
|
|
118
|
+
[tool.pyright.defineConstant]
|
|
119
|
+
PYDANTIC_V2 = true
|
|
120
|
+
|
|
121
|
+
[tool.nonebot]
|
|
122
|
+
adapters = [
|
|
123
|
+
{ name = "OneBot V11", module_name = "nonebot.adapters.onebot.v11" },
|
|
124
|
+
{ name = "Satori", module_name = "nonebot.adapters.satori" },
|
|
125
|
+
{ name = "QQ", module_name = "nonebot.adapters.qq" },
|
|
126
|
+
]
|
|
127
|
+
plugins = [
|
|
128
|
+
"example",
|
|
129
|
+
]
|
|
130
|
+
plugin_dirs = []
|
|
131
|
+
builtin_plugins = []
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from nonebot.plugin import PluginMetadata
|
|
2
|
+
|
|
3
|
+
from .constraint import SupportAdapterModule
|
|
4
|
+
from .fetch import InfoFetcher as InfoFetcher
|
|
5
|
+
from .model import Session as Session
|
|
6
|
+
from .params import Interface as Interface
|
|
7
|
+
from .params import QryItrface as QryItrface
|
|
8
|
+
from .params import QueryInterface as QueryInterface
|
|
9
|
+
from .params import UniSession as UniSession
|
|
10
|
+
from .params import Uninfo as Uninfo
|
|
11
|
+
from .params import get_interface as get_interface
|
|
12
|
+
from .params import get_session as get_session
|
|
13
|
+
from .permission import ADMIN as ADMIN
|
|
14
|
+
from .permission import GROUP as GROUP
|
|
15
|
+
from .permission import GUILD as GUILD
|
|
16
|
+
from .permission import MEMBER as MEMBER
|
|
17
|
+
from .permission import OWNER as OWNER
|
|
18
|
+
from .permission import PRIVATE as PRIVATE
|
|
19
|
+
from .permission import ROLE_IN as ROLE_IN
|
|
20
|
+
from .permission import ROLE_LEVEL as ROLE_LEVEL
|
|
21
|
+
from .permission import ROLE_NOT_IN as ROLE_NOT_IN
|
|
22
|
+
from .permission import SCENE_IN as SCENE_IN
|
|
23
|
+
from .permission import SCENE_NOT_IN as SCENE_NOT_IN
|
|
24
|
+
from .permission import USER_IN as USER_IN
|
|
25
|
+
from .permission import USER_NOT_IN as USER_NOT_IN
|
|
26
|
+
|
|
27
|
+
__plugin_meta__ = PluginMetadata(
|
|
28
|
+
name="通用信息",
|
|
29
|
+
description="多平台的会话信息(用户、群组、频道)获取插件",
|
|
30
|
+
usage="session_info: Uninfo",
|
|
31
|
+
type="library",
|
|
32
|
+
homepage="https://github.com/RF-Tar-Railt/nonebot-plugin-uninfo",
|
|
33
|
+
supported_adapters=set(SupportAdapterModule.__members__.values()),
|
|
34
|
+
)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
import os
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import cast
|
|
5
|
+
from warnings import warn
|
|
6
|
+
|
|
7
|
+
from nonebot import get_adapters
|
|
8
|
+
|
|
9
|
+
from ..fetch import InfoFetcher
|
|
10
|
+
from ..loader import BaseLoader
|
|
11
|
+
|
|
12
|
+
root = Path(__file__).parent
|
|
13
|
+
loaders: dict[str, BaseLoader] = {}
|
|
14
|
+
_adapters = [path.stem for path in root.iterdir() if path.is_dir() and not path.stem.startswith("_")]
|
|
15
|
+
for name in _adapters:
|
|
16
|
+
try:
|
|
17
|
+
module = importlib.import_module(f".{name}", __package__)
|
|
18
|
+
loader = cast(BaseLoader, getattr(module, "Loader")())
|
|
19
|
+
loaders[loader.get_adapter().value] = loader
|
|
20
|
+
except Exception as e:
|
|
21
|
+
warn(f"Failed to import uniseg adapter {name}: {e}", RuntimeWarning, 5)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
INFO_FETCHER_MAPPING: dict[str, InfoFetcher] = {}
|
|
25
|
+
adapters = {}
|
|
26
|
+
try:
|
|
27
|
+
adapters = get_adapters()
|
|
28
|
+
except Exception as e:
|
|
29
|
+
warn(f"Failed to get nonebot adapters: {e}", RuntimeWarning, 5)
|
|
30
|
+
|
|
31
|
+
if os.environ.get("PLUGIN_UNINFO_TESTENV"):
|
|
32
|
+
for adapter, loader in loaders.items():
|
|
33
|
+
try:
|
|
34
|
+
INFO_FETCHER_MAPPING[adapter] = loaders[adapter].get_fetcher()
|
|
35
|
+
except Exception as e:
|
|
36
|
+
warn(f"Failed to load uniseg adapter {adapter}: {e}", RuntimeWarning, 5)
|
|
37
|
+
elif not adapters:
|
|
38
|
+
warn(
|
|
39
|
+
"No adapters found, please make sure you have installed at least one adapter.",
|
|
40
|
+
RuntimeWarning,
|
|
41
|
+
5,
|
|
42
|
+
)
|
|
43
|
+
else:
|
|
44
|
+
for adapter in adapters:
|
|
45
|
+
if adapter in loaders:
|
|
46
|
+
try:
|
|
47
|
+
INFO_FETCHER_MAPPING[adapter] = loaders[adapter].get_fetcher()
|
|
48
|
+
except Exception as e:
|
|
49
|
+
warn(f"Failed to load uniseg adapter {adapter}: {e}", RuntimeWarning, 5)
|
|
50
|
+
else:
|
|
51
|
+
warn(
|
|
52
|
+
f"Adapter {adapter} is not found in the uniseg.adapters,"
|
|
53
|
+
f"please go to the github repo and create an issue for it.",
|
|
54
|
+
RuntimeWarning,
|
|
55
|
+
5,
|
|
56
|
+
)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from nonebot_plugin_uninfo.constraint import SupportAdapter
|
|
2
|
+
from nonebot_plugin_uninfo.fetch import InfoFetcher
|
|
3
|
+
from nonebot_plugin_uninfo.loader import BaseLoader
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Loader(BaseLoader):
|
|
7
|
+
def get_adapter(self) -> SupportAdapter:
|
|
8
|
+
return SupportAdapter.console
|
|
9
|
+
|
|
10
|
+
def get_fetcher(self) -> InfoFetcher:
|
|
11
|
+
from .main import fetcher
|
|
12
|
+
|
|
13
|
+
return fetcher
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from nonebot.adapters.console import Bot
|
|
4
|
+
from nonebot.adapters.console.event import Event
|
|
5
|
+
|
|
6
|
+
from nonebot_plugin_uninfo.constraint import SupportAdapter, SupportScope
|
|
7
|
+
from nonebot_plugin_uninfo.fetch import InfoFetcher as BaseInfoFetcher
|
|
8
|
+
from nonebot_plugin_uninfo.fetch import SuppliedData
|
|
9
|
+
from nonebot_plugin_uninfo.model import Scene, SceneType, User
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class InfoFetcher(BaseInfoFetcher):
|
|
13
|
+
def extract_user(self, data):
|
|
14
|
+
return User(
|
|
15
|
+
id=data["user_id"],
|
|
16
|
+
name=data["name"],
|
|
17
|
+
avatar=data["avatar"],
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
def extract_scene(self, data):
|
|
21
|
+
return Scene(
|
|
22
|
+
id=data["user_id"],
|
|
23
|
+
type=SceneType.PRIVATE,
|
|
24
|
+
name=data["name"],
|
|
25
|
+
avatar=data["avatar"],
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
def extract_member(self, data, user: Optional[User]):
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
async def query_user(self, bot: Bot):
|
|
32
|
+
raise NotImplementedError
|
|
33
|
+
|
|
34
|
+
async def query_scene(self, bot: Bot, guild_id: Optional[str]):
|
|
35
|
+
raise NotImplementedError
|
|
36
|
+
|
|
37
|
+
async def query_member(self, bot: Bot, guild_id: str):
|
|
38
|
+
raise NotImplementedError
|
|
39
|
+
|
|
40
|
+
def supply_self(self, bot: Bot) -> SuppliedData:
|
|
41
|
+
return {
|
|
42
|
+
"self_id": str(bot.self_id),
|
|
43
|
+
"adapter": SupportAdapter.console,
|
|
44
|
+
"scope": SupportScope.console,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
fetcher = InfoFetcher(SupportAdapter.console)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@fetcher.supply_wildcard
|
|
52
|
+
async def _(bot: Bot, event: Event):
|
|
53
|
+
return {
|
|
54
|
+
"user_id": event.user.id,
|
|
55
|
+
"name": event.user.nickname,
|
|
56
|
+
"avatar": f"https://emojicdn.elk.sh/{event.user.avatar}?style=twitter",
|
|
57
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from nonebot_plugin_uninfo.constraint import SupportAdapter
|
|
2
|
+
from nonebot_plugin_uninfo.fetch import InfoFetcher
|
|
3
|
+
from nonebot_plugin_uninfo.loader import BaseLoader
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Loader(BaseLoader):
|
|
7
|
+
def get_adapter(self) -> SupportAdapter:
|
|
8
|
+
return SupportAdapter.discord
|
|
9
|
+
|
|
10
|
+
def get_fetcher(self) -> InfoFetcher:
|
|
11
|
+
from .main import fetcher
|
|
12
|
+
|
|
13
|
+
return fetcher
|