21b3e97571
Restore plan floating P/L and st-done greens; fix panel-item and stats-split-col in light mode; observe journal lists; bump theme assets to v3. Co-authored-by: Cursor <cursoragent@cursor.com>
97 lines
4.0 KiB
Python
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=3"></script>\n'
|
|
CSS_LINK = ' <link rel="stylesheet" href="/static/instance_theme.css?v=3">\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()
|