清理项目冗余文件与死代码

删除内容:
- config.py:旧架构配置残留,已被 core/config.py 替代
- README_SOCKS.md:内容严重过时(引用已删除的 api_server.py 和测试脚本),功能说明已合并至 README
- frontend/src/api/types.js:纯 JSDoc typedef,未被任何模块引用,属于死文档
- frontend/src/assets/vue.svg:默认模板资源,项目中无任何页面引用
- frontend/src/utils/clipboard.js:移除 copyTextFallback 函数(使用已废弃的 document.execCommand)
This commit is contained in:
祀梦
2026-04-02 12:18:58 +08:00
parent 96bac1a7c1
commit 33a038367d
5 changed files with 0 additions and 239 deletions

View File

@@ -1,89 +0,0 @@
# SOCKS 代理支持说明
## 更新内容
已成功为代理池系统添加 SOCKS4/SOCKS5 代理验证支持!
## 技术实现
### 1. 新增依赖
```
aiohttp-socks==0.9.1
```
### 2. 验证器升级 (`core/validator.py`)
- 新增 `ProxyValidator` 类,完整支持 HTTP/HTTPS/SOCKS4/SOCKS5
- SOCKS 代理使用 `aiohttp_socks.ProxyConnector` 进行验证
- 支持远程 DNS 解析 (rdns=True),避免 DNS 泄漏
### 3. 协议识别
以下插件已更新支持 SOCKS 协议:
| 插件 | 支持协议 |
|-----|---------|
| Fate0聚合源 | HTTP, HTTPS, SOCKS4, SOCKS5 |
| SpeedX代理源 | HTTP, SOCKS4, SOCKS5 |
| ProxyListDownload | HTTP, HTTPS, SOCKS4, SOCKS5 |
| 快代理 | HTTP, HTTPS |
| IP3366 | HTTP, HTTPS |
| 89免费代理 | HTTP |
| 云代理 | HTTP, HTTPS |
## 使用说明
### 启动服务
```bash
# 安装依赖
pip install -r requirements.txt
# 启动后端
python api_server.py
# 启动前端
cd frontend && npm run dev
```
### 抓取 SOCKS 代理
1. 打开 WebUI (http://localhost:9948)
2. 进入"插件管理"页面
3. 点击 SpeedX 或 ProxyListDownload 插件的"立即爬取"
4. 系统自动识别 SOCKS 代理并进行验证
### 查看 SOCKS 代理
1. 进入"代理列表"页面
2. 使用协议筛选器选择 SOCKS4 或 SOCKS5
3. 查看验证结果和延迟
## 验证流程
```
+-------------+ +------------------+ +-----------------+
| 插件爬取 | --> | 识别协议类型 | --> | SOCKS验证器 |
+-------------+ +------------------+ +-----------------+
|
v
+-------------+ +------------------+ +-----------------+
| 存储结果 | <-- | 评分更新 | <-- | 延迟测试 |
+-------------+ +------------------+ +-----------------+
```
## SOCKS 验证特点
1. **连接器类型**: 使用 `ProxyConnector` 替代 `TCPConnector`
2. **DNS 解析**: 远程解析避免泄漏真实 IP
3. **协议区分**: 明确区分 SOCKS4 和 SOCKS5
4. **统一接口**: 与 HTTP/HTTPS 代理使用相同的验证接口
## 测试
运行测试脚本验证 SOCKS 支持:
```bash
python test_socks_validator.py
python test_plugins_socks.py
```
## 注意事项
1. SOCKS 代理验证比 HTTP 代理稍慢,因为有额外的握手过程
2. 部分 SOCKS 代理可能只支持 TCP 而不支持 UDP
3. SOCKS5 支持认证,当前版本使用无认证模式

View File

@@ -1,70 +0,0 @@
"""
代理池系统配置管理
统一管理所有配置项,支持环境变量覆盖
"""
import os
from typing import Optional
class Config:
# 数据库配置
DB_PATH: str = os.getenv("DB_PATH", "db/proxies.db")
# API服务配置
HOST: str = os.getenv("HOST", "0.0.0.0")
PORT: int = int(os.getenv("PORT", "9949"))
# 验证器配置
VALIDATOR_TIMEOUT: int = int(os.getenv("VALIDATOR_TIMEOUT", "5"))
VALIDATOR_MAX_CONCURRENCY: int = int(os.getenv("VALIDATOR_MAX_CONCURRENCY", "200"))
VALIDATOR_CONNECT_TIMEOUT: int = int(os.getenv("VALIDATOR_CONNECT_TIMEOUT", "3"))
# 爬虫配置
CRAWLER_NUM_VALIDATORS: int = int(os.getenv("CRAWLER_NUM_VALIDATORS", "50"))
CRAWLER_MAX_QUEUE_SIZE: int = int(os.getenv("CRAWLER_MAX_QUEUE_SIZE", "500"))
# 定时任务配置
SCHEDULER_INTERVAL_MINUTES: int = int(os.getenv("SCHEDULER_INTERVAL_MINUTES", "60"))
SCHEDULER_ENABLED: bool = os.getenv("SCHEDULER_ENABLED", "true").lower() == "true"
# 日志配置
LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO")
LOG_DIR: str = os.getenv("LOG_DIR", "logs")
# 导出配置
EXPORT_MAX_RECORDS: int = int(os.getenv("EXPORT_MAX_RECORDS", "10000"))
# 代理评分配置
SCORE_VALID: int = int(os.getenv("SCORE_VALID", "10"))
SCORE_INVALID: int = int(os.getenv("SCORE_INVALID", "-5"))
SCORE_MIN: int = int(os.getenv("SCORE_MIN", "0"))
SCORE_MAX: int = int(os.getenv("SCORE_MAX", "100"))
# WebSocket配置
WS_PING_INTERVAL: int = int(os.getenv("WS_PING_INTERVAL", "20"))
WS_PING_TIMEOUT: int = int(os.getenv("WS_PING_TIMEOUT", "20"))
# 插件配置
PLUGINS_DIR: str = os.getenv("PLUGINS_DIR", "plugins")
# CORS配置
CORS_ORIGINS: str = os.getenv("CORS_ORIGINS", "http://localhost:8080,http://localhost:5173")
@classmethod
def get(cls, key: str, default=None):
"""获取配置项"""
return getattr(cls, key, default)
@classmethod
def set(cls, key: str, value):
"""设置配置项(仅限运行时)"""
setattr(cls, key, value)
@classmethod
def update(cls, updates: dict):
"""批量更新配置"""
for key, value in updates.items():
if hasattr(cls, key):
setattr(cls, key, value)
# 全局配置实例
config = Config()

View File

@@ -1,57 +0,0 @@
/**
* @typedef {object} ApiResponse<T>
* @property {number} code
* @property {string} message
* @property {T} data
*/
/**
* @typedef {object} StatsData
* @property {number} total
* @property {number} available
* @property {number} today_new
* @property {number} avg_score
* @property {number} http_count
* @property {number} https_count
* @property {number} socks4_count
* @property {number} socks5_count
*/
/**
* @typedef {object} Proxy
* @property {string} ip
* @property {number} port
* @property {string} protocol
* @property {number} score
* @property {string} last_check
*/
/**
* @typedef {object} ProxyListData
* @property {Proxy[]} list
* @property {number} total
*/
/**
* @typedef {object} Plugin
* @property {string|number} id
* @property {string} name
* @property {string} description
* @property {boolean} enabled
* @property {number} success_count
* @property {number} failure_count
* @property {string|null} last_run
*/
/**
* @typedef {object} SettingsData
* @property {string} db_path
* @property {number} crawl_timeout
* @property {number} validation_timeout
* @property {number} max_retries
* @property {number} default_concurrency
* @property {number} min_proxy_score
* @property {number} proxy_expiry_days
*/
export {}

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

Before

Width:  |  Height:  |  Size: 496 B

View File

@@ -39,25 +39,3 @@ export async function copyProxy(proxy) {
return copyToClipboard(text) return copyToClipboard(text)
} }
/**
* 复制文本(备选方案:使用 DOM
* @param {string} text
* @returns {boolean}
*/
export function copyTextFallback(text) {
const textarea = document.createElement('textarea')
textarea.value = text
textarea.style.cssText = 'position:fixed;left:-9999px;opacity:0;'
document.body.appendChild(textarea)
try {
textarea.select()
textarea.setSelectionRange(0, text.length)
const success = document.execCommand('copy')
document.body.removeChild(textarea)
return success
} catch {
document.body.removeChild(textarea)
return false
}
}