This commit is contained in:
Manchik
2026-04-17 22:22:40 +03:00
commit c82866b58a
135 changed files with 18493 additions and 0 deletions
+78
View File
@@ -0,0 +1,78 @@
import random
import aiohttp
from aiohttp_socks import ProxyConnector
from loguru import logger
from app.database import get_db
def build_proxy_url(address: str, protocol: str) -> str:
"""Convert stored address to standard proxy URL (proto://login:pass@ip:port).
The frontend always normalizes addresses to login:pass@ip:port (or plain ip:port),
so we just prepend the scheme.
"""
if "://" in address:
return address
scheme = protocol if protocol in ("socks5", "socks4") else "http"
return f"{scheme}://{address}"
class ProxyManager:
def __init__(self) -> None:
self._proxies: list[dict] = []
self._index: int = 0
async def load(self) -> None:
db = await get_db()
cursor = await db.execute(
"SELECT * FROM proxies WHERE is_alive = 1 ORDER BY fail_count ASC"
)
self._proxies = [dict(r) for r in await cursor.fetchall()]
logger.info(f"Loaded {len(self._proxies)} alive proxies")
def get_next(self) -> dict | None:
if not self._proxies:
return None
proxy = self._proxies[self._index % len(self._proxies)]
self._index += 1
return proxy
def get_random(self) -> dict | None:
if not self._proxies:
return None
return random.choice(self._proxies)
def get_connector(self, proxy: dict | None = None) -> aiohttp.TCPConnector | ProxyConnector:
if proxy is None:
return aiohttp.TCPConnector()
url = build_proxy_url(proxy["address"], proxy.get("protocol", "http"))
return ProxyConnector.from_url(url, ssl=False)
async def mark_failed(self, proxy_id: int) -> None:
db = await get_db()
await db.execute(
"UPDATE proxies SET fail_count = fail_count + 1, last_checked = datetime('now') WHERE id = ?",
(proxy_id,),
)
await db.execute(
"UPDATE proxies SET is_alive = 0 WHERE id = ? AND fail_count >= 5",
(proxy_id,),
)
await db.commit()
async def mark_alive(self, proxy_id: int) -> None:
db = await get_db()
await db.execute(
"UPDATE proxies SET fail_count = 0, is_alive = 1, last_checked = datetime('now') WHERE id = ?",
(proxy_id,),
)
await db.commit()
@property
def count(self) -> int:
return len(self._proxies)
proxy_manager = ProxyManager()