初步增加 web 界面

This commit is contained in:
yml2213
2026-06-22 13:11:15 +08:00
parent 4c924375aa
commit 347edb8103
66 changed files with 6816 additions and 21 deletions
+71 -20
View File
@@ -3,6 +3,7 @@
import json
import re
import threading
import time
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
from datetime import datetime
@@ -566,17 +567,15 @@ class DouyuLoginApp:
self.whitelist_status_var.set(status)
self.whitelist_test_btn.configure(state='normal' if enabled else 'disabled')
@staticmethod
def _get_exit_ip_for_test(proxy_config: ProxyConfig) -> Optional[str]:
def _get_exit_ip_for_test(self, proxy_config: ProxyConfig) -> Optional[str]:
"""获取出口IP用于白名单测试"""
proxy_url = None
if proxy_config.enabled:
if proxy_config.api_url:
try:
resp = requests.get(proxy_config.api_url, timeout=10)
match = re.search(r'(\d+\.\d+\.\d+\.\d+):(\d+)', resp.text)
if match:
proxy_url = f"http://{match.group(1)}:{match.group(2)}"
resp.raise_for_status()
proxy_url = DouyuLoginApp._parse_proxy_url(resp.text.strip())
except Exception:
pass
if not proxy_url:
@@ -755,15 +754,37 @@ class DouyuLoginApp:
self.proxy_test_queue.put(result)
@staticmethod
def _fetch_proxy_from_api(api_url: str) -> str:
"""从代理API获取一个代理地址。"""
response = requests.get(api_url, timeout=10)
response.raise_for_status()
text = response.text.strip()
def _parse_proxy_url(text: str) -> str:
"""从代理API响应中解析代理地址。"""
# ip:port 格式
match = re.search(r'(\d+\.\d+\.\d+\.\d+):(\d+)', text)
if not match:
return ''
return f'http://{match.group(1)}:{match.group(2)}'
if match:
return f'http://{match.group(1)}:{match.group(2)}'
# JSON 格式: {"ip": "...", "port": ...} 等
try:
data = json.loads(text) if text else {}
if isinstance(data, dict):
ip = data.get('ip') or data.get('host') or data.get('proxy')
port = data.get('port')
if ip and port:
return f'http://{ip}:{port}'
if ip:
match = re.search(r'(\d+\.\d+\.\d+\.\d+):?(\d+)?', str(ip))
if match:
return f'http://{match.group(1)}:{match.group(2) or "80"}'
except Exception:
pass
return ''
@staticmethod
def _extract_whitelist_ip_from_error(text: str) -> Optional[str]:
"""从代理API白名单错误消息中提取需要添加的IP。"""
if '添加白名单' in text or '白名单' in text:
match = re.search(r'(\d+\.\d+\.\d+\.\d+)', text)
if match:
return match.group(1)
return None
@staticmethod
def _extract_origin_ip(response: requests.Response) -> str:
@@ -795,7 +816,7 @@ class DouyuLoginApp:
'http': proxy_config.http or proxy_url,
'https': proxy_config.https or proxy_url,
}
last_error = ''
errors = []
for name, url in PROXY_TEST_TARGETS:
try:
@@ -809,28 +830,58 @@ class DouyuLoginApp:
origin = DouyuLoginApp._extract_origin_ip(response)
return True, f'代理可用,出口IP: {origin}{name}'
except Exception as exc:
last_error = f'{name} 验证失败: {exc}'
err_msg = str(exc)
if 'Tunnel connection failed' in err_msg or '503' in err_msg:
detail = '代理拒绝连接(白名单可能未生效)'
elif 'timed out' in err_msg.lower():
detail = '连接超时'
else:
detail = type(exc).__name__
errors.append(f'{name}: {detail}')
return False, last_error or '代理验证失败'
return False, '; '.join(errors) or '代理验证失败'
def _resolve_working_proxy_config(self, proxy_config: ProxyConfig) -> dict:
"""获取并验证可用代理,成功后返回可用于登录的代理配置。"""
attempts = PROXY_API_TEST_ATTEMPTS if proxy_config.api_url else PROXY_STATIC_TEST_ATTEMPTS
last_message = ''
synced_whitelist = False
for attempt in range(1, attempts + 1):
proxy_url = proxy_config.http or proxy_config.https
if proxy_config.api_url:
self.log_queue.put(('info', f'代理预检 {attempt}/{attempts}: 正在获取代理'))
try:
proxy_url = self._fetch_proxy_from_api(proxy_config.api_url)
response = requests.get(proxy_config.api_url, timeout=10)
response.raise_for_status()
text = response.text.strip()
proxy_url = self._parse_proxy_url(text)
# 代理API返回了白名单错误,提取需要添加的IP
if not proxy_url and not synced_whitelist and proxy_config.whitelist_enabled:
whitelist_ip = self._extract_whitelist_ip_from_error(text)
if whitelist_ip:
self.log_queue.put(
('warning', f'代理需要白名单IP: {whitelist_ip},自动同步...'))
manager = WhitelistManager(
proxy_config.whitelist_uid, proxy_config.whitelist_ukey)
ok, msg = manager.sync_ip(whitelist_ip)
self.log_queue.put(
('success' if ok else 'error', f'白名单同步: {msg}'))
if ok:
synced_whitelist = True
self.log_queue.put(('info', '白名单已更新,等待2秒后重试获取代理...'))
time.sleep(2)
continue
last_message = f'白名单同步失败: {msg}'
else:
last_message = f'代理API响应无法解析: {text[:60]}'
elif not proxy_url:
last_message = f'代理API响应无法解析: {text[:60]}'
except Exception as exc:
last_message = f'代理API请求失败: {exc}'
self.log_queue.put(('warning', f'代理预检 {attempt}/{attempts}: {last_message}'))
continue
if not proxy_url:
last_message = '代理API未返回有效的 ip:port'
self.log_queue.put(('warning', f'代理预检 {attempt}/{attempts}: {last_message}'))
continue
else: