flash-sim 0.0.1__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.
- flash/__init__.py +157 -0
- flash/_bootstrap.py +35 -0
- flash/_core/__init__.py +39 -0
- flash/_core/credentials/__init__.py +44 -0
- flash/_core/credentials/_config.py +191 -0
- flash/_core/credentials/_core.py +277 -0
- flash/_core/credentials/_flash_entries.py +83 -0
- flash/_core/credentials/_minimal.py +73 -0
- flash/_core/credentials/api_keys.py +225 -0
- flash/_core/credentials/deepseek.py +187 -0
- flash/_core/credentials/flash_ssh.py +472 -0
- flash/_core/credentials/gitee.py +220 -0
- flash/_core/credentials/manage.py +359 -0
- flash/_core/credentials/pypi.py +144 -0
- flash/_core/credentials.py +1103 -0
- flash/_core/interface.py +90 -0
- flash/_core/registry.py +35 -0
- flash/_core/schema.py +118 -0
- flash/config/__init__.py +105 -0
- flash/flash_run/PROCESS.md +435 -0
- flash/flash_run/README.md +205 -0
- flash/flash_run/__init__.py +25 -0
- flash/flash_run/env/README.md +272 -0
- flash/flash_run/env/__init__.py +12 -0
- flash/flash_run/env/env_manager.py +535 -0
- flash/flash_run/env/resource_config.py +650 -0
- flash/flash_run/remote/README.md +313 -0
- flash/flash_run/remote/__init__.py +20 -0
- flash/flash_run/remote/remote_check.py +70 -0
- flash/flash_run/remote/remote_deploy.py +792 -0
- flash/flash_run/remote/remote_workflow.py +142 -0
- flash/flash_run/remote/route_tester.py +465 -0
- flash/flash_run/remote/ssh_check.py +107 -0
- flash/input_gen/README.md +535 -0
- flash/input_gen/__init__.py +170 -0
- flash/input_gen/gen_Grid_markRefineDerefine/GEN_GRID_GUIDE.md +68 -0
- flash/input_gen/gen_Grid_markRefineDerefine/README.md +327 -0
- flash/input_gen/gen_Grid_markRefineDerefine/__init__.py +0 -0
- flash/input_gen/gen_Grid_markRefineDerefine/generator.py +567 -0
- flash/input_gen/gen_checker/GEN_CHECKER_GUIDE.md +148 -0
- flash/input_gen/gen_checker/__init__.py +6 -0
- flash/input_gen/gen_checker/checker.py +274 -0
- flash/input_gen/gen_checker/ploter/__init__.py +13 -0
- flash/input_gen/gen_checker/ploter/density_plotter.py +195 -0
- flash/input_gen/gen_checker/ploter/pulse_plotter.py +158 -0
- flash/input_gen/gen_checker/ploter/ray_plotter.py +277 -0
- flash/input_gen/gen_config/GEN_CONFIG_GUIDE.md +534 -0
- flash/input_gen/gen_config/__init__.py +9 -0
- flash/input_gen/gen_config/generator.py +205 -0
- flash/input_gen/gen_eos_op/GEN_EOS_OP_GUIDE.md +224 -0
- flash/input_gen/gen_eos_op/__init__.py +10 -0
- flash/input_gen/gen_eos_op/generator.py +481 -0
- flash/input_gen/gen_f90/__init__.py +0 -0
- flash/input_gen/gen_makefile/GEN_MAKEFILE_GUIDE.md +56 -0
- flash/input_gen/gen_makefile/__init__.py +9 -0
- flash/input_gen/gen_makefile/generator.py +32 -0
- flash/input_gen/gen_newpara/README.md +400 -0
- flash/input_gen/gen_newpara/RP_Reference.md +639 -0
- flash/input_gen/gen_newpara/__init__.py +19 -0
- flash/input_gen/gen_newpara/generator.py +643 -0
- flash/input_gen/gen_otherf90s/GEN_OTHER_F90S_GUIDE.md +231 -0
- flash/input_gen/gen_otherf90s/__init__.py +0 -0
- flash/input_gen/gen_par/GEN_PAR_GUIDE.md +657 -0
- flash/input_gen/gen_par/__init__.py +18 -0
- flash/input_gen/gen_par/defaults.py +510 -0
- flash/input_gen/gen_par/generator.py +445 -0
- flash/input_gen/gen_par/materials.py +141 -0
- flash/input_gen/gen_shell_script/GEN_SHELL_SCRIPT_GUIDE.md +120 -0
- flash/input_gen/gen_shell_script/__init__.py +12 -0
- flash/input_gen/gen_shell_script/generator.py +850 -0
- flash/input_gen/gen_sim_data/GEN_SIM_DATA_GUIDE.md +306 -0
- flash/input_gen/gen_sim_data/__init__.py +10 -0
- flash/input_gen/gen_sim_data/generator.py +87 -0
- flash/input_gen/gen_sim_init/GEN_SIM_INIT_GUIDE.md +216 -0
- flash/input_gen/gen_sim_init/__init__.py +9 -0
- flash/input_gen/gen_sim_init/generator.py +104 -0
- flash/input_gen/gen_sim_initblock/GEN_SIM_INITBLOCK_GUIDE.md +330 -0
- flash/input_gen/gen_sim_initblock/__init__.py +17 -0
- flash/input_gen/gen_sim_initblock/generator.py +432 -0
- flash/input_gen/gen_sim_initblock/grid.py +278 -0
- flash/input_gen/gen_sim_initblock/visualizer.py +250 -0
- flash/interface.py +398 -0
- flash/output_processors/__init__.py +50 -0
- flash/output_processors/conftest.py +41 -0
- flash/output_processors/docs/api_reference.md +597 -0
- flash/output_processors/docs/how_to_add_custom_variables.md +417 -0
- flash/output_processors/docs/output_processors_usage.md +596 -0
- flash/output_processors/docs/performance_tuning.md +365 -0
- flash/output_processors/docs/workflow.md +101 -0
- flash/output_processors/hdf5processor/__init__.py +21 -0
- flash/output_processors/hdf5processor/flash_hdf5.py +1224 -0
- flash/output_processors/loader/__init__.py +7 -0
- flash/output_processors/loader/data_loader.py +392 -0
- flash/output_processors/parallel.py +580 -0
- flash/output_processors/plotter/__init__.py +8 -0
- flash/output_processors/plotter/plot_generator.py +471 -0
- flash/output_processors/plotter/plot_style.py +240 -0
- flash/physics/ele_nonlocal/Knudsen_Nonlocal_Summary.md +576 -0
- flash/projects/__init__.py +0 -0
- flash/projects/projects_demo/README.md +94 -0
- flash/projects/projects_demo/__init__.py +17 -0
- flash/projects/projects_demo/ch_center_demo/__init__.py +16 -0
- flash/projects/projects_demo/ch_center_demo/plot_compare.py +169 -0
- flash/projects/projects_demo/ch_center_demo/run_compare.py +148 -0
- flash/scenarios/README.md +669 -0
- flash/scenarios/SNBtest/__init__.py +0 -0
- flash/scenarios/__init__.py +18 -0
- flash/scenarios/base.py +50 -0
- flash/scenarios/center_evolution/__init__.py +2 -0
- flash/scenarios/center_evolution/ch_center/__init__.py +361 -0
- flash/scenarios/center_evolution/ch_center/laserslab1d_local_custom.py +804 -0
- flash/scenarios/collision_compression/__init__.py +38 -0
- flash/scenarios/flash_demo/__init__.py +0 -0
- flash/scenarios/flash_demo/demo_hpc/__init__.py +0 -0
- flash/scenarios/flash_demo/demo_hpc/_plot_utils.py +128 -0
- flash/scenarios/flash_demo/demo_hpc/laserslab1d_hpc_demo_batch.py +1035 -0
- flash/scenarios/flash_demo/demo_hpc/laserslab1d_supercomputer_demo.py +778 -0
- flash/scenarios/flash_demo/demo_hpc/remote_analysis.py +428 -0
- flash/scenarios/flash_demo/demo_hpc/remote_plot_script.py +444 -0
- flash/scenarios/flash_demo/demo_hpc/remote_ssh_helper.py +457 -0
- flash/scenarios/flash_demo/demo_local/__init__.py +0 -0
- flash/scenarios/flash_demo/demo_local/laserslab1d_local_demo.py +343 -0
- flash/scenarios/flash_demo/hello_flash/README.md +447 -0
- flash/scenarios/flash_demo/hello_flash/analyze_density.py +416 -0
- flash/scenarios/flash_demo/hello_flash/deploy_flash.py +828 -0
- flash/scenarios/interpolator.py +286 -0
- flash/scenarios/plasma_preparation/__init__.py +1 -0
- flash/scenarios/registry.py +61 -0
- flash/scenarios/simulator.py +1045 -0
- flash/test/__init__.py +1 -0
- flash/test/flash_mathtest_custom01.py +413 -0
- flash/test/math_test.py +596 -0
- flash/utils/__init__.py +9 -0
- flash/utils/check_hdf5_time.py +22 -0
- flash/utils/convert_pdf_to_md.py +134 -0
- flash/utils/convert_text_to_md.py +102 -0
- flash/utils/extract_knowledge.py +200 -0
- flash_sim-0.0.1.dist-info/METADATA +811 -0
- flash_sim-0.0.1.dist-info/RECORD +143 -0
- flash_sim-0.0.1.dist-info/WHEEL +4 -0
- flash_sim-0.0.1.dist-info/entry_points.txt +3 -0
- flash_sim-0.0.1.dist-info/licenses/LICENSE +386 -0
- flash_sim-0.0.1.dist-info/licenses/NOTICE +138 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Flash 凭据管理 -- Gitee 凭据管理
|
|
3
|
+
=====================================
|
|
4
|
+
管理 Gitee 访问令牌。
|
|
5
|
+
|
|
6
|
+
用法:
|
|
7
|
+
python -m flash._core.credentials.gitee # 交互菜单
|
|
8
|
+
python -m flash._core.credentials.gitee setup # 设置 Gitee 凭据
|
|
9
|
+
python -m flash._core.credentials.gitee show # 查看 Gitee 凭据
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import sys
|
|
13
|
+
from typing import Optional
|
|
14
|
+
|
|
15
|
+
from ._core import (
|
|
16
|
+
ask_one,
|
|
17
|
+
get_credential_manager,
|
|
18
|
+
mask_secret,
|
|
19
|
+
)
|
|
20
|
+
from ._config import DEFAULT_USER_NAME, DEFAULT_PASSWORD
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def setup_gitee() -> bool:
|
|
24
|
+
"""设置 Gitee 凭据。"""
|
|
25
|
+
cm = get_credential_manager()
|
|
26
|
+
|
|
27
|
+
print(f"\n 📝 设置 Gitee 凭据")
|
|
28
|
+
print(f" {'─' * 50}")
|
|
29
|
+
|
|
30
|
+
# 获取默认值
|
|
31
|
+
entry_def = next((e for e in __import__("_config", fromlist=["ENTRIES"]).ENTRIES if e["name"] == "gitee"), None)
|
|
32
|
+
if entry_def is None:
|
|
33
|
+
print("\n ❌ 未找到 Gitee 配置定义。")
|
|
34
|
+
return False
|
|
35
|
+
|
|
36
|
+
data = {}
|
|
37
|
+
for key, label, default in entry_def["fields"]:
|
|
38
|
+
# 使用全局默认值
|
|
39
|
+
if key == "username" and default == "hello":
|
|
40
|
+
default = DEFAULT_USER_NAME
|
|
41
|
+
elif key == "token" and default == "123":
|
|
42
|
+
default = DEFAULT_PASSWORD
|
|
43
|
+
data[key] = ask_one(label, default)
|
|
44
|
+
|
|
45
|
+
cm.set("gitee", data)
|
|
46
|
+
print(f"\n ✅ Gitee 凭据已保存。")
|
|
47
|
+
return True
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def show_gitee(raw: bool = False) -> None:
|
|
51
|
+
"""查看 Gitee 凭据。"""
|
|
52
|
+
cm = get_credential_manager()
|
|
53
|
+
data = cm.get("gitee")
|
|
54
|
+
|
|
55
|
+
if not data:
|
|
56
|
+
print("\n [提示] 尚未设置 Gitee 凭据。")
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
print(f"\n {'─' * 50}")
|
|
60
|
+
print(f" Gitee 凭据")
|
|
61
|
+
print(f" {'─' * 50}")
|
|
62
|
+
|
|
63
|
+
display = data if raw else mask_secret(data)
|
|
64
|
+
for k, v in display.items():
|
|
65
|
+
print(f" {k:12s}: {v}")
|
|
66
|
+
print(f" {'─' * 50}")
|
|
67
|
+
if not raw:
|
|
68
|
+
print(f" 💡 使用 --raw 查看原始 token")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def delete_gitee() -> bool:
|
|
72
|
+
"""删除 Gitee 凭据。"""
|
|
73
|
+
cm = get_credential_manager()
|
|
74
|
+
|
|
75
|
+
if not cm.get("gitee"):
|
|
76
|
+
print("\n [提示] 尚未设置 Gitee 凭据。")
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
confirm = input("\n 确认删除 Gitee 凭据? [y/N]: ").strip().lower()
|
|
80
|
+
if confirm != "y":
|
|
81
|
+
print("\n [已取消]")
|
|
82
|
+
return False
|
|
83
|
+
|
|
84
|
+
try:
|
|
85
|
+
cm.delete("gitee")
|
|
86
|
+
print("\n ✅ Gitee 凭据已删除。")
|
|
87
|
+
return True
|
|
88
|
+
except Exception as e:
|
|
89
|
+
print(f"\n ❌ 删除失败: {e}")
|
|
90
|
+
return False
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def test_gitee() -> bool:
|
|
94
|
+
"""测试 Gitee 连接。"""
|
|
95
|
+
cm = get_credential_manager()
|
|
96
|
+
data = cm.get("gitee")
|
|
97
|
+
|
|
98
|
+
if not data:
|
|
99
|
+
print("\n [提示] 尚未设置 Gitee 凭据。")
|
|
100
|
+
return False
|
|
101
|
+
|
|
102
|
+
token = data.get("token")
|
|
103
|
+
username = data.get("username")
|
|
104
|
+
repo_url = data.get("repo_url", "")
|
|
105
|
+
|
|
106
|
+
print(f"\n 🔧 测试 Gitee 连接...")
|
|
107
|
+
print(f" 用户名: {username}")
|
|
108
|
+
print(f" 仓库: {repo_url}")
|
|
109
|
+
|
|
110
|
+
# 解析仓库 owner 和 repo name
|
|
111
|
+
import re
|
|
112
|
+
match = re.search(r"gitee\.com[:/]([^/]+)/([^/.]+)", repo_url)
|
|
113
|
+
if not match:
|
|
114
|
+
print(f"\n ⚠️ 无法解析仓库 URL: {repo_url}")
|
|
115
|
+
print(f" 请确保 URL 格式类似: https://gitee.com/owner/repo.git")
|
|
116
|
+
return False
|
|
117
|
+
|
|
118
|
+
owner, repo = match.group(1), match.group(2).rstrip(".git")
|
|
119
|
+
|
|
120
|
+
# 测试 1: 验证 token (获取用户信息)
|
|
121
|
+
print(f"\n [1/2] 验证访问令牌...")
|
|
122
|
+
import urllib.request
|
|
123
|
+
import urllib.error
|
|
124
|
+
import json
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
# 获取用户信息
|
|
128
|
+
url = f"https://gitee.com/api/v5/user?access_token={token}"
|
|
129
|
+
req = urllib.request.Request(url)
|
|
130
|
+
with urllib.request.urlopen(req, timeout=10) as resp:
|
|
131
|
+
user_info = json.loads(resp.read().decode("utf-8"))
|
|
132
|
+
|
|
133
|
+
if "login" in user_info:
|
|
134
|
+
print(f" ✅ Token 有效 (用户: {user_info.get('login')})")
|
|
135
|
+
else:
|
|
136
|
+
print(f" ❌ Token 验证失败: {user_info}")
|
|
137
|
+
return False
|
|
138
|
+
|
|
139
|
+
except urllib.error.HTTPError as e:
|
|
140
|
+
error_msg = e.read().decode("utf-8")
|
|
141
|
+
print(f" ❌ Token 验证失败 (HTTP {e.code}): {error_msg}")
|
|
142
|
+
return False
|
|
143
|
+
except Exception as e:
|
|
144
|
+
print(f" ❌ 连接失败: {e}")
|
|
145
|
+
return False
|
|
146
|
+
|
|
147
|
+
# 测试 2: 验证仓库访问
|
|
148
|
+
print(f"\n [2/2] 验证仓库访问...")
|
|
149
|
+
try:
|
|
150
|
+
url = f"https://gitee.com/api/v5/repos/{owner}/{repo}?access_token={token}"
|
|
151
|
+
req = urllib.request.Request(url)
|
|
152
|
+
with urllib.request.urlopen(req, timeout=10) as resp:
|
|
153
|
+
repo_info = json.loads(resp.read().decode("utf-8"))
|
|
154
|
+
|
|
155
|
+
if "name" in repo_info:
|
|
156
|
+
print(f" ✅ 仓库可访问: {repo_info.get('name')}")
|
|
157
|
+
print(f" 仓库 URL: {repo_info.get('html_url', repo_url)}")
|
|
158
|
+
else:
|
|
159
|
+
print(f" ⚠️ 仓库访问异常: {repo_info}")
|
|
160
|
+
return False
|
|
161
|
+
|
|
162
|
+
except urllib.error.HTTPError as e:
|
|
163
|
+
if e.code == 404:
|
|
164
|
+
print(f" ⚠️ 仓库不存在或无访问权限: {owner}/{repo}")
|
|
165
|
+
print(f" 请检查仓库 URL 是否正确,以及 token 是否有访问权限")
|
|
166
|
+
else:
|
|
167
|
+
error_msg = e.read().decode("utf-8")
|
|
168
|
+
print(f" ❌ 仓库访问失败 (HTTP {e.code}): {error_msg}")
|
|
169
|
+
return False
|
|
170
|
+
except Exception as e:
|
|
171
|
+
print(f" ❌ 连接失败: {e}")
|
|
172
|
+
return False
|
|
173
|
+
|
|
174
|
+
print(f"\n ✅ Gitee 连接测试通过!")
|
|
175
|
+
return True
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def interactive_menu() -> None:
|
|
179
|
+
"""交互式菜单。"""
|
|
180
|
+
while True:
|
|
181
|
+
print(f"\n {'=' * 50}")
|
|
182
|
+
print(f" Gitee 凭据管理")
|
|
183
|
+
print(f" {'=' * 50}")
|
|
184
|
+
print(" [1] 设置/修改 Gitee 凭据")
|
|
185
|
+
print(" [2] 查看 Gitee 凭据")
|
|
186
|
+
print(" [3] 删除 Gitee 凭据")
|
|
187
|
+
print(" [4] 测试 Gitee 连接")
|
|
188
|
+
print(" [0] 返回")
|
|
189
|
+
|
|
190
|
+
choice = input("\n 请选择 [0-4]: ").strip()
|
|
191
|
+
|
|
192
|
+
if choice == "1":
|
|
193
|
+
setup_gitee()
|
|
194
|
+
elif choice == "2":
|
|
195
|
+
raw = input(" 显示原始 token? [y/N]: ").strip().lower() == "y"
|
|
196
|
+
show_gitee(raw)
|
|
197
|
+
elif choice == "3":
|
|
198
|
+
delete_gitee()
|
|
199
|
+
elif choice == "4":
|
|
200
|
+
test_gitee()
|
|
201
|
+
elif choice == "0":
|
|
202
|
+
break
|
|
203
|
+
else:
|
|
204
|
+
print(" [无效选择]")
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
if __name__ == "__main__":
|
|
208
|
+
main_arg = sys.argv[1] if len(sys.argv) > 1 else None
|
|
209
|
+
|
|
210
|
+
if main_arg == "setup":
|
|
211
|
+
setup_gitee()
|
|
212
|
+
elif main_arg == "show":
|
|
213
|
+
raw = "--raw" in sys.argv
|
|
214
|
+
show_gitee(raw)
|
|
215
|
+
elif main_arg == "del":
|
|
216
|
+
delete_gitee()
|
|
217
|
+
elif main_arg == "test":
|
|
218
|
+
test_gitee()
|
|
219
|
+
else:
|
|
220
|
+
interactive_menu()
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Flash 凭据管理 -- 统一管理脚本
|
|
3
|
+
==============================
|
|
4
|
+
主入口菜单,可导航到各个凭据管理模块。2
|
|
5
|
+
|
|
6
|
+
用法:
|
|
7
|
+
python -m flash._core.credentials.manage # 主菜单 (模块方式,推荐)
|
|
8
|
+
python -m flash._core.credentials.manage setup # 一键设置所有凭据
|
|
9
|
+
python -m flash._core.credentials.manage ssh # 直接进入 SSH 管理
|
|
10
|
+
python -m flash._core.credentials.manage gitee # 直接进入 Gitee 管理
|
|
11
|
+
python -m flash._core.credentials.manage api # 直接进入 API 管理
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import sys
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
# =======================================================================
|
|
18
|
+
# 直接运行时的自动转换:
|
|
19
|
+
# 如果 __package__ 为 None,说明是直接运行 (python manage.py),
|
|
20
|
+
# 此时用 runpy 以模块方式重新运行,使相对导入能正常工作。
|
|
21
|
+
# =======================================================================
|
|
22
|
+
if __name__ == "__main__" and __package__ is None:
|
|
23
|
+
_CRED_DIR = Path(__file__).resolve().parent # .../flash/_core/credentials/
|
|
24
|
+
_CORE_DIR = _CRED_DIR.parent # .../flash/_core/
|
|
25
|
+
_FLASH_DIR = _CORE_DIR.parent # .../flash/
|
|
26
|
+
_PARENT = _FLASH_DIR.parent # flash/ 的父目录
|
|
27
|
+
|
|
28
|
+
# standalone 模式: 将 flash/ 的父目录加入 sys.path
|
|
29
|
+
if str(_PARENT) not in sys.path:
|
|
30
|
+
sys.path.insert(0, str(_PARENT))
|
|
31
|
+
|
|
32
|
+
# 用 runpy 以模块方式重新运行自己
|
|
33
|
+
import warnings
|
|
34
|
+
warnings.filterwarnings("ignore", category=RuntimeWarning, module="runpy")
|
|
35
|
+
|
|
36
|
+
import runpy
|
|
37
|
+
sys.argv.insert(0, __file__) # 保留原始 argv
|
|
38
|
+
runpy.run_module("flash._core.credentials.manage", run_name="__main__")
|
|
39
|
+
sys.exit(0)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# =======================================================================
|
|
43
|
+
# 所有导入使用相对导入 (flash 独立包模式)
|
|
44
|
+
# =======================================================================
|
|
45
|
+
from ._core import get_credential_manager, get_user_name, get_user_name_source, set_user_name
|
|
46
|
+
from ._config import DEFAULT_USER_NAME
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _print_header():
|
|
50
|
+
"""打印标题和状态。"""
|
|
51
|
+
try:
|
|
52
|
+
cm = get_credential_manager()
|
|
53
|
+
existing = cm.list_all()
|
|
54
|
+
real_keys = [k for k in existing if k != "__meta__"]
|
|
55
|
+
user_name = get_user_name()
|
|
56
|
+
except SystemExit:
|
|
57
|
+
real_keys = []
|
|
58
|
+
try:
|
|
59
|
+
user_name = get_user_name()
|
|
60
|
+
except Exception:
|
|
61
|
+
user_name = "hello"
|
|
62
|
+
|
|
63
|
+
print(f"\n {'=' * 55}")
|
|
64
|
+
print(f" Flash 凭据管理中心")
|
|
65
|
+
source = get_user_name_source()
|
|
66
|
+
source_note = f" (继承 {source})" if source == "physimx_core" else " (独立)"
|
|
67
|
+
print(f" 当前用户: {user_name}{source_note}")
|
|
68
|
+
if real_keys:
|
|
69
|
+
print(f" 已保存凭据: {', '.join(real_keys)}")
|
|
70
|
+
else:
|
|
71
|
+
print(f" 当前未保存任何凭据")
|
|
72
|
+
print(f" {'=' * 55}")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _set_user_name() -> None:
|
|
76
|
+
"""设置默认用户名。"""
|
|
77
|
+
current = get_user_name()
|
|
78
|
+
print(f"\n 👤 设置默认用户名")
|
|
79
|
+
print(f" {'─' * 55}")
|
|
80
|
+
print(f" 当前用户名: {current}")
|
|
81
|
+
print(f" {'─' * 55}")
|
|
82
|
+
|
|
83
|
+
new_name = input(f"\n 输入新用户名 [回车保留 '{current}']: ").strip()
|
|
84
|
+
if not new_name:
|
|
85
|
+
print("\n [未修改]")
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
set_user_name(new_name)
|
|
89
|
+
print(f"\n ✅ 用户名已设为: {new_name}")
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _setup_ssh_presconfigured() -> None:
|
|
93
|
+
"""设置预配置 SSH 账户(带路由测试)。"""
|
|
94
|
+
from ._config import ENTRIES, ENTRIES_BY_NAME
|
|
95
|
+
from .flash_ssh import _get_ssh_username, test_all_routes, test_route
|
|
96
|
+
from ._core import get_credential_manager, ask_one, set_primary_ssh, collect_ssh_accounts
|
|
97
|
+
|
|
98
|
+
cm = get_credential_manager()
|
|
99
|
+
|
|
100
|
+
# 收集预配置账号
|
|
101
|
+
presconfigured = []
|
|
102
|
+
for entry in ENTRIES:
|
|
103
|
+
if not entry["name"].startswith("flash_ssh"):
|
|
104
|
+
continue
|
|
105
|
+
name = entry["name"]
|
|
106
|
+
title = entry.get("title", name)
|
|
107
|
+
ssh_user = _get_ssh_username(name)
|
|
108
|
+
presconfigured.append((name, title, ssh_user, entry))
|
|
109
|
+
|
|
110
|
+
if not presconfigured:
|
|
111
|
+
print("\n [提示] 未找到预配置 SSH 账户。")
|
|
112
|
+
return
|
|
113
|
+
|
|
114
|
+
# 显示预配置账号
|
|
115
|
+
print(f"\n 📋 预配置 SSH 账户:")
|
|
116
|
+
for i, (name, title, ssh_user, entry) in enumerate(presconfigured, 1):
|
|
117
|
+
existing = cm.get(name)
|
|
118
|
+
status = "✅ 已配置" if existing else "⬜ 未配置"
|
|
119
|
+
print(f" [{i}] {title}")
|
|
120
|
+
print(f" 账号: {ssh_user} [{status}]")
|
|
121
|
+
|
|
122
|
+
print(f"\n 选项:")
|
|
123
|
+
print(f" [1-{len(presconfigured)}] 设置对应的预配置账号")
|
|
124
|
+
print(f" [A] 设置所有预配置账号")
|
|
125
|
+
print(f" [0] 跳过")
|
|
126
|
+
|
|
127
|
+
choice = input(f"\n 请选择: ").strip().lower()
|
|
128
|
+
|
|
129
|
+
if choice == "0":
|
|
130
|
+
print("\n [已跳过]")
|
|
131
|
+
return
|
|
132
|
+
elif choice == "a":
|
|
133
|
+
# 设置所有预配置账号
|
|
134
|
+
accounts = collect_ssh_accounts(cm)
|
|
135
|
+
|
|
136
|
+
# 先进行路由测试
|
|
137
|
+
print(f"\n 🔍 进行路由测试...")
|
|
138
|
+
try:
|
|
139
|
+
results = test_all_routes()
|
|
140
|
+
if results:
|
|
141
|
+
print(f"\n {'─' * 60}")
|
|
142
|
+
print(f" 路由测试结果 (延迟越低越好)")
|
|
143
|
+
print(f" {'─' * 60}")
|
|
144
|
+
sorted_results = sorted(results.items(), key=lambda x: x[1][1])
|
|
145
|
+
for name, (ok, delay, host, port, title) in sorted_results:
|
|
146
|
+
status = f"✅ {delay:.3f}s" if ok else f"❌ 超时"
|
|
147
|
+
print(f" {title}")
|
|
148
|
+
print(f" {host}:{port} → {status}")
|
|
149
|
+
|
|
150
|
+
# 自动选择延迟最低的作为主账户
|
|
151
|
+
if accounts:
|
|
152
|
+
best_name = sorted_results[0][0]
|
|
153
|
+
set_primary_ssh(cm, best_name)
|
|
154
|
+
print(f"\n ✅ 已自动选择延迟最低的账号作为主账户: {best_name}")
|
|
155
|
+
except Exception as e:
|
|
156
|
+
print(f"\n ⚠️ 路由测试失败: {e}")
|
|
157
|
+
|
|
158
|
+
# 依次设置每个预配置账号
|
|
159
|
+
for name, title, ssh_user, entry in presconfigured:
|
|
160
|
+
print(f"\n {'=' * 60}")
|
|
161
|
+
print(f" 📝 设置: {title}")
|
|
162
|
+
print(f" {'=' * 60}")
|
|
163
|
+
print(f" 账号: {ssh_user}")
|
|
164
|
+
print(f" {'─' * 60}")
|
|
165
|
+
|
|
166
|
+
data = {}
|
|
167
|
+
for key, label, default in entry.get("fields", []):
|
|
168
|
+
if key == "password":
|
|
169
|
+
print(f"\n ⚠️ 请为账号 {ssh_user} 设置密码")
|
|
170
|
+
data[key] = ask_one(label, default)
|
|
171
|
+
|
|
172
|
+
# 如果连接模式是 manual,询问额外字段
|
|
173
|
+
if data.get("connection_mode") == "manual":
|
|
174
|
+
print("\n [手动模式] 需要额外信息:")
|
|
175
|
+
for key, label, default in entry.get("manual_fields", []):
|
|
176
|
+
data[key] = ask_one(label, default)
|
|
177
|
+
|
|
178
|
+
cm.set(name, data)
|
|
179
|
+
print(f"\n ✅ {title} 已保存。")
|
|
180
|
+
|
|
181
|
+
print(f"\n ✅ 所有预配置 SSH 账号设置完成!")
|
|
182
|
+
elif choice.isdigit() and 1 <= int(choice) <= len(presconfigured):
|
|
183
|
+
idx = int(choice) - 1
|
|
184
|
+
name, title, ssh_user, entry = presconfigured[idx]
|
|
185
|
+
|
|
186
|
+
print(f"\n 📝 设置: {title}")
|
|
187
|
+
print(f" {'─' * 50}")
|
|
188
|
+
print(f" 账号: {ssh_user}")
|
|
189
|
+
print(f" {'─' * 50}")
|
|
190
|
+
|
|
191
|
+
# 先进行路由测试
|
|
192
|
+
try:
|
|
193
|
+
results = test_all_routes()
|
|
194
|
+
if name in results:
|
|
195
|
+
ok, delay, host, port, _ = results[name]
|
|
196
|
+
status = f"✅ {delay:.3f}s" if ok else f"❌ 超时"
|
|
197
|
+
print(f"\n 🔍 路由测试: {host}:{port} → {status}")
|
|
198
|
+
except Exception:
|
|
199
|
+
pass
|
|
200
|
+
|
|
201
|
+
data = {}
|
|
202
|
+
for key, label, default in entry.get("fields", []):
|
|
203
|
+
if key == "password":
|
|
204
|
+
print(f"\n ⚠️ 请为账号 {ssh_user} 设置密码")
|
|
205
|
+
data[key] = ask_one(label, default)
|
|
206
|
+
|
|
207
|
+
if data.get("connection_mode") == "manual":
|
|
208
|
+
print("\n [手动模式] 需要额外信息:")
|
|
209
|
+
for key, label, default in entry.get("manual_fields", []):
|
|
210
|
+
data[key] = ask_one(label, default)
|
|
211
|
+
|
|
212
|
+
cm.set(name, data)
|
|
213
|
+
print(f"\n ✅ {title} 已保存。")
|
|
214
|
+
|
|
215
|
+
# 如果是第一个账户,设为主账户
|
|
216
|
+
accounts = collect_ssh_accounts(cm)
|
|
217
|
+
if len(accounts) == 1:
|
|
218
|
+
set_primary_ssh(cm, name)
|
|
219
|
+
print(f" ✅ 已设为默认主账户。")
|
|
220
|
+
else:
|
|
221
|
+
print("\n [无效选择]")
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def _setup_all() -> None:
|
|
225
|
+
"""一键设置所有凭据。"""
|
|
226
|
+
user_name = get_user_name()
|
|
227
|
+
print(f"\n 🚀 一键设置所有凭据")
|
|
228
|
+
print(f" {'─' * 55}")
|
|
229
|
+
print(f" 默认值: 用户名={user_name}, 密码=123")
|
|
230
|
+
print(f" {'─' * 55}\n")
|
|
231
|
+
|
|
232
|
+
# 1. FLASH SSH
|
|
233
|
+
print(" [1/4] FLASH SSH 凭据")
|
|
234
|
+
print(f" {'─' * 55}")
|
|
235
|
+
_setup_ssh_presconfigured()
|
|
236
|
+
|
|
237
|
+
# 2. Gitee
|
|
238
|
+
print(f"\n [2/4] Gitee 凭据")
|
|
239
|
+
print(f" {'─' * 55}")
|
|
240
|
+
from .gitee import setup_gitee
|
|
241
|
+
setup_gitee()
|
|
242
|
+
|
|
243
|
+
# 3. DeepSeek API
|
|
244
|
+
print(f"\n [3/4] DeepSeek API 凭据")
|
|
245
|
+
print(f" {'─' * 55}")
|
|
246
|
+
from .api_keys import setup_api
|
|
247
|
+
setup_api("deepseek_api")
|
|
248
|
+
|
|
249
|
+
print(f"\n ✅ 所有凭据设置完成!")
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def main():
|
|
253
|
+
"""主入口。"""
|
|
254
|
+
args = sys.argv[1:]
|
|
255
|
+
|
|
256
|
+
# 命令行模式
|
|
257
|
+
if args:
|
|
258
|
+
if args[0] in ("setup", "all"):
|
|
259
|
+
force = "--force" in args or "-f" in args
|
|
260
|
+
_setup_all()
|
|
261
|
+
return
|
|
262
|
+
elif args[0] == "ssh":
|
|
263
|
+
from .flash_ssh import interactive_menu
|
|
264
|
+
cm = get_credential_manager()
|
|
265
|
+
interactive_menu(cm)
|
|
266
|
+
return
|
|
267
|
+
elif args[0] == "gitee":
|
|
268
|
+
from .gitee import interactive_menu
|
|
269
|
+
interactive_menu()
|
|
270
|
+
return
|
|
271
|
+
elif args[0] == "api":
|
|
272
|
+
from .api_keys import interactive_menu
|
|
273
|
+
interactive_menu()
|
|
274
|
+
return
|
|
275
|
+
elif args[0] in ("pypi", "py"):
|
|
276
|
+
from .pypi import setup_pypi, show_pypi
|
|
277
|
+
if "--show" in args:
|
|
278
|
+
show_pypi()
|
|
279
|
+
else:
|
|
280
|
+
setup_pypi(args[1] if len(args) > 1 and not args[1].startswith("-") else None)
|
|
281
|
+
return
|
|
282
|
+
|
|
283
|
+
# 交互模式
|
|
284
|
+
try:
|
|
285
|
+
get_credential_manager()
|
|
286
|
+
except SystemExit:
|
|
287
|
+
return
|
|
288
|
+
|
|
289
|
+
while True:
|
|
290
|
+
_print_header()
|
|
291
|
+
print(" [1] 一键设置所有凭据")
|
|
292
|
+
print(" [2] FLASH SSH 账户管理 (增/删/改)")
|
|
293
|
+
print(" [3] Gitee 访问令牌管理 (设置/查看/删除)")
|
|
294
|
+
print(" [4] API 密钥管理 (AI API)")
|
|
295
|
+
print(" [5] PyPI 发布令牌管理 (pypi.org / test.pypi.org)")
|
|
296
|
+
print(" [6] 查看所有已保存凭据")
|
|
297
|
+
print(" [7] 设置默认用户名 (当前: {}, 默认: {})".format(get_user_name(), DEFAULT_USER_NAME))
|
|
298
|
+
print(" [0] 退出")
|
|
299
|
+
|
|
300
|
+
choice = input("\n 请选择 [0-7]: ").strip()
|
|
301
|
+
|
|
302
|
+
if choice == "1":
|
|
303
|
+
_setup_all()
|
|
304
|
+
elif choice == "2":
|
|
305
|
+
from .flash_ssh import interactive_menu
|
|
306
|
+
cm = get_credential_manager()
|
|
307
|
+
interactive_menu(cm)
|
|
308
|
+
elif choice == "3":
|
|
309
|
+
from .gitee import interactive_menu
|
|
310
|
+
interactive_menu()
|
|
311
|
+
elif choice == "4":
|
|
312
|
+
from .api_keys import interactive_menu
|
|
313
|
+
interactive_menu()
|
|
314
|
+
elif choice == "5":
|
|
315
|
+
from .pypi import setup_pypi, show_pypi
|
|
316
|
+
print("\n [P] 设置令牌")
|
|
317
|
+
print(" [V] 查看状态")
|
|
318
|
+
sub = input(" 请选择 [P/V]: ").strip().lower()
|
|
319
|
+
if sub in ("v", "view"):
|
|
320
|
+
show_pypi()
|
|
321
|
+
else:
|
|
322
|
+
setup_pypi()
|
|
323
|
+
elif choice == "6":
|
|
324
|
+
cm = get_credential_manager()
|
|
325
|
+
existing = cm.list_all()
|
|
326
|
+
real_keys = [k for k in existing if k != "__meta__"]
|
|
327
|
+
if not real_keys:
|
|
328
|
+
print("\n 当前没有保存任何凭据。")
|
|
329
|
+
else:
|
|
330
|
+
print(f"\n {'─' * 55}")
|
|
331
|
+
print(f" 已保存凭据 ({len(real_keys)} 组)")
|
|
332
|
+
print(f" {'─' * 55}")
|
|
333
|
+
for name, data in existing.items():
|
|
334
|
+
if name == "__meta__":
|
|
335
|
+
continue
|
|
336
|
+
print(f"\n [{name}]")
|
|
337
|
+
for k, v in data.items():
|
|
338
|
+
print(f" {k:12s}: {v}")
|
|
339
|
+
print(f"\n {'─' * 55}")
|
|
340
|
+
# 显示 Flash 专属存储位置
|
|
341
|
+
try:
|
|
342
|
+
storage_dir = cm._cred_dir
|
|
343
|
+
except AttributeError:
|
|
344
|
+
# 兼容旧版(无 subdir 支持)
|
|
345
|
+
from pathlib import Path
|
|
346
|
+
storage_dir = Path.home() / ".physimx" / "flash"
|
|
347
|
+
print(f" 存储位置: {storage_dir}/")
|
|
348
|
+
input("\n 按回车返回...")
|
|
349
|
+
elif choice == "7":
|
|
350
|
+
_set_user_name()
|
|
351
|
+
elif choice == "0":
|
|
352
|
+
print("\n 再见!\n")
|
|
353
|
+
break
|
|
354
|
+
else:
|
|
355
|
+
print(" [无效选择]")
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
if __name__ == "__main__":
|
|
359
|
+
main()
|