ErisPulse 2.2.1.dev0__py3-none-any.whl → 2.3.0__py3-none-any.whl

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.
Files changed (36) hide show
  1. ErisPulse/Core/Bases/__init__.py +14 -0
  2. ErisPulse/Core/Bases/adapter.py +196 -0
  3. ErisPulse/Core/Bases/module.py +54 -0
  4. ErisPulse/Core/Event/__init__.py +14 -0
  5. ErisPulse/Core/Event/base.py +15 -2
  6. ErisPulse/Core/Event/command.py +21 -2
  7. ErisPulse/Core/Event/message.py +15 -0
  8. ErisPulse/Core/Event/meta.py +15 -0
  9. ErisPulse/Core/Event/notice.py +15 -0
  10. ErisPulse/Core/Event/request.py +16 -1
  11. ErisPulse/Core/__init__.py +38 -19
  12. ErisPulse/Core/{erispulse_config.py → _self_config.py} +27 -2
  13. ErisPulse/Core/adapter.py +374 -377
  14. ErisPulse/Core/config.py +137 -38
  15. ErisPulse/Core/exceptions.py +6 -1
  16. ErisPulse/Core/lifecycle.py +167 -0
  17. ErisPulse/Core/logger.py +97 -49
  18. ErisPulse/Core/module.py +279 -56
  19. ErisPulse/Core/router.py +112 -23
  20. ErisPulse/Core/storage.py +258 -77
  21. ErisPulse/Core/ux.py +635 -0
  22. ErisPulse/__init__.py +722 -244
  23. ErisPulse/__main__.py +1 -1999
  24. ErisPulse/utils/__init__.py +17 -0
  25. ErisPulse/utils/cli.py +1092 -0
  26. ErisPulse/utils/console.py +53 -0
  27. ErisPulse/utils/package_manager.py +845 -0
  28. ErisPulse/utils/reload_handler.py +111 -0
  29. {erispulse-2.2.1.dev0.dist-info → erispulse-2.3.0.dist-info}/METADATA +24 -6
  30. erispulse-2.3.0.dist-info/RECORD +34 -0
  31. {erispulse-2.2.1.dev0.dist-info → erispulse-2.3.0.dist-info}/WHEEL +1 -1
  32. {erispulse-2.2.1.dev0.dist-info → erispulse-2.3.0.dist-info}/licenses/LICENSE +1 -1
  33. ErisPulse/Core/env.py +0 -15
  34. ErisPulse/Core/module_registry.py +0 -227
  35. erispulse-2.2.1.dev0.dist-info/RECORD +0 -26
  36. {erispulse-2.2.1.dev0.dist-info → erispulse-2.3.0.dist-info}/entry_points.txt +0 -0
ErisPulse/Core/adapter.py CHANGED
@@ -1,240 +1,26 @@
1
1
  """
2
2
  ErisPulse 适配器系统
3
3
 
4
- 提供平台适配器基类、消息发送DSL和适配器管理功能。支持多平台消息处理、事件驱动和生命周期管理。
5
-
6
- {!--< tips >!--}
7
- 1. 适配器必须继承BaseAdapter并实现必要方法
8
- 2. 使用SendDSL实现链式调用风格的消息发送接口
9
- 3. 适配器管理器支持多平台适配器的注册和生命周期管理
10
- 4. 支持OneBot12协议的事件处理
11
- {!--< /tips >!--}
4
+ 提供平台适配器管理功能。支持多平台消息处理、事件驱动和生命周期管理。
12
5
  """
13
6
 
14
7
  import functools
15
8
  import asyncio
16
9
  from typing import (
17
- Callable, Any, Dict, List, Type, Optional, Set,
18
- Union, Awaitable
10
+ Callable, Any, Dict, List, Type, Optional, Set
19
11
  )
20
12
  from collections import defaultdict
21
13
  from .logger import logger
22
-
23
- class SendDSLBase:
24
- """
25
- 消息发送DSL基类
26
-
27
- 用于实现 Send.To(...).Func(...) 风格的链式调用接口
28
-
29
- {!--< tips >!--}
30
- 1. 子类应实现具体的消息发送方法(如Text, Image等)
31
- 2. 通过__getattr__实现动态方法调用
32
- {!--< /tips >!--}
33
- """
34
-
35
- def __init__(self, adapter: 'BaseAdapter', target_type: Optional[str] = None, target_id: Optional[str] = None, account_id: Optional[str] = None):
36
- """
37
- 初始化DSL发送器
38
-
39
- :param adapter: 所属适配器实例
40
- :param target_type: 目标类型(可选)
41
- :param target_id: 目标ID(可选)
42
- :param _account_id: 发送账号(可选)
43
- """
44
- self._adapter = adapter
45
- self._target_type = target_type
46
- self._target_id = target_id
47
- self._target_to = target_id
48
- self._account_id = account_id
49
-
50
- def To(self, target_type: str = None, target_id: Union[str, int] = None) -> 'SendDSL':
51
- """
52
- 设置消息目标
53
-
54
- :param target_type: 目标类型(可选)
55
- :param target_id: 目标ID(可选)
56
- :return: SendDSL实例
57
-
58
- :example:
59
- >>> adapter.Send.To("user", "123").Text("Hello")
60
- >>> adapter.Send.To("123").Text("Hello") # 简化形式
61
- """
62
- if target_id is None and target_type is not None:
63
- target_id = target_type
64
- target_type = None
65
-
66
- return self.__class__(self._adapter, target_type, target_id, self._account_id)
67
-
68
- def Using(self, account_id: Union[str, int]) -> 'SendDSL':
69
- """
70
- 设置发送账号
71
-
72
- :param _account_id: 发送账号
73
- :return: SendDSL实例
74
-
75
- :example:
76
- >>> adapter.Send.Using("bot1").To("123").Text("Hello")
77
- >>> adapter.Send.To("123").Using("bot1").Text("Hello") # 支持乱序
78
- """
79
- return self.__class__(self._adapter, self._target_type, self._target_id, account_id)
80
-
81
-
82
- class BaseAdapter:
83
- """
84
- 适配器基类
85
-
86
- 提供与外部平台交互的标准接口,子类必须实现必要方法
87
-
88
- {!--< tips >!--}
89
- 1. 必须实现call_api, start和shutdown方法
90
- 2. 可以自定义Send类实现平台特定的消息发送逻辑
91
- 3. 通过on装饰器注册事件处理器
92
- 4. 支持OneBot12协议的事件处理
93
- {!--< /tips >!--}
94
- """
95
-
96
- class Send(SendDSLBase):
97
- """
98
- 消息发送DSL实现
99
-
100
- {!--< tips >!--}
101
- 1. 子类可以重写Text方法提供平台特定实现
102
- 2. 可以添加新的消息类型(如Image, Voice等)
103
- {!--< /tips >!--}
104
- """
105
-
106
- def Example(self, text: str) -> Awaitable[Any]:
107
- """
108
- 示例消息发送方法
109
-
110
- :param text: 文本内容
111
- :return: 异步任务
112
- :example:
113
- >>> await adapter.Send.To("123").Example("Hello")
114
- """
115
- logger.debug(f"适配器 {self._adapter.__class__.__name__} 发送了实例类型的消息: {text}")
116
-
117
-
118
- def __init__(self):
119
- """
120
- 初始化适配器
121
- """
122
- self._handlers = defaultdict(list)
123
- self._middlewares = []
124
- self.Send = self.__class__.Send(self)
125
-
126
- def on(self, event_type: str = "*") -> Callable[[Callable], Callable]:
127
- """
128
- 适配器事件监听装饰器
129
-
130
- :param event_type: 事件类型
131
- :return: 装饰器函数
132
- """
133
- def decorator(func: Callable) -> Callable:
134
- @functools.wraps(func)
135
- async def wrapper(*args, **kwargs):
136
- return await func(*args, **kwargs)
137
- self._handlers[event_type].append(wrapper)
138
-
139
- return wrapper
140
- return decorator
141
-
142
- def middleware(self, func: Callable) -> Callable:
143
- """
144
- 添加中间件处理器
145
-
146
- :param func: 中间件函数
147
- :return: 中间件函数
148
-
149
- :example:
150
- >>> @adapter.middleware
151
- >>> async def log_middleware(data):
152
- >>> print(f"处理数据: {data}")
153
- >>> return data
154
- """
155
- self._middlewares.append(func)
156
- return func
157
-
158
- async def call_api(self, endpoint: str, **params: Any) -> Any:
159
- """
160
- 调用平台API的抽象方法
161
-
162
- :param endpoint: API端点
163
- :param params: API参数
164
- :return: API调用结果
165
- :raises NotImplementedError: 必须由子类实现
166
- """
167
- raise NotImplementedError("适配器必须实现call_api方法")
168
-
169
- async def start(self) -> None:
170
- """
171
- 启动适配器的抽象方法
172
-
173
- :raises NotImplementedError: 必须由子类实现
174
- """
175
- raise NotImplementedError("适配器必须实现start方法")
176
-
177
- async def shutdown(self) -> None:
178
- """
179
- 关闭适配器的抽象方法
180
-
181
- :raises NotImplementedError: 必须由子类实现
182
- """
183
- raise NotImplementedError("适配器必须实现shutdown方法")
184
-
185
- async def emit(self, event_type: str, data: Any) -> None:
186
- """
187
- 触发原生协议事件
188
-
189
- :param event_type: 事件类型
190
- :param data: 事件数据
191
-
192
- :example:
193
- >>> await adapter.emit("message", {"text": "Hello"})
194
- """
195
- # 先执行中间件
196
- for middleware in self._middlewares:
197
- data = await middleware(data)
198
-
199
- # 触发具体事件类型的处理器
200
- if event_type in self._handlers:
201
- for handler in self._handlers[event_type]:
202
- await handler(data)
203
-
204
- # 触发通配符 "*" 的处理器
205
- for handler in self._handlers.get("*", []):
206
- await handler(data)
207
-
208
- async def send(self, target_type: str, target_id: str, message: Any, **kwargs: Any) -> Any:
209
- """
210
- 发送消息的便捷方法
211
-
212
- :param target_type: 目标类型
213
- :param target_id: 目标ID
214
- :param message: 消息内容
215
- :param kwargs: 其他参数
216
- - method: 发送方法名(默认为"Text")
217
- :return: 发送结果
218
-
219
- :raises AttributeError: 当发送方法不存在时抛出
220
-
221
- :example:
222
- >>> await adapter.send("user", "123", "Hello")
223
- >>> await adapter.send("group", "456", "Hello", method="Markdown")
224
- """
225
- method_name = kwargs.pop("method", "Text")
226
- method = getattr(self.Send.To(target_type, target_id), method_name, None)
227
- if not method:
228
- raise AttributeError(f"未找到 {method_name} 方法,请确保已在 Send 类中定义")
229
- return await method(text=message, **kwargs)
230
-
14
+ from .Bases.adapter import BaseAdapter
15
+ from .config import config
16
+ from .lifecycle import lifecycle
231
17
 
232
18
  class AdapterManager:
233
19
  """
234
20
  适配器管理器
235
-
236
- 管理多个平台适配器的注册、启动和关闭
237
-
21
+
22
+ 管理多个平台适配器的注册、启动和关闭,提供与模块管理器一致的接口
23
+
238
24
  {!--< tips >!--}
239
25
  1. 通过register方法注册适配器
240
26
  2. 通过startup方法启动适配器
@@ -242,133 +28,76 @@ class AdapterManager:
242
28
  4. 通过on装饰器注册OneBot12协议事件处理器
243
29
  {!--< /tips >!--}
244
30
  """
245
-
31
+
246
32
  def __init__(self):
247
- self._adapters: Dict[str, BaseAdapter] = {}
248
- self._adapter_instances: Dict[Type[BaseAdapter], BaseAdapter] = {}
249
- self._platform_to_instance: Dict[str, BaseAdapter] = {}
250
- self._started_instances: Set[BaseAdapter] = set()
251
-
33
+ # 适配器存储 - 简化数据结构
34
+ self._adapters: Dict[str, BaseAdapter] = {} # 平台名到实例的映射
35
+ self._started_instances: Set[BaseAdapter] = set() # 已启动的实例
36
+ self._adapter_info: Dict[str, Dict] = {} # 适配器信息
37
+
252
38
  # OneBot12事件处理器
253
39
  self._onebot_handlers = defaultdict(list)
254
40
  self._onebot_middlewares = []
41
+ # 原生事件处理器
42
+ self._raw_handlers = defaultdict(list)
255
43
 
256
- @property
257
- def Adapter(self) -> Type[BaseAdapter]:
258
- """
259
- 获取BaseAdapter类,用于访问原始事件监听
260
-
261
- :return: BaseAdapter类
262
-
263
- :example:
264
- >>> @sdk.adapter.Adapter.on("raw_event")
265
- >>> async def handle_raw(data):
266
- >>> print("收到原始事件:", data)
267
- """
268
- return BaseAdapter
44
+ # ==================== 适配器注册与管理 ====================
269
45
 
270
- def on(self, event_type: str = "*") -> Callable[[Callable], Callable]:
271
- """
272
- OneBot12协议事件监听装饰器
273
-
274
- :param event_type: OneBot12事件类型
275
- :return: 装饰器函数
276
-
277
- :example:
278
- >>> @sdk.adapter.on("message")
279
- >>> async def handle_message(data):
280
- >>> print(f"收到OneBot12消息: {data}")
46
+ def register(self, platform: str, adapter_class: Type[BaseAdapter], adapter_info: Optional[Dict] = None) -> bool:
281
47
  """
282
- def decorator(func: Callable) -> Callable:
283
- @functools.wraps(func)
284
- async def wrapper(*args, **kwargs):
285
- return await func(*args, **kwargs)
286
-
287
- self._onebot_handlers[event_type].append(wrapper)
288
- return wrapper
289
- return decorator
48
+ 注册新的适配器类(标准化注册方法)
290
49
 
291
- def middleware(self, func: Callable) -> Callable:
292
- """
293
- 添加OneBot12中间件处理器
294
-
295
- :param func: 中间件函数
296
- :return: 中间件函数
297
-
298
- :example:
299
- >>> @sdk.adapter.middleware
300
- >>> async def onebot_middleware(data):
301
- >>> print("处理OneBot12数据:", data)
302
- >>> return data
303
- """
304
- self._onebot_middlewares.append(func)
305
- return func
306
-
307
- async def emit(self, data: Any) -> None:
308
- """
309
- 提交OneBot12协议事件到指定平台
310
-
311
- :param platform: 平台名称
312
- :param event_type: OneBot12事件类型
313
- :param data: 符合OneBot12标准的事件数据
314
-
315
- :raises ValueError: 当平台未注册时抛出
316
-
317
- :example:
318
- >>> await sdk.adapter.emit("MyPlatform", "message", {
319
- >>> "id": "123",
320
- >>> "time": 1620000000,
321
- >>> "type": "message",
322
- >>> "detail_type": "private",
323
- >>> "message": [{"type": "text", "data": {"text": "Hello"}}]
324
- >>> })
325
- """
326
- platform = data.get("platform", "unknown")
327
- event_type = data.get("type", "unknown")
328
-
329
- if platform not in self._adapters:
330
- raise ValueError(f"平台 {platform} 未注册")
331
-
332
- # 先执行OneBot12中间件
333
- processed_data = data
334
- for middleware in self._onebot_middlewares:
335
- processed_data = await middleware(processed_data)
336
-
337
- # 分发到OneBot12事件处理器
338
- if event_type in self._onebot_handlers:
339
- for handler in self._onebot_handlers[event_type]:
340
- await handler(processed_data)
341
- for handler in self._onebot_handlers.get("*", []):
342
- await handler(processed_data)
343
-
344
- def register(self, platform: str, adapter_class: Type[BaseAdapter]) -> bool:
345
- """
346
- 注册新的适配器类
347
-
348
50
  :param platform: 平台名称
349
51
  :param adapter_class: 适配器类
52
+ :param adapter_info: 适配器信息
350
53
  :return: 注册是否成功
351
-
54
+
352
55
  :raises TypeError: 当适配器类无效时抛出
353
-
56
+
354
57
  :example:
355
58
  >>> adapter.register("MyPlatform", MyPlatformAdapter)
356
59
  """
60
+ logger.info(f"注册适配器 {platform}({adapter_class.__name__})")
357
61
  if not issubclass(adapter_class, BaseAdapter):
358
- raise TypeError("适配器必须继承自BaseAdapter")
359
- from .. import sdk
360
-
361
- # 如果该类已经创建过实例,复用
362
- if adapter_class in self._adapter_instances:
363
- instance = self._adapter_instances[adapter_class]
62
+ raise TypeError("适配器必须继承自BaseAdapter,否则我们无法加载这个适配器,它会导致未知的错误")
63
+
64
+ # 检查是否已存在该平台的适配器
65
+ if platform in self._adapters:
66
+ logger.warning(f"平台 {platform} 已存在,将覆盖原适配器")
67
+
68
+ if adapter_info:
69
+ self._adapter_info[platform] = adapter_info
70
+
71
+ # 检查是否已存在相同类的适配器实例
72
+ existing_instance = None
73
+ for existing_platform, existing_adapter in self._adapters.items():
74
+ if existing_adapter.__class__ == adapter_class:
75
+ existing_instance = existing_adapter
76
+ break
77
+
78
+ # 如果存在相同类的适配器实例,直接绑定到已注册的实例
79
+ if existing_instance is not None:
80
+ self._adapters[platform] = existing_instance
81
+ logger.debug(f"适配器 {platform} 已绑定到已注册的实例 {existing_platform}")
364
82
  else:
83
+ # 创建适配器实例
84
+ from .. import sdk
365
85
  instance = adapter_class(sdk)
366
- self._adapter_instances[adapter_class] = instance
367
-
368
- # 注册平台名,并统一映射到该实例
369
- self._adapters[platform] = instance
370
- self._platform_to_instance[platform] = instance
371
-
86
+ self._adapters[platform] = instance
87
+ logger.debug(f"适配器 {platform} 注册成功")
88
+
89
+ # 注册平台名称的多种大小写形式作为属性
90
+ self._register_platform_attributes(platform, self._adapters[platform])
91
+
92
+ return True
93
+
94
+ def _register_platform_attributes(self, platform: str, instance: BaseAdapter) -> None:
95
+ """
96
+ 注册平台名称的多种大小写形式作为属性
97
+
98
+ :param platform: 平台名称
99
+ :param instance: 适配器实例
100
+ """
372
101
  if len(platform) <= 10:
373
102
  from itertools import product
374
103
  combinations = [''.join(c) for c in product(*[(ch.lower(), ch.upper()) for ch in platform])]
@@ -380,16 +109,14 @@ class AdapterManager:
380
109
  setattr(self, platform.upper(), instance)
381
110
  setattr(self, platform.capitalize(), instance)
382
111
 
383
- return True
384
-
385
- async def startup(self, platforms: List[str] = None) -> None:
112
+ async def startup(self, platforms = None) -> None:
386
113
  """
387
114
  启动指定的适配器
388
-
115
+
389
116
  :param platforms: 要启动的平台列表,None表示所有平台
390
-
117
+
391
118
  :raises ValueError: 当平台未注册时抛出
392
-
119
+
393
120
  :example:
394
121
  >>> # 启动所有适配器
395
122
  >>> await adapter.startup()
@@ -403,20 +130,29 @@ class AdapterManager:
403
130
  for platform in platforms:
404
131
  if platform not in self._adapters:
405
132
  raise ValueError(f"平台 {platform} 未注册")
406
-
133
+
407
134
  logger.info(f"启动适配器 {platforms}")
408
135
 
409
- from .router import adapter_server
410
- from .erispulse_config import get_server_config
136
+ # 提交适配器启动开始事件
137
+ await lifecycle.submit_event(
138
+ "adapter.start",
139
+ msg="开始启动适配器",
140
+ data={
141
+ "platforms": platforms
142
+ }
143
+ )
144
+
145
+ from .router import router
146
+ from ._self_config import get_server_config
411
147
  server_config = get_server_config()
412
148
 
413
149
  host = server_config["host"]
414
150
  port = server_config["port"]
415
151
  ssl_cert = server_config.get("ssl_certfile", None)
416
152
  ssl_key = server_config.get("ssl_keyfile", None)
417
-
153
+
418
154
  # 启动服务器
419
- await adapter_server.start(
155
+ await router.start(
420
156
  host=host,
421
157
  port=port,
422
158
  ssl_certfile=ssl_cert,
@@ -442,7 +178,7 @@ class AdapterManager:
442
178
  """
443
179
  {!--< internal-use >!--}
444
180
  运行适配器实例
445
-
181
+
446
182
  :param adapter: 适配器实例
447
183
  :param platform: 平台名称
448
184
  """
@@ -460,15 +196,49 @@ class AdapterManager:
460
196
  fixed_delay = 3 * 60 * 60
461
197
  backoff_intervals = [60, 10 * 60, 30 * 60, 60 * 60]
462
198
 
199
+ # 提交适配器状态变化事件(starting)
200
+ await lifecycle.submit_event(
201
+ "adapter.status.change",
202
+ msg=f"适配器 {platform} 状态变化: starting",
203
+ data={
204
+ "platform": platform,
205
+ "status": "starting",
206
+ "retry_count": retry_count
207
+ }
208
+ )
209
+
463
210
  while True:
464
211
  try:
465
212
  await adapter.start()
466
213
  self._started_instances.add(adapter)
214
+
215
+ # 提交适配器状态变化事件(started)
216
+ await lifecycle.submit_event(
217
+ "adapter.status.change",
218
+ msg=f"适配器 {platform} 状态变化: started",
219
+ data={
220
+ "platform": platform,
221
+ "status": "started"
222
+ }
223
+ )
224
+
467
225
  return
468
226
  except Exception as e:
469
227
  retry_count += 1
470
228
  logger.error(f"平台 {platform} 启动失败(第{retry_count}次重试): {e}")
471
229
 
230
+ # 提交适配器状态变化事件(start_failed)
231
+ await lifecycle.submit_event(
232
+ "adapter.status.change",
233
+ msg=f"适配器 {platform} 状态变化: start_failed",
234
+ data={
235
+ "platform": platform,
236
+ "status": "start_failed",
237
+ "retry_count": retry_count,
238
+ "error": str(e)
239
+ }
240
+ )
241
+
472
242
  try:
473
243
  await adapter.shutdown()
474
244
  except Exception as stop_err:
@@ -482,73 +252,300 @@ class AdapterManager:
482
252
 
483
253
  logger.info(f"将在 {wait_time // 60} 分钟后再次尝试重启 {platform}")
484
254
  await asyncio.sleep(wait_time)
485
-
486
255
  async def shutdown(self) -> None:
487
256
  """
488
257
  关闭所有适配器
489
-
490
- :example:
491
- >>> await adapter.shutdown()
492
258
  """
259
+ # 提交适配器关闭开始事件
260
+ await lifecycle.submit_event(
261
+ "adapter.stop",
262
+ msg="开始关闭适配器",
263
+ data={}
264
+ )
265
+
493
266
  for adapter in self._adapters.values():
494
267
  await adapter.shutdown()
495
-
496
- from .router import adapter_server
497
- await adapter_server.stop()
498
268
 
499
- def get(self, platform: str) -> Optional[BaseAdapter]:
269
+ from .router import router
270
+ await router.stop()
271
+
272
+ # 提交适配器关闭完成事件
273
+ await lifecycle.submit_event(
274
+ "adapter.stopped",
275
+ msg="适配器关闭完成"
276
+ )
277
+
278
+ # ==================== 适配器配置管理 ====================
279
+
280
+ def _config_register(self, platform: str, enabled: bool = False) -> bool:
500
281
  """
501
- 获取指定平台的适配器实例
502
-
282
+ 注册新平台适配器(仅当平台不存在时注册)
283
+
503
284
  :param platform: 平台名称
504
- :return: 适配器实例或None
505
-
285
+ :param enabled: [bool] 是否启用适配器
286
+ :return: [bool] 操作是否成功
287
+ """
288
+ if self.exists(platform):
289
+ return True
290
+
291
+ # 平台不存在,进行注册
292
+ config.setConfig(f"ErisPulse.adapters.status.{platform}", enabled)
293
+ status = "启用" if enabled else "禁用"
294
+ logger.info(f"平台适配器 {platform} 已注册并{status}")
295
+ return True
296
+
297
+ def exists(self, platform: str) -> bool:
298
+ """
299
+ 检查平台是否存在
300
+
301
+ :param platform: 平台名称
302
+ :return: [bool] 平台是否存在
303
+ """
304
+ # 检查平台是否在配置中注册
305
+ adapter_statuses = config.getConfig("ErisPulse.adapters.status", {})
306
+ return platform in adapter_statuses
307
+
308
+ def is_enabled(self, platform: str) -> bool:
309
+ """
310
+ 检查平台适配器是否启用
311
+
312
+ :param platform: 平台名称
313
+ :return: [bool] 平台适配器是否启用
314
+ """
315
+ # 不使用默认值,如果配置不存在则返回 None
316
+ status = config.getConfig(f"ErisPulse.adapters.status.{platform}")
317
+
318
+ # 如果状态不存在,说明是新适配器
319
+ if status is None:
320
+ return False # 新适配器默认不启用,需要在初始化时处理
321
+
322
+ # 处理字符串形式的布尔值
323
+ if isinstance(status, str):
324
+ return status.lower() not in ('false', '0', 'no', 'off')
325
+
326
+ return bool(status)
327
+
328
+ def enable(self, platform: str) -> bool:
329
+ """
330
+ 启用平台适配器
331
+
332
+ :param platform: 平台名称
333
+ :return: [bool] 操作是否成功
334
+ """
335
+ if not self.exists(platform):
336
+ logger.error(f"平台 {platform} 不存在")
337
+ return False
338
+
339
+ config.setConfig(f"ErisPulse.adapters.status.{platform}", True)
340
+ logger.info(f"平台 {platform} 已启用")
341
+ return True
342
+
343
+ def disable(self, platform: str) -> bool:
344
+ """
345
+ 禁用平台适配器
346
+
347
+ :param platform: 平台名称
348
+ :return: [bool] 操作是否成功
349
+ """
350
+ if not self.exists(platform):
351
+ logger.error(f"平台 {platform} 不存在")
352
+ return False
353
+
354
+ config.setConfig(f"ErisPulse.adapters.status.{platform}", False)
355
+ logger.info(f"平台 {platform} 已禁用")
356
+ return True
357
+
358
+ def list_adapters(self) -> Dict[str, bool]:
359
+ """
360
+ 列出所有平台适配器状态
361
+
362
+ :return: [Dict[str, bool]] 平台适配器状态字典
363
+ """
364
+ return config.getConfig("ErisPulse.adapters.status", {})
365
+
366
+ # ==================== 事件处理与消息发送 ====================
367
+
368
+ def on(self, event_type: str = "*", *, raw: bool = False, platform: Optional[str] = None) -> Callable[[Callable], Callable]:
369
+ """
370
+ OneBot12协议事件监听装饰器
371
+
372
+ :param event_type: OneBot12事件类型
373
+ :param raw: 是否监听原生事件
374
+ :param platform: 指定平台,None表示监听所有平台
375
+ :return: 装饰器函数
376
+
506
377
  :example:
507
- >>> adapter = adapter.get("MyPlatform")
378
+ >>> # 监听OneBot12标准事件(所有平台)
379
+ >>> @sdk.adapter.on("message")
380
+ >>> async def handle_message(data):
381
+ >>> print(f"收到OneBot12消息: {data}")
382
+ >>>
383
+ >>> # 监听特定平台的OneBot12标准事件
384
+ >>> @sdk.adapter.on("message", platform="onebot11")
385
+ >>> async def handle_onebot11_message(data):
386
+ >>> print(f"收到OneBot11标准消息: {data}")
387
+ >>>
388
+ >>> # 监听平台原生事件
389
+ >>> @sdk.adapter.on("message", raw=True, platform="onebot11")
390
+ >>> async def handle_raw_message(data):
391
+ >>> print(f"收到OneBot11原生事件: {data}")
392
+ >>>
393
+ >>> # 监听所有平台的原生事件
394
+ >>> @sdk.adapter.on("message", raw=True)
395
+ >>> async def handle_all_raw_message(data):
396
+ >>> print(f"收到原生事件: {data}")
508
397
  """
509
- platform_lower = platform.lower()
510
- for registered, instance in self._adapters.items():
511
- if registered.lower() == platform_lower:
512
- return instance
513
- return None
398
+ def decorator(func: Callable) -> Callable:
399
+ @functools.wraps(func)
400
+ async def wrapper(*args, **kwargs):
401
+ return await func(*args, **kwargs)
514
402
 
515
- def __getattr__(self, platform: str) -> BaseAdapter:
403
+ # 创建带元信息的处理器包装器
404
+ handler_wrapper = {
405
+ 'func': wrapper,
406
+ 'platform': platform
407
+ }
408
+
409
+ if raw:
410
+ self._raw_handlers[event_type].append(handler_wrapper)
411
+ else:
412
+ self._onebot_handlers[event_type].append(handler_wrapper)
413
+ return wrapper
414
+ return decorator
415
+
416
+ def middleware(self, func: Callable) -> Callable:
516
417
  """
517
- 通过属性访问获取适配器实例
518
-
418
+ 添加OneBot12中间件处理器
419
+
420
+ :param func: 中间件函数
421
+ :return: 中间件函数
422
+
423
+ :example:
424
+ >>> @sdk.adapter.middleware
425
+ >>> async def onebot_middleware(data):
426
+ >>> print("处理OneBot12数据:", data)
427
+ >>> return data
428
+ """
429
+ self._onebot_middlewares.append(func)
430
+ return func
431
+
432
+ async def emit(self, data: Any) -> None:
433
+ """
434
+ 提交OneBot12协议事件到指定平台
435
+
436
+ :param data: 符合OneBot12标准的事件数据
437
+
438
+ :example:
439
+ >>> await sdk.adapter.emit({
440
+ >>> "id": "123",
441
+ >>> "time": 1620000000,
442
+ >>> "type": "message",
443
+ >>> "detail_type": "private",
444
+ >>> "message": [{"type": "text", "data": {"text": "Hello"}}],
445
+ >>> "platform": "myplatform",
446
+ >>> "myplatform_raw": {...平台原生事件数据...},
447
+ >>> "myplatform_raw_type": "text_message"
448
+ >>> })
449
+ """
450
+ platform = data.get("platform", "unknown")
451
+ event_type = data.get("type", "unknown")
452
+ platform_raw = data.get(f"{platform}_raw", {})
453
+ raw_event_type = data.get(f"{platform}_raw_type")
454
+
455
+ # 先执行OneBot12中间件
456
+ processed_data = data
457
+ for middleware in self._onebot_middlewares:
458
+ processed_data = await middleware(processed_data)
459
+
460
+ # 分发到OneBot12事件处理器
461
+ handlers_to_call = []
462
+
463
+ # 处理特定事件类型的处理器
464
+ if event_type in self._onebot_handlers:
465
+ handlers_to_call.extend(self._onebot_handlers[event_type])
466
+
467
+ # 处理通配符处理器
468
+ handlers_to_call.extend(self._onebot_handlers.get("*", []))
469
+
470
+ # 调用符合条件的标准事件处理器
471
+ for handler_wrapper in handlers_to_call:
472
+ handler_platform = handler_wrapper.get('platform')
473
+ # 如果处理器没有指定平台,或者指定的平台与当前事件平台匹配
474
+ if handler_platform is None or handler_platform == platform:
475
+ await handler_wrapper['func'](processed_data)
476
+
477
+ # 只有当存在原生事件数据时才分发原生事件
478
+ if raw_event_type and platform_raw is not None:
479
+ raw_handlers_to_call = []
480
+
481
+ # 处理特定原生事件类型的处理器
482
+ if raw_event_type in self._raw_handlers:
483
+ raw_handlers_to_call.extend(self._raw_handlers[raw_event_type])
484
+
485
+ # 处理原生事件的通配符处理器
486
+ raw_handlers_to_call.extend(self._raw_handlers.get("*", []))
487
+
488
+ # 调用符合条件的原生事件处理器
489
+ for handler_wrapper in raw_handlers_to_call:
490
+ handler_platform = handler_wrapper.get('platform')
491
+ # 如果处理器没有指定平台,或者指定的平台与当前事件平台匹配
492
+ if handler_platform is None or handler_platform == platform:
493
+ await handler_wrapper['func'](platform_raw)
494
+
495
+ # ==================== 工具方法 ====================
496
+
497
+ def get(self, platform: str) -> Optional[BaseAdapter]:
498
+ """
499
+ 获取指定平台的适配器实例
500
+
519
501
  :param platform: 平台名称
520
- :return: 适配器实例
521
-
522
- :raises AttributeError: 当平台未注册时抛出
523
-
502
+ :return: 适配器实例或None
503
+
524
504
  :example:
525
- >>> adapter = adapter.MyPlatform
505
+ >>> adapter = adapter.get("MyPlatform")
526
506
  """
527
507
  platform_lower = platform.lower()
528
508
  for registered, instance in self._adapters.items():
529
509
  if registered.lower() == platform_lower:
530
510
  return instance
531
- raise AttributeError(f"平台 {platform} 的适配器未注册")
511
+ return None
532
512
 
533
513
  @property
534
514
  def platforms(self) -> List[str]:
535
515
  """
536
516
  获取所有已注册的平台列表
537
-
517
+
538
518
  :return: 平台名称列表
539
-
519
+
540
520
  :example:
541
521
  >>> print("已注册平台:", adapter.platforms)
542
522
  """
543
523
  return list(self._adapters.keys())
544
524
 
525
+ def __getattr__(self, platform: str) -> BaseAdapter:
526
+ """
527
+ 通过属性访问获取适配器实例
528
+
529
+ :param platform: 平台名称
530
+ :return: 适配器实例
531
+ :raises AttributeError: 当平台不存在或未启用时
532
+ """
533
+ adapter_instance = self.get(platform)
534
+ if adapter_instance is None:
535
+ raise AttributeError(f"平台 {platform} 不存在或未启用")
536
+ return adapter_instance
537
+
538
+ def __contains__(self, platform: str) -> bool:
539
+ """
540
+ 检查平台是否存在且处于启用状态
541
+
542
+ :param platform: 平台名称
543
+ :return: [bool] 平台是否存在且启用
544
+ """
545
+ return self.exists(platform) and self.is_enabled(platform)
545
546
 
546
- AdapterFather = BaseAdapter
547
547
  adapter = AdapterManager()
548
- SendDSL = SendDSLBase
549
548
 
550
549
  __all__ = [
551
- "AdapterFather",
552
- "adapter",
553
- "SendDSL"
550
+ "adapter"
554
551
  ]