ErisPulse 1.1.14.dev1__py3-none-any.whl → 1.1.16__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 +189 -164
- ErisPulse/__main__.py +74 -2
- ErisPulse/adapter.py +211 -32
- ErisPulse/db.py +408 -36
- ErisPulse/logger.py +101 -57
- ErisPulse/mods.py +235 -19
- ErisPulse/raiserr.py +65 -38
- {erispulse-1.1.14.dev1.dist-info → erispulse-1.1.16.dist-info}/METADATA +78 -45
- erispulse-1.1.16.dist-info/RECORD +13 -0
- {erispulse-1.1.14.dev1.dist-info → erispulse-1.1.16.dist-info}/entry_points.txt +2 -2
- erispulse-1.1.14.dev1.dist-info/RECORD +0 -13
- {erispulse-1.1.14.dev1.dist-info → erispulse-1.1.16.dist-info}/WHEEL +0 -0
- {erispulse-1.1.14.dev1.dist-info → erispulse-1.1.16.dist-info}/licenses/LICENSE +0 -0
ErisPulse/__init__.py
CHANGED
|
@@ -36,10 +36,13 @@ sdk.logger.info("SDK已初始化")
|
|
|
36
36
|
|
|
37
37
|
"""
|
|
38
38
|
|
|
39
|
-
import types
|
|
40
|
-
sdk = types.SimpleNamespace()
|
|
41
39
|
import os
|
|
42
40
|
import sys
|
|
41
|
+
|
|
42
|
+
# 依赖类型
|
|
43
|
+
import types
|
|
44
|
+
|
|
45
|
+
# BaseModules: SDK核心模块
|
|
43
46
|
from . import util
|
|
44
47
|
from .raiserr import raiserr
|
|
45
48
|
from .logger import logger
|
|
@@ -50,177 +53,199 @@ from .adapter import adapter, BaseAdapter, SendDSL
|
|
|
50
53
|
# 这里不能删,确保windows下的shell能正确显示颜色
|
|
51
54
|
os.system('')
|
|
52
55
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
56
|
+
sdk = types.SimpleNamespace()
|
|
57
|
+
|
|
58
|
+
BaseModules = {
|
|
59
|
+
"util" : util,
|
|
60
|
+
"logger" : logger,
|
|
61
|
+
"env" : env,
|
|
62
|
+
"mods" : mods,
|
|
63
|
+
"adapter" : adapter,
|
|
64
|
+
"SendDSL" : SendDSL, # 链式发送基类 - 兼容原 sdk.SendDSL | 待弃用, 需要在 Adapter继承类中手动创建嵌套类并集成 super().SendDSL()
|
|
65
|
+
"AdapterFather" : BaseAdapter,
|
|
66
|
+
"BaseAdapter" : BaseAdapter
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
BaseErrors = {
|
|
70
|
+
"ExternalError" : "外部捕获异常",
|
|
71
|
+
"CaughtExternalError" : "捕获的非SDK抛出的异常",
|
|
72
|
+
"InitError" : "SDK初始化错误",
|
|
73
|
+
"MissingDependencyError" : "缺少依赖错误",
|
|
74
|
+
"InvalidDependencyError" : "依赖无效错误",
|
|
75
|
+
"CycleDependencyError" : "依赖循环错误",
|
|
76
|
+
"ModuleLoadError" : "模块加载错误"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for module, moduleObj in BaseModules.items():
|
|
80
|
+
try:
|
|
81
|
+
setattr(sdk, module, moduleObj)
|
|
82
|
+
except Exception as e:
|
|
83
|
+
raise e
|
|
84
|
+
|
|
85
|
+
for error, doc in BaseErrors.items():
|
|
86
|
+
try:
|
|
87
|
+
raiserr.register(error, doc=doc)
|
|
88
|
+
except Exception as e:
|
|
89
|
+
raise e
|
|
90
|
+
|
|
91
|
+
def _prepare_environment() -> bool:
|
|
92
|
+
# 检查环境
|
|
93
|
+
logger.info("[Init] 准备初始化环境...")
|
|
71
94
|
try:
|
|
72
|
-
logger.info("[Init] SDK 正在初始化...")
|
|
73
95
|
if env.create_env_file_if_not_exists():
|
|
74
96
|
logger.info("[Init] 项目首次初始化,建议先配置环境变量")
|
|
75
97
|
if input("是否立即退出?(y/n): ").strip().lower() == "y":
|
|
76
|
-
|
|
98
|
+
return False
|
|
77
99
|
env.load_env_file()
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if not hasattr(moduleObj, "moduleInfo") or not isinstance(moduleObj.moduleInfo, dict):
|
|
100
|
-
logger.warning(f"模块 {module_name} 缺少有效的 'moduleInfo' 字典.")
|
|
101
|
-
continue
|
|
102
|
-
if "name" not in moduleObj.moduleInfo.get("meta", {}):
|
|
103
|
-
logger.warning(f"模块 {module_name} 的 'moduleInfo' 字典 缺少必要 'name' 键.")
|
|
104
|
-
continue
|
|
105
|
-
if not hasattr(moduleObj, "Main"):
|
|
106
|
-
logger.warning(f"模块 {module_name} 缺少 'Main' 类.")
|
|
107
|
-
continue
|
|
108
|
-
|
|
109
|
-
meta_name = moduleObj.moduleInfo["meta"]["name"]
|
|
110
|
-
module_info = mods.get_module(meta_name)
|
|
111
|
-
if module_info is None:
|
|
112
|
-
module_info = {
|
|
113
|
-
"status": True,
|
|
114
|
-
"info": moduleObj.moduleInfo
|
|
115
|
-
}
|
|
116
|
-
mods.set_module(meta_name, module_info)
|
|
117
|
-
logger.info(f"模块 {meta_name} 信息已初始化并存储到数据库")
|
|
118
|
-
|
|
119
|
-
if not module_info.get('status', True):
|
|
120
|
-
disabledModules.append(module_name)
|
|
121
|
-
logger.warning(f"模块 {meta_name} 已禁用,跳过加载")
|
|
122
|
-
continue
|
|
123
|
-
|
|
124
|
-
required_deps = moduleObj.moduleInfo.get("dependencies", {}).get("requires", [])
|
|
125
|
-
missing_required_deps = [dep for dep in required_deps if dep not in TempModules]
|
|
126
|
-
if missing_required_deps:
|
|
127
|
-
logger.error(f"模块 {module_name} 缺少必需依赖: {missing_required_deps}")
|
|
128
|
-
raiserr.MissingDependencyError(f"模块 {module_name} 缺少必需依赖: {missing_required_deps}")
|
|
129
|
-
|
|
130
|
-
optional_deps = moduleObj.moduleInfo.get("dependencies", {}).get("optional", [])
|
|
131
|
-
available_optional_deps = []
|
|
132
|
-
for dep in optional_deps:
|
|
133
|
-
if isinstance(dep, list):
|
|
134
|
-
available_deps = [d for d in dep if d in TempModules]
|
|
135
|
-
if available_deps:
|
|
136
|
-
available_optional_deps.extend(available_deps)
|
|
137
|
-
elif dep in TempModules:
|
|
138
|
-
available_optional_deps.append(dep)
|
|
139
|
-
|
|
140
|
-
if optional_deps and not available_optional_deps:
|
|
141
|
-
logger.warning(f"模块 {module_name} 缺少所有可选依赖: {optional_deps}")
|
|
142
|
-
|
|
143
|
-
module_objs[module_name] = moduleObj
|
|
144
|
-
sdkInstalledModuleNames.append(module_name)
|
|
145
|
-
|
|
146
|
-
except Exception as e:
|
|
147
|
-
logger.warning(f"模块 {module_name} 加载失败: {e}")
|
|
100
|
+
return True
|
|
101
|
+
except Exception as e:
|
|
102
|
+
logger.error(f"环境准备失败: {e}")
|
|
103
|
+
return False
|
|
104
|
+
def _scan_modules(module_path: str) -> tuple[dict, list, list]:
|
|
105
|
+
# 扫描并验证模块
|
|
106
|
+
module_objs = {}
|
|
107
|
+
enabled_modules = []
|
|
108
|
+
disabled_modules = []
|
|
109
|
+
|
|
110
|
+
if not os.path.exists(module_path):
|
|
111
|
+
os.makedirs(module_path)
|
|
112
|
+
sys.path.append(module_path)
|
|
113
|
+
|
|
114
|
+
for module_name in os.listdir(module_path):
|
|
115
|
+
if not os.path.isdir(os.path.join(module_path, module_name)):
|
|
116
|
+
continue
|
|
117
|
+
|
|
118
|
+
try:
|
|
119
|
+
moduleObj = __import__(module_name)
|
|
120
|
+
if not _validate_module(moduleObj, module_name):
|
|
148
121
|
continue
|
|
149
|
-
|
|
150
|
-
# ==== 构建依赖图并进行拓扑排序 ====
|
|
151
|
-
sdkModuleDependencies = {}
|
|
152
|
-
for module_name in sdkInstalledModuleNames:
|
|
153
|
-
moduleObj = module_objs[module_name]
|
|
154
|
-
meta_name = moduleObj.moduleInfo["meta"]["name"]
|
|
155
|
-
|
|
156
|
-
req_deps = moduleObj.moduleInfo.get("dependencies", {}).get("requires", [])
|
|
157
|
-
opt_deps = moduleObj.moduleInfo.get("dependencies", {}).get("optional", [])
|
|
158
|
-
|
|
159
|
-
available_optional_deps = [dep for dep in opt_deps if dep in sdkInstalledModuleNames]
|
|
160
|
-
deps = req_deps + available_optional_deps
|
|
161
|
-
|
|
162
|
-
for dep in deps:
|
|
163
|
-
if dep in disabledModules:
|
|
164
|
-
logger.warning(f"模块 {meta_name} 的依赖模块 {dep} 已禁用,跳过加载")
|
|
165
|
-
continue
|
|
166
|
-
|
|
167
|
-
if not all(dep in sdkInstalledModuleNames for dep in deps):
|
|
168
|
-
raiserr.InvalidDependencyError(f"模块 {meta_name} 的依赖无效: {deps}")
|
|
169
|
-
sdkModuleDependencies[module_name] = deps
|
|
170
|
-
|
|
171
|
-
sdkInstalledModuleNames: list[str] = sdk.util.topological_sort(
|
|
172
|
-
sdkInstalledModuleNames, sdkModuleDependencies, raiserr.CycleDependencyError
|
|
173
|
-
)
|
|
174
|
-
# 存储模块依赖关系到env
|
|
175
|
-
env.set('module_dependencies', {
|
|
176
|
-
'modules': sdkInstalledModuleNames,
|
|
177
|
-
'dependencies': sdkModuleDependencies
|
|
178
|
-
})
|
|
179
|
-
|
|
180
|
-
# ==== 注册适配器 ====
|
|
181
|
-
logger.debug("[Init] 开始注册适配器...")
|
|
182
|
-
for module_name in sdkInstalledModuleNames:
|
|
183
|
-
moduleObj = module_objs[module_name]
|
|
122
|
+
|
|
184
123
|
meta_name = moduleObj.moduleInfo["meta"]["name"]
|
|
185
|
-
|
|
186
|
-
try:
|
|
187
|
-
if hasattr(moduleObj, "adapterInfo") and isinstance(moduleObj.adapterInfo, dict):
|
|
188
|
-
for platform_name, adapter_class in moduleObj.adapterInfo.items():
|
|
189
|
-
sdk.adapter.register(platform_name, adapter_class)
|
|
190
|
-
logger.info(f"模块 {meta_name} 注册了适配器: {platform_name}")
|
|
191
|
-
except Exception as e:
|
|
192
|
-
logger.error(f"模块 {meta_name} 注册适配器失败: {e}")
|
|
193
|
-
|
|
194
|
-
# ==== 存储模块信息到数据库 ====
|
|
195
|
-
all_modules_info = {}
|
|
196
|
-
for module_name in sdkInstalledModuleNames:
|
|
197
|
-
moduleObj = module_objs[module_name]
|
|
198
|
-
moduleInfo: dict = moduleObj.moduleInfo
|
|
199
|
-
|
|
200
|
-
meta_name = moduleInfo.get("meta", {}).get("name", None)
|
|
201
|
-
module_info = mods.get_module(meta_name)
|
|
202
|
-
mods.set_module(meta_name, {
|
|
124
|
+
module_info = mods.get_module(meta_name) or {
|
|
203
125
|
"status": True,
|
|
204
|
-
"info": moduleInfo
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
moduleObj = module_objs[module_name]
|
|
212
|
-
meta_name = moduleObj.moduleInfo["meta"]["name"]
|
|
213
|
-
|
|
214
|
-
module_status = mods.get_module_status(meta_name)
|
|
215
|
-
if not module_status:
|
|
126
|
+
"info": moduleObj.moduleInfo
|
|
127
|
+
}
|
|
128
|
+
mods.set_module(meta_name, module_info)
|
|
129
|
+
|
|
130
|
+
if not module_info.get('status', True):
|
|
131
|
+
disabled_modules.append(module_name)
|
|
132
|
+
logger.warning(f"模块 {meta_name} 已禁用,跳过加载")
|
|
216
133
|
continue
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
134
|
+
|
|
135
|
+
_check_dependencies(moduleObj, module_name, os.listdir(module_path))
|
|
136
|
+
module_objs[module_name] = moduleObj
|
|
137
|
+
enabled_modules.append(module_name)
|
|
138
|
+
|
|
139
|
+
except Exception as e:
|
|
140
|
+
logger.warning(f"模块 {module_name} 加载失败: {e}")
|
|
141
|
+
|
|
142
|
+
return module_objs, enabled_modules, disabled_modules
|
|
143
|
+
|
|
144
|
+
def _validate_module(moduleObj, module_name: str) -> bool:
|
|
145
|
+
# 验证模块基本结构
|
|
146
|
+
if not hasattr(moduleObj, "moduleInfo") or not isinstance(moduleObj.moduleInfo, dict):
|
|
147
|
+
logger.warning(f"模块 {module_name} 缺少有效的 'moduleInfo' 字典")
|
|
148
|
+
return False
|
|
149
|
+
if "name" not in moduleObj.moduleInfo.get("meta", {}):
|
|
150
|
+
logger.warning(f"模块 {module_name} 缺少必要 'name' 键")
|
|
151
|
+
return False
|
|
152
|
+
if not hasattr(moduleObj, "Main"):
|
|
153
|
+
logger.warning(f"模块 {module_name} 缺少 'Main' 类")
|
|
154
|
+
return False
|
|
155
|
+
return True
|
|
156
|
+
|
|
157
|
+
def _check_dependencies(moduleObj, module_name: str, available_modules: list):
|
|
158
|
+
# 检查模块依赖关系
|
|
159
|
+
required_deps = moduleObj.moduleInfo.get("dependencies", {}).get("requires", [])
|
|
160
|
+
if missing := [dep for dep in required_deps if dep not in available_modules]:
|
|
161
|
+
logger.error(f"模块 {module_name} 缺少必需依赖: {missing}")
|
|
162
|
+
raiserr.MissingDependencyError(f"模块 {module_name} 缺少必需依赖: {missing}")
|
|
163
|
+
|
|
164
|
+
optional_deps = moduleObj.moduleInfo.get("dependencies", {}).get("optional", [])
|
|
165
|
+
available_optional = [
|
|
166
|
+
dep for dep in optional_deps
|
|
167
|
+
if (isinstance(dep, list) and any(d in available_modules for d in dep))
|
|
168
|
+
or (not isinstance(dep, list) and dep in available_modules)
|
|
169
|
+
]
|
|
170
|
+
if optional_deps and not available_optional:
|
|
171
|
+
logger.warning(f"模块 {module_name} 缺少所有可选依赖: {optional_deps}")
|
|
172
|
+
|
|
173
|
+
def _resolve_dependencies(modules: list, module_objs: dict) -> list:
|
|
174
|
+
# 解析模块依赖关系并进行拓扑排序
|
|
175
|
+
dependencies = {}
|
|
176
|
+
for module_name in modules:
|
|
177
|
+
moduleObj = module_objs[module_name]
|
|
178
|
+
req_deps = moduleObj.moduleInfo.get("dependencies", {}).get("requires", [])
|
|
179
|
+
opt_deps = moduleObj.moduleInfo.get("dependencies", {}).get("optional", [])
|
|
180
|
+
available_opt = [dep for dep in opt_deps if dep in modules]
|
|
181
|
+
dependencies[module_name] = req_deps + available_opt
|
|
182
|
+
|
|
183
|
+
sorted_modules = sdk.util.topological_sort(modules, dependencies, raiserr.CycleDependencyError)
|
|
184
|
+
env.set('module_dependencies', {
|
|
185
|
+
'modules': sorted_modules,
|
|
186
|
+
'dependencies': dependencies
|
|
187
|
+
})
|
|
188
|
+
return sorted_modules
|
|
189
|
+
|
|
190
|
+
def _register_adapters(modules: list, module_objs: dict) -> bool:
|
|
191
|
+
# 注册适配器
|
|
192
|
+
success = True
|
|
193
|
+
logger.debug("[Init] 开始注册适配器...")
|
|
194
|
+
for module_name in modules:
|
|
195
|
+
moduleObj = module_objs[module_name]
|
|
196
|
+
meta_name = moduleObj.moduleInfo["meta"]["name"]
|
|
197
|
+
|
|
198
|
+
try:
|
|
199
|
+
if hasattr(moduleObj, "adapterInfo") and isinstance(moduleObj.adapterInfo, dict):
|
|
200
|
+
for platform, adapter_class in moduleObj.adapterInfo.items():
|
|
201
|
+
sdk.adapter.register(platform, adapter_class)
|
|
202
|
+
logger.info(f"模块 {meta_name} 注册适配器: {platform}")
|
|
203
|
+
except Exception as e:
|
|
204
|
+
logger.error(f"模块 {meta_name} 适配器注册失败: {e}")
|
|
205
|
+
success = False
|
|
206
|
+
return success
|
|
207
|
+
|
|
208
|
+
def _initialize_modules(modules: list, module_objs: dict) -> bool:
|
|
209
|
+
# 初始化模块
|
|
210
|
+
success = True
|
|
211
|
+
logger.debug("[Init] 开始实例化模块...")
|
|
212
|
+
for module_name in modules:
|
|
213
|
+
moduleObj = module_objs[module_name]
|
|
214
|
+
meta_name = moduleObj.moduleInfo["meta"]["name"]
|
|
215
|
+
|
|
216
|
+
try:
|
|
217
|
+
if mods.get_module_status(meta_name):
|
|
218
|
+
moduleMain = moduleObj.Main(sdk)
|
|
219
|
+
setattr(moduleMain, "moduleInfo", moduleObj.moduleInfo)
|
|
220
|
+
setattr(sdk, meta_name, moduleMain)
|
|
221
|
+
logger.debug(f"模块 {meta_name} 初始化完成")
|
|
222
|
+
except Exception as e:
|
|
223
|
+
logger.error(f"模块 {meta_name} 初始化失败: {e}")
|
|
224
|
+
success = False
|
|
225
|
+
return success
|
|
226
|
+
|
|
227
|
+
def init() -> bool:
|
|
228
|
+
logger.info("[Init] SDK 正在初始化...")
|
|
229
|
+
try:
|
|
230
|
+
if not _prepare_environment():
|
|
231
|
+
return False
|
|
232
|
+
|
|
233
|
+
module_path = os.path.join(os.path.dirname(__file__), "modules")
|
|
234
|
+
module_objs, enabled_modules, _ = _scan_modules(module_path)
|
|
235
|
+
|
|
236
|
+
if not enabled_modules:
|
|
237
|
+
logger.warning("没有找到可用的模块")
|
|
238
|
+
return True
|
|
239
|
+
|
|
240
|
+
sorted_modules = _resolve_dependencies(enabled_modules, module_objs)
|
|
241
|
+
if not _register_adapters(sorted_modules, module_objs):
|
|
242
|
+
return False
|
|
243
|
+
|
|
244
|
+
return _initialize_modules(sorted_modules, module_objs)
|
|
245
|
+
|
|
222
246
|
except Exception as e:
|
|
247
|
+
logger.critical(f"SDK初始化严重错误: {e}")
|
|
223
248
|
raiserr.InitError(f"sdk初始化失败: {e}", exit=True)
|
|
249
|
+
return False
|
|
224
250
|
|
|
225
|
-
|
|
226
|
-
sdk.init = init
|
|
251
|
+
sdk.init = init
|
ErisPulse/__main__.py
CHANGED
|
@@ -44,6 +44,7 @@ epsdk origin add https://example.com/map.json
|
|
|
44
44
|
"""
|
|
45
45
|
|
|
46
46
|
import argparse
|
|
47
|
+
import importlib
|
|
47
48
|
import os
|
|
48
49
|
import sys
|
|
49
50
|
import time
|
|
@@ -549,7 +550,74 @@ def install_pip_dependencies(dependencies):
|
|
|
549
550
|
shellprint.panel(f"安装pip依赖失败: {e.stderr}", "错误", "error")
|
|
550
551
|
return False
|
|
551
552
|
|
|
553
|
+
def install_local_module(module_path, force=False):
|
|
554
|
+
"""安装本地目录中的模块"""
|
|
555
|
+
module_path = os.path.abspath(module_path)
|
|
556
|
+
if not os.path.exists(module_path):
|
|
557
|
+
shellprint.panel(f"路径不存在: {module_path}", "错误", "error")
|
|
558
|
+
return False
|
|
559
|
+
|
|
560
|
+
# 尝试从目录名获取模块名
|
|
561
|
+
module_name = os.path.basename(module_path.rstrip('/\\'))
|
|
562
|
+
|
|
563
|
+
# 检查是否是有效的模块目录
|
|
564
|
+
init_py = os.path.join(module_path, '__init__.py')
|
|
565
|
+
if not os.path.exists(init_py):
|
|
566
|
+
shellprint.panel(f"目录 {module_path} 不是一个有效的Python模块", "错误", "error")
|
|
567
|
+
return False
|
|
568
|
+
|
|
569
|
+
# 尝试导入模块获取moduleInfo
|
|
570
|
+
try:
|
|
571
|
+
spec = importlib.util.spec_from_file_location(module_name, init_py)
|
|
572
|
+
module = importlib.util.module_from_spec(spec)
|
|
573
|
+
spec.loader.exec_module(module)
|
|
574
|
+
if not hasattr(module, 'moduleInfo'):
|
|
575
|
+
shellprint.panel(f"模块 {module_name} 缺少 moduleInfo 定义", "错误", "error")
|
|
576
|
+
return False
|
|
577
|
+
except Exception as e:
|
|
578
|
+
shellprint.panel(f"导入模块 {module_name} 失败: {e}", "错误", "error")
|
|
579
|
+
return False
|
|
580
|
+
|
|
581
|
+
module_info = mods.get_module(module_name)
|
|
582
|
+
if module_info and not force:
|
|
583
|
+
meta = module_info.get('info', {}).get('meta', {})
|
|
584
|
+
shellprint.panel(
|
|
585
|
+
f"{Shell_Printer.BOLD}{module_name}{Shell_Printer.RESET}\n版本: {meta.get('version', '未知')}\n描述: {meta.get('description', '无描述')}",
|
|
586
|
+
"模块已存在",
|
|
587
|
+
"info"
|
|
588
|
+
)
|
|
589
|
+
if not shellprint.confirm("是否要强制重新安装?", default=False):
|
|
590
|
+
return False
|
|
591
|
+
|
|
592
|
+
# 复制模块到modules目录
|
|
593
|
+
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
594
|
+
target_dir = os.path.join(script_dir, 'modules', module_name)
|
|
595
|
+
|
|
596
|
+
try:
|
|
597
|
+
if os.path.exists(target_dir):
|
|
598
|
+
shutil.rmtree(target_dir)
|
|
599
|
+
shutil.copytree(module_path, target_dir)
|
|
600
|
+
except Exception as e:
|
|
601
|
+
shellprint.panel(f"复制模块文件失败: {e}", "错误", "error")
|
|
602
|
+
return False
|
|
603
|
+
|
|
604
|
+
# 注册模块信息
|
|
605
|
+
mods.set_module(module_name, {
|
|
606
|
+
'status': True,
|
|
607
|
+
'info': {
|
|
608
|
+
'meta': module.moduleInfo.get('meta', {}),
|
|
609
|
+
'dependencies': module.moduleInfo.get('dependencies', {})
|
|
610
|
+
}
|
|
611
|
+
})
|
|
612
|
+
|
|
613
|
+
shellprint.panel(f"本地模块 {Shell_Printer.BOLD}{module_name}{Shell_Printer.RESET} 安装成功", "成功", "success")
|
|
614
|
+
return True
|
|
615
|
+
|
|
552
616
|
def install_module(module_name, force=False):
|
|
617
|
+
# 检查是否是本地路径
|
|
618
|
+
if module_name.startswith('.') or os.path.isabs(module_name):
|
|
619
|
+
return install_local_module(module_name, force)
|
|
620
|
+
|
|
553
621
|
shellprint.panel(f"准备安装模块: {Shell_Printer.BOLD}{module_name}{Shell_Printer.RESET}", "安装摘要", "info")
|
|
554
622
|
last_update_time = env.get('last_origin_update_time', None)
|
|
555
623
|
if last_update_time:
|
|
@@ -925,7 +993,6 @@ def list_modules(module_name=None):
|
|
|
925
993
|
|
|
926
994
|
def main():
|
|
927
995
|
parser = argparse.ArgumentParser(
|
|
928
|
-
|
|
929
996
|
prog="epsdk",
|
|
930
997
|
formatter_class=argparse.RawTextHelpFormatter
|
|
931
998
|
)
|
|
@@ -1147,7 +1214,12 @@ def main():
|
|
|
1147
1214
|
else:
|
|
1148
1215
|
shellprint.panel(f"运行脚本: {Shell_Printer.BOLD}{script_path}{Shell_Printer.RESET}", "执行", "info")
|
|
1149
1216
|
import runpy
|
|
1150
|
-
|
|
1217
|
+
|
|
1218
|
+
# 添加KeyboardInterrupt异常捕捉
|
|
1219
|
+
try:
|
|
1220
|
+
runpy.run_path(script_path, run_name="__main__")
|
|
1221
|
+
except KeyboardInterrupt:
|
|
1222
|
+
shellprint.panel("脚本执行已中断", "中断", "info")
|
|
1151
1223
|
|
|
1152
1224
|
elif args.command == 'origin':
|
|
1153
1225
|
if args.origin_command == 'add':
|