Files
ProxyPool/app/models/domain.py
祀梦 7bc6d4e4de feat: JSON 配置、质量分与仪表盘,及设置与爬取流程
- 后端改为 config/app.json;pytest 使用 config/app.test.json 与 set_config_file,不再依赖环境变量;移除 pydantic-settings。

- 前端 API/WebSocket 由 config/webui.json 经 Vite define 注入。

- 代理分数按延迟与随机取用次数计算,新增 use_count 与 proxy_scoring;保存设置时同步调度器启停。

- 仪表盘双饼图(可用/待验证协议);设置页去掉调度器启停按钮并移动立即验证;爬取全部结束后自动提交全量验证。

- 删除 script/settings_maintain.py(此前已标记删除)。

Made-with: Cursor
2026-04-05 16:08:32 +08:00

63 lines
1.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""领域模型 - 纯数据结构,不依赖任何框架"""
from dataclasses import dataclass, field
from datetime import datetime
from typing import List, Optional
@dataclass
class ProxyRaw:
"""爬虫爬取的原始代理数据"""
ip: str
port: int
protocol: str = "http"
def __post_init__(self):
self.protocol = self.protocol.lower().strip()
if self.protocol not in ("http", "https", "socks4", "socks5"):
self.protocol = "http"
if not isinstance(self.port, int) or not (1 <= self.port <= 65535):
raise ValueError(f"port must be between 1 and 65535, got {self.port}")
@dataclass
class Proxy:
"""数据库中的代理实体"""
ip: str
port: int
protocol: str
score: int
response_time_ms: Optional[float] = None
last_check: Optional[datetime] = None
created_at: Optional[datetime] = None
validated: int = 0 # 0 待验证 1 已验证(可参与分数与对外取用)
use_count: int = 0 # 被随机 API 取用的累计次数(用于降权)
@dataclass
class PluginInfo:
"""插件元数据"""
id: str
name: str
display_name: str
description: str
enabled: bool
last_run: Optional[datetime] = None
success_count: int = 0
failure_count: int = 0
@dataclass
class CrawlResult:
"""插件爬取结果
success_count: 最近一轮成功爬取到的代理条数(去重后),非「验证通过数」
failure_count: 最近一轮是否爬取失败(健康检查/超时/异常为 1否则为 0
"""
plugin_name: str
proxies: List[ProxyRaw] = field(default_factory=list)
success_count: int = 0
failure_count: int = 0
error: Optional[str] = None