Some checks failed
CD Pipeline / deploy (push) Failing after 59s
- 建立 Gitea Actions CD pipeline (.gitea/workflows/cd.yaml) - 部署模式: rsync Python 檔案至 188 → docker restart (volume mount) - Dockerfile/requirements 變動時自動重建 Docker image - 部署通知: Telegram (開始/成功/失敗) - 健康檢查: https://mo.wooo.work/health (最多 5 次重試) - 同步最新 CLAUDE.md / ADR-008 / memory (2026-04-19) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
125 lines
6.0 KiB
Python
125 lines
6.0 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
批量更新所有 HTML 文件的導航列結構
|
||
從 9 個平鋪項目改為 6 個項目(含下拉菜單)
|
||
"""
|
||
|
||
import os
|
||
import re
|
||
from pathlib import Path
|
||
|
||
# 新的導航列HTML(6個項目,含下拉菜單)
|
||
NEW_NAVBAR_ITEMS = ''' <ul class="navbar-nav me-auto">
|
||
<li class="nav-item"><a class="nav-link{active_dashboard}" href="/"><i class="fas fa-chart-line me-1"></i>商品看板</a></li>
|
||
<li class="nav-item"><a class="nav-link{active_edm}" href="/edm"><i class="fas fa-bullhorn me-1"></i>活動看板</a></li>
|
||
<li class="nav-item dropdown">
|
||
<a class="nav-link dropdown-toggle{active_analysis}" href="#" role="button" data-bs-toggle="dropdown">
|
||
<i class="fas fa-chart-bar me-1"></i>分析報表
|
||
</a>
|
||
<ul class="dropdown-menu">
|
||
<li><a class="dropdown-item" href="/sales_analysis"><i class="fas fa-chart-bar me-2"></i>業績分析</a></li>
|
||
<li><a class="dropdown-item" href="/daily_sales"><i class="fas fa-calendar-day me-2"></i>當日業績</a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="nav-item"><a class="nav-link{active_vendor}" href="/vendor-stockout"><i class="fas fa-box-open me-1"></i>廠商缺貨</a></li>
|
||
<li class="nav-item"><a class="nav-link{active_import}" href="/auto_import"><i class="fas fa-cloud-download-alt me-1"></i>雲端匯入</a></li>
|
||
<li class="nav-item dropdown">
|
||
<a class="nav-link dropdown-toggle{active_system}" href="#" role="button" data-bs-toggle="dropdown">
|
||
<i class="fas fa-cog me-1"></i>系統管理
|
||
</a>
|
||
<ul class="dropdown-menu">
|
||
<li><a class="dropdown-item" href="/crawler_management"><i class="fas fa-robot me-2"></i>爬蟲管理</a></li>
|
||
<li><a class="dropdown-item" href="/settings"><i class="fas fa-cog me-2"></i>爬蟲設定</a></li>
|
||
<li><a class="dropdown-item" href="/system_settings"><i class="fas fa-sliders-h me-2"></i>系統設定</a></li>
|
||
<li><a class="dropdown-item" href="/logs"><i class="fas fa-file-alt me-2"></i>系統日誌</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>'''
|
||
|
||
# 頁面對應的 active 標記
|
||
PAGE_ACTIVE_MAP = {
|
||
'dashboard.html': {'active_dashboard': ' active'},
|
||
'edm_dashboard.html': {'active_edm': '{edm_active}'}, # 保留原有的 Jinja2 邏輯
|
||
'sales_analysis.html': {'active_analysis': ' active'},
|
||
'daily_sales.html': {'active_analysis': ' active'},
|
||
'vendor_stockout_index.html': {'active_vendor': ' active'},
|
||
'vendor_stockout_list.html': {'active_vendor': ' active'},
|
||
'vendor_stockout_import.html': {'active_vendor': ' active'},
|
||
'vendor_stockout_send_email.html': {'active_vendor': ' active'},
|
||
'vendor_stockout_history.html': {'active_vendor': ' active'},
|
||
'auto_import_index.html': {'active_import': ' active'},
|
||
'settings.html': {'active_system': ' active'},
|
||
'system_settings.html': {'active_system': ' active'},
|
||
'logs.html': {'active_system': ' active'},
|
||
}
|
||
|
||
def update_navbar_in_file(file_path):
|
||
"""更新單個 HTML 文件的導航列"""
|
||
with open(file_path, 'r', encoding='utf-8') as f:
|
||
content = f.read()
|
||
|
||
# 檢查是否有舊的導航列結構
|
||
if '<ul class="navbar-nav me-auto">' not in content:
|
||
print(f"⏭️ 跳過 {file_path.name}(沒有找到導航列)")
|
||
return False
|
||
|
||
# 確定這個頁面的 active 標記
|
||
filename = file_path.name
|
||
active_map = PAGE_ACTIVE_MAP.get(filename, {})
|
||
|
||
# 準備新的導航列內容
|
||
navbar_items = NEW_NAVBAR_ITEMS
|
||
navbar_items = navbar_items.replace('{active_dashboard}', active_map.get('active_dashboard', ''))
|
||
navbar_items = navbar_items.replace('{active_edm}', active_map.get('active_edm', ''))
|
||
navbar_items = navbar_items.replace('{active_analysis}', active_map.get('active_analysis', ''))
|
||
navbar_items = navbar_items.replace('{active_vendor}', active_map.get('active_vendor', ''))
|
||
navbar_items = navbar_items.replace('{active_import}', active_map.get('active_import', ''))
|
||
navbar_items = navbar_items.replace('{active_system}', active_map.get('active_system', ''))
|
||
|
||
# 特殊處理 edm_dashboard.html 的 Jinja2 邏輯
|
||
if filename == 'edm_dashboard.html':
|
||
navbar_items = navbar_items.replace('{edm_active}', " {% if current_promo_page in ['edm', 'festival'] %}active{% endif %}")
|
||
else:
|
||
navbar_items = navbar_items.replace('{edm_active}', '')
|
||
|
||
# 替換導航列項目(使用正則匹配從 <ul class="navbar-nav me-auto"> 到 </ul>)
|
||
pattern = r'<ul class="navbar-nav me-auto">.*?</ul>'
|
||
new_content = re.sub(pattern, navbar_items, content, flags=re.DOTALL)
|
||
|
||
if new_content == content:
|
||
print(f"⏭️ 跳過 {file_path.name}(沒有變更)")
|
||
return False
|
||
|
||
# 同時確保使用 navbar-expand-xl
|
||
new_content = re.sub(r'<nav class="navbar navbar-dark', '<nav class="navbar navbar-expand-xl navbar-dark', new_content)
|
||
|
||
# 寫回文件
|
||
with open(file_path, 'w', encoding='utf-8') as f:
|
||
f.write(new_content)
|
||
|
||
print(f"✅ 已更新 {file_path.name}")
|
||
return True
|
||
|
||
def main():
|
||
"""主函數"""
|
||
base_dir = Path(__file__).parent
|
||
html_files = list(base_dir.glob('*.html'))
|
||
|
||
# 排除特定文件
|
||
exclude_files = {'maintenance.html', 'login.html'}
|
||
html_files = [f for f in html_files if f.name not in exclude_files]
|
||
|
||
print(f"找到 {len(html_files)} 個 HTML 文件")
|
||
print("=" * 50)
|
||
|
||
updated_count = 0
|
||
for html_file in sorted(html_files):
|
||
if update_navbar_in_file(html_file):
|
||
updated_count += 1
|
||
|
||
print("=" * 50)
|
||
print(f"\n✅ 完成!更新了 {updated_count} 個文件")
|
||
|
||
if __name__ == '__main__':
|
||
main()
|