feat: 新增 Plan B 整目录重装脚本,不影响 setup_env 一键安装
添加 deploy/reinstall.sh 备份 env、克隆、调 setup_env、恢复配置并 PM2 启动; 附带 pm2_start_all.sh 与 hub_settings 清理工具。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python3
|
||||
"""重装后清理 hub_settings.json 中已废弃的 gate_bot / 第四账户条目。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
DROP_KEYS = frozenset({"gate_bot", "gate-bot"})
|
||||
DROP_MARKERS = (
|
||||
"gate_bot",
|
||||
"crypto_monitor_gate_bot",
|
||||
"15203",
|
||||
":5002",
|
||||
)
|
||||
|
||||
|
||||
def _text(*parts: object) -> str:
|
||||
return " ".join(str(p) for p in parts if p is not None).lower()
|
||||
|
||||
|
||||
def should_drop(ex: dict) -> bool:
|
||||
key = str(ex.get("key") or "").strip().lower()
|
||||
if key in DROP_KEYS:
|
||||
return True
|
||||
blob = _text(
|
||||
ex.get("name"),
|
||||
ex.get("flask_url"),
|
||||
ex.get("agent_url"),
|
||||
ex.get("review_url"),
|
||||
)
|
||||
if any(m in blob for m in DROP_MARKERS):
|
||||
return True
|
||||
ex_id = str(ex.get("id") or "").strip()
|
||||
if ex_id == "3" and key not in ("gate", ""):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def sanitize_settings(data: dict) -> tuple[dict, list[str]]:
|
||||
removed: list[str] = []
|
||||
exchanges = data.get("exchanges")
|
||||
if not isinstance(exchanges, list):
|
||||
return data, removed
|
||||
|
||||
kept: list[dict] = []
|
||||
seen_keys: set[str] = set()
|
||||
for ex in exchanges:
|
||||
if not isinstance(ex, dict):
|
||||
continue
|
||||
key = str(ex.get("key") or "").strip().lower()
|
||||
label = f"id={ex.get('id')} key={key} name={ex.get('name')}"
|
||||
if should_drop(ex):
|
||||
removed.append(label)
|
||||
continue
|
||||
if key and key in seen_keys:
|
||||
removed.append(f"duplicate {label}")
|
||||
continue
|
||||
if key:
|
||||
seen_keys.add(key)
|
||||
kept.append(ex)
|
||||
|
||||
out = dict(data)
|
||||
out["exchanges"] = kept
|
||||
return out, removed
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
args = argv if argv is not None else sys.argv[1:]
|
||||
if len(args) != 1:
|
||||
print("用法: python deploy/sanitize_hub_settings.py <hub_settings.json>", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
path = Path(args[0])
|
||||
if not path.is_file():
|
||||
print(f"文件不存在: {path}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
try:
|
||||
data = json.loads(path.read_text(encoding="utf-8"))
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"JSON 解析失败: {e}", file=sys.stderr)
|
||||
return 1
|
||||
if not isinstance(data, dict):
|
||||
print("hub_settings.json 根节点必须是 object", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
cleaned, removed = sanitize_settings(data)
|
||||
if removed:
|
||||
path.write_text(json.dumps(cleaned, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
print("已移除条目:")
|
||||
for line in removed:
|
||||
print(f" - {line}")
|
||||
else:
|
||||
print("无需修改(未发现 gate_bot / 第四账户)")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user