ErisPulse 2.2.1.dev0__py3-none-any.whl → 2.3.0.dev5__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.
- ErisPulse/Core/Bases/__init__.py +14 -0
- ErisPulse/Core/Bases/adapter.py +196 -0
- ErisPulse/Core/Bases/module.py +54 -0
- ErisPulse/Core/Event/__init__.py +14 -0
- ErisPulse/Core/Event/base.py +15 -2
- ErisPulse/Core/Event/command.py +21 -2
- ErisPulse/Core/Event/message.py +15 -0
- ErisPulse/Core/Event/meta.py +15 -0
- ErisPulse/Core/Event/notice.py +15 -0
- ErisPulse/Core/Event/request.py +16 -1
- ErisPulse/Core/__init__.py +38 -19
- ErisPulse/Core/{erispulse_config.py → _self_config.py} +16 -3
- ErisPulse/Core/adapter.py +374 -377
- ErisPulse/Core/config.py +137 -38
- ErisPulse/Core/exceptions.py +6 -1
- ErisPulse/Core/lifecycle.py +167 -0
- ErisPulse/Core/logger.py +97 -49
- ErisPulse/Core/module.py +279 -56
- ErisPulse/Core/router.py +112 -23
- ErisPulse/Core/storage.py +258 -77
- ErisPulse/Core/ux.py +664 -0
- ErisPulse/__init__.py +587 -242
- ErisPulse/__main__.py +1 -1999
- ErisPulse/utils/__init__.py +15 -0
- ErisPulse/utils/cli.py +1102 -0
- ErisPulse/utils/package_manager.py +847 -0
- ErisPulse/utils/reload_handler.py +135 -0
- {erispulse-2.2.1.dev0.dist-info → erispulse-2.3.0.dev5.dist-info}/METADATA +24 -6
- erispulse-2.3.0.dev5.dist-info/RECORD +33 -0
- {erispulse-2.2.1.dev0.dist-info → erispulse-2.3.0.dev5.dist-info}/WHEEL +1 -1
- {erispulse-2.2.1.dev0.dist-info → erispulse-2.3.0.dev5.dist-info}/licenses/LICENSE +1 -1
- ErisPulse/Core/env.py +0 -15
- ErisPulse/Core/module_registry.py +0 -227
- erispulse-2.2.1.dev0.dist-info/RECORD +0 -26
- {erispulse-2.2.1.dev0.dist-info → erispulse-2.3.0.dev5.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ErisPulse SDK 热重载处理器
|
|
3
|
+
|
|
4
|
+
实现热重载功能,监控文件变化并重启进程
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
import os
|
|
9
|
+
import subprocess
|
|
10
|
+
import sys
|
|
11
|
+
import threading
|
|
12
|
+
import time
|
|
13
|
+
from watchdog.events import FileSystemEventHandler
|
|
14
|
+
|
|
15
|
+
from rich.console import Console
|
|
16
|
+
|
|
17
|
+
# 全局控制台实例,从CLI模块导入
|
|
18
|
+
console = Console()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ReloadHandler(FileSystemEventHandler):
|
|
22
|
+
"""
|
|
23
|
+
文件系统事件处理器
|
|
24
|
+
|
|
25
|
+
实现热重载功能,监控文件变化并重启进程
|
|
26
|
+
|
|
27
|
+
{!--< tips >!--}
|
|
28
|
+
1. 支持.py文件修改重载
|
|
29
|
+
2. 支持配置文件修改重载
|
|
30
|
+
{!--< /tips >!--}
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(self, script_path: str, reload_mode: bool = False):
|
|
34
|
+
"""
|
|
35
|
+
初始化处理器
|
|
36
|
+
|
|
37
|
+
:param script_path: 要监控的脚本路径
|
|
38
|
+
:param reload_mode: 是否启用重载模式
|
|
39
|
+
"""
|
|
40
|
+
super().__init__()
|
|
41
|
+
self.script_path = os.path.abspath(script_path)
|
|
42
|
+
self.process = None
|
|
43
|
+
self.last_reload = time.time()
|
|
44
|
+
self.reload_mode = reload_mode
|
|
45
|
+
self.start_process()
|
|
46
|
+
self.watched_files = set()
|
|
47
|
+
|
|
48
|
+
def start_process(self):
|
|
49
|
+
"""启动监控进程"""
|
|
50
|
+
if self.process:
|
|
51
|
+
self._terminate_process()
|
|
52
|
+
|
|
53
|
+
console.print(f"[bold]启动进程: [path]{self.script_path}[/][/]")
|
|
54
|
+
try:
|
|
55
|
+
self.process = subprocess.Popen(
|
|
56
|
+
[sys.executable, self.script_path],
|
|
57
|
+
stdin=sys.stdin,
|
|
58
|
+
stdout=sys.stdout,
|
|
59
|
+
stderr=sys.stderr
|
|
60
|
+
)
|
|
61
|
+
self.last_reload = time.time()
|
|
62
|
+
except Exception as e:
|
|
63
|
+
console.print(f"[error]启动进程失败: {e}[/]")
|
|
64
|
+
raise
|
|
65
|
+
|
|
66
|
+
def _terminate_process(self):
|
|
67
|
+
"""
|
|
68
|
+
终止当前进程
|
|
69
|
+
|
|
70
|
+
:raises subprocess.TimeoutExpired: 进程终止超时时抛出
|
|
71
|
+
"""
|
|
72
|
+
try:
|
|
73
|
+
self.process.terminate()
|
|
74
|
+
# 等待最多2秒让进程正常退出
|
|
75
|
+
self.process.wait(timeout=2)
|
|
76
|
+
except subprocess.TimeoutExpired:
|
|
77
|
+
console.print("[warning]进程未正常退出,强制终止...[/]")
|
|
78
|
+
self.process.kill()
|
|
79
|
+
self.process.wait()
|
|
80
|
+
except Exception as e:
|
|
81
|
+
console.print(f"[error]终止进程时出错: {e}[/]")
|
|
82
|
+
|
|
83
|
+
def on_modified(self, event):
|
|
84
|
+
"""
|
|
85
|
+
文件修改事件处理
|
|
86
|
+
|
|
87
|
+
:param event: 文件系统事件
|
|
88
|
+
"""
|
|
89
|
+
now = time.time()
|
|
90
|
+
if now - self.last_reload < 1.0: # 防抖
|
|
91
|
+
return
|
|
92
|
+
|
|
93
|
+
if event.src_path.endswith(".py") and self.reload_mode:
|
|
94
|
+
self._handle_reload(event, "文件变动")
|
|
95
|
+
# elif event.src_path.endswith(("config.toml", ".env")):
|
|
96
|
+
# self._handle_reload(event, "配置变动")
|
|
97
|
+
|
|
98
|
+
def _handle_reload(self, event, reason: str):
|
|
99
|
+
"""
|
|
100
|
+
处理热重载逻辑
|
|
101
|
+
:param event: 文件系统事件
|
|
102
|
+
:param reason: 重载原因
|
|
103
|
+
"""
|
|
104
|
+
from ErisPulse.Core import adapter, logger
|
|
105
|
+
# 在重载前确保所有适配器正确停止
|
|
106
|
+
try:
|
|
107
|
+
# 检查适配器是否正在运行
|
|
108
|
+
if hasattr(adapter, '_started_instances') and adapter._started_instances:
|
|
109
|
+
logger.info("正在停止适配器...")
|
|
110
|
+
# 创建新的事件循环来运行异步停止操作
|
|
111
|
+
|
|
112
|
+
# 如果在主线程中
|
|
113
|
+
if threading.current_thread() is threading.main_thread():
|
|
114
|
+
try:
|
|
115
|
+
# 在新线程中运行适配器停止
|
|
116
|
+
stop_thread = threading.Thread(target=lambda: asyncio.run(adapter.shutdown()))
|
|
117
|
+
stop_thread.start()
|
|
118
|
+
stop_thread.join(timeout=10) # 最多等待10秒
|
|
119
|
+
except RuntimeError:
|
|
120
|
+
# 没有运行中的事件循环
|
|
121
|
+
asyncio.run(adapter.shutdown())
|
|
122
|
+
else:
|
|
123
|
+
# 在非主线程中,创建新的事件循环
|
|
124
|
+
new_loop = asyncio.new_event_loop()
|
|
125
|
+
asyncio.set_event_loop(new_loop)
|
|
126
|
+
new_loop.run_until_complete(adapter.shutdown())
|
|
127
|
+
|
|
128
|
+
logger.info("适配器已停止")
|
|
129
|
+
except Exception as e:
|
|
130
|
+
logger.warning(f"停止适配器时出错: {e}")
|
|
131
|
+
|
|
132
|
+
# 原有的重载逻辑
|
|
133
|
+
logger.info(f"检测到文件变更 ({reason}),正在重启...")
|
|
134
|
+
self._terminate_process()
|
|
135
|
+
self.start_process()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ErisPulse
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0.dev5
|
|
4
4
|
Summary: ErisPulse 是一个模块化、可扩展的异步 Python SDK 框架,主要用于构建高效、可维护的机器人应用程序。
|
|
5
5
|
Author-email: "艾莉丝·格雷拉特(WSu2059)" <wsu2059@qq.com>
|
|
6
6
|
License: MIT License
|
|
@@ -37,7 +37,7 @@ License: MIT License
|
|
|
37
37
|
|
|
38
38
|
感谢所有为开源社区做出贡献的开发者和作者
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
请尊重每一位开源作者的劳动成果,您需要承诺在使用、修改和分发本软件时,严格遵守相关许可证条款,并保留所有原始版权声明
|
|
41
41
|
|
|
42
42
|
开源精神的核心在于分享、协作与尊重。我们希望通过本项目,能够传承这一精神,为开源社区的发展贡献一份力量
|
|
43
43
|
License-File: LICENSE
|
|
@@ -73,6 +73,7 @@ Description-Content-Type: text/markdown
|
|
|
73
73
|
|
|
74
74
|
[](https://pypi.org/project/ErisPulse/)
|
|
75
75
|
[](https://pypi.org/project/ErisPulse/)
|
|
76
|
+
[](https://github.com/astral-sh/ruff)
|
|
76
77
|
[](https://socket.dev/pypi/package/ErisPulse)
|
|
77
78
|
|
|
78
79
|
## 文档资源
|
|
@@ -149,7 +150,7 @@ python -c "from ErisPulse import sdk; sdk.init()"
|
|
|
149
150
|
|
|
150
151
|
### 5. 运行测试
|
|
151
152
|
|
|
152
|
-
我们提供了一个交互式测试脚本,可以帮助您快速验证SDK
|
|
153
|
+
我们提供了一个交互式测试脚本,可以帮助您快速验证SDK功能:
|
|
153
154
|
|
|
154
155
|
```bash
|
|
155
156
|
uv run devs/test.py
|
|
@@ -162,6 +163,25 @@ uv run devs/test.py
|
|
|
162
163
|
- 工具函数测试
|
|
163
164
|
- 适配器功能测试
|
|
164
165
|
|
|
166
|
+
## 项目结构
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
ErisPulse/
|
|
170
|
+
├── src/
|
|
171
|
+
│ └── ErisPulse/ # 核心源代码
|
|
172
|
+
│ ├── Core/ # 核心模块
|
|
173
|
+
│ │ ├── Bases/ # 基础类定义
|
|
174
|
+
│ │ ├── Event/ # 事件系统
|
|
175
|
+
│ │ └── ... # 其他核心组件
|
|
176
|
+
│ └── __init__.py # SDK入口点
|
|
177
|
+
├── examples/ # 示例代码
|
|
178
|
+
├── devs/ # 开发工具
|
|
179
|
+
├── docs/ # 文档
|
|
180
|
+
├── tests/ # 测试代码
|
|
181
|
+
├── scripts/ # 脚本文件
|
|
182
|
+
└── config.toml # 默认配置文件
|
|
183
|
+
```
|
|
184
|
+
|
|
165
185
|
## 贡献指南
|
|
166
186
|
|
|
167
187
|
我们欢迎各种形式的贡献,包括但不限于:
|
|
@@ -182,6 +202,4 @@ uv run devs/test.py
|
|
|
182
202
|
|
|
183
203
|
---
|
|
184
204
|
|
|
185
|
-
[](https://starchart.cc/ErisPulse/ErisPulse)
|
|
186
|
-
|
|
187
|
-
|
|
205
|
+
[](https://starchart.cc/ErisPulse/ErisPulse)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
ErisPulse/__init__.py,sha256=6foVg_ZnQhO9Cg8vwmyHhJSxmnSwLCrzITFE5CP8qLc,42583
|
|
2
|
+
ErisPulse/__main__.py,sha256=x1VV2mbn1B9RVRhG5uumTCrvZCLzJjGWN0wFll-G0H4,471
|
|
3
|
+
ErisPulse/Core/__init__.py,sha256=9RNwUq9Hbe3r6nA8QBvq2pvMJN4QiBfo71N0u_ywiwI,1398
|
|
4
|
+
ErisPulse/Core/_self_config.py,sha256=7PdOfJj1_s4fViayUSzqiUWDTb7Tie_1KjdRcIveK8w,3281
|
|
5
|
+
ErisPulse/Core/adapter.py,sha256=9wpaE9B6LixlGTJ0p341wYe4AE3SVuczToMOWd7UkL4,19707
|
|
6
|
+
ErisPulse/Core/config.py,sha256=cV0R2eUWNECIogYLFbhNu1pYl8HStPG-DNbCe3lkY4E,5873
|
|
7
|
+
ErisPulse/Core/exceptions.py,sha256=tTOOs57SD8aSp4HXomuXtVYgHJCJtfP3AS4JIIq1LPk,3920
|
|
8
|
+
ErisPulse/Core/lifecycle.py,sha256=oPKxg0hBadSgAn9X_weGo6KeCZ9SUV5A_Se-18qWglM,5547
|
|
9
|
+
ErisPulse/Core/logger.py,sha256=nktXT-6cxF50NYsUErMsf8J79brzXg2faaJ4Agt2Gro,12599
|
|
10
|
+
ErisPulse/Core/module.py,sha256=13rI03GwEzVd66hIhZnZNybiA9wj7ITzQILi1-nCjhQ,12944
|
|
11
|
+
ErisPulse/Core/router.py,sha256=rtvUjbRHVeTTgWBBG-yxK91oEjs5Tw3ReryqCI-rMYc,12411
|
|
12
|
+
ErisPulse/Core/storage.py,sha256=WbREN-GTpzPls8Vx3t8F2U_lzmCKEsI4OcecWWmvaSk,25238
|
|
13
|
+
ErisPulse/Core/ux.py,sha256=DQHzSXJGGI2CHoVQg1Od5qYDDdxXObEJOaqAoGZEegQ,31631
|
|
14
|
+
ErisPulse/Core/Bases/__init__.py,sha256=hHKsI2zQfBdahnEuHlMgzOX2_ygRDOVN8-VqTIrcxP4,230
|
|
15
|
+
ErisPulse/Core/Bases/adapter.py,sha256=aCupQdc8M5Ds7m5dZMCmtoyC-0Zqh5K_6F3uKle8WXE,6490
|
|
16
|
+
ErisPulse/Core/Bases/module.py,sha256=TtzZQ4x4u09S6yDibsIHa9srlGLFPXCHdn2WxZ3nmdo,1154
|
|
17
|
+
ErisPulse/Core/Event/__init__.py,sha256=pZ3ASQop7qbQd3OybyCp5I2Zln3l-DEoiGKH8Zxmp38,1487
|
|
18
|
+
ErisPulse/Core/Event/base.py,sha256=ygF5aPjQ76VTVei1XrCDFj4QobiGoQqjIAAl5HrJC_Y,4019
|
|
19
|
+
ErisPulse/Core/Event/command.py,sha256=d9lopDO4B0qCxTQmnUJhte7pZ6IImVfKpiovA6pI7yg,17889
|
|
20
|
+
ErisPulse/Core/Event/exceptions.py,sha256=iGcuPaC7F4cZeujcvBdZb9bzQGnHBdb9CcPKoB760Bo,711
|
|
21
|
+
ErisPulse/Core/Event/message.py,sha256=wxg_GJsI1ZvPrV9611xELLxnlk2bcxMJH7EBEkoWwgE,4024
|
|
22
|
+
ErisPulse/Core/Event/meta.py,sha256=0cs0Cg5r58kll3P4lNtnVWAKLQiL6MoXPkbkk6_IEko,3660
|
|
23
|
+
ErisPulse/Core/Event/notice.py,sha256=tU28tc3Ig-FMB2EJUDO2Z9ewfJjzEPh2O2J4lU7GYDk,4557
|
|
24
|
+
ErisPulse/Core/Event/request.py,sha256=rYjFjRJccNRZ6bkY89ig8Q2YntnoytUfg-_PGntJxXg,2956
|
|
25
|
+
ErisPulse/utils/__init__.py,sha256=GTLeWbAkQSWPJ3NjFDV2DYZaTZ6bx56VumrtqkI8upA,255
|
|
26
|
+
ErisPulse/utils/cli.py,sha256=fwxyGAcIh57rQkZ-YF6TQKou0v2Wrtjg1XUFp-IOcHI,40924
|
|
27
|
+
ErisPulse/utils/package_manager.py,sha256=8auzSigymzff6JBMKVy-6XntPPFGeO7qTUSKoY-vYFE,32767
|
|
28
|
+
ErisPulse/utils/reload_handler.py,sha256=ulVJEK7NsdsTXUkqp40iLf9D5rC8WjFut48UIRj9JyQ,4552
|
|
29
|
+
erispulse-2.3.0.dev5.dist-info/METADATA,sha256=mAAjbybK9-vZPmSMt80JKRBS7YNfDhVhS_J29KEU1pw,7478
|
|
30
|
+
erispulse-2.3.0.dev5.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
31
|
+
erispulse-2.3.0.dev5.dist-info/entry_points.txt,sha256=Jss71M6nEha0TA-DyVZugPYdcL14s9QpiOeIlgWxzOc,182
|
|
32
|
+
erispulse-2.3.0.dev5.dist-info/licenses/LICENSE,sha256=tJjKWuY4OPWNgriiixWLvmFb8Pf8p_-4NMq_zZN3gWg,1858
|
|
33
|
+
erispulse-2.3.0.dev5.dist-info/RECORD,,
|
|
@@ -32,6 +32,6 @@ This ensures consistent behavior and interoperability across all adapter impleme
|
|
|
32
32
|
|
|
33
33
|
感谢所有为开源社区做出贡献的开发者和作者
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
请尊重每一位开源作者的劳动成果,您需要承诺在使用、修改和分发本软件时,严格遵守相关许可证条款,并保留所有原始版权声明
|
|
36
36
|
|
|
37
37
|
开源精神的核心在于分享、协作与尊重。我们希望通过本项目,能够传承这一精神,为开源社区的发展贡献一份力量
|
ErisPulse/Core/env.py
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
ErisPulse 环境模块 (已弃用)
|
|
3
|
-
|
|
4
|
-
此模块已重命名为 storage,为保持向后兼容性而保留。
|
|
5
|
-
建议使用 from ErisPulse.Core import storage 替代 from ErisPulse.Core import env
|
|
6
|
-
|
|
7
|
-
{!--< deprecated >!--} 请使用 storage 模块替代
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
from .storage import storage
|
|
11
|
-
|
|
12
|
-
# 向后兼容性
|
|
13
|
-
env = storage
|
|
14
|
-
|
|
15
|
-
__all__ = ['env']
|
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
ErisPulse 模块管理器
|
|
3
|
-
|
|
4
|
-
提供模块的注册、状态管理和依赖关系处理功能。支持模块的启用/禁用、版本控制和依赖解析。
|
|
5
|
-
|
|
6
|
-
{!--< tips >!--}
|
|
7
|
-
1. 使用模块前缀区分不同模块的配置
|
|
8
|
-
2. 支持模块状态持久化存储
|
|
9
|
-
3. 自动处理模块间的依赖关系
|
|
10
|
-
{!--< /tips >!--}
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
from typing import Dict, Optional, Any, List, Set, Tuple, Union, Type, FrozenSet
|
|
14
|
-
|
|
15
|
-
class ModuleRegistry:
|
|
16
|
-
"""
|
|
17
|
-
ErisPulse 模块注册表
|
|
18
|
-
|
|
19
|
-
管理所有模块的注册信息和启用状态
|
|
20
|
-
|
|
21
|
-
{!--< tips >!--}
|
|
22
|
-
1. 模块信息通过 set_module/get_module 管理
|
|
23
|
-
2. 模块状态通过 set_module_status/get_module_status 控制
|
|
24
|
-
3. 支持批量操作模块信息
|
|
25
|
-
{!--< /tips >!--}
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
DEFAULT_MODULE_PREFIX = "erispulse.data.modules.info:"
|
|
29
|
-
DEFAULT_STATUS_PREFIX = "erispulse.data.modules.status:"
|
|
30
|
-
|
|
31
|
-
def __init__(self):
|
|
32
|
-
from .storage import storage
|
|
33
|
-
self.storage = storage
|
|
34
|
-
self._ensure_prefixes()
|
|
35
|
-
|
|
36
|
-
def _ensure_prefixes(self) -> None:
|
|
37
|
-
"""
|
|
38
|
-
{!--< internal-use >!--}
|
|
39
|
-
确保模块前缀配置存在
|
|
40
|
-
"""
|
|
41
|
-
if not self.storage.get("erispulse.system.module_prefix"):
|
|
42
|
-
self.storage.set("erispulse.system.module_prefix", self.DEFAULT_MODULE_PREFIX)
|
|
43
|
-
if not self.storage.get("erispulse.system.status_prefix"):
|
|
44
|
-
self.storage.set("erispulse.system.status_prefix", self.DEFAULT_STATUS_PREFIX)
|
|
45
|
-
|
|
46
|
-
@property
|
|
47
|
-
def module_prefix(self) -> str:
|
|
48
|
-
"""
|
|
49
|
-
获取模块数据前缀
|
|
50
|
-
|
|
51
|
-
:return: 模块数据前缀字符串
|
|
52
|
-
"""
|
|
53
|
-
return self.storage.get("erispulse.system.module_prefix")
|
|
54
|
-
|
|
55
|
-
@property
|
|
56
|
-
def status_prefix(self) -> str:
|
|
57
|
-
"""
|
|
58
|
-
获取模块状态前缀
|
|
59
|
-
|
|
60
|
-
:return: 模块状态前缀字符串
|
|
61
|
-
"""
|
|
62
|
-
return self.storage.get("erispulse.system.status_prefix")
|
|
63
|
-
|
|
64
|
-
def set_module_status(self, module_name: str, status: bool) -> None:
|
|
65
|
-
"""
|
|
66
|
-
设置模块启用状态
|
|
67
|
-
|
|
68
|
-
:param module_name: [str] 模块名称
|
|
69
|
-
:param status: [bool] 启用状态 (True=启用, False=禁用)
|
|
70
|
-
|
|
71
|
-
:example:
|
|
72
|
-
>>> # 启用模块
|
|
73
|
-
>>> module_registry.set_module_status("MyModule", True)
|
|
74
|
-
>>> # 禁用模块
|
|
75
|
-
>>> module_registry.set_module_status("MyModule", False)
|
|
76
|
-
"""
|
|
77
|
-
from .logger import logger
|
|
78
|
-
self.storage.set(f"{self.status_prefix}{module_name}", bool(status))
|
|
79
|
-
logger.debug(f"模块 {module_name} 状态已设置为 {status}")
|
|
80
|
-
|
|
81
|
-
def get_module_status(self, module_name: str) -> bool:
|
|
82
|
-
"""
|
|
83
|
-
获取模块启用状态
|
|
84
|
-
|
|
85
|
-
:param module_name: [str] 模块名称
|
|
86
|
-
:return: [bool] 模块是否启用
|
|
87
|
-
|
|
88
|
-
:example:
|
|
89
|
-
>>> if module_registry.get_module_status("MyModule"):
|
|
90
|
-
>>> print("模块已启用")
|
|
91
|
-
"""
|
|
92
|
-
status = self.storage.get(f"{self.status_prefix}{module_name}", True)
|
|
93
|
-
if isinstance(status, str):
|
|
94
|
-
return status.lower() not in ('false', '0', 'no', 'off')
|
|
95
|
-
return bool(status)
|
|
96
|
-
|
|
97
|
-
def set_module(self, module_name: str, module_info: Dict[str, Any]) -> None:
|
|
98
|
-
"""
|
|
99
|
-
注册或更新模块信息
|
|
100
|
-
|
|
101
|
-
:param module_name: [str] 模块名称
|
|
102
|
-
:param module_info: [Dict[str, Any]] 模块信息字典
|
|
103
|
-
必须包含 version 和 description 字段
|
|
104
|
-
|
|
105
|
-
:example:
|
|
106
|
-
>>> module_registry.set_module("MyModule", {
|
|
107
|
-
>>> "version": "1.0.0",
|
|
108
|
-
>>> "description": "我的模块",
|
|
109
|
-
>>> "dependencies": [],
|
|
110
|
-
>>> "author": "开发者",
|
|
111
|
-
>>> "license": "MIT"
|
|
112
|
-
>>> })
|
|
113
|
-
"""
|
|
114
|
-
self.storage.set(f"{self.module_prefix}{module_name}", module_info)
|
|
115
|
-
|
|
116
|
-
def get_module(self, module_name: str) -> Optional[Dict[str, Any]]:
|
|
117
|
-
"""
|
|
118
|
-
获取模块信息
|
|
119
|
-
|
|
120
|
-
:param module_name: [str] 模块名称
|
|
121
|
-
:return: [Optional[Dict[str, Any]]] 模块信息字典或None
|
|
122
|
-
|
|
123
|
-
:example:
|
|
124
|
-
>>> module_info = module_registry.get_module("MyModule")
|
|
125
|
-
>>> if module_info:
|
|
126
|
-
>>> print(f"模块版本: {module_info.get('version')}")
|
|
127
|
-
"""
|
|
128
|
-
return self.storage.get(f"{self.module_prefix}{module_name}")
|
|
129
|
-
|
|
130
|
-
def set_all_modules(self, modules_info: Dict[str, Dict[str, Any]]) -> None:
|
|
131
|
-
"""
|
|
132
|
-
批量设置模块信息
|
|
133
|
-
|
|
134
|
-
:param modules_info: [Dict[str, Dict[str, Any]]] 模块信息字典
|
|
135
|
-
格式: {模块名: 模块信息}
|
|
136
|
-
|
|
137
|
-
:example:
|
|
138
|
-
>>> module_registry.set_all_modules({
|
|
139
|
-
>>> "Module1": {"version": "1.0", "status": True},
|
|
140
|
-
>>> "Module2": {"version": "2.0", "status": False}
|
|
141
|
-
>>> })
|
|
142
|
-
"""
|
|
143
|
-
for module_name, module_info in modules_info.items():
|
|
144
|
-
self.set_module(module_name, module_info)
|
|
145
|
-
|
|
146
|
-
def get_all_modules(self) -> Dict[str, Dict[str, Any]]:
|
|
147
|
-
"""
|
|
148
|
-
获取所有已注册模块信息
|
|
149
|
-
|
|
150
|
-
:return: [Dict[str, Dict[str, Any]]] 所有模块信息字典
|
|
151
|
-
|
|
152
|
-
:example:
|
|
153
|
-
>>> all_modules = module_registry.get_all_modules()
|
|
154
|
-
>>> for name, info in all_modules.items():
|
|
155
|
-
>>> print(f"{name}: {info.get('status')}")
|
|
156
|
-
"""
|
|
157
|
-
modules_info = {}
|
|
158
|
-
all_keys = self.storage.get_all_keys()
|
|
159
|
-
prefix_len = len(self.module_prefix)
|
|
160
|
-
|
|
161
|
-
for key in all_keys:
|
|
162
|
-
if key.startswith(self.module_prefix):
|
|
163
|
-
module_name = key[prefix_len:]
|
|
164
|
-
module_info = self.get_module(module_name)
|
|
165
|
-
if module_info:
|
|
166
|
-
modules_info[module_name] = module_info
|
|
167
|
-
return modules_info
|
|
168
|
-
|
|
169
|
-
def update_module(self, module_name: str, module_info: Dict[str, Any]) -> None:
|
|
170
|
-
"""
|
|
171
|
-
更新模块信息
|
|
172
|
-
|
|
173
|
-
:param module_name: 模块名称
|
|
174
|
-
:param module_info: 完整的模块信息字典
|
|
175
|
-
"""
|
|
176
|
-
self.set_module(module_name, module_info)
|
|
177
|
-
|
|
178
|
-
def remove_module(self, module_name: str) -> bool:
|
|
179
|
-
"""
|
|
180
|
-
移除模块注册信息
|
|
181
|
-
|
|
182
|
-
:param module_name: [str] 模块名称
|
|
183
|
-
:return: [bool] 是否成功移除
|
|
184
|
-
|
|
185
|
-
:example:
|
|
186
|
-
>>> if module_registry.remove_module("OldModule"):
|
|
187
|
-
>>> print("模块已移除")
|
|
188
|
-
"""
|
|
189
|
-
module_key = f"{self.module_prefix}{module_name}"
|
|
190
|
-
status_key = f"{self.status_prefix}{module_name}"
|
|
191
|
-
|
|
192
|
-
if self.storage.get(module_key) is not None:
|
|
193
|
-
self.storage.delete(module_key)
|
|
194
|
-
self.storage.delete(status_key)
|
|
195
|
-
return True
|
|
196
|
-
return False
|
|
197
|
-
|
|
198
|
-
def update_prefixes(self, module_prefix: Optional[str] = None, status_prefix: Optional[str] = None) -> None:
|
|
199
|
-
"""
|
|
200
|
-
更新模块存储前缀配置
|
|
201
|
-
|
|
202
|
-
:param module_prefix: [Optional[str]] 模块数据前缀 (默认: "erispulse.data.modules.info:")
|
|
203
|
-
:param status_prefix: [Optional[str]] 模块状态前缀 (默认: "erispulse.data.modules.status:")
|
|
204
|
-
|
|
205
|
-
:example:
|
|
206
|
-
>>> # 更新模块前缀
|
|
207
|
-
>>> module_registry.update_prefixes(
|
|
208
|
-
>>> module_prefix="custom.module.data:",
|
|
209
|
-
>>> status_prefix="custom.module.status:"
|
|
210
|
-
>>> )
|
|
211
|
-
"""
|
|
212
|
-
if module_prefix:
|
|
213
|
-
if not module_prefix.endswith(':'):
|
|
214
|
-
module_prefix += ':'
|
|
215
|
-
self.storage.set("erispulse.system.module_prefix", module_prefix)
|
|
216
|
-
|
|
217
|
-
if status_prefix:
|
|
218
|
-
if not status_prefix.endswith(':'):
|
|
219
|
-
status_prefix += ':'
|
|
220
|
-
self.storage.set("erispulse.system.status_prefix", status_prefix)
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
module_registry = ModuleRegistry()
|
|
224
|
-
|
|
225
|
-
__all__ = [
|
|
226
|
-
"module_registry",
|
|
227
|
-
]
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
ErisPulse/__init__.py,sha256=L-YLh-5qMYydReBiBO9weceeH7PVv2ONBo40o5ekr3Y,27133
|
|
2
|
-
ErisPulse/__main__.py,sha256=GUh_30fEkWmE0udDFe1Kkwf41hg2v4WgbRY1RswJ9Uc,76331
|
|
3
|
-
ErisPulse/Core/__init__.py,sha256=96QS7gD0QNt27wQkIprye7y_Nja_IH2XUqPstZ4uLsY,589
|
|
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=g8HgpzK3k-WpnuiU_UQKWdw4s7BLLHOS23uDFrO_7W8,11285
|
|
10
|
-
ErisPulse/Core/module.py,sha256=wCIFC3qHukeu7DSj8TuNMw8s_gzTwk7_coM4oflmieA,4680
|
|
11
|
-
ErisPulse/Core/module_registry.py,sha256=BeOQwh3Pwv2fceBLJEObF6Ek65td0VOFzv3L0aEudXY,7740
|
|
12
|
-
ErisPulse/Core/router.py,sha256=s2EBh2qpt3UXYhB06Ppc1XTFuZ3u0ZfXENJxwkgPoq8,8542
|
|
13
|
-
ErisPulse/Core/storage.py,sha256=oRum4eVaTc3yxcaafggoIvrk41LPbvApSCxkGM3YmzU,17904
|
|
14
|
-
ErisPulse/Core/Event/__init__.py,sha256=ixL1jaF0qXt0LbHckRWPH7Xu159qeeXQcsp4ZOs8J6Y,1120
|
|
15
|
-
ErisPulse/Core/Event/base.py,sha256=sZ5Vpp3EVRrtSi_yA3rn61s_4VOWSCUMdRBFeXzg1pc,3614
|
|
16
|
-
ErisPulse/Core/Event/command.py,sha256=fcLGOTjs_06KPyzkH4Eprvqzm_XToLUdbEO6NbJ_cFg,17453
|
|
17
|
-
ErisPulse/Core/Event/exceptions.py,sha256=iGcuPaC7F4cZeujcvBdZb9bzQGnHBdb9CcPKoB760Bo,711
|
|
18
|
-
ErisPulse/Core/Event/message.py,sha256=tB51ACG_2RzJtVm-4gl2zpss5flQjVIUnabWFlrO1Fk,3677
|
|
19
|
-
ErisPulse/Core/Event/meta.py,sha256=Bb5JZgF44bN8I-FsqMAEG5w35YU0vuAN4U91TXgfTtY,3300
|
|
20
|
-
ErisPulse/Core/Event/notice.py,sha256=aHmkICmrTaWk5GWAB004gRMu9SY61lSXcUdxCLcuYhc,4222
|
|
21
|
-
ErisPulse/Core/Event/request.py,sha256=eZk4AQsbhkK3z-7nO83bvW97e6FqDMSYMAAxeacALU4,2616
|
|
22
|
-
erispulse-2.2.1.dev0.dist-info/METADATA,sha256=l3rkS2DX-q4GPNk5mvHFdAwt8qcO4MhkIt6nBvYF1hQ,6650
|
|
23
|
-
erispulse-2.2.1.dev0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
24
|
-
erispulse-2.2.1.dev0.dist-info/entry_points.txt,sha256=Jss71M6nEha0TA-DyVZugPYdcL14s9QpiOeIlgWxzOc,182
|
|
25
|
-
erispulse-2.2.1.dev0.dist-info/licenses/LICENSE,sha256=b2XwzcfWuv_36Op3xGdjcuPHgfCz62yT3bXYjfStpxY,1852
|
|
26
|
-
erispulse-2.2.1.dev0.dist-info/RECORD,,
|
|
File without changes
|