Files
crypto_monitor/scripts/patch_instance_theme_templates.py
T
2026-06-04 12:52:27 +08:00

97 lines
4.0 KiB
Python

#!/usr/bin/env python3
"""为四所 templates 注入 instance_theme 脚本/样式与切换按钮。"""
from __future__ import annotations
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
EXCHANGES = ("crypto_monitor_binance", "crypto_monitor_okx", "crypto_monitor_gate", "crypto_monitor_gate_bot")
FILES = ("index.html", "login.html", "key_focus_v2.html", "order_focus_v2.html")
SCRIPT_TAG = ' <script src="/static/instance_theme.js?v=1"></script>\n'
CSS_LINK = ' <link rel="stylesheet" href="/static/instance_theme.css?v=1">\n'
THEME_TOGGLE = """ <div class="theme-toggle instance-theme-toggle" role="group" aria-label="界面主题">
<button type="button" class="theme-toggle-btn is-active" data-theme-value="dark" aria-pressed="true" title="暗色主题">
<svg class="theme-icon" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true">
<path fill="currentColor" d="M12.1 3a9 9 0 1 0 8.9 11 6.5 6.5 0 1 1-8.9-11z"/>
</svg>
</button>
<button type="button" class="theme-toggle-btn" data-theme-value="light" aria-pressed="false" title="亮色主题">
<svg class="theme-icon" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
<circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/>
</svg>
</button>
</div>
"""
INDEX_HEADER_OLD = """ <div class="header">
<h1>加密货币|交易监控 + AI复盘一体化</h1>
<div class="exchange-tag">{{ exchange_display }}</div>
</div>"""
INDEX_HEADER_NEW = """ <div class="header">
<h1>加密货币|交易监控 + AI复盘一体化</h1>
<div class="header-row">
<div class="exchange-tag">{{ exchange_display }}</div>
""" + THEME_TOGGLE + """ </div>
</div>"""
def patch_file(path: Path) -> bool:
text = path.read_text(encoding="utf-8")
orig = text
if 'data-theme="dark"' not in text:
text = text.replace('<html lang="zh-CN">', '<html lang="zh-CN" data-theme="dark">', 1)
if "/static/instance_theme.js" not in text:
text = text.replace(
"<meta charset=\"UTF-8\">",
"<meta charset=\"UTF-8\">\n" + SCRIPT_TAG.strip() + "\n",
1,
)
if "/static/instance_theme.css" not in text:
text = text.replace("</style>", "</style>\n" + CSS_LINK, 1)
if path.name == "index.html" and INDEX_HEADER_OLD in text and "instance-theme-toggle" not in text:
text = text.replace(INDEX_HEADER_OLD, INDEX_HEADER_NEW)
if path.name == "login.html" and "instance-theme-toggle" not in text:
text = text.replace(
"<body>",
'<div class="login-theme-bar">\n' + THEME_TOGGLE + "</div>\n<body>",
1,
)
if path.name == "key_focus_v2.html" and "instance-theme-toggle" not in text:
marker = '<div class="row" style="justify-content:space-between">'
if marker in text:
text = text.replace(
marker,
marker + "\n " + THEME_TOGGLE.replace("\n", "\n "),
1,
)
if path.name == "order_focus_v2.html" and "instance-theme-toggle" not in text:
marker = '<div class="row" style="justify-content:space-between">'
if marker in text:
text = text.replace(
marker,
marker + "\n " + THEME_TOGGLE.replace("\n", "\n "),
1,
)
if text != orig:
path.write_text(text, encoding="utf-8")
return True
return False
def main() -> None:
n = 0
for ex in EXCHANGES:
for fn in FILES:
p = ROOT / ex / "templates" / fn
if p.is_file() and patch_file(p):
print("patched", p.relative_to(ROOT))
n += 1
print("done", n, "files")
if __name__ == "__main__":
main()