Spaces:
Paused
Paused
Upload 55 files
Browse files- app/api/dashboard.py +1 -1
- app/config/settings.py +11 -8
- app/main.py +13 -8
- app/templates/index.html +44 -21
- app/utils/maintenance.py +46 -5
- app/utils/version.py +8 -9
app/api/dashboard.py
CHANGED
|
@@ -95,7 +95,7 @@ async def get_dashboard_data():
|
|
| 95 |
api_key_stats.sort(key=lambda x: x['usage_percent'], reverse=True)
|
| 96 |
|
| 97 |
# 获取最近的日志
|
| 98 |
-
recent_logs = log_manager.get_recent_logs(
|
| 99 |
|
| 100 |
# 返回JSON格式的数据
|
| 101 |
return {
|
|
|
|
| 95 |
api_key_stats.sort(key=lambda x: x['usage_percent'], reverse=True)
|
| 96 |
|
| 97 |
# 获取最近的日志
|
| 98 |
+
recent_logs = log_manager.get_recent_logs(500) # 获取最近50条日志
|
| 99 |
|
| 100 |
# 返回JSON格式的数据
|
| 101 |
return {
|
app/config/settings.py
CHANGED
|
@@ -8,12 +8,13 @@ BASE_DIR = pathlib.Path(__file__).parent.parent
|
|
| 8 |
|
| 9 |
# 流式响应配置
|
| 10 |
FAKE_STREAMING = os.environ.get("FAKE_STREAMING", "true").lower() in ["true", "1", "yes"]
|
|
|
|
|
|
|
| 11 |
|
| 12 |
#随机字符串
|
| 13 |
RANDOM_STRING = os.environ.get("RANDOM_STRING", "true").lower() in ["true", "1", "yes"]
|
| 14 |
-
RANDOM_STRING_LENGTH = int(os.environ.get("RANDOM_STRING_LENGTH", "
|
| 15 |
-
|
| 16 |
-
FAKE_STREAMING_INTERVAL = float(os.environ.get("FAKE_STREAMING_INTERVAL", "1"))
|
| 17 |
|
| 18 |
# 日志配置
|
| 19 |
logging.getLogger("uvicorn").disabled = True
|
|
@@ -39,10 +40,12 @@ REMOVE_CACHE_AFTER_USE = os.environ.get("REMOVE_CACHE_AFTER_USE", "true").lower(
|
|
| 39 |
REQUEST_HISTORY_EXPIRY_TIME = int(os.environ.get("REQUEST_HISTORY_EXPIRY_TIME", "600")) # 默认10分钟
|
| 40 |
ENABLE_RECONNECT_DETECTION = os.environ.get("ENABLE_RECONNECT_DETECTION", "true").lower() in ["true", "1", "yes"]
|
| 41 |
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
|
|
|
|
|
|
| 46 |
|
| 47 |
# API调用统计
|
| 48 |
api_call_stats = {
|
|
@@ -71,4 +74,4 @@ DEFAULT_BLOCKED_MODELS = []
|
|
| 71 |
# 环境变量格式应为逗号分隔的模型名称字符串
|
| 72 |
BLOCKED_MODELS = os.environ.get("BLOCKED_MODELS", ",".join(DEFAULT_BLOCKED_MODELS))
|
| 73 |
# 将字符串转换为列表
|
| 74 |
-
BLOCKED_MODELS = [model.strip() for model in BLOCKED_MODELS.split(",") if model.strip()]
|
|
|
|
| 8 |
|
| 9 |
# 流式响应配置
|
| 10 |
FAKE_STREAMING = os.environ.get("FAKE_STREAMING", "true").lower() in ["true", "1", "yes"]
|
| 11 |
+
# 假流式请求的空内容返回间隔(秒)
|
| 12 |
+
FAKE_STREAMING_INTERVAL = float(os.environ.get("FAKE_STREAMING_INTERVAL", "1"))
|
| 13 |
|
| 14 |
#随机字符串
|
| 15 |
RANDOM_STRING = os.environ.get("RANDOM_STRING", "true").lower() in ["true", "1", "yes"]
|
| 16 |
+
RANDOM_STRING_LENGTH = int(os.environ.get("RANDOM_STRING_LENGTH", "20"))
|
| 17 |
+
|
|
|
|
| 18 |
|
| 19 |
# 日志配置
|
| 20 |
logging.getLogger("uvicorn").disabled = True
|
|
|
|
| 40 |
REQUEST_HISTORY_EXPIRY_TIME = int(os.environ.get("REQUEST_HISTORY_EXPIRY_TIME", "600")) # 默认10分钟
|
| 41 |
ENABLE_RECONNECT_DETECTION = os.environ.get("ENABLE_RECONNECT_DETECTION", "true").lower() in ["true", "1", "yes"]
|
| 42 |
|
| 43 |
+
|
| 44 |
+
version={
|
| 45 |
+
"local_version":"0.0.0",
|
| 46 |
+
"remote_version":"0.0.0",
|
| 47 |
+
"has_update":False
|
| 48 |
+
}
|
| 49 |
|
| 50 |
# API调用统计
|
| 51 |
api_call_stats = {
|
|
|
|
| 74 |
# 环境变量格式应为逗号分隔的模型名称字符串
|
| 75 |
BLOCKED_MODELS = os.environ.get("BLOCKED_MODELS", ",".join(DEFAULT_BLOCKED_MODELS))
|
| 76 |
# 将字符串转换为列表
|
| 77 |
+
BLOCKED_MODELS = [model.strip() for model in BLOCKED_MODELS.split(",") if model.strip()]
|
app/main.py
CHANGED
|
@@ -22,6 +22,8 @@ from app.api import router, init_router, dashboard_router, init_dashboard_router
|
|
| 22 |
from app.config.settings import (
|
| 23 |
FAKE_STREAMING,
|
| 24 |
FAKE_STREAMING_INTERVAL,
|
|
|
|
|
|
|
| 25 |
PASSWORD,
|
| 26 |
MAX_REQUESTS_PER_MINUTE,
|
| 27 |
MAX_REQUESTS_PER_DAY_PER_IP,
|
|
@@ -34,9 +36,7 @@ from app.config.settings import (
|
|
| 34 |
ENABLE_RECONNECT_DETECTION,
|
| 35 |
api_call_stats,
|
| 36 |
client_request_history,
|
| 37 |
-
|
| 38 |
-
remote_version,
|
| 39 |
-
has_update,
|
| 40 |
API_KEY_DAILY_LIMIT
|
| 41 |
)
|
| 42 |
from app.config.safety import SAFETY_SETTINGS, SAFETY_SETTINGS_G2
|
|
@@ -115,7 +115,6 @@ async def startup_event():
|
|
| 115 |
|
| 116 |
# 检查版本
|
| 117 |
await check_version()
|
| 118 |
-
|
| 119 |
available_keys = await check_keys()
|
| 120 |
if available_keys:
|
| 121 |
key_manager.api_keys = available_keys
|
|
@@ -202,7 +201,7 @@ async def root(request: Request):
|
|
| 202 |
continue
|
| 203 |
|
| 204 |
# 获取最近的日志
|
| 205 |
-
recent_logs = log_manager.get_recent_logs(
|
| 206 |
|
| 207 |
# 获取缓存统计
|
| 208 |
total_cache = len(response_cache_manager.cache)
|
|
@@ -267,9 +266,15 @@ async def root(request: Request):
|
|
| 267 |
"current_time": datetime.now().strftime('%H:%M:%S'),
|
| 268 |
"logs": recent_logs,
|
| 269 |
# 添加版本信息
|
| 270 |
-
"local_version": local_version,
|
| 271 |
-
"remote_version": remote_version,
|
| 272 |
-
"has_update": has_update,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 273 |
# 添加缓存信息
|
| 274 |
"cache_entries": total_cache,
|
| 275 |
"valid_cache": valid_cache,
|
|
|
|
| 22 |
from app.config.settings import (
|
| 23 |
FAKE_STREAMING,
|
| 24 |
FAKE_STREAMING_INTERVAL,
|
| 25 |
+
RANDOM_STRING,
|
| 26 |
+
RANDOM_STRING_LENGTH,
|
| 27 |
PASSWORD,
|
| 28 |
MAX_REQUESTS_PER_MINUTE,
|
| 29 |
MAX_REQUESTS_PER_DAY_PER_IP,
|
|
|
|
| 36 |
ENABLE_RECONNECT_DETECTION,
|
| 37 |
api_call_stats,
|
| 38 |
client_request_history,
|
| 39 |
+
version,
|
|
|
|
|
|
|
| 40 |
API_KEY_DAILY_LIMIT
|
| 41 |
)
|
| 42 |
from app.config.safety import SAFETY_SETTINGS, SAFETY_SETTINGS_G2
|
|
|
|
| 115 |
|
| 116 |
# 检查版本
|
| 117 |
await check_version()
|
|
|
|
| 118 |
available_keys = await check_keys()
|
| 119 |
if available_keys:
|
| 120 |
key_manager.api_keys = available_keys
|
|
|
|
| 201 |
continue
|
| 202 |
|
| 203 |
# 获取最近的日志
|
| 204 |
+
recent_logs = log_manager.get_recent_logs(500) # 获取最近50条日志
|
| 205 |
|
| 206 |
# 获取缓存统计
|
| 207 |
total_cache = len(response_cache_manager.cache)
|
|
|
|
| 266 |
"current_time": datetime.now().strftime('%H:%M:%S'),
|
| 267 |
"logs": recent_logs,
|
| 268 |
# 添加版本信息
|
| 269 |
+
"local_version": version["local_version"],
|
| 270 |
+
"remote_version": version["remote_version"],
|
| 271 |
+
"has_update": version["has_update"],
|
| 272 |
+
# 添加流式响应配置
|
| 273 |
+
"fake_streaming": FAKE_STREAMING,
|
| 274 |
+
"fake_streaming_interval": FAKE_STREAMING_INTERVAL,
|
| 275 |
+
# 添加随机字符串配置
|
| 276 |
+
"random_string": RANDOM_STRING,
|
| 277 |
+
"random_string_length": RANDOM_STRING_LENGTH,
|
| 278 |
# 添加缓存信息
|
| 279 |
"cache_entries": total_cache,
|
| 280 |
"valid_cache": valid_cache,
|
app/templates/index.html
CHANGED
|
@@ -240,6 +240,15 @@
|
|
| 240 |
.progress-bar.high {
|
| 241 |
background-color: #dc3545; /* 红色 - 高使用率 */
|
| 242 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 243 |
</style>
|
| 244 |
</head>
|
| 245 |
<body>
|
|
@@ -294,6 +303,9 @@
|
|
| 294 |
|
| 295 |
<div class="info-box">
|
| 296 |
<h2 class="section-title">⚙️ 环境配置</h2>
|
|
|
|
|
|
|
|
|
|
| 297 |
<div class="stats-grid">
|
| 298 |
<div class="stat-card">
|
| 299 |
<div class="stat-value">{{ max_requests_per_minute }}</div>
|
|
@@ -308,30 +320,41 @@
|
|
| 308 |
<div class="stat-label">当前服务器时间</div>
|
| 309 |
</div>
|
| 310 |
</div>
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
<
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
</div>
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
<div
|
| 322 |
-
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
|
| 328 |
-
|
| 329 |
-
|
| 330 |
-
|
| 331 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 332 |
</div>
|
|
|
|
| 333 |
</div>
|
| 334 |
-
{% endif %}
|
| 335 |
</div>
|
| 336 |
</div>
|
| 337 |
|
|
|
|
| 240 |
.progress-bar.high {
|
| 241 |
background-color: #dc3545; /* 红色 - 高使用率 */
|
| 242 |
}
|
| 243 |
+
|
| 244 |
+
/* 版本更新状态样式 */
|
| 245 |
+
.update-needed {
|
| 246 |
+
color: #dc3545; /* 红色 - 需要更新 */
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
.up-to-date {
|
| 250 |
+
color: #28a745; /* 绿色 - 已是最新 */
|
| 251 |
+
}
|
| 252 |
</style>
|
| 253 |
</head>
|
| 254 |
<body>
|
|
|
|
| 303 |
|
| 304 |
<div class="info-box">
|
| 305 |
<h2 class="section-title">⚙️ 环境配置</h2>
|
| 306 |
+
|
| 307 |
+
<!-- 基本配置 -->
|
| 308 |
+
<h3 class="section-title">基本配置</h3>
|
| 309 |
<div class="stats-grid">
|
| 310 |
<div class="stat-card">
|
| 311 |
<div class="stat-value">{{ max_requests_per_minute }}</div>
|
|
|
|
| 320 |
<div class="stat-label">当前服务器时间</div>
|
| 321 |
</div>
|
| 322 |
</div>
|
| 323 |
+
|
| 324 |
+
<!-- 功能配置 -->
|
| 325 |
+
<h3 class="section-title">功能配置</h3>
|
| 326 |
+
<div class="stats-grid">
|
| 327 |
+
<div class="stat-card">
|
| 328 |
+
<div class="stat-value">{{ "启用" if fake_streaming else "禁用" }}</div>
|
| 329 |
+
<div class="stat-label">假流式响应</div>
|
| 330 |
</div>
|
| 331 |
+
<div class="stat-card">
|
| 332 |
+
<div class="stat-value">{{ fake_streaming_interval }}秒</div>
|
| 333 |
+
<div class="stat-label">假流式间隔</div>
|
| 334 |
+
</div>
|
| 335 |
+
<div class="stat-card">
|
| 336 |
+
<div class="stat-value">{{ "启用" if random_string else "禁用" }}</div>
|
| 337 |
+
<div class="stat-label">伪装信息</div>
|
| 338 |
+
</div>
|
| 339 |
+
</div>
|
| 340 |
+
|
| 341 |
+
<!-- 版本信息 -->
|
| 342 |
+
<h3 class="section-title">版本信息</h3>
|
| 343 |
+
<div class="stats-grid">
|
| 344 |
+
<div class="stat-card">
|
| 345 |
+
<div class="stat-value">{{ local_version }}</div>
|
| 346 |
+
<div class="stat-label">当前版本</div>
|
| 347 |
+
</div>
|
| 348 |
+
<div class="stat-card">
|
| 349 |
+
<div class="stat-value">{{ remote_version }}</div>
|
| 350 |
+
<div class="stat-label">最新版本</div>
|
| 351 |
+
</div>
|
| 352 |
+
<div class="stat-card">
|
| 353 |
+
<div class="stat-value {% if has_update %}update-needed{% else %}up-to-date{% endif %}">
|
| 354 |
+
{{ "需要更新" if has_update else "已是最新" }}
|
| 355 |
</div>
|
| 356 |
+
<div class="stat-label">更新状态</div>
|
| 357 |
</div>
|
|
|
|
| 358 |
</div>
|
| 359 |
</div>
|
| 360 |
|
app/utils/maintenance.py
CHANGED
|
@@ -1,9 +1,12 @@
|
|
| 1 |
-
import sys
|
| 2 |
-
from apscheduler.schedulers.background import BackgroundScheduler
|
|
|
|
| 3 |
from app.utils.logging import log
|
| 4 |
from app.utils.stats import clean_expired_stats
|
| 5 |
from app.config import api_call_stats
|
| 6 |
from app.utils import check_version
|
|
|
|
|
|
|
| 7 |
def handle_exception(exc_type, exc_value, exc_traceback):
|
| 8 |
"""
|
| 9 |
全局异常处理函数
|
|
@@ -16,7 +19,7 @@ def handle_exception(exc_type, exc_value, exc_traceback):
|
|
| 16 |
from app.utils.error_handling import translate_error
|
| 17 |
error_message = translate_error(str(exc_value))
|
| 18 |
log('error', f"未捕获的异常: {error_message}", status_code=500, error_message=error_message)
|
| 19 |
-
|
| 20 |
def schedule_cache_cleanup(response_cache_manager, active_requests_manager):
|
| 21 |
"""
|
| 22 |
设置定期清理缓存和活跃请求的定时任务
|
|
@@ -30,7 +33,45 @@ def schedule_cache_cleanup(response_cache_manager, active_requests_manager):
|
|
| 30 |
scheduler.add_job(active_requests_manager.clean_completed, 'interval', seconds=30) # 每30秒清理已完成的活跃请求
|
| 31 |
scheduler.add_job(active_requests_manager.clean_long_running, 'interval', minutes=5, args=[300]) # 每5分钟清理运行超过5分钟的任务
|
| 32 |
scheduler.add_job(clean_expired_stats, 'interval', minutes=5,args=[api_call_stats]) # 每5分钟清理过期的统计数据
|
| 33 |
-
scheduler.add_job(check_version, 'interval', minutes=
|
| 34 |
scheduler.start()
|
| 35 |
|
| 36 |
-
return scheduler
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys,asyncio
|
| 2 |
+
#from apscheduler.schedulers.background import BackgroundScheduler
|
| 3 |
+
from apscheduler.schedulers.asyncio import AsyncIOScheduler # 替换为异步调度器
|
| 4 |
from app.utils.logging import log
|
| 5 |
from app.utils.stats import clean_expired_stats
|
| 6 |
from app.config import api_call_stats
|
| 7 |
from app.utils import check_version
|
| 8 |
+
from zoneinfo import ZoneInfo
|
| 9 |
+
from app.config import settings
|
| 10 |
def handle_exception(exc_type, exc_value, exc_traceback):
|
| 11 |
"""
|
| 12 |
全局异常处理函数
|
|
|
|
| 19 |
from app.utils.error_handling import translate_error
|
| 20 |
error_message = translate_error(str(exc_value))
|
| 21 |
log('error', f"未捕获的异常: {error_message}", status_code=500, error_message=error_message)
|
| 22 |
+
'''
|
| 23 |
def schedule_cache_cleanup(response_cache_manager, active_requests_manager):
|
| 24 |
"""
|
| 25 |
设置定期清理缓存和活跃请求的定时任务
|
|
|
|
| 33 |
scheduler.add_job(active_requests_manager.clean_completed, 'interval', seconds=30) # 每30秒清理已完成的活跃请求
|
| 34 |
scheduler.add_job(active_requests_manager.clean_long_running, 'interval', minutes=5, args=[300]) # 每5分钟清理运行超过5分钟的任务
|
| 35 |
scheduler.add_job(clean_expired_stats, 'interval', minutes=5,args=[api_call_stats]) # 每5分钟清理过期的统计数据
|
| 36 |
+
scheduler.add_job(check_version, 'interval', minutes=1) # 每4小时检查更新
|
| 37 |
scheduler.start()
|
| 38 |
|
| 39 |
+
return scheduler
|
| 40 |
+
|
| 41 |
+
'''
|
| 42 |
+
def schedule_cache_cleanup(response_cache_manager, active_requests_manager):
|
| 43 |
+
"""
|
| 44 |
+
设置定期清理缓存和活跃请求的定时任务
|
| 45 |
+
顺便定时检查更新
|
| 46 |
+
Args:
|
| 47 |
+
response_cache_manager: 响应缓存管理器实例
|
| 48 |
+
active_requests_manager: 活跃请求管理器实例
|
| 49 |
+
"""
|
| 50 |
+
beijing_tz = ZoneInfo("Asia/Shanghai")
|
| 51 |
+
scheduler = AsyncIOScheduler(timezone=beijing_tz) # 使用 AsyncIOScheduler 替代 BackgroundScheduler
|
| 52 |
+
|
| 53 |
+
# 添加任务时直接传递异步函数(无需额外包装)
|
| 54 |
+
scheduler.add_job(response_cache_manager.clean_expired, 'interval', minutes=1)
|
| 55 |
+
scheduler.add_job(active_requests_manager.clean_completed, 'interval', seconds=30)
|
| 56 |
+
scheduler.add_job(active_requests_manager.clean_long_running, 'interval', minutes=5, args=[300])
|
| 57 |
+
scheduler.add_job(clean_expired_stats, 'interval', minutes=5, args=[api_call_stats])
|
| 58 |
+
scheduler.add_job(check_version, 'interval', hours=4)
|
| 59 |
+
scheduler.add_job(api_call_stats_clean, 'cron', hour=16,minute=0)
|
| 60 |
+
scheduler.start()
|
| 61 |
+
return scheduler
|
| 62 |
+
|
| 63 |
+
def api_call_stats_clean():
|
| 64 |
+
settings.api_call_stats = {
|
| 65 |
+
'last_24h': {
|
| 66 |
+
'total': {},
|
| 67 |
+
'by_endpoint': {}
|
| 68 |
+
},
|
| 69 |
+
'hourly': {
|
| 70 |
+
'total': {},
|
| 71 |
+
'by_endpoint': {}
|
| 72 |
+
},
|
| 73 |
+
'minute': {
|
| 74 |
+
'total': {},
|
| 75 |
+
'by_endpoint': {}
|
| 76 |
+
}
|
| 77 |
+
}
|
app/utils/version.py
CHANGED
|
@@ -13,18 +13,17 @@ async def check_version():
|
|
| 13 |
# 读取本地版本
|
| 14 |
with open("./version.txt", "r") as f:
|
| 15 |
version_line = f.read().strip()
|
| 16 |
-
settings.local_version = version_line.split("=")[1] if "=" in version_line else "0.0.0"
|
| 17 |
|
| 18 |
# 获取远程版本
|
| 19 |
github_url = "https://raw.githubusercontent.com/wyeeeee/hajimi/refs/heads/main/version.txt"
|
| 20 |
response = requests.get(github_url, timeout=5)
|
| 21 |
if response.status_code == 200:
|
| 22 |
version_line = response.text.strip()
|
| 23 |
-
settings.remote_version
|
| 24 |
-
|
| 25 |
# 比较版本号
|
| 26 |
-
local_parts = [int(x) for x in settings.local_version.split(".")]
|
| 27 |
-
remote_parts = [int(x) for x in settings.remote_version.split(".")]
|
| 28 |
|
| 29 |
# 确保两个列表长度相同
|
| 30 |
while len(local_parts) < len(remote_parts):
|
|
@@ -33,18 +32,18 @@ async def check_version():
|
|
| 33 |
remote_parts.append(0)
|
| 34 |
|
| 35 |
# 比较版本号
|
| 36 |
-
settings.has_update = False
|
| 37 |
for i in range(len(local_parts)):
|
| 38 |
if remote_parts[i] > local_parts[i]:
|
| 39 |
-
settings.has_update = True
|
| 40 |
break
|
| 41 |
elif remote_parts[i] < local_parts[i]:
|
| 42 |
break
|
| 43 |
|
| 44 |
-
log('info', f"版本检查: 本地版本 {settings.local_version}, 远程版本 {settings.remote_version}, 有更新: {settings.has_update}")
|
| 45 |
else:
|
| 46 |
log('warning', f"无法获取远程版本信息,HTTP状态码: {response.status_code}")
|
| 47 |
except Exception as e:
|
| 48 |
log('error', f"版本检查失败: {str(e)}")
|
| 49 |
|
| 50 |
-
return settings.
|
|
|
|
| 13 |
# 读取本地版本
|
| 14 |
with open("./version.txt", "r") as f:
|
| 15 |
version_line = f.read().strip()
|
| 16 |
+
settings.version['local_version'] = version_line.split("=")[1] if "=" in version_line else "0.0.0"
|
| 17 |
|
| 18 |
# 获取远程版本
|
| 19 |
github_url = "https://raw.githubusercontent.com/wyeeeee/hajimi/refs/heads/main/version.txt"
|
| 20 |
response = requests.get(github_url, timeout=5)
|
| 21 |
if response.status_code == 200:
|
| 22 |
version_line = response.text.strip()
|
| 23 |
+
settings.version['remote_version']= version_line.split("=")[1] if "=" in version_line else "0.0.0"
|
|
|
|
| 24 |
# 比较版本号
|
| 25 |
+
local_parts = [int(x) for x in settings.version['local_version'].split(".")]
|
| 26 |
+
remote_parts = [int(x) for x in settings.version['remote_version'].split(".")]
|
| 27 |
|
| 28 |
# 确保两个列表长度相同
|
| 29 |
while len(local_parts) < len(remote_parts):
|
|
|
|
| 32 |
remote_parts.append(0)
|
| 33 |
|
| 34 |
# 比较版本号
|
| 35 |
+
settings.version['has_update'] = False
|
| 36 |
for i in range(len(local_parts)):
|
| 37 |
if remote_parts[i] > local_parts[i]:
|
| 38 |
+
settings.version['has_update'] = True
|
| 39 |
break
|
| 40 |
elif remote_parts[i] < local_parts[i]:
|
| 41 |
break
|
| 42 |
|
| 43 |
+
log('info', f"版本检查: 本地版本 {settings.version['local_version']}, 远程版本 {settings.version['remote_version']}, 有更新: {settings.version['has_update']}")
|
| 44 |
else:
|
| 45 |
log('warning', f"无法获取远程版本信息,HTTP状态码: {response.status_code}")
|
| 46 |
except Exception as e:
|
| 47 |
log('error', f"版本检查失败: {str(e)}")
|
| 48 |
|
| 49 |
+
return settings.version['has_update']
|