ErisPulse 2.3.9.dev3__tar.gz → 2.4.0.dev2__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.
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/PKG-INFO +2 -1
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/README.md +2 -1
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/pyproject.toml +1 -1
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Bases/adapter.py +166 -118
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Bases/adapter.pyi +22 -10
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Bases/manager.py +38 -40
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Bases/manager.pyi +5 -5
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Bases/module.py +22 -20
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Bases/module.pyi +4 -3
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/__init__.py +15 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/__init__.pyi +2 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/base.py +32 -24
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/base.pyi +2 -1
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/command.py +187 -150
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/command.pyi +9 -8
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/message.py +43 -29
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/message.pyi +2 -1
- erispulse-2.4.0.dev2/src/ErisPulse/Core/Event/message_builder.py +270 -0
- erispulse-2.4.0.dev2/src/ErisPulse/Core/Event/message_builder.pyi +163 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/meta.py +39 -28
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/meta.pyi +2 -1
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/notice.py +47 -34
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/notice.pyi +2 -1
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/request.py +32 -23
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/request.pyi +2 -1
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/session_type.py +91 -81
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/session_type.pyi +27 -21
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/wrapper.py +341 -108
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Event/wrapper.pyi +142 -18
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/__init__.py +2 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/__init__.pyi +1 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/adapter.py +370 -118
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/adapter.pyi +80 -12
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/config.py +30 -24
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/config.pyi +2 -2
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/lifecycle.py +65 -47
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/lifecycle.pyi +4 -3
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/logger.py +42 -102
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/logger.pyi +22 -41
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/module.py +128 -125
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/module.pyi +16 -16
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/router.py +123 -103
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/router.pyi +12 -11
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/storage.py +174 -146
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/storage.pyi +18 -8
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/bases/finder.py +51 -50
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/bases/finder.pyi +2 -1
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/adapter.py +87 -79
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/adapter.pyi +14 -14
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/bases/loader.py +48 -45
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/bases/loader.pyi +1 -1
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/module.py +417 -280
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/module.pyi +19 -19
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/strategy.py +29 -29
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/strategy.pyi +3 -3
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/runtime/frame_config.py +4 -4
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/runtime/frame_config.pyi +2 -2
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/sdk.py +5 -4
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/.gitignore +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/LICENSE +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/__init__.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/__init__.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/base.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/base.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/cli.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/cli.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/__init__.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/__init__.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/init.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/init.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/install.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/install.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/list.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/list.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/list_remote.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/list_remote.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/run.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/run.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/self_update.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/self_update.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/uninstall.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/uninstall.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/upgrade.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/commands/upgrade.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/console.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/console.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/registry.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/registry.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/utils/__init__.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/utils/__init__.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/utils/package_manager.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/CLI/utils/package_manager.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Bases/__init__.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/Core/Bases/__init__.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/__init__.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/__init__.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/__main__.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/__main__.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/__init__.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/__init__.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/adapter.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/adapter.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/bases/__init__.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/bases/__init__.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/cli.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/cli.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/module.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/finders/module.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/__init__.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/__init__.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/bases/__init__.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/loaders/bases/__init__.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/runtime/__init__.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/runtime/__init__.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/runtime/cleanup.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/runtime/cleanup.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/runtime/exceptions.py +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/runtime/exceptions.pyi +0 -0
- {erispulse-2.3.9.dev3 → erispulse-2.4.0.dev2}/src/ErisPulse/sdk.pyi +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ErisPulse
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0.dev2
|
|
4
4
|
Summary: ErisPulse 是一个模块化、可扩展的异步 Python SDK 框架,主要用于构建高效、可维护的机器人应用程序。
|
|
5
5
|
Author-email: ErisDev <erisdev@88.com>
|
|
6
6
|
Maintainer-email: "艾莉丝·格雷拉特(WSu2059)" <wsu2059@qq.com>
|
|
@@ -205,6 +205,7 @@ epsdk run main.py --reload
|
|
|
205
205
|
- [OneBot12](https://github.com/ErisPulse/ErisPulse-OneBot12Adapter) - OneBot12 标准
|
|
206
206
|
- [邮件](https://github.com/ErisPulse/ErisPulse-EmailAdapter) - 邮件收发处理
|
|
207
207
|
- [沙箱](https://github.com/ErisPulse/ErisPulse-SandboxAdapter) - 网页调试界面,无需接入实际平台
|
|
208
|
+
- [Kook](https://github.com/shanfishapp/ErisPulse-KookAdapter) - Kook(开黑啦)即时通讯平台
|
|
208
209
|
|
|
209
210
|
查看 [适配器详情介绍](docs/zh-CN/platform-guide/README.md)
|
|
210
211
|
|
|
@@ -144,7 +144,8 @@ epsdk run main.py --reload
|
|
|
144
144
|
- [OneBot11](https://github.com/ErisPulse/ErisPulse-OneBot11Adapter) - 通用机器人接口标准
|
|
145
145
|
- [OneBot12](https://github.com/ErisPulse/ErisPulse-OneBot12Adapter) - OneBot12 标准
|
|
146
146
|
- [邮件](https://github.com/ErisPulse/ErisPulse-EmailAdapter) - 邮件收发处理
|
|
147
|
-
- [沙箱](https://github.com/ErisPulse/ErisPulse-SandboxAdapter) - 网页调试界面,无需接入实际平台
|
|
147
|
+
- [沙箱](https://github.com/ErisPulse/ErisPulse-SandboxAdapter) - 网页调试界面,无需接入实际平台
|
|
148
|
+
- [Kook](https://github.com/shanfishapp/ErisPulse-KookAdapter) - Kook(开黑啦)即时通讯平台
|
|
148
149
|
|
|
149
150
|
查看 [适配器详情介绍](docs/zh-CN/platform-guide/README.md)
|
|
150
151
|
|
|
@@ -10,27 +10,33 @@ ErisPulse 适配器基础模块
|
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
import asyncio
|
|
13
|
-
from
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
from abc import ABC, abstractmethod
|
|
14
|
+
from typing import Any
|
|
15
|
+
from collections.abc import Awaitable
|
|
16
|
+
|
|
17
17
|
|
|
18
18
|
class SendDSL:
|
|
19
19
|
"""
|
|
20
20
|
消息发送DSL基类
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
用于实现 Send.To(...).Func(...) 风格的链式调用接口
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
{!--< tips >!--}
|
|
25
25
|
1. 子类应实现具体的消息发送方法(如Text, Image等)
|
|
26
26
|
2. 通过__getattr__实现动态方法调用
|
|
27
27
|
{!--< /tips >!--}
|
|
28
28
|
"""
|
|
29
|
-
|
|
30
|
-
def __init__(
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
adapter: "BaseAdapter",
|
|
33
|
+
target_type: str | None = None,
|
|
34
|
+
target_id: str | None = None,
|
|
35
|
+
account_id: str | None = None,
|
|
36
|
+
):
|
|
31
37
|
"""
|
|
32
38
|
初始化DSL发送器
|
|
33
|
-
|
|
39
|
+
|
|
34
40
|
:param adapter: 所属适配器实例
|
|
35
41
|
:param target_type: 目标类型(可选)
|
|
36
42
|
:param target_id: 目标ID(可选)
|
|
@@ -41,14 +47,14 @@ class SendDSL:
|
|
|
41
47
|
self._target_id = target_id
|
|
42
48
|
self._target_to = target_id
|
|
43
49
|
self._account_id = account_id
|
|
44
|
-
|
|
50
|
+
|
|
45
51
|
def __getattr__(self, name: str):
|
|
46
52
|
"""
|
|
47
53
|
动态属性访问处理,实现大小写不敏感调用
|
|
48
|
-
|
|
54
|
+
|
|
49
55
|
1. 如果找到匹配的方法(忽略大小写),返回该方法
|
|
50
56
|
2. 如果没找到,打印警告并抛出 AttributeError
|
|
51
|
-
|
|
57
|
+
|
|
52
58
|
:param name: 属性名
|
|
53
59
|
:return: 匹配的方法或属性
|
|
54
60
|
:raises AttributeError: 当属性不存在时抛出
|
|
@@ -56,9 +62,9 @@ class SendDSL:
|
|
|
56
62
|
# 检查所有实际存在的方法
|
|
57
63
|
for attr_name in dir(self.__class__):
|
|
58
64
|
# 跳过特殊方法
|
|
59
|
-
if attr_name.startswith(
|
|
65
|
+
if attr_name.startswith("_"):
|
|
60
66
|
continue
|
|
61
|
-
|
|
67
|
+
|
|
62
68
|
# 大小写不敏感匹配
|
|
63
69
|
if attr_name.lower() == name.lower():
|
|
64
70
|
# 返回实际的方法绑定到当前实例
|
|
@@ -66,65 +72,76 @@ class SendDSL:
|
|
|
66
72
|
if callable(attr):
|
|
67
73
|
return attr.__get__(self, self.__class__)
|
|
68
74
|
return attr
|
|
69
|
-
|
|
75
|
+
|
|
70
76
|
# 没有找到匹配的方法,打印警告
|
|
71
|
-
from .. import logger
|
|
77
|
+
from ..logger import logger
|
|
78
|
+
|
|
72
79
|
logger.warning(
|
|
73
|
-
f"平台 {self._adapter.__class__.__name__} "
|
|
74
|
-
f"未实现 {name} 发送方法"
|
|
80
|
+
f"平台 {self._adapter.__class__.__name__} 未实现 {name} 发送方法"
|
|
75
81
|
)
|
|
76
|
-
|
|
82
|
+
|
|
77
83
|
# 抛出 AttributeError,这样 hasattr() 能正常工作
|
|
78
|
-
raise AttributeError(
|
|
79
|
-
|
|
80
|
-
def At(self, **kwargs):
|
|
81
|
-
from .. import logger
|
|
82
|
-
logger.warning(
|
|
83
|
-
f"平台 {self._adapter.__class__.__name__} 未实现 At 方法,该修饰方法将被忽略。"
|
|
84
|
-
f"参数: {kwargs}"
|
|
84
|
+
raise AttributeError(
|
|
85
|
+
f"'{self.__class__.__name__}' object has no attribute '{name}'"
|
|
85
86
|
)
|
|
86
|
-
|
|
87
|
-
def
|
|
88
|
-
|
|
87
|
+
|
|
88
|
+
def _unimplemented_modifier(self, method_name: str, **kwargs) -> "SendDSL":
|
|
89
|
+
"""处理未实现的修饰方法,记录警告并返回自身以保持链式调用"""
|
|
90
|
+
from ..logger import logger
|
|
91
|
+
|
|
89
92
|
logger.warning(
|
|
90
|
-
f"平台 {self._adapter.__class__.__name__} 未实现
|
|
93
|
+
f"平台 {self._adapter.__class__.__name__} 未实现 {method_name} 方法,该修饰方法将被忽略。"
|
|
91
94
|
f"参数: {kwargs}"
|
|
92
95
|
)
|
|
93
|
-
return self
|
|
96
|
+
return self
|
|
97
|
+
|
|
98
|
+
def At(self, **kwargs):
|
|
99
|
+
return self._unimplemented_modifier("At", **kwargs)
|
|
100
|
+
|
|
101
|
+
def Reply(self, **kwargs):
|
|
102
|
+
return self._unimplemented_modifier("Reply", **kwargs)
|
|
103
|
+
|
|
94
104
|
def AtAll(self, **kwargs):
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
logger.warning(
|
|
111
|
-
f"平台 {self._adapter.__class__.__name__} 未实现 Raw_json 方法,该修饰方法将被忽略。"
|
|
112
|
-
f"参数: {kwargs}"
|
|
105
|
+
return self._unimplemented_modifier("AtAll", **kwargs)
|
|
106
|
+
|
|
107
|
+
def Raw_ob12(self, message, **kwargs):
|
|
108
|
+
"""
|
|
109
|
+
发送 OneBot12 格式消息段(必须由适配器子类重写)
|
|
110
|
+
|
|
111
|
+
:param message: OneBot12 消息段列表或单个消息段
|
|
112
|
+
:param kwargs: 其他参数
|
|
113
|
+
:return: asyncio.Task
|
|
114
|
+
"""
|
|
115
|
+
from ..logger import logger
|
|
116
|
+
|
|
117
|
+
logger.error(
|
|
118
|
+
f"平台 {self._adapter.__class__.__name__} 未实现 Raw_ob12 方法,"
|
|
119
|
+
f"消息未被发送。适配器必须实现此方法以支持 OneBot12 消息段发送。"
|
|
113
120
|
)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
121
|
+
|
|
122
|
+
async def _not_impl():
|
|
123
|
+
return {
|
|
124
|
+
"status": "failed",
|
|
125
|
+
"retcode": 10002,
|
|
126
|
+
"data": None,
|
|
127
|
+
"message_id": "",
|
|
128
|
+
"message": f"平台 {self._adapter.__class__.__name__} 未实现 Raw_ob12 方法",
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return asyncio.create_task(_not_impl())
|
|
132
|
+
|
|
133
|
+
def To(self, target_type: str = None, target_id: str | int = None) -> "SendDSL":
|
|
117
134
|
"""
|
|
118
135
|
设置消息目标
|
|
119
|
-
|
|
136
|
+
|
|
120
137
|
支持自动类型转换:
|
|
121
138
|
- 当 target_type 为 "private" 时,自动转换为 "user"
|
|
122
139
|
- 当只提供 target_id(字符串或数字)时,默认推断为 "user"
|
|
123
|
-
|
|
140
|
+
|
|
124
141
|
:param target_type: 目标类型(可选)
|
|
125
142
|
:param target_id: 目标ID(可选)
|
|
126
143
|
:return: SendDSL实例
|
|
127
|
-
|
|
144
|
+
|
|
128
145
|
:example:
|
|
129
146
|
>>> # 标准用法
|
|
130
147
|
>>> adapter.Send.To("user", "123").Text("Hello")
|
|
@@ -134,12 +151,12 @@ class SendDSL:
|
|
|
134
151
|
>>> adapter.Send.To("123").Text("Hello")
|
|
135
152
|
"""
|
|
136
153
|
from ..Event.session_type import is_standard_type
|
|
137
|
-
|
|
154
|
+
|
|
138
155
|
# 处理简化形式:只提供一个参数作为 target_id
|
|
139
156
|
if target_id is None and target_type is not None:
|
|
140
157
|
target_id = target_type
|
|
141
158
|
target_type = None
|
|
142
|
-
|
|
159
|
+
|
|
143
160
|
# 如果没有明确指定 target_type,尝试推断
|
|
144
161
|
if target_type is None:
|
|
145
162
|
# 将 target_id 作为字符串处理
|
|
@@ -147,45 +164,50 @@ class SendDSL:
|
|
|
147
164
|
# 默认推断为 user(对应 private)
|
|
148
165
|
# 这里我们假设如果只提供 ID,通常是发送给用户
|
|
149
166
|
target_type = "user"
|
|
150
|
-
|
|
167
|
+
|
|
151
168
|
# 自动转换 private → user
|
|
152
169
|
if target_type == "private":
|
|
153
170
|
target_type = "user"
|
|
154
|
-
|
|
171
|
+
|
|
155
172
|
return self.__class__(self._adapter, target_type, target_id, self._account_id)
|
|
156
173
|
|
|
157
|
-
def Using(self, account_id:
|
|
174
|
+
def Using(self, account_id: str | int) -> "SendDSL":
|
|
158
175
|
"""
|
|
159
176
|
设置发送账号
|
|
160
|
-
|
|
177
|
+
|
|
161
178
|
:param _account_id: 发送账号
|
|
162
179
|
:return: SendDSL实例
|
|
163
|
-
|
|
180
|
+
|
|
164
181
|
:example:
|
|
165
182
|
>>> adapter.Send.Using("bot1").To("123").Text("Hello")
|
|
166
183
|
>>> adapter.Send.To("123").Using("bot1").Text("Hello") # 支持乱序
|
|
167
184
|
"""
|
|
168
|
-
return self.__class__(
|
|
169
|
-
|
|
170
|
-
|
|
185
|
+
return self.__class__(
|
|
186
|
+
self._adapter, self._target_type, self._target_id, account_id
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
def Account(self, account_id: str | int) -> "SendDSL":
|
|
171
190
|
"""
|
|
172
191
|
设置发送账号
|
|
173
|
-
|
|
192
|
+
|
|
174
193
|
:param _account_id: 发送账号
|
|
175
194
|
:return: SendDSL实例
|
|
176
|
-
|
|
195
|
+
|
|
177
196
|
:example:
|
|
178
197
|
>>> adapter.Send.Account("bot1").To("123").Text("Hello")
|
|
179
198
|
>>> adapter.Send.To("123").Account("bot1").Text("Hello") # 支持乱序
|
|
180
199
|
"""
|
|
181
|
-
return self.__class__(
|
|
200
|
+
return self.__class__(
|
|
201
|
+
self._adapter, self._target_type, self._target_id, account_id
|
|
202
|
+
)
|
|
182
203
|
|
|
183
|
-
|
|
204
|
+
|
|
205
|
+
class BaseAdapter(ABC):
|
|
184
206
|
"""
|
|
185
207
|
适配器基类
|
|
186
|
-
|
|
208
|
+
|
|
187
209
|
提供与外部平台交互的标准接口,子类必须实现必要方法
|
|
188
|
-
|
|
210
|
+
|
|
189
211
|
{!--< tips >!--}
|
|
190
212
|
1. 必须实现call_api, start和shutdown方法
|
|
191
213
|
2. 可以自定义Send类实现平台特定的消息发送逻辑
|
|
@@ -193,66 +215,69 @@ class BaseAdapter:
|
|
|
193
215
|
4. 支持OneBot12协议的事件处理
|
|
194
216
|
{!--< /tips >!--}
|
|
195
217
|
"""
|
|
196
|
-
|
|
218
|
+
|
|
197
219
|
class Send(SendDSL):
|
|
198
220
|
"""
|
|
199
221
|
消息发送DSL实现
|
|
200
|
-
|
|
222
|
+
|
|
201
223
|
{!--< tips >!--}
|
|
202
224
|
1. 子类可以重写Text方法提供平台特定实现
|
|
203
225
|
2. 可以添加新的消息类型(如Image, Voice等)
|
|
204
226
|
{!--< /tips >!--}
|
|
205
227
|
"""
|
|
206
|
-
|
|
228
|
+
|
|
207
229
|
def Example(self, text: str) -> Awaitable[Any]:
|
|
208
230
|
"""
|
|
209
231
|
示例消息发送方法
|
|
210
|
-
|
|
232
|
+
|
|
211
233
|
:param text: 文本内容
|
|
212
234
|
:return: 异步任务
|
|
213
235
|
:example:
|
|
214
236
|
>>> await adapter.Send.To("123").Example("Hello")
|
|
215
237
|
"""
|
|
238
|
+
mock_response = {
|
|
239
|
+
"status": "ok",
|
|
240
|
+
"retcode": 0,
|
|
241
|
+
"data": {"message_id": "1234567890", "time": 1755801512},
|
|
242
|
+
"message_id": "1234567890",
|
|
243
|
+
"message": "",
|
|
244
|
+
"echo": None,
|
|
245
|
+
"example_raw": {
|
|
246
|
+
"result": "success",
|
|
247
|
+
},
|
|
248
|
+
}
|
|
216
249
|
|
|
217
|
-
text = {
|
|
218
|
-
"status": "ok",
|
|
219
|
-
"retcode": 0,
|
|
220
|
-
"data": {
|
|
221
|
-
"message_id": "1234567890",
|
|
222
|
-
"time": 1755801512
|
|
223
|
-
},
|
|
224
|
-
"message_id": "1234567890",
|
|
225
|
-
"message": "",
|
|
226
|
-
"echo": None,
|
|
227
|
-
"example_raw": {
|
|
228
|
-
"result": "success",
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
250
|
async def _send_example():
|
|
232
|
-
from .. import logger
|
|
251
|
+
from ..logger import logger
|
|
252
|
+
|
|
233
253
|
logger.info(f"发送示例消息: {text}")
|
|
234
|
-
return
|
|
254
|
+
return mock_response
|
|
255
|
+
|
|
235
256
|
return asyncio.create_task(_send_example())
|
|
236
257
|
|
|
237
258
|
def Raw_ob12(self, message, **kwargs: Any) -> Awaitable[Any]:
|
|
238
259
|
"""
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
260
|
+
发送 OneBot12 格式消息段(必须由适配器子类重写)
|
|
261
|
+
|
|
262
|
+
此方法是反向转换(OneBot12 → 平台)的统一入口,适配器必须重写此方法。
|
|
263
|
+
未重写时,基类默认实现会记录错误日志并返回标准错误响应。
|
|
264
|
+
|
|
244
265
|
:param message: OneBot12 格式的消息段数组或单个消息段
|
|
266
|
+
[
|
|
267
|
+
{"type": "text", "data": {"text": "Hello"}},
|
|
268
|
+
{"type": "image", "data": {"file": "https://..."}},
|
|
269
|
+
]
|
|
245
270
|
:param kwargs: 其他参数
|
|
246
|
-
:return:
|
|
247
|
-
|
|
271
|
+
:return: asyncio.Task,await 后返回标准响应格式
|
|
272
|
+
|
|
248
273
|
:example:
|
|
249
274
|
>>> # 用户调用
|
|
250
275
|
>>> await adapter.Send.To("user", "123").Raw_ob12([
|
|
251
276
|
>>> {"type": "text", "data": {"text": "Hello"}},
|
|
252
|
-
>>> {"type": "image", "data": {"
|
|
277
|
+
>>> {"type": "image", "data": {"file": "https://..."}}
|
|
253
278
|
>>> ])
|
|
254
|
-
|
|
255
|
-
>>> #
|
|
279
|
+
|
|
280
|
+
>>> # 适配器子类重写示例(必须)
|
|
256
281
|
>>> def Raw_ob12(self, message, **kwargs):
|
|
257
282
|
>>> return asyncio.create_task(
|
|
258
283
|
>>> self._adapter.call_api(
|
|
@@ -265,20 +290,32 @@ class BaseAdapter:
|
|
|
265
290
|
>>> )
|
|
266
291
|
>>> )
|
|
267
292
|
"""
|
|
293
|
+
|
|
268
294
|
async def _send_raw():
|
|
269
|
-
from .. import logger
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
295
|
+
from ..logger import logger
|
|
296
|
+
|
|
297
|
+
logger.error(
|
|
298
|
+
f"适配器 {self._adapter.__class__.__name__} 未实现 Raw_ob12 方法,"
|
|
299
|
+
f"消息未被发送。适配器必须实现此方法以支持 OneBot12 消息段发送。"
|
|
300
|
+
)
|
|
301
|
+
return {
|
|
302
|
+
"status": "failed",
|
|
303
|
+
"retcode": 10002,
|
|
304
|
+
"data": None,
|
|
305
|
+
"message_id": "",
|
|
306
|
+
"message": f"适配器 {self._adapter.__class__.__name__} 未实现 Raw_ob12 方法",
|
|
307
|
+
}
|
|
308
|
+
|
|
273
309
|
return asyncio.create_task(_send_raw())
|
|
274
310
|
|
|
275
311
|
def __init__(self):
|
|
276
312
|
self.Send = self.__class__.Send(self)
|
|
277
313
|
|
|
314
|
+
@abstractmethod
|
|
278
315
|
async def call_api(self, endpoint: str, **params: Any) -> Any:
|
|
279
316
|
"""
|
|
280
317
|
调用平台API的抽象方法
|
|
281
|
-
|
|
318
|
+
|
|
282
319
|
:param endpoint: API端点
|
|
283
320
|
:param params: API参数
|
|
284
321
|
:return: API调用结果
|
|
@@ -286,54 +323,65 @@ class BaseAdapter:
|
|
|
286
323
|
"""
|
|
287
324
|
raise NotImplementedError("适配器必须实现call_api方法")
|
|
288
325
|
|
|
326
|
+
@abstractmethod
|
|
289
327
|
async def start(self) -> None:
|
|
290
328
|
"""
|
|
291
329
|
启动适配器的抽象方法
|
|
292
|
-
|
|
330
|
+
|
|
293
331
|
:raises NotImplementedError: 必须由子类实现
|
|
294
332
|
"""
|
|
295
333
|
raise NotImplementedError("适配器必须实现start方法")
|
|
296
|
-
|
|
334
|
+
|
|
335
|
+
@abstractmethod
|
|
297
336
|
async def shutdown(self) -> None:
|
|
298
337
|
"""
|
|
299
338
|
关闭适配器的抽象方法
|
|
300
|
-
|
|
339
|
+
|
|
301
340
|
:raises NotImplementedError: 必须由子类实现
|
|
302
341
|
"""
|
|
303
342
|
raise NotImplementedError("适配器必须实现shutdown方法")
|
|
304
|
-
|
|
343
|
+
|
|
305
344
|
async def emit(self) -> None:
|
|
306
|
-
from .. import logger
|
|
307
|
-
logger.error("适配器调用了一个被弃用的原生方法emit,请检查适配器的实现,如果你是开发者请查看ErisPulse的文档进行更新。如果你是普通用户请查看本适配器是否有更新")
|
|
345
|
+
from ..logger import logger
|
|
308
346
|
|
|
309
|
-
|
|
347
|
+
logger.error(
|
|
348
|
+
"适配器调用了一个被弃用的原生方法emit,请检查适配器的实现,如果你是开发者请查看ErisPulse的文档进行更新。如果你是普通用户请查看本适配器是否有更新"
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
def send(
|
|
352
|
+
self, target_type: str, target_id: str, message: Any, **kwargs: Any
|
|
353
|
+
) -> asyncio.Task:
|
|
310
354
|
"""
|
|
311
355
|
发送消息的便捷方法,返回一个 asyncio Task
|
|
312
|
-
|
|
356
|
+
|
|
313
357
|
:param target_type: 目标类型
|
|
314
358
|
:param target_id: 目标ID
|
|
315
359
|
:param message: 消息内容
|
|
316
360
|
:param kwargs: 其他参数
|
|
317
361
|
- method: 发送方法名(默认为"Text")
|
|
318
362
|
:return: asyncio.Task 对象,用户可以自主决定是否等待
|
|
319
|
-
|
|
363
|
+
|
|
320
364
|
:raises AttributeError: 当发送方法不存在时抛出
|
|
321
|
-
|
|
365
|
+
|
|
322
366
|
:example:
|
|
323
367
|
>>> task = adapter.send("user", "123", "Hello")
|
|
324
368
|
>>> # 用户可以选择等待: result = await task
|
|
325
369
|
>>> # 或者不等待让其在后台执行
|
|
326
370
|
>>> await adapter.send("group", "456", "Hello", method="Markdown") # 直接等待
|
|
327
371
|
"""
|
|
372
|
+
|
|
328
373
|
async def _send_wrapper():
|
|
329
374
|
method_name = kwargs.pop("method", "Text")
|
|
330
375
|
method = getattr(self.Send.To(target_type, target_id), method_name, None)
|
|
331
376
|
if not method:
|
|
332
|
-
raise AttributeError(
|
|
377
|
+
raise AttributeError(
|
|
378
|
+
f"未找到 {method_name} 方法,请确保已在 Send 类中定义"
|
|
379
|
+
)
|
|
333
380
|
return await method(message, **kwargs)
|
|
334
|
-
|
|
381
|
+
|
|
335
382
|
return asyncio.create_task(_send_wrapper())
|
|
336
383
|
|
|
384
|
+
|
|
337
385
|
__all__ = [
|
|
338
386
|
"BaseAdapter",
|
|
339
387
|
"SendDSL",
|
|
@@ -16,7 +16,9 @@ ErisPulse 适配器基础模块
|
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
18
|
import asyncio
|
|
19
|
-
from
|
|
19
|
+
from abc import ABC, abstractmethod
|
|
20
|
+
from typing import Any
|
|
21
|
+
from collections.abc import Awaitable
|
|
20
22
|
|
|
21
23
|
class SendDSL:
|
|
22
24
|
"""
|
|
@@ -29,7 +31,7 @@ class SendDSL:
|
|
|
29
31
|
2. 通过__getattr__实现动态方法调用
|
|
30
32
|
{!--< /tips >!--}
|
|
31
33
|
"""
|
|
32
|
-
def __init__(self: None, adapter: BaseAdapter, target_type:
|
|
34
|
+
def __init__(self: None, adapter: BaseAdapter, target_type: str | None = ..., target_id: str | None = ..., account_id: str | None = ...) -> ...:
|
|
33
35
|
"""
|
|
34
36
|
初始化DSL发送器
|
|
35
37
|
|
|
@@ -51,17 +53,27 @@ class SendDSL:
|
|
|
51
53
|
:raises AttributeError: 当属性不存在时抛出
|
|
52
54
|
"""
|
|
53
55
|
...
|
|
56
|
+
def _unimplemented_modifier(self: object, method_name: str, **kwargs: ...) -> SendDSL:
|
|
57
|
+
"""
|
|
58
|
+
处理未实现的修饰方法,记录警告并返回自身以保持链式调用
|
|
59
|
+
"""
|
|
60
|
+
...
|
|
54
61
|
def At(self: object, **kwargs: ...) -> ...:
|
|
55
62
|
...
|
|
56
63
|
def Reply(self: object, **kwargs: ...) -> ...:
|
|
57
64
|
...
|
|
58
65
|
def AtAll(self: object, **kwargs: ...) -> ...:
|
|
59
66
|
...
|
|
60
|
-
def Raw_ob12(self: object, **kwargs: ...) -> ...:
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
def Raw_ob12(self: object, message: ..., **kwargs: ...) -> ...:
|
|
68
|
+
"""
|
|
69
|
+
发送 OneBot12 格式消息段(必须由适配器子类重写)
|
|
70
|
+
|
|
71
|
+
:param message: OneBot12 消息段列表或单个消息段
|
|
72
|
+
:param kwargs: 其他参数
|
|
73
|
+
:return: asyncio.Task
|
|
74
|
+
"""
|
|
63
75
|
...
|
|
64
|
-
def To(self: object, target_type: str = ..., target_id:
|
|
76
|
+
def To(self: object, target_type: str = ..., target_id: str | int = ...) -> SendDSL:
|
|
65
77
|
"""
|
|
66
78
|
设置消息目标
|
|
67
79
|
|
|
@@ -82,7 +94,7 @@ class SendDSL:
|
|
|
82
94
|
>>> adapter.Send.To("123").Text("Hello")
|
|
83
95
|
"""
|
|
84
96
|
...
|
|
85
|
-
def Using(self: object, account_id:
|
|
97
|
+
def Using(self: object, account_id: str | int) -> SendDSL:
|
|
86
98
|
"""
|
|
87
99
|
设置发送账号
|
|
88
100
|
|
|
@@ -94,7 +106,7 @@ class SendDSL:
|
|
|
94
106
|
>>> adapter.Send.To("123").Using("bot1").Text("Hello") # 支持乱序
|
|
95
107
|
"""
|
|
96
108
|
...
|
|
97
|
-
def Account(self: object, account_id:
|
|
109
|
+
def Account(self: object, account_id: str | int) -> SendDSL:
|
|
98
110
|
"""
|
|
99
111
|
设置发送账号
|
|
100
112
|
|
|
@@ -107,7 +119,7 @@ class SendDSL:
|
|
|
107
119
|
"""
|
|
108
120
|
...
|
|
109
121
|
|
|
110
|
-
class BaseAdapter:
|
|
122
|
+
class BaseAdapter(ABC):
|
|
111
123
|
"""
|
|
112
124
|
适配器基类
|
|
113
125
|
|
|
@@ -160,7 +172,7 @@ class BaseAdapter:
|
|
|
160
172
|
:return: asyncio.Task 对象,用户可以自主决定是否等待
|
|
161
173
|
|
|
162
174
|
:raises AttributeError: 当发送方法不存在时抛出
|
|
163
|
-
|
|
175
|
+
|
|
164
176
|
:example:
|
|
165
177
|
>>> task = adapter.send("user", "123", "Hello")
|
|
166
178
|
>>> # 用户可以选择等待: result = await task
|