Spaces:
Sleeping
Sleeping
File size: 3,189 Bytes
7d67a69 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | # utils.py
# 此檔案包含各種工具函數
# 包括字型下載、IP 分類、繪圖輔助等
import os
import urllib.request
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import pandas as pd
import numpy as np
import seaborn as sns
import io
import base64
import datetime
import warnings
from config import FONT_PATH
# --- 解決 Matplotlib 中文顯示問題 ---
def setup_chinese_font():
"""下載並設定中文字型"""
if not os.path.exists(FONT_PATH):
try:
print("📥 正在下載中文字型...")
urllib.request.urlretrieve('https://github.com/StellarCN/scp_zh/raw/master/fonts/SimHei.ttf', FONT_PATH)
except Exception as e:
print(f"⚠️ 字型下載失敗: {e}")
if os.path.exists(FONT_PATH):
fm.fontManager.addfont(FONT_PATH)
plt.rc('font', family='SimHei')
plt.rcParams['axes.unicode_minus'] = False
# Seaborn 近期會對舊的 pandas option 發出 FutureWarning(純警告、非功能錯誤)
# 重整前端會觸發繪圖端點,因此你會在 terminal 看到重複訊息。
def suppress_warnings():
"""抑制不必要的警告"""
warnings.filterwarnings(
"ignore",
category=FutureWarning,
message="use_inf_as_na option is deprecated*",
)
# --- IP 分類函數 ---
def get_ip_category(ip_str):
"""根據 IP 地址分類"""
ip = str(ip_str).split(" ")[0]
if ip.startswith("140.124."): return 0.0
elif ip.startswith("61.228."): return 1.0
elif ip.startswith("210.61."): return 2.0
elif ip.startswith("45.33."): return 3.0
else: return 4.0
def get_geo_level(ip_str):
"""根據 IP 地址獲取地理等級"""
ip = str(ip_str).split(" ")[0]
if ip == "140.124.71.55": return 0
elif ip == "140.124.18.22": return 1
elif ip.startswith("61.228."): return 2
elif ip.startswith("210.61."): return 3
elif ip.startswith("45.33."): return 4
else: return 5
def update_system_weights(ow, tw, iw, dw, gw, fw):
"""更新系統權重"""
from config import SYSTEM_WEIGHTS
SYSTEM_WEIGHTS.update({
"ow": float(ow), "tw": float(tw), "iw": float(iw),
"dw": float(dw), "gw": float(gw), "fw": float(fw)
})
return f"✅ 系統權重已更新 - 總體: {ow}%, 時間: {tw}%, IP: {iw}%, 裝置: {dw}%, 地理: {gw}%, 頻率: {fw}%"
def _extract_gr_update_value(update_obj):
"""
Gradio 的 gr.update(...) 可能回傳 dict 形式或物件形式。
這裡統一抓出其中的 `value`,否則回傳 None。
"""
if update_obj is None:
return None
if isinstance(update_obj, dict):
return update_obj.get("value")
# Fallback: try attribute access
try:
return getattr(update_obj, "value", None)
except Exception:
return None
def get_current_time():
"""獲取當前時間(台灣時區)"""
return datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=8))).strftime("%Y-%m-%d %H:%M:%S")
def validate_time_format(time_str):
"""驗證時間格式"""
try:
pd.to_datetime(str(time_str))
return True
except Exception:
return False |