135cdc13ba
Avoid load_markets hangs on weak networks; enable login-required sim defaults and document Baota Nginx reverse proxy. Co-authored-by: Cursor <cursoragent@cursor.com>
105 lines
3.6 KiB
Python
105 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
"""首次部署:自动生成登录会话密钥与初始账号(仅空/占位时写入,不覆盖已有).
|
|
|
|
- FLASK_SECRET_KEY
|
|
- APP_USERNAME=admin / APP_PASSWORD=admin123(仅空时)
|
|
- HUB_BRIDGE_TOKEN(仅空时,供后期中控)
|
|
- 云服务器测试默认:监听/鉴权/模拟盘(仅空或占位时)
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import os
|
|
import secrets
|
|
import sys
|
|
|
|
_REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
if _REPO not in sys.path:
|
|
sys.path.insert(0, _REPO)
|
|
|
|
from lib.env.env_file_lib import apply_env_updates, env_get, read_env_lines
|
|
|
|
FLASK_PLACEHOLDERS = frozenset(
|
|
{
|
|
"",
|
|
"CHANGE_TO_LONG_RANDOM_SECRET",
|
|
"crypto_monitor_2026_secret_key",
|
|
"coinox_2026_secret_key",
|
|
}
|
|
)
|
|
PASSWORD_PLACEHOLDERS = frozenset({"", "CHANGE_ME_STRONG_PASSWORD"})
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description="Bootstrap deploy secrets for CoinOX")
|
|
parser.add_argument("--dry-run", action="store_true", help="只打印将写入的项,不改文件")
|
|
args = parser.parse_args()
|
|
|
|
env_path = os.path.join(_REPO, ".env")
|
|
if not os.path.isfile(env_path):
|
|
print(f" 跳过: 未找到 {env_path}")
|
|
return 0
|
|
|
|
lines = read_env_lines(env_path)
|
|
updates: dict[str, str] = {}
|
|
|
|
cur_secret = env_get(lines, "FLASK_SECRET_KEY")
|
|
if (cur_secret or "").strip() in FLASK_PLACEHOLDERS:
|
|
updates["FLASK_SECRET_KEY"] = secrets.token_urlsafe(48)
|
|
|
|
if not (env_get(lines, "APP_USERNAME") or "").strip():
|
|
updates["APP_USERNAME"] = "admin"
|
|
|
|
cur_pass = env_get(lines, "APP_PASSWORD")
|
|
if (cur_pass or "").strip() in PASSWORD_PLACEHOLDERS:
|
|
updates["APP_PASSWORD"] = "admin123"
|
|
|
|
if not (env_get(lines, "HUB_BRIDGE_TOKEN") or "").strip():
|
|
updates["HUB_BRIDGE_TOKEN"] = secrets.token_urlsafe(32)
|
|
|
|
# 云服务器测试默认(仅空时写入;不覆盖用户已改配置)
|
|
if not (env_get(lines, "APP_HOST") or "").strip():
|
|
updates["APP_HOST"] = "0.0.0.0"
|
|
if not (env_get(lines, "APP_PORT") or "").strip():
|
|
updates["APP_PORT"] = "5010"
|
|
if not (env_get(lines, "APP_DEBUG") or "").strip():
|
|
updates["APP_DEBUG"] = "false"
|
|
if not (env_get(lines, "APP_AUTH_DISABLED") or "").strip():
|
|
updates["APP_AUTH_DISABLED"] = "false"
|
|
if not (env_get(lines, "SIM_DEFAULT_MODE") or "").strip():
|
|
updates["SIM_DEFAULT_MODE"] = "sim"
|
|
if not (env_get(lines, "OKX_OPTIONS_MARGIN_MODE") or "").strip():
|
|
updates["OKX_OPTIONS_MARGIN_MODE"] = "coin"
|
|
if not (env_get(lines, "EXCHANGE_DISPLAY_NAME") or "").strip():
|
|
updates["EXCHANGE_DISPLAY_NAME"] = "CoinOX"
|
|
if not (env_get(lines, "OKX_OPTIONS_ENABLED") or "").strip():
|
|
updates["OKX_OPTIONS_ENABLED"] = "true"
|
|
if not (env_get(lines, "OKX_TRADE_MODE") or "").strip():
|
|
updates["OKX_TRADE_MODE"] = "perp_options"
|
|
live = (env_get(lines, "LIVE_TRADING_ENABLED") or "").strip().lower()
|
|
if live in ("",):
|
|
updates["LIVE_TRADING_ENABLED"] = "false"
|
|
|
|
if not updates:
|
|
print(" 密钥已存在,无需写入")
|
|
return 0
|
|
|
|
print(f" 将更新 {env_path}: {', '.join(updates.keys())}")
|
|
if args.dry_run:
|
|
for k, v in updates.items():
|
|
shown = (
|
|
"***"
|
|
if k in ("APP_PASSWORD", "HUB_BRIDGE_TOKEN") or "SECRET" in k
|
|
else v
|
|
)
|
|
print(f" {k}={shown}")
|
|
return 0
|
|
|
|
apply_env_updates(env_path, updates)
|
|
print(" 已写入云服务器测试默认(请尽快修改 APP_PASSWORD;公网保持 APP_AUTH_DISABLED=false)")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|