初步增加 web 界面
This commit is contained in:
+71
-20
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user