feat: fpw plugins, validation/crawl perf, WS stats, test DB isolation
- Add Free_Proxy_Website-style fpw_* plugins and register them - Per-plugin crawl timeout (crawl_timeout_seconds=120); remove global crawl_timeout setting - Validator: fix connect vs total timeout on save; SOCKS session LRU cache; drop redundant semaphore - Validation handler uses single DB connection; batch upsert after crawl; WorkerPool put_nowait - Remove unused max_retries from settings API/UI; settings maintenance SQL + init_db cleanup of deprecated keys - WebSocket dashboard stats; ProxyList pool_filter and API alignment - POST /api/proxies/delete-one for IPv6-safe deletes; task poll stops on 404 - pytest uses PROXYPOOL_DB_PATH=db/proxies.test.sqlite so tests do not wipe production DB - .gitignore: explicit proxies.test.sqlite patterns; fix plugin_service ValidationException import Made-with: Cursor
This commit is contained in:
@@ -5,7 +5,8 @@ from fastapi.responses import StreamingResponse
|
||||
|
||||
from app.services.proxy_service import ProxyService
|
||||
from app.services.scheduler_service import SchedulerService
|
||||
from app.models.schemas import ProxyListRequest, BatchDeleteRequest
|
||||
from app.services.dashboard_stats import get_dashboard_stats
|
||||
from app.models.schemas import ProxyListRequest, BatchDeleteRequest, ProxyDeleteItem
|
||||
from app.api.deps import get_proxy_service, get_scheduler_service
|
||||
from app.api.common import success_response, format_proxy
|
||||
from app.core.exceptions import ProxyPoolException, ProxyNotFoundException
|
||||
@@ -15,11 +16,9 @@ router = APIRouter(prefix="/api/proxies", tags=["proxies"])
|
||||
|
||||
@router.get("/stats")
|
||||
async def get_stats(
|
||||
proxy_service: ProxyService = Depends(get_proxy_service),
|
||||
scheduler_service: SchedulerService = Depends(get_scheduler_service),
|
||||
):
|
||||
stats = await proxy_service.get_stats()
|
||||
stats["scheduler_running"] = scheduler_service.running
|
||||
stats = await get_dashboard_stats(scheduler_service.running)
|
||||
return success_response("获取统计信息成功", stats)
|
||||
|
||||
|
||||
@@ -36,6 +35,7 @@ async def list_proxies(
|
||||
max_score=request.max_score,
|
||||
sort_by=request.sort_by,
|
||||
sort_order=request.sort_order,
|
||||
pool_filter=request.pool_filter,
|
||||
)
|
||||
return success_response(
|
||||
"获取代理列表成功",
|
||||
@@ -75,6 +75,16 @@ async def export_proxies(
|
||||
)
|
||||
|
||||
|
||||
@router.post("/delete-one")
|
||||
async def delete_proxy_one(
|
||||
item: ProxyDeleteItem,
|
||||
service: ProxyService = Depends(get_proxy_service),
|
||||
):
|
||||
"""JSON 删除(推荐):IPv6 等含冒号 IP 不受路径分段影响。"""
|
||||
await service.delete_proxy(item.ip, item.port)
|
||||
return success_response("删除代理成功")
|
||||
|
||||
|
||||
@router.delete("/{ip}/{port}")
|
||||
async def delete_proxy(ip: str, port: int, service: ProxyService = Depends(get_proxy_service)):
|
||||
await service.delete_proxy(ip, port)
|
||||
|
||||
Reference in New Issue
Block a user