ErisPulse 2.1.15.dev3__py3-none-any.whl → 2.2.0.dev0__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.
@@ -0,0 +1,49 @@
1
+ from .. import adapter
2
+ """
3
+ ErisPulse 事件处理模块
4
+
5
+ 提供统一的事件处理接口,支持命令、消息、通知、请求和元事件处理
6
+ """
7
+
8
+ from .cmd import command
9
+ from .message import message
10
+ from .notice import notice
11
+ from .request import request
12
+ from .meta import meta
13
+ from .manager import event_manager
14
+ from . import exceptions
15
+ from .. import config
16
+
17
+ # 初始化默认配置
18
+ def _setup_default_config():
19
+ """
20
+ 设置默认配置
21
+
22
+ {!--< internal-use >!--}
23
+ 内部使用的方法,用于初始化默认配置
24
+ """
25
+ default_config = {
26
+ "command": {
27
+ "prefix": "/",
28
+ "case_sensitive": True
29
+ },
30
+ "message": {
31
+ "ignore_self": True
32
+ }
33
+ }
34
+
35
+ current_config = config.getConfig("ErisPulse.event")
36
+ if current_config is None:
37
+ config.setConfig("ErisPulse.event", default_config)
38
+
39
+ _setup_default_config()
40
+
41
+ __all__ = [
42
+ "command",
43
+ "message",
44
+ "notice",
45
+ "request",
46
+ "meta",
47
+ "event_manager",
48
+ "exceptions"
49
+ ]
@@ -0,0 +1,118 @@
1
+ """
2
+ ErisPulse 事件处理基础模块
3
+
4
+ 提供事件处理的核心功能,包括事件注册、处理和中间件支持
5
+ """
6
+
7
+ from .. import adapter, logger
8
+ from typing import Callable, Any, Dict, List, Optional, Union
9
+ import asyncio
10
+ import functools
11
+
12
+ class BaseEventHandler:
13
+ """
14
+ 基础事件处理器
15
+
16
+ 提供事件处理的基本功能,包括处理器注册、中间件支持等
17
+ """
18
+
19
+ def __init__(self, event_type: str, module_name: str = None):
20
+ """
21
+ 初始化事件处理器
22
+
23
+ :param event_type: 事件类型
24
+ :param module_name: 模块名称
25
+ """
26
+ self.event_type = event_type
27
+ self.module_name = module_name
28
+ self.handlers: List[Dict] = []
29
+ self.middlewares: List[Callable] = []
30
+
31
+ def middleware(self, func: Callable) -> Callable:
32
+ """
33
+ 添加中间件
34
+
35
+ :param func: 中间件函数
36
+ :return: 中间件函数
37
+ """
38
+ self.middlewares.append(func)
39
+ return func
40
+
41
+ def register(self, handler: Callable, priority: int = 0, condition: Callable = None):
42
+ """
43
+ 注册事件处理器
44
+
45
+ :param handler: 事件处理器函数
46
+ :param priority: 处理器优先级,数值越小优先级越高
47
+ :param condition: 处理器条件函数,返回True时才会执行处理器
48
+ """
49
+ handler_info = {
50
+ "func": handler,
51
+ "priority": priority,
52
+ "condition": condition,
53
+ "module": self.module_name
54
+ }
55
+ self.handlers.append(handler_info)
56
+ # 按优先级排序
57
+ self.handlers.sort(key=lambda x: x["priority"])
58
+
59
+ # 注册到适配器
60
+ if self.event_type:
61
+ adapter.on(self.event_type)(self._process_event)
62
+
63
+ def __call__(self, priority: int = 0, condition: Callable = None):
64
+ """
65
+ 装饰器方式注册事件处理器
66
+
67
+ :param priority: 处理器优先级
68
+ :param condition: 处理器条件函数
69
+ :return: 装饰器函数
70
+ """
71
+ def decorator(func: Callable):
72
+ self.register(func, priority, condition)
73
+ return func
74
+ return decorator
75
+
76
+ async def _process_event(self, event: Dict[str, Any]):
77
+ """
78
+ 处理事件
79
+
80
+ {!--< internal-use >!--}
81
+ 内部使用的方法,用于处理事件
82
+
83
+ :param event: 事件数据
84
+ """
85
+ # 执行中间件
86
+ processed_event = event
87
+ for middleware in self.middlewares:
88
+ try:
89
+ if asyncio.iscoroutinefunction(middleware):
90
+ processed_event = await middleware(processed_event)
91
+ else:
92
+ processed_event = middleware(processed_event)
93
+ except Exception as e:
94
+ logger.error(f"中间件执行错误: {e}")
95
+
96
+ # 执行处理器
97
+ for handler_info in self.handlers:
98
+ condition = handler_info.get("condition")
99
+ # 检查条件
100
+ if condition and not condition(processed_event):
101
+ continue
102
+
103
+ handler = handler_info["func"]
104
+ try:
105
+ if asyncio.iscoroutinefunction(handler):
106
+ await handler(processed_event)
107
+ else:
108
+ handler(processed_event)
109
+ except Exception as e:
110
+ logger.error(f"事件处理器执行错误: {e}")
111
+
112
+ def unregister(self, handler: Callable):
113
+ """
114
+ 注销事件处理器
115
+
116
+ :param handler: 要注销的事件处理器
117
+ """
118
+ self.handlers = [h for h in self.handlers if h["func"] != handler]
@@ -0,0 +1,212 @@
1
+ """
2
+ ErisPulse 命令处理模块
3
+
4
+ 提供基于装饰器的命令注册和处理功能
5
+ """
6
+
7
+ from .base import BaseEventHandler
8
+ from .manager import event_manager
9
+ from .. import adapter, config, logger
10
+ from typing import Callable, Union, List, Dict, Any, Optional
11
+ import re
12
+ import asyncio
13
+
14
+ class CommandHandler:
15
+ """
16
+ 命令处理器
17
+
18
+ 提供命令注册、解析和执行功能
19
+ """
20
+
21
+ def __init__(self):
22
+ """
23
+ 初始化命令处理器
24
+ """
25
+ self.commands: Dict[str, Dict] = {}
26
+ self.aliases: Dict[str, str] = {} # 别名映射
27
+ self.groups: Dict[str, List[str]] = {} # 命令组
28
+ self.prefix = config.getConfig("ErisPulse.event.command.prefix", "/")
29
+ self.handler = event_manager.create_event_handler("message", "command")
30
+
31
+ # 注册消息处理器
32
+ self.handler.register(self._handle_message)
33
+
34
+ def __call__(self,
35
+ name: Union[str, List[str]] = None,
36
+ aliases: List[str] = None,
37
+ group: str = None,
38
+ priority: int = 0,
39
+ help: str = None,
40
+ usage: str = None):
41
+ """
42
+ 命令装饰器
43
+
44
+ :param name: 命令名称,可以是字符串或字符串列表
45
+ :param aliases: 命令别名列表
46
+ :param group: 命令组名称
47
+ :param priority: 处理器优先级
48
+ :param help: 命令帮助信息
49
+ :param usage: 命令使用方法
50
+ :return: 装饰器函数
51
+ """
52
+ def decorator(func: Callable):
53
+ cmd_names = []
54
+ if isinstance(name, str):
55
+ cmd_names = [name]
56
+ elif isinstance(name, list):
57
+ cmd_names = name
58
+ else:
59
+ # 使用函数名作为命令名
60
+ cmd_names = [func.__name__]
61
+
62
+ main_name = cmd_names[0]
63
+
64
+ # 添加别名
65
+ alias_list = aliases or []
66
+ if len(cmd_names) > 1:
67
+ alias_list.extend(cmd_names[1:])
68
+
69
+ # 注册命令
70
+ for cmd_name in cmd_names:
71
+ self.commands[cmd_name] = {
72
+ "func": func,
73
+ "help": help,
74
+ "usage": usage,
75
+ "group": group,
76
+ "main_name": main_name
77
+ }
78
+
79
+ # 注册别名映射
80
+ if cmd_name != main_name:
81
+ self.aliases[cmd_name] = main_name
82
+
83
+ # 添加到命令组
84
+ if group:
85
+ if group not in self.groups:
86
+ self.groups[group] = []
87
+ for cmd_name in cmd_names:
88
+ if cmd_name not in self.groups[group]:
89
+ self.groups[group].append(cmd_name)
90
+
91
+ return func
92
+ return decorator
93
+
94
+ async def _handle_message(self, event: Dict[str, Any]):
95
+ """
96
+ 处理消息事件中的命令
97
+
98
+ {!--< internal-use >!--}
99
+ 内部使用的方法,用于从消息中解析并执行命令
100
+
101
+ :param event: 消息事件数据
102
+ """
103
+ # 检查是否为文本消息
104
+ if event.get("type") != "message":
105
+ return
106
+
107
+ message_segments = event.get("message", [])
108
+ text_content = ""
109
+ for segment in message_segments:
110
+ if segment.get("type") == "text":
111
+ text_content = segment.get("data", {}).get("text", "")
112
+ break
113
+
114
+ if not text_content:
115
+ return
116
+
117
+ # 检查前缀
118
+ if not text_content.startswith(self.prefix):
119
+ return
120
+
121
+ # 解析命令和参数
122
+ command_text = text_content[len(self.prefix):].strip()
123
+ parts = command_text.split()
124
+ if not parts:
125
+ return
126
+
127
+ cmd_name = parts[0]
128
+ args = parts[1:] if len(parts) > 1 else []
129
+
130
+ # 处理别名
131
+ actual_cmd_name = self.aliases.get(cmd_name, cmd_name)
132
+
133
+ # 查找命令处理器
134
+ if actual_cmd_name in self.commands:
135
+ cmd_info = self.commands[actual_cmd_name]
136
+ handler = cmd_info["func"]
137
+
138
+ # 添加命令相关信息到事件
139
+ command_info = {
140
+ "name": actual_cmd_name,
141
+ "main_name": cmd_info["main_name"],
142
+ "args": args,
143
+ "raw": command_text,
144
+ "help": cmd_info["help"],
145
+ "usage": cmd_info["usage"],
146
+ "group": cmd_info["group"]
147
+ }
148
+
149
+ event["command"] = command_info
150
+
151
+ try:
152
+ if asyncio.iscoroutinefunction(handler):
153
+ await handler(event)
154
+ else:
155
+ handler(event)
156
+ except Exception as e:
157
+ logger.error(f"命令执行错误: {e}")
158
+ # 可以发送错误信息给用户
159
+
160
+ def get_command(self, name: str) -> Optional[Dict]:
161
+ """
162
+ 获取命令信息
163
+
164
+ :param name: 命令名称
165
+ :return: 命令信息字典,如果不存在则返回None
166
+ """
167
+ actual_name = self.aliases.get(name, name)
168
+ return self.commands.get(actual_name)
169
+
170
+ def get_commands(self) -> Dict[str, Dict]:
171
+ """
172
+ 获取所有命令
173
+
174
+ :return: 命令信息字典
175
+ """
176
+ return self.commands
177
+
178
+ def get_group_commands(self, group: str) -> List[str]:
179
+ """
180
+ 获取命令组中的命令
181
+
182
+ :param group: 命令组名称
183
+ :return: 命令名称列表
184
+ """
185
+ return self.groups.get(group, [])
186
+
187
+ def help(self, command_name: str = None) -> str:
188
+ """
189
+ 生成帮助信息
190
+
191
+ :param command_name: 命令名称,如果为None则生成所有命令的帮助
192
+ :return: 帮助信息字符串
193
+ """
194
+ if command_name:
195
+ cmd_info = self.get_command(command_name)
196
+ if cmd_info:
197
+ help_text = cmd_info.get("help", "无帮助信息")
198
+ usage = cmd_info.get("usage", f"{self.prefix}{command_name}")
199
+ return f"命令: {command_name}\n用法: {usage}\n说明: {help_text}"
200
+ else:
201
+ return f"未找到命令: {command_name}"
202
+ else:
203
+ # 生成所有命令的帮助
204
+ help_lines = ["可用命令:"]
205
+ for cmd_name, cmd_info in self.commands.items():
206
+ if cmd_name == cmd_info["main_name"]: # 只显示主命令
207
+ help_text = cmd_info.get("help", "无说明")
208
+ help_lines.append(f" {self.prefix}{cmd_name} - {help_text}")
209
+ return "\n".join(help_lines)
210
+
211
+ # 创建全局命令处理器实例
212
+ command = CommandHandler()
@@ -0,0 +1,37 @@
1
+ """
2
+ ErisPulse 事件系统异常处理模块
3
+
4
+ 提供事件系统中可能发生的各种异常类型定义
5
+ """
6
+
7
+ class EventException(Exception):
8
+ """
9
+ 事件系统基础异常
10
+
11
+ 所有事件系统相关异常的基类
12
+ """
13
+ pass
14
+
15
+ class CommandException(EventException):
16
+ """
17
+ 命令处理异常
18
+
19
+ 当命令处理过程中发生错误时抛出
20
+ """
21
+ pass
22
+
23
+ class EventHandlerException(EventException):
24
+ """
25
+ 事件处理器异常
26
+
27
+ 当事件处理器执行过程中发生错误时抛出
28
+ """
29
+ pass
30
+
31
+ class EventNotFoundException(EventException):
32
+ """
33
+ 事件未找到异常
34
+
35
+ 当尝试获取不存在的事件处理器时抛出
36
+ """
37
+ pass
@@ -0,0 +1,128 @@
1
+ """
2
+ ErisPulse 事件管理器
3
+
4
+ 提供全局事件管理功能,包括事件处理器创建、模块事件管理等
5
+ """
6
+
7
+ from .. import adapter, logger, mods
8
+ from .base import BaseEventHandler
9
+ from .exceptions import EventNotFoundException
10
+ from typing import Dict, List, Optional, Callable, Any
11
+ import asyncio
12
+
13
+ class EventManager:
14
+ """
15
+ 事件管理器
16
+
17
+ 管理所有事件处理器,提供全局事件处理功能
18
+ """
19
+
20
+ def __init__(self):
21
+ """
22
+ 初始化事件管理器
23
+ """
24
+ self.event_handlers: Dict[str, BaseEventHandler] = {}
25
+ self.module_events: Dict[str, List[str]] = {}
26
+ self.global_middlewares: List[Callable] = []
27
+
28
+ def create_event_handler(self, event_type: str, module_name: str = None) -> BaseEventHandler:
29
+ """
30
+ 创建事件处理器
31
+
32
+ :param event_type: 事件类型
33
+ :param module_name: 模块名称
34
+ :return: 事件处理器实例
35
+ """
36
+ if event_type not in self.event_handlers:
37
+ handler = BaseEventHandler(event_type, module_name)
38
+ self.event_handlers[event_type] = handler
39
+ return self.event_handlers[event_type]
40
+
41
+ def get_event_handler(self, event_type: str) -> Optional[BaseEventHandler]:
42
+ """
43
+ 获取事件处理器
44
+
45
+ :param event_type: 事件类型
46
+ :return: 事件处理器实例,如果不存在则返回None
47
+ """
48
+ return self.event_handlers.get(event_type)
49
+
50
+ def register_module_event(self, module_name: str, event_type: str):
51
+ """
52
+ 注册模块事件
53
+
54
+ :param module_name: 模块名称
55
+ :param event_type: 事件类型
56
+ """
57
+ if module_name not in self.module_events:
58
+ self.module_events[module_name] = []
59
+ if event_type not in self.module_events[module_name]:
60
+ self.module_events[module_name].append(event_type)
61
+
62
+ def middleware(self, func: Callable):
63
+ """
64
+ 添加全局中间件
65
+
66
+ :param func: 中间件函数
67
+ :return: 中间件函数
68
+ """
69
+ self.global_middlewares.append(func)
70
+ return func
71
+
72
+ async def emit(self, event_type: str, event_data: Dict[str, Any]):
73
+ """
74
+ 触发事件
75
+
76
+ :param event_type: 事件类型
77
+ :param event_data: 事件数据
78
+ """
79
+ # 执行全局中间件
80
+ processed_data = event_data
81
+ for middleware in self.global_middlewares:
82
+ try:
83
+ if asyncio.iscoroutinefunction(middleware):
84
+ processed_data = await middleware(processed_data)
85
+ else:
86
+ processed_data = middleware(processed_data)
87
+ except Exception as e:
88
+ logger.error(f"全局中间件执行错误: {e}")
89
+
90
+ # 触发事件处理器
91
+ if event_type in self.event_handlers:
92
+ handler = self.event_handlers[event_type]
93
+ await handler._process_event(processed_data)
94
+
95
+ # 触发通配符处理器
96
+ if "*" in self.event_handlers:
97
+ handler = self.event_handlers["*"]
98
+ await handler._process_event(processed_data)
99
+
100
+ def get_module_events(self, module_name: str) -> List[str]:
101
+ """
102
+ 获取模块注册的事件
103
+
104
+ :param module_name: 模块名称
105
+ :return: 事件类型列表
106
+ """
107
+ return self.module_events.get(module_name, [])
108
+
109
+ def cleanup_module_events(self, module_name: str):
110
+ """
111
+ 清理模块事件
112
+
113
+ :param module_name: 模块名称
114
+ """
115
+ if module_name in self.module_events:
116
+ event_types = self.module_events[module_name]
117
+ for event_type in event_types:
118
+ if event_type in self.event_handlers:
119
+ # 移除该模块注册的处理器
120
+ handler = self.event_handlers[event_type]
121
+ handler.handlers = [
122
+ h for h in handler.handlers
123
+ if h.get("module") != module_name
124
+ ]
125
+ del self.module_events[module_name]
126
+
127
+ # 全局事件管理器实例
128
+ event_manager = EventManager()
@@ -0,0 +1,91 @@
1
+ """
2
+ ErisPulse 消息处理模块
3
+
4
+ 提供基于装饰器的消息事件处理功能
5
+ """
6
+
7
+ from .base import BaseEventHandler
8
+ from .manager import event_manager
9
+ from .. import adapter
10
+ from typing import Callable, Dict, Any
11
+ import asyncio
12
+
13
+ class MessageHandler:
14
+ """
15
+ 消息处理器
16
+
17
+ 提供不同类型消息事件的处理功能
18
+ """
19
+
20
+ def __init__(self):
21
+ """
22
+ 初始化消息处理器
23
+ """
24
+ self.handler = event_manager.create_event_handler("message", "message")
25
+
26
+ def on_message(self, priority: int = 0):
27
+ """
28
+ 消息事件装饰器
29
+
30
+ :param priority: 处理器优先级
31
+ :return: 装饰器函数
32
+ """
33
+ def decorator(func: Callable):
34
+ self.handler.register(func, priority)
35
+ return func
36
+ return decorator
37
+
38
+ def on_private_message(self, priority: int = 0):
39
+ """
40
+ 私聊消息事件装饰器
41
+
42
+ :param priority: 处理器优先级
43
+ :return: 装饰器函数
44
+ """
45
+ def condition(event: Dict[str, Any]) -> bool:
46
+ return event.get("detail_type") == "private"
47
+
48
+ def decorator(func: Callable):
49
+ self.handler.register(func, priority, condition)
50
+ return func
51
+ return decorator
52
+
53
+ def on_group_message(self, priority: int = 0):
54
+ """
55
+ 群聊消息事件装饰器
56
+
57
+ :param priority: 处理器优先级
58
+ :return: 装饰器函数
59
+ """
60
+ def condition(event: Dict[str, Any]) -> bool:
61
+ return event.get("detail_type") == "group"
62
+
63
+ def decorator(func: Callable):
64
+ self.handler.register(func, priority, condition)
65
+ return func
66
+ return decorator
67
+
68
+ def on_at_message(self, priority: int = 0):
69
+ """
70
+ @消息事件装饰器
71
+
72
+ :param priority: 处理器优先级
73
+ :return: 装饰器函数
74
+ """
75
+ def condition(event: Dict[str, Any]) -> bool:
76
+ # 检查消息中是否有@机器人
77
+ message_segments = event.get("message", [])
78
+ self_id = event.get("self", {}).get("user_id")
79
+
80
+ for segment in message_segments:
81
+ if segment.get("type") == "mention" and segment.get("data", {}).get("user_id") == self_id:
82
+ return True
83
+ return False
84
+
85
+ def decorator(func: Callable):
86
+ self.handler.register(func, priority, condition)
87
+ return func
88
+ return decorator
89
+
90
+ # 创建全局消息处理器实例
91
+ message = MessageHandler()
@@ -0,0 +1,82 @@
1
+ """
2
+ ErisPulse 元事件处理模块
3
+
4
+ 提供基于装饰器的元事件处理功能
5
+ """
6
+
7
+ from .base import BaseEventHandler
8
+ from .manager import event_manager
9
+ from typing import Callable, Dict, Any
10
+
11
+ class MetaHandler:
12
+ """
13
+ 元事件处理器
14
+
15
+ 提供元事件(如连接、断开连接、心跳等)的处理功能
16
+ """
17
+
18
+ def __init__(self):
19
+ """
20
+ 初始化元事件处理器
21
+ """
22
+ self.handler = event_manager.create_event_handler("meta", "meta")
23
+
24
+ def on_meta(self, priority: int = 0):
25
+ """
26
+ 通用元事件装饰器
27
+
28
+ :param priority: 处理器优先级
29
+ :return: 装饰器函数
30
+ """
31
+ def decorator(func: Callable):
32
+ self.handler.register(func, priority)
33
+ return func
34
+ return decorator
35
+
36
+ def on_connect(self, priority: int = 0):
37
+ """
38
+ 连接事件装饰器
39
+
40
+ :param priority: 处理器优先级
41
+ :return: 装饰器函数
42
+ """
43
+ def condition(event: Dict[str, Any]) -> bool:
44
+ return event.get("detail_type") == "connect"
45
+
46
+ def decorator(func: Callable):
47
+ self.handler.register(func, priority, condition)
48
+ return func
49
+ return decorator
50
+
51
+ def on_disconnect(self, priority: int = 0):
52
+ """
53
+ 断开连接事件装饰器
54
+
55
+ :param priority: 处理器优先级
56
+ :return: 装饰器函数
57
+ """
58
+ def condition(event: Dict[str, Any]) -> bool:
59
+ return event.get("detail_type") == "disconnect"
60
+
61
+ def decorator(func: Callable):
62
+ self.handler.register(func, priority, condition)
63
+ return func
64
+ return decorator
65
+
66
+ def on_heartbeat(self, priority: int = 0):
67
+ """
68
+ 心跳事件装饰器
69
+
70
+ :param priority: 处理器优先级
71
+ :return: 装饰器函数
72
+ """
73
+ def condition(event: Dict[str, Any]) -> bool:
74
+ return event.get("detail_type") == "heartbeat"
75
+
76
+ def decorator(func: Callable):
77
+ self.handler.register(func, priority, condition)
78
+ return func
79
+ return decorator
80
+
81
+ # 创建全局元事件处理器实例
82
+ meta = MetaHandler()
@@ -0,0 +1,97 @@
1
+ """
2
+ ErisPulse 通知处理模块
3
+
4
+ 提供基于装饰器的通知事件处理功能
5
+ """
6
+
7
+ from .base import BaseEventHandler
8
+ from .manager import event_manager
9
+ from typing import Callable, Dict, Any
10
+
11
+ class NoticeHandler:
12
+ """
13
+ 通知处理器
14
+
15
+ 提供不同类型通知事件的处理功能
16
+ """
17
+
18
+ def __init__(self):
19
+ """
20
+ 初始化通知处理器
21
+ """
22
+ self.handler = event_manager.create_event_handler("notice", "notice")
23
+
24
+ def on_notice(self, priority: int = 0):
25
+ """
26
+ 通用通知事件装饰器
27
+
28
+ :param priority: 处理器优先级
29
+ :return: 装饰器函数
30
+ """
31
+ def decorator(func: Callable):
32
+ self.handler.register(func, priority)
33
+ return func
34
+ return decorator
35
+
36
+ def on_friend_add(self, priority: int = 0):
37
+ """
38
+ 好友添加通知事件装饰器
39
+
40
+ :param priority: 处理器优先级
41
+ :return: 装饰器函数
42
+ """
43
+ def condition(event: Dict[str, Any]) -> bool:
44
+ return event.get("detail_type") == "friend_increase"
45
+
46
+ def decorator(func: Callable):
47
+ self.handler.register(func, priority, condition)
48
+ return func
49
+ return decorator
50
+
51
+ def on_friend_remove(self, priority: int = 0):
52
+ """
53
+ 好友删除通知事件装饰器
54
+
55
+ :param priority: 处理器优先级
56
+ :return: 装饰器函数
57
+ """
58
+ def condition(event: Dict[str, Any]) -> bool:
59
+ return event.get("detail_type") == "friend_decrease"
60
+
61
+ def decorator(func: Callable):
62
+ self.handler.register(func, priority, condition)
63
+ return func
64
+ return decorator
65
+
66
+ def on_group_increase(self, priority: int = 0):
67
+ """
68
+ 群成员增加通知事件装饰器
69
+
70
+ :param priority: 处理器优先级
71
+ :return: 装饰器函数
72
+ """
73
+ def condition(event: Dict[str, Any]) -> bool:
74
+ return event.get("detail_type") == "group_member_increase"
75
+
76
+ def decorator(func: Callable):
77
+ self.handler.register(func, priority, condition)
78
+ return func
79
+ return decorator
80
+
81
+ def on_group_decrease(self, priority: int = 0):
82
+ """
83
+ 群成员减少通知事件装饰器
84
+
85
+ :param priority: 处理器优先级
86
+ :return: 装饰器函数
87
+ """
88
+ def condition(event: Dict[str, Any]) -> bool:
89
+ return event.get("detail_type") == "group_member_decrease"
90
+
91
+ def decorator(func: Callable):
92
+ self.handler.register(func, priority, condition)
93
+ return func
94
+ return decorator
95
+
96
+ # 创建全局通知处理器实例
97
+ notice = NoticeHandler()
@@ -0,0 +1,67 @@
1
+ """
2
+ ErisPulse 请求处理模块
3
+
4
+ 提供基于装饰器的请求事件处理功能
5
+ """
6
+
7
+ from .base import BaseEventHandler
8
+ from .manager import event_manager
9
+ from typing import Callable, Dict, Any
10
+
11
+ class RequestHandler:
12
+ """
13
+ 请求处理器
14
+
15
+ 提供不同类型请求事件的处理功能(如好友申请、群邀请等)
16
+ """
17
+
18
+ def __init__(self):
19
+ """
20
+ 初始化请求处理器
21
+ """
22
+ self.handler = event_manager.create_event_handler("request", "request")
23
+
24
+ def on_request(self, priority: int = 0):
25
+ """
26
+ 通用请求事件装饰器
27
+
28
+ :param priority: 处理器优先级
29
+ :return: 装饰器函数
30
+ """
31
+ def decorator(func: Callable):
32
+ self.handler.register(func, priority)
33
+ return func
34
+ return decorator
35
+
36
+ def on_friend_request(self, priority: int = 0):
37
+ """
38
+ 好友请求事件装饰器
39
+
40
+ :param priority: 处理器优先级
41
+ :return: 装饰器函数
42
+ """
43
+ def condition(event: Dict[str, Any]) -> bool:
44
+ return event.get("detail_type") == "friend"
45
+
46
+ def decorator(func: Callable):
47
+ self.handler.register(func, priority, condition)
48
+ return func
49
+ return decorator
50
+
51
+ def on_group_request(self, priority: int = 0):
52
+ """
53
+ 群邀请请求事件装饰器
54
+
55
+ :param priority: 处理器优先级
56
+ :return: 装饰器函数
57
+ """
58
+ def condition(event: Dict[str, Any]) -> bool:
59
+ return event.get("detail_type") == "group"
60
+
61
+ def decorator(func: Callable):
62
+ self.handler.register(func, priority, condition)
63
+ return func
64
+ return decorator
65
+
66
+ # 创建全局请求处理器实例
67
+ request = RequestHandler()
@@ -7,9 +7,13 @@ from .router import router, adapter_server
7
7
  from .config import config
8
8
  from . import exceptions
9
9
 
10
+ from . import Event
11
+
10
12
  BaseAdapter = AdapterFather
11
13
 
12
14
  __all__ = [
15
+ 'Event',
16
+
13
17
  'BaseAdapter',
14
18
  'AdapterFather',
15
19
  'SendDSL',
ErisPulse/__init__.py CHANGED
@@ -10,7 +10,7 @@ ErisPulse SDK 主模块
10
10
  {!--< /tips >!--}
11
11
  """
12
12
 
13
- __version__ = "2.1.15-dev.3"
13
+ __version__ = "2.1.15-dev.4"
14
14
  __author__ = "ErisPulse"
15
15
 
16
16
  import os
@@ -31,10 +31,12 @@ from .Core import adapter, AdapterFather, SendDSL
31
31
  from .Core import router, adapter_server
32
32
  from .Core import exceptions
33
33
  from .Core import config
34
+ from .Core import Event
34
35
 
35
36
  sdk = sys.modules[__name__]
36
37
 
37
38
  BaseModules = {
39
+ "Event": Event,
38
40
  "logger": logger,
39
41
  "config": config,
40
42
  "exceptions": exceptions,
ErisPulse/__main__.py CHANGED
@@ -339,28 +339,44 @@ class PackageManager:
339
339
  [sys.executable, "-m", "pip"] + args,
340
340
  stdout=subprocess.PIPE,
341
341
  stderr=subprocess.PIPE,
342
- universal_newlines=True
342
+ universal_newlines=True,
343
+ bufsize=1 # 行缓冲
343
344
  )
344
345
 
345
346
  stdout_lines = []
346
347
  stderr_lines = []
347
348
 
348
- # 实时读取输出
349
- while True:
350
- stdout_line = process.stdout.readline()
351
- stderr_line = process.stderr.readline()
352
-
353
- if stdout_line:
354
- stdout_lines.append(stdout_line)
355
- progress.update(task, advance=1)
356
-
357
- if stderr_line:
358
- stderr_lines.append(stderr_line)
359
- progress.update(task, advance=1)
360
-
361
- if stdout_line == '' and stderr_line == '' and process.poll() is not None:
362
- break
363
-
349
+ # 使用超时机制避免永久阻塞
350
+ import threading
351
+ import queue
352
+
353
+ def read_output(pipe, lines_list):
354
+ try:
355
+ for line in iter(pipe.readline, ''):
356
+ lines_list.append(line)
357
+ progress.update(task, advance=5) # 每行增加进度
358
+ pipe.close()
359
+ except Exception:
360
+ pass
361
+
362
+ stdout_thread = threading.Thread(target=read_output, args=(process.stdout, stdout_lines))
363
+ stderr_thread = threading.Thread(target=read_output, args=(process.stderr, stderr_lines))
364
+
365
+ stdout_thread.start()
366
+ stderr_thread.start()
367
+
368
+ # 等待进程结束,最多等待5分钟
369
+ try:
370
+ process.wait(timeout=300)
371
+ except subprocess.TimeoutExpired:
372
+ process.kill()
373
+ process.wait()
374
+ console.print("[warning]命令执行超时,已强制终止[/]")
375
+ return False, "", "命令执行超时"
376
+
377
+ stdout_thread.join(timeout=10)
378
+ stderr_thread.join(timeout=10)
379
+
364
380
  stdout = ''.join(stdout_lines)
365
381
  stderr = ''.join(stderr_lines)
366
382
 
@@ -368,7 +384,9 @@ class PackageManager:
368
384
  except subprocess.CalledProcessError as e:
369
385
  console.print(f"[error]命令执行失败: {e}[/]")
370
386
  return False, "", str(e)
371
-
387
+ except Exception as e:
388
+ console.print(f"[error]执行过程中发生异常: {e}[/]")
389
+ return False, "", str(e)
372
390
 
373
391
  def _compare_versions(self, version1: str, version2: str) -> int:
374
392
  """
@@ -813,34 +831,83 @@ class PackageManager:
813
831
  if target_version:
814
832
  package_spec += f"=={target_version}"
815
833
 
816
- # 执行更新命令
817
- success, stdout, stderr = self._run_pip_command_with_output(
818
- ["install", "--upgrade", package_spec],
819
- f"更新 ErisPulse SDK {f'到 {target_version}' if target_version else '到最新版本'}"
820
- )
821
-
822
- if success:
823
- new_version = target_version or "最新版本"
824
- console.print(Panel(
825
- f"[success]ErisPulse SDK 更新成功[/]\n"
826
- f" 当前版本: [bold]{current_version}[/]\n"
827
- f" 更新版本: [bold]{new_version}[/]\n\n"
828
- f"[dim]{stdout}[/]",
829
- title="更新完成",
830
- border_style="success"
831
- ))
834
+ # 检查是否在Windows上且尝试更新自身
835
+ if sys.platform == "win32":
836
+ # 构建更新脚本
837
+ update_script = f"""
838
+ import time
839
+ import subprocess
840
+ import sys
841
+ import os
842
+
843
+ # 等待原进程结束
844
+ time.sleep(2)
845
+
846
+ # 执行更新命令
847
+ try:
848
+ result = subprocess.run([
849
+ sys.executable, "-m", "pip", "install", "--upgrade", "{package_spec}"
850
+ ], capture_output=True, text=True, timeout=300)
851
+
852
+ if result.returncode == 0:
853
+ print("更新成功!")
854
+ print(result.stdout)
855
+ else:
856
+ print("更新失败:")
857
+ print(result.stderr)
858
+ except Exception as e:
859
+ print(f"更新过程中出错: {{e}}")
860
+
861
+ # 清理临时脚本
862
+ try:
863
+ os.remove(__file__)
864
+ except:
865
+ pass
866
+ """
867
+ # 创建临时更新脚本
868
+ import tempfile
869
+ script_path = os.path.join(tempfile.gettempdir(), "epsdk_update.py")
870
+ with open(script_path, "w", encoding="utf-8") as f:
871
+ f.write(update_script)
872
+
873
+ # 启动更新进程并退出当前进程
874
+ console.print("[info]正在启动更新进程...[/]")
875
+ console.print("[info]请稍后重新运行CLI以使用新版本[/]")
832
876
 
833
- if not target_version:
834
- console.print("[info]请重新启动CLI以使用新版本[/]")
877
+ subprocess.Popen([
878
+ sys.executable, script_path
879
+ ], creationflags=subprocess.CREATE_NEW_CONSOLE)
880
+
881
+ return True
835
882
  else:
836
- console.print(Panel(
837
- f"[error]ErisPulse SDK 更新失败[/]\n\n"
838
- f"[dim]{stderr}[/]",
839
- title="更新失败",
840
- border_style="error"
841
- ))
883
+ # 非Windows平台
884
+ success, stdout, stderr = self._run_pip_command_with_output(
885
+ ["install", "--upgrade", package_spec],
886
+ f"更新 ErisPulse SDK {f'到 {target_version}' if target_version else '到最新版本'}"
887
+ )
842
888
 
843
- return success
889
+ if success:
890
+ new_version = target_version or "最新版本"
891
+ console.print(Panel(
892
+ f"[success]ErisPulse SDK 更新成功[/]\n"
893
+ f" 当前版本: [bold]{current_version}[/]\n"
894
+ f" 更新版本: [bold]{new_version}[/]\n\n"
895
+ f"[dim]{stdout}[/]",
896
+ title="更新完成",
897
+ border_style="success"
898
+ ))
899
+
900
+ if not target_version:
901
+ console.print("[info]请重新启动CLI以使用新版本[/]")
902
+ else:
903
+ console.print(Panel(
904
+ f"[error]ErisPulse SDK 更新失败[/]\n\n"
905
+ f"[dim]{stderr}[/]",
906
+ title="更新失败",
907
+ border_style="error"
908
+ ))
909
+
910
+ return success
844
911
 
845
912
  class ReloadHandler(FileSystemEventHandler):
846
913
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ErisPulse
3
- Version: 2.1.15.dev3
3
+ Version: 2.2.0.dev0
4
4
  Summary: ErisPulse 是一个模块化、可扩展的异步 Python SDK 框架,主要用于构建高效、可维护的机器人应用程序。
5
5
  Author-email: "艾莉丝·格雷拉特(WSu2059)" <wsu2059@qq.com>
6
6
  License: MIT License
@@ -34,6 +34,12 @@ License: MIT License
34
34
  - Metadata definitions
35
35
 
36
36
  This ensures consistent behavior and interoperability across all adapter implementations.
37
+
38
+ 感谢所有为开源社区做出贡献的开发者和作者
39
+
40
+ 请尊重每一位开源作者的劳动成果,承诺在使用、修改和分发本软件时,将严格遵守相关许可证条款,并保留所有原始版权声明
41
+
42
+ 开源精神的核心在于分享、协作与尊重。我们希望通过本项目,能够传承这一精神,为开源社区的发展贡献一份力量
37
43
  License-File: LICENSE
38
44
  Classifier: Development Status :: 5 - Production/Stable
39
45
  Classifier: Intended Audience :: Developers
@@ -0,0 +1,26 @@
1
+ ErisPulse/__init__.py,sha256=c9pE-jRF89x4p5GF3QNU7wFxkli39tCOR_PyD_Tr8qQ,26834
2
+ ErisPulse/__main__.py,sha256=HTq7Y7446eukTCHDX2_O9Ie8i-A7KHUCEJCmxx_j5co,76276
3
+ ErisPulse/Core/__init__.py,sha256=gl-0UAI5_syGt1_23Lgy8P3vGjGxusWfYnTi281f5qI,520
4
+ ErisPulse/Core/adapter.py,sha256=y75u_heNmpYLDjIBtVTfMzTHZFixWtYFv0JVskNI-2w,18300
5
+ ErisPulse/Core/config.py,sha256=y0ChfCuw-6jAqs9Ii2tPJg0e4A765qzQLRcK6O8zh4c,2425
6
+ ErisPulse/Core/env.py,sha256=IT_6Xks5Ka089O_4SVTvYNIC9Ly1IHX_Esb3SsleRj8,338
7
+ ErisPulse/Core/erispulse_config.py,sha256=QDx401hNX9JcSHqCSVK33X6VTubl6HI1znAK3T_J0K0,3034
8
+ ErisPulse/Core/exceptions.py,sha256=zuTREGczwGzbYT4Z6dACqHwgNRpiJeLFR8aCxFdOg7k,3667
9
+ ErisPulse/Core/logger.py,sha256=6p53nQE7NFXSqs_lftW-HQB1BQcgruAYOpIYx25QLVA,11252
10
+ ErisPulse/Core/mods.py,sha256=vKLEDr2nQ4kUULHmUQYFbRL04ePIKlwLEOGB-ldMYS8,7130
11
+ ErisPulse/Core/router.py,sha256=s2EBh2qpt3UXYhB06Ppc1XTFuZ3u0ZfXENJxwkgPoq8,8542
12
+ ErisPulse/Core/storage.py,sha256=oRum4eVaTc3yxcaafggoIvrk41LPbvApSCxkGM3YmzU,17904
13
+ ErisPulse/Core/Event/__init__.py,sha256=fgK9bskLqVYau9ORfhGNBxSBJo7oZheeSYvwucigpEU,1042
14
+ ErisPulse/Core/Event/base.py,sha256=NQb9_mA7OwxCGbcpunOQD_aV9Zq3i7xLQ1AzKM-ebl8,3758
15
+ ErisPulse/Core/Event/cmd.py,sha256=B7c-PUaCn5qhubCqgI1pDSvvjofTLQHzmBaD0TuqJF4,6964
16
+ ErisPulse/Core/Event/exceptions.py,sha256=iGcuPaC7F4cZeujcvBdZb9bzQGnHBdb9CcPKoB760Bo,711
17
+ ErisPulse/Core/Event/manager.py,sha256=xIdK29jY2h-cCLFeq7JqPxuzYvuU7jAPdJMq2CPgwcQ,4270
18
+ ErisPulse/Core/Event/message.py,sha256=n5ObSaGmyU3z5QSM5-5VwOBr69FY7p4TdRoy6Xy0Nzg,2640
19
+ ErisPulse/Core/Event/meta.py,sha256=tr5aKoFtqCjybkpbUJ6JfuppZTk34eAipGvggPkGeSs,2282
20
+ ErisPulse/Core/Event/notice.py,sha256=YLe5OphsF4sf1nvOokQ9bgCpCRf6MuGKRa1QjWotiK8,2825
21
+ ErisPulse/Core/Event/request.py,sha256=FOkbW9WcUnc2uywkUWfUim4xJXXmlY1gYK6SD8Cd7So,1853
22
+ erispulse-2.2.0.dev0.dist-info/METADATA,sha256=38Qx-4vuxUcOKVRUHlxg9qV76NE6QQtUtgsS9txSU6k,7290
23
+ erispulse-2.2.0.dev0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
24
+ erispulse-2.2.0.dev0.dist-info/entry_points.txt,sha256=Jss71M6nEha0TA-DyVZugPYdcL14s9QpiOeIlgWxzOc,182
25
+ erispulse-2.2.0.dev0.dist-info/licenses/LICENSE,sha256=b2XwzcfWuv_36Op3xGdjcuPHgfCz62yT3bXYjfStpxY,1852
26
+ erispulse-2.2.0.dev0.dist-info/RECORD,,
@@ -28,4 +28,10 @@ This SDK's core adapter standardization layer strictly follows OneBot12 specific
28
28
  - Message segment definitions
29
29
  - Metadata definitions
30
30
 
31
- This ensures consistent behavior and interoperability across all adapter implementations.
31
+ This ensures consistent behavior and interoperability across all adapter implementations.
32
+
33
+ 感谢所有为开源社区做出贡献的开发者和作者
34
+
35
+ 请尊重每一位开源作者的劳动成果,承诺在使用、修改和分发本软件时,将严格遵守相关许可证条款,并保留所有原始版权声明
36
+
37
+ 开源精神的核心在于分享、协作与尊重。我们希望通过本项目,能够传承这一精神,为开源社区的发展贡献一份力量
@@ -1,17 +0,0 @@
1
- ErisPulse/__init__.py,sha256=ElwKDJgga0oePhwPXuxgUsWMevpfXdsii0X0zuJPmC0,26790
2
- ErisPulse/__main__.py,sha256=ePvZuyPEq5-ODog3aFMPQJCbj3TNKsZU_N3kynJ6aek,73908
3
- ErisPulse/Core/__init__.py,sha256=VCYMC8Ehfw603jV9KFaWdiWAh4UORSqrMTRuVfXZK0I,481
4
- ErisPulse/Core/adapter.py,sha256=y75u_heNmpYLDjIBtVTfMzTHZFixWtYFv0JVskNI-2w,18300
5
- ErisPulse/Core/config.py,sha256=y0ChfCuw-6jAqs9Ii2tPJg0e4A765qzQLRcK6O8zh4c,2425
6
- ErisPulse/Core/env.py,sha256=IT_6Xks5Ka089O_4SVTvYNIC9Ly1IHX_Esb3SsleRj8,338
7
- ErisPulse/Core/erispulse_config.py,sha256=QDx401hNX9JcSHqCSVK33X6VTubl6HI1znAK3T_J0K0,3034
8
- ErisPulse/Core/exceptions.py,sha256=zuTREGczwGzbYT4Z6dACqHwgNRpiJeLFR8aCxFdOg7k,3667
9
- ErisPulse/Core/logger.py,sha256=6p53nQE7NFXSqs_lftW-HQB1BQcgruAYOpIYx25QLVA,11252
10
- ErisPulse/Core/mods.py,sha256=vKLEDr2nQ4kUULHmUQYFbRL04ePIKlwLEOGB-ldMYS8,7130
11
- ErisPulse/Core/router.py,sha256=s2EBh2qpt3UXYhB06Ppc1XTFuZ3u0ZfXENJxwkgPoq8,8542
12
- ErisPulse/Core/storage.py,sha256=oRum4eVaTc3yxcaafggoIvrk41LPbvApSCxkGM3YmzU,17904
13
- erispulse-2.1.15.dev3.dist-info/METADATA,sha256=2F6t5xA_I3utUv6eRjgXJ24--oYEpHWQ8ZauCLRbI6I,6856
14
- erispulse-2.1.15.dev3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
15
- erispulse-2.1.15.dev3.dist-info/entry_points.txt,sha256=Jss71M6nEha0TA-DyVZugPYdcL14s9QpiOeIlgWxzOc,182
16
- erispulse-2.1.15.dev3.dist-info/licenses/LICENSE,sha256=4jyqikiB0G0n06CEEMMTzTXjE4IShghSlB74skMSPQs,1464
17
- erispulse-2.1.15.dev3.dist-info/RECORD,,