forked from FOSS/Steam-Panel
124 lines
3.8 KiB
Python
124 lines
3.8 KiB
Python
import asyncio
|
|
|
|
from fastapi import APIRouter, HTTPException
|
|
from loguru import logger
|
|
|
|
from app.database import get_db
|
|
from app.models import ProxyCreate, ProxyOut
|
|
|
|
router = APIRouter(prefix="/api/proxies", tags=["proxies"])
|
|
|
|
|
|
@router.get("", response_model=list[ProxyOut])
|
|
async def list_proxies():
|
|
db = await get_db()
|
|
cursor = await db.execute("SELECT * FROM proxies ORDER BY id")
|
|
rows = await cursor.fetchall()
|
|
return [dict(r) for r in rows]
|
|
|
|
|
|
@router.post("", response_model=ProxyOut, status_code=201)
|
|
async def add_proxy(proxy: ProxyCreate):
|
|
db = await get_db()
|
|
try:
|
|
cursor = await db.execute(
|
|
"INSERT INTO proxies (address, protocol) VALUES (?, ?)",
|
|
(proxy.address, proxy.protocol),
|
|
)
|
|
await db.commit()
|
|
except Exception:
|
|
raise HTTPException(status_code=409, detail="Proxy already exists")
|
|
|
|
new_cursor = await db.execute(
|
|
"SELECT * FROM proxies WHERE id = ?", (cursor.lastrowid,)
|
|
)
|
|
return dict(await new_cursor.fetchone())
|
|
|
|
|
|
@router.delete("/all", status_code=200)
|
|
async def delete_all_proxies():
|
|
db = await get_db()
|
|
cursor = await db.execute("SELECT COUNT(*) as cnt FROM proxies")
|
|
row = await cursor.fetchone()
|
|
count = row["cnt"]
|
|
await db.execute("DELETE FROM proxies")
|
|
await db.commit()
|
|
from app.core.proxy_manager import proxy_manager
|
|
await proxy_manager.load()
|
|
logger.info(f"Deleted all {count} proxies")
|
|
return {"deleted": count}
|
|
|
|
|
|
@router.delete("/{proxy_id}", status_code=204)
|
|
async def delete_proxy(proxy_id: int):
|
|
db = await get_db()
|
|
result = await db.execute("DELETE FROM proxies WHERE id = ?", (proxy_id,))
|
|
await db.commit()
|
|
if result.rowcount == 0:
|
|
raise HTTPException(status_code=404, detail="Proxy not found")
|
|
|
|
|
|
@router.post("/bulk")
|
|
async def bulk_add_proxies(proxies: list[ProxyCreate]):
|
|
db = await get_db()
|
|
added = 0
|
|
for p in proxies:
|
|
try:
|
|
await db.execute(
|
|
"INSERT OR IGNORE INTO proxies (address, protocol) VALUES (?, ?)",
|
|
(p.address, p.protocol),
|
|
)
|
|
added += 1
|
|
except Exception:
|
|
pass
|
|
await db.commit()
|
|
logger.info(f"Bulk added {added} proxies")
|
|
return {"added": added}
|
|
|
|
|
|
async def _check_one_proxy(proxy_id: int, address: str, protocol: str) -> dict:
|
|
"""Check proxy by making a real HTTP request through it."""
|
|
import aiohttp
|
|
from aiohttp_socks import ProxyConnector
|
|
from app.core.proxy_manager import build_proxy_url
|
|
|
|
try:
|
|
proxy_url = build_proxy_url(address, protocol)
|
|
connector = ProxyConnector.from_url(proxy_url, ssl=False)
|
|
|
|
async with aiohttp.ClientSession(connector=connector) as session:
|
|
async with session.get(
|
|
"https://steamcommunity.com/robots.txt",
|
|
timeout=aiohttp.ClientTimeout(total=3),
|
|
) as resp:
|
|
alive = resp.status == 200
|
|
except Exception:
|
|
alive = False
|
|
|
|
db = await get_db()
|
|
await db.execute(
|
|
"UPDATE proxies SET is_alive = ?, last_checked = datetime('now') WHERE id = ?",
|
|
(int(alive), proxy_id),
|
|
)
|
|
await db.commit()
|
|
return {"id": proxy_id, "alive": alive}
|
|
|
|
|
|
@router.post("/check")
|
|
async def check_proxies():
|
|
db = await get_db()
|
|
cursor = await db.execute("SELECT id, address, protocol FROM proxies ORDER BY id")
|
|
rows = await cursor.fetchall()
|
|
if not rows:
|
|
return {"total": 0, "alive": 0, "dead": 0}
|
|
|
|
sem = asyncio.Semaphore(300)
|
|
|
|
async def limited(row):
|
|
async with sem:
|
|
return await _check_one_proxy(row["id"], row["address"], row["protocol"])
|
|
|
|
results = await asyncio.gather(*(limited(r) for r in rows))
|
|
alive_count = sum(1 for r in results if r["alive"])
|
|
return {"total": len(results), "alive": alive_count, "dead": len(results) - alive_count}
|