ErisPulse 1.1.6__py3-none-any.whl → 1.1.8__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/__init__.py +4 -2
- ErisPulse/adapter.py +47 -23
- ErisPulse/db.py +3 -4
- ErisPulse/logger.py +3 -0
- {erispulse-1.1.6.dist-info → erispulse-1.1.8.dist-info}/METADATA +1 -1
- erispulse-1.1.8.dist-info/RECORD +13 -0
- erispulse-1.1.6.dist-info/RECORD +0 -13
- {erispulse-1.1.6.dist-info → erispulse-1.1.8.dist-info}/WHEEL +0 -0
- {erispulse-1.1.6.dist-info → erispulse-1.1.8.dist-info}/entry_points.txt +0 -0
- {erispulse-1.1.6.dist-info → erispulse-1.1.8.dist-info}/top_level.txt +0 -0
ErisPulse/__init__.py
CHANGED
|
@@ -22,8 +22,6 @@ setattr(sdk, "adapter", adapter)
|
|
|
22
22
|
setattr(sdk, "SendDSL", SendDSL)
|
|
23
23
|
setattr(sdk, "BaseAdapter", BaseAdapter)
|
|
24
24
|
|
|
25
|
-
env.load_env_file()
|
|
26
|
-
|
|
27
25
|
# 注册 ErrorHook 并预注册常用错误类型
|
|
28
26
|
raiserr.register("CaughtExternalError" , doc="捕获的非SDK抛出的异常")
|
|
29
27
|
raiserr.register("InitError" , doc="SDK初始化错误")
|
|
@@ -34,6 +32,10 @@ raiserr.register("ModuleLoadError" , doc="模块加载错误")
|
|
|
34
32
|
|
|
35
33
|
def init():
|
|
36
34
|
try:
|
|
35
|
+
logger.info("[Init] SDK 正在初始化...")
|
|
36
|
+
env.create_env_file_if_not_exists()
|
|
37
|
+
env.load_env_file()
|
|
38
|
+
|
|
37
39
|
sdkModulePath = os.path.join(os.path.dirname(__file__), "modules")
|
|
38
40
|
|
|
39
41
|
if not os.path.exists(sdkModulePath):
|
ErisPulse/adapter.py
CHANGED
|
@@ -10,8 +10,13 @@ class SendDSLBase:
|
|
|
10
10
|
self._adapter = adapter
|
|
11
11
|
self._target_type = target_type
|
|
12
12
|
self._target_id = target_id
|
|
13
|
+
self._target_to = target_id
|
|
14
|
+
|
|
15
|
+
def To(self, target_type: str = None, target_id: str = None) -> 'SendDSL':
|
|
16
|
+
if target_id is None and target_type is not None:
|
|
17
|
+
target_id = target_type
|
|
18
|
+
target_type = None
|
|
13
19
|
|
|
14
|
-
def To(self, target_type: str, target_id: str) -> 'SendDSL':
|
|
15
20
|
return self.__class__(self._adapter, target_type, target_id)
|
|
16
21
|
|
|
17
22
|
def __getattr__(self, name: str):
|
|
@@ -83,60 +88,79 @@ class AdapterManager:
|
|
|
83
88
|
def __init__(self):
|
|
84
89
|
self._adapters: Dict[str, BaseAdapter] = {}
|
|
85
90
|
self._adapter_instances: Dict[Type[BaseAdapter], BaseAdapter] = {}
|
|
91
|
+
self._platform_to_instance: Dict[str, BaseAdapter] = {}
|
|
86
92
|
self._started_instances: Set[BaseAdapter] = set()
|
|
93
|
+
|
|
87
94
|
def register(self, platform: str, adapter_class: Type[BaseAdapter]) -> bool:
|
|
88
95
|
if not issubclass(adapter_class, BaseAdapter):
|
|
89
96
|
raise TypeError("适配器必须继承自BaseAdapter")
|
|
90
97
|
from . import sdk
|
|
91
98
|
|
|
99
|
+
# 如果该类已经创建过实例,复用
|
|
92
100
|
if adapter_class in self._adapter_instances:
|
|
93
|
-
|
|
101
|
+
instance = self._adapter_instances[adapter_class]
|
|
94
102
|
else:
|
|
95
103
|
instance = adapter_class(sdk)
|
|
96
|
-
self._adapters[platform] = instance
|
|
97
104
|
self._adapter_instances[adapter_class] = instance
|
|
98
105
|
|
|
106
|
+
# 注册平台名,并统一映射到该实例
|
|
107
|
+
self._adapters[platform] = instance
|
|
108
|
+
self._platform_to_instance[platform] = instance
|
|
109
|
+
|
|
99
110
|
return True
|
|
100
111
|
|
|
101
112
|
async def startup(self, platforms: List[str] = None):
|
|
102
113
|
if platforms is None:
|
|
103
114
|
platforms = list(self._adapters.keys())
|
|
104
115
|
|
|
116
|
+
# 已经被调度过的 adapter 实例集合(防止重复调度)
|
|
117
|
+
scheduled_adapters = set()
|
|
118
|
+
|
|
105
119
|
for platform in platforms:
|
|
106
120
|
if platform not in self._adapters:
|
|
107
121
|
raise ValueError(f"平台 {platform} 未注册")
|
|
108
122
|
adapter = self._adapters[platform]
|
|
109
123
|
|
|
110
|
-
#
|
|
111
|
-
if adapter in self._started_instances:
|
|
124
|
+
# 如果该实例已经被启动或已调度,跳过
|
|
125
|
+
if adapter in self._started_instances or adapter in scheduled_adapters:
|
|
112
126
|
continue
|
|
113
127
|
|
|
114
|
-
|
|
128
|
+
# 加入调度队列
|
|
129
|
+
scheduled_adapters.add(adapter)
|
|
115
130
|
asyncio.create_task(self._run_adapter(adapter, platform))
|
|
116
131
|
|
|
117
132
|
async def _run_adapter(self, adapter: BaseAdapter, platform: str):
|
|
118
133
|
from . import sdk
|
|
119
134
|
retry_count = 0
|
|
120
135
|
max_retry = 3
|
|
121
|
-
while retry_count < max_retry:
|
|
122
|
-
try:
|
|
123
|
-
await adapter.start()
|
|
124
|
-
sdk.logger.debug(f"尝试启动适配器 {platform},实例ID: {id(adapter)}")
|
|
125
|
-
if adapter in self._started_instances:
|
|
126
|
-
sdk.logger.info(f"适配器 {platform}(实例ID: {id(adapter)})已启动,跳过")
|
|
127
|
-
break
|
|
128
|
-
except Exception as e:
|
|
129
|
-
retry_count += 1
|
|
130
|
-
sdk.logger.error(f"平台 {platform} 启动失败(第{retry_count}次重试): {e}")
|
|
131
|
-
try:
|
|
132
|
-
await adapter.shutdown()
|
|
133
|
-
except Exception as stop_err:
|
|
134
|
-
sdk.logger.warning(f"停止适配器失败: {stop_err}")
|
|
135
136
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
# 加锁防止并发启动
|
|
138
|
+
if not getattr(adapter, "_starting_lock", None):
|
|
139
|
+
adapter._starting_lock = asyncio.Lock()
|
|
140
|
+
|
|
141
|
+
async with adapter._starting_lock:
|
|
142
|
+
# 再次确认是否已经被启动
|
|
143
|
+
if adapter in self._started_instances:
|
|
144
|
+
sdk.logger.info(f"适配器 {platform}(实例ID: {id(adapter)})已被其他协程启动,跳过")
|
|
145
|
+
return
|
|
139
146
|
|
|
147
|
+
while retry_count < max_retry:
|
|
148
|
+
try:
|
|
149
|
+
await adapter.start()
|
|
150
|
+
self._started_instances.add(adapter)
|
|
151
|
+
sdk.logger.info(f"适配器 {platform}(实例ID: {id(adapter)})已启动")
|
|
152
|
+
break
|
|
153
|
+
except Exception as e:
|
|
154
|
+
retry_count += 1
|
|
155
|
+
sdk.logger.error(f"平台 {platform} 启动失败(第{retry_count}次重试): {e}")
|
|
156
|
+
try:
|
|
157
|
+
await adapter.shutdown()
|
|
158
|
+
except Exception as stop_err:
|
|
159
|
+
sdk.logger.warning(f"停止适配器失败: {stop_err}")
|
|
160
|
+
|
|
161
|
+
if retry_count >= max_retry:
|
|
162
|
+
sdk.logger.critical(f"平台 {platform} 达到最大重试次数,放弃重启")
|
|
163
|
+
raise sdk.raiserr.AdapterStartFailedError(f"平台 {platform} 适配器无法重写启动: {e}")
|
|
140
164
|
async def shutdown(self):
|
|
141
165
|
for adapter in self._adapters.values():
|
|
142
166
|
await adapter.shutdown()
|
ErisPulse/db.py
CHANGED
|
@@ -16,7 +16,6 @@ class EnvManager:
|
|
|
16
16
|
def __init__(self):
|
|
17
17
|
if not hasattr(self, "_initialized"):
|
|
18
18
|
self._init_db()
|
|
19
|
-
self._create_env_file_if_not_exists()
|
|
20
19
|
self._initialized = True
|
|
21
20
|
|
|
22
21
|
def _init_db(self):
|
|
@@ -90,7 +89,7 @@ class EnvManager:
|
|
|
90
89
|
if not key.startswith("__") and isinstance(value, (dict, list, str, int, float, bool)):
|
|
91
90
|
self.set(key, value)
|
|
92
91
|
|
|
93
|
-
def
|
|
92
|
+
def create_env_file_if_not_exists(self):
|
|
94
93
|
env_file = Path("env.py")
|
|
95
94
|
if not env_file.exists():
|
|
96
95
|
content = '''# env.py
|
|
@@ -122,7 +121,7 @@ from ErisPulse import sdk
|
|
|
122
121
|
try:
|
|
123
122
|
return self.get(key)
|
|
124
123
|
except KeyError:
|
|
125
|
-
from . import
|
|
126
|
-
|
|
124
|
+
from .logger import logger
|
|
125
|
+
logger.error(f"配置项 {key} 不存在")
|
|
127
126
|
|
|
128
127
|
env = EnvManager()
|
ErisPulse/logger.py
CHANGED
|
@@ -148,5 +148,8 @@ class Logger:
|
|
|
148
148
|
if self._get_effective_level(caller_module) <= logging.CRITICAL:
|
|
149
149
|
self._save_in_memory(caller_module, msg)
|
|
150
150
|
self._logger.critical(f"[{caller_module}] {msg}", *args, **kwargs)
|
|
151
|
+
from .raiserr import raiserr
|
|
152
|
+
raiserr.register("CriticalError", doc="发生致命错误")
|
|
153
|
+
raiserr.CriticalError(f"程序发生致命错误:{msg}", exit=True)
|
|
151
154
|
|
|
152
155
|
logger = Logger()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ErisPulse
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.8
|
|
4
4
|
Summary: ErisPulse 是一个模块化、可扩展的异步 Python SDK 框架,主要用于构建高效、可维护的机器人应用程序。
|
|
5
5
|
Author-email: "艾莉丝·格雷拉特(WSu2059)" <wsu2059@qq.com>, runoneall <runoobsteve@gmail.com>
|
|
6
6
|
Classifier: Development Status :: 5 - Production/Stable
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
ErisPulse/__init__.py,sha256=wNfAnZu0-jFzCLyQhfiXvj7lb0DxSLmRCBUowxUYJW0,7783
|
|
2
|
+
ErisPulse/__main__.py,sha256=-UdhsYP_X7EagomCjo73Y_qQdXwtMbDS5KoOSrI-OcU,32181
|
|
3
|
+
ErisPulse/adapter.py,sha256=u7XdJxIEHxGRh4RXwTX-vv1R1_oP0M6ZJBehe3rKi0I,6807
|
|
4
|
+
ErisPulse/db.py,sha256=OIndsysBOUfSyGMhKs-YVYj9dv5D92YIAltM0ZmwrkA,4379
|
|
5
|
+
ErisPulse/logger.py,sha256=sMA1mUZvwJ8wHwdyCrgIf_VRICv_uBCkx3tmd1stF3E,6094
|
|
6
|
+
ErisPulse/mods.py,sha256=M9XQWUQYNZ11m845hxbewBAauWXnysy-aOdLwb5xy_M,3312
|
|
7
|
+
ErisPulse/raiserr.py,sha256=z8BigWkVrBE9dD_dJa5np2YYREwdugyWXKE4_-LEO_Q,2616
|
|
8
|
+
ErisPulse/util.py,sha256=b9TqyRZKkpclN2fkHmWqBl3lnBMnUbucMvKvbqD5Ws8,2541
|
|
9
|
+
erispulse-1.1.8.dist-info/METADATA,sha256=UnKdj5QcnPTnmW0zRHWo2mxUME2CjJSM9ffcB1UUQNM,2282
|
|
10
|
+
erispulse-1.1.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
11
|
+
erispulse-1.1.8.dist-info/entry_points.txt,sha256=AjKvOdYR7QGXVpEJhjUYUwV2JluE4lm9vNbknC3hjOM,155
|
|
12
|
+
erispulse-1.1.8.dist-info/top_level.txt,sha256=Lm_qtkVvNJR8_dXh_qEDdl_12cZGpic-i4HUlVVUMZc,10
|
|
13
|
+
erispulse-1.1.8.dist-info/RECORD,,
|
erispulse-1.1.6.dist-info/RECORD
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
ErisPulse/__init__.py,sha256=ZQlAumhGUM3skHfBRwSbbP_koy3FJaHiotVh-fD7YYc,7678
|
|
2
|
-
ErisPulse/__main__.py,sha256=-UdhsYP_X7EagomCjo73Y_qQdXwtMbDS5KoOSrI-OcU,32181
|
|
3
|
-
ErisPulse/adapter.py,sha256=cpynhF4HSSTUdPKlkXnGFf4RCfjzBmXxdXDm3K0M9Hw,5848
|
|
4
|
-
ErisPulse/db.py,sha256=cd2AUfm-ZPzXlU8PLKK23QGd6VF0eSgYQl9dyRRpl_Y,4425
|
|
5
|
-
ErisPulse/logger.py,sha256=HIQMYD75K-PL4IETMlm7V6Eyg0ussZ11_riEw5E5a08,5899
|
|
6
|
-
ErisPulse/mods.py,sha256=M9XQWUQYNZ11m845hxbewBAauWXnysy-aOdLwb5xy_M,3312
|
|
7
|
-
ErisPulse/raiserr.py,sha256=z8BigWkVrBE9dD_dJa5np2YYREwdugyWXKE4_-LEO_Q,2616
|
|
8
|
-
ErisPulse/util.py,sha256=b9TqyRZKkpclN2fkHmWqBl3lnBMnUbucMvKvbqD5Ws8,2541
|
|
9
|
-
erispulse-1.1.6.dist-info/METADATA,sha256=KQ1UD2ORHTkr4dr1LcshMQ2DZVrrpe96f-AzjxDucTI,2282
|
|
10
|
-
erispulse-1.1.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
11
|
-
erispulse-1.1.6.dist-info/entry_points.txt,sha256=AjKvOdYR7QGXVpEJhjUYUwV2JluE4lm9vNbknC3hjOM,155
|
|
12
|
-
erispulse-1.1.6.dist-info/top_level.txt,sha256=Lm_qtkVvNJR8_dXh_qEDdl_12cZGpic-i4HUlVVUMZc,10
|
|
13
|
-
erispulse-1.1.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|