forked from carrydela/autoClaude
feat: Add core mail service and proxy pool modules, and integrate them into the bot.
This commit is contained in:
@@ -8,14 +8,18 @@
|
||||
- 线程安全
|
||||
"""
|
||||
|
||||
import logging
|
||||
import random
|
||||
import threading
|
||||
import time
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
from typing import Callable, Optional
|
||||
|
||||
import requests as std_requests
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# --- 配置常量 ---
|
||||
_PROJECT_ROOT = Path(__file__).parent.parent
|
||||
@@ -184,6 +188,7 @@ class ProxyPool:
|
||||
|
||||
def test_one(self, proxy: Proxy) -> dict:
|
||||
"""测试单个代理,返回结果 dict"""
|
||||
logger.info(f"🔍 测试代理: {proxy.masked_url}")
|
||||
proxies = {"http": proxy.url, "https": proxy.url}
|
||||
try:
|
||||
start = time.time()
|
||||
@@ -202,11 +207,13 @@ class ProxyPool:
|
||||
proxy.last_test_ok = True
|
||||
proxy.success_count += 1
|
||||
proxy.priority = min(proxy.priority + _SUCCESS_BONUS, _MAX_PRIORITY)
|
||||
logger.info(f" ✅ 通过 {proxy.masked_url} | {round(latency)}ms | HTTP {resp.status_code}")
|
||||
return {"ok": True, "latency_ms": round(latency), "status": resp.status_code}
|
||||
else:
|
||||
proxy.last_test_ok = False
|
||||
proxy.fail_count += 1
|
||||
proxy.priority -= _FAIL_PENALTY
|
||||
logger.warning(f" ❌ 失败 {proxy.masked_url} | HTTP {resp.status_code}")
|
||||
return {"ok": False, "latency_ms": round(latency), "error": f"HTTP {resp.status_code}"}
|
||||
|
||||
except std_requests.exceptions.ConnectTimeout:
|
||||
@@ -214,35 +221,58 @@ class ProxyPool:
|
||||
proxy.fail_count += 1
|
||||
proxy.priority -= _FAIL_PENALTY
|
||||
proxy.last_test_time = time.time()
|
||||
logger.warning(f" ❌ 超时 {proxy.masked_url}")
|
||||
return {"ok": False, "latency_ms": -1, "error": "连接超时"}
|
||||
except std_requests.exceptions.ProxyError as e:
|
||||
proxy.last_test_ok = False
|
||||
proxy.fail_count += 1
|
||||
proxy.priority -= _FAIL_PENALTY
|
||||
proxy.last_test_time = time.time()
|
||||
logger.warning(f" ❌ 代理错误 {proxy.masked_url}: {e}")
|
||||
return {"ok": False, "latency_ms": -1, "error": f"代理错误: {e}"}
|
||||
except Exception as e:
|
||||
proxy.last_test_ok = False
|
||||
proxy.fail_count += 1
|
||||
proxy.priority -= _FAIL_PENALTY
|
||||
proxy.last_test_time = time.time()
|
||||
logger.warning(f" ❌ 异常 {proxy.masked_url}: {e}")
|
||||
return {"ok": False, "latency_ms": -1, "error": str(e)}
|
||||
|
||||
def test_all(self) -> list[dict]:
|
||||
def test_all(self, progress_callback: Optional[Callable] = None) -> list[dict]:
|
||||
"""
|
||||
测试所有代理,返回结果列表。
|
||||
测试后自动清理优先级过低的代理。
|
||||
|
||||
Args:
|
||||
progress_callback: 可选回调函数,签名 (current, total, result_dict) -> None
|
||||
每测完一个代理后调用,用于更新前端进度。
|
||||
"""
|
||||
results = []
|
||||
with self._lock:
|
||||
proxies_snapshot = list(self._proxies)
|
||||
|
||||
for proxy in proxies_snapshot:
|
||||
total = len(proxies_snapshot)
|
||||
logger.info(f"📡 开始批量测试 {total} 个代理...")
|
||||
|
||||
for i, proxy in enumerate(proxies_snapshot, 1):
|
||||
result = self.test_one(proxy)
|
||||
result["proxy"] = proxy.masked_url
|
||||
result["priority"] = proxy.priority
|
||||
results.append(result)
|
||||
|
||||
if progress_callback:
|
||||
try:
|
||||
progress_callback(i, total, result)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
ok_count = sum(1 for r in results if r["ok"])
|
||||
fail_count = total - ok_count
|
||||
logger.info(
|
||||
f"📡 代理测试完成: ✅ 通过 {ok_count} | ❌ 失败 {fail_count} | "
|
||||
f"剩余可用 {self.active_count}"
|
||||
)
|
||||
|
||||
with self._lock:
|
||||
self._cleanup()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user