diff --git a/aggregator.py b/aggregator.py index b3c3457..b35c43e 100644 --- a/aggregator.py +++ b/aggregator.py @@ -1034,6 +1034,44 @@ h1{{font-size:24px}} @app.get("/") async def home_page(): title = settings.get("general", {}).get("title", "ZernProxy") + da_url = settings.get("payments", {}).get("donationalerts", {}).get("url", "") + + conn = get_db() + try: + total = conn.execute("SELECT COUNT(*) as c FROM users").fetchone()["c"] + finally: + conn.close() + + statuses = await fetch_servers_status() + + servers_html = "" + for s in statuses: + chk = s.get("checks", {}) + cpu = chk.get("CPU", {}).get("value") + ram = chk.get("RAM", {}).get("value") + disk = chk.get("Disk /", {}).get("value") + net_raw = chk.get("Net ↓↑", {}).get("value", "") + server_name = s.get("server_name", s["name"].upper()) + + service_icons = "" + for key in ("Caddy", "Minecraft", "Bio site", "Main site", "3x-UI"): + val = chk.get(key, {}).get("value", "") + if val: + dot = "🟢" if "🟢" in val else ("🔴" if "🔴" in val or "🔴" in str(val) else ("🟡" if "🟡" in val else "")) + service_icons += f'{dot or "●"}' + + servers_html += f''' +
+
{get_flag_emoji(s.get("country",""))} {server_name}
+
+
CPU
{f"{cpu:.1f}%" if cpu is not None else "—"}
+
RAM
{f"{ram:.1f}%" if ram is not None else "—"}
+
DISK
{f"{disk:.1f}%" if disk is not None else "—"}
+
NET
{net_raw}
+
+ {f'
{service_icons}
' if service_icons else ''} +
''' + return HTMLResponse(content=f''' @@ -1043,39 +1081,90 @@ async def home_page():
- -

{title}

-

Быстрый и надёжный VPN. Подписка на основе подписки. Безлимитный трафик на всех тарифах.

-
-
🆓

Free

Базовый доступ к серверам. Безлимитный трафик.

-
🧪

Test 7 дней

Пробный период за 50₽. 5GB трафика.

-

Premium

Полный доступ, приоритетные серверы. От 150₽/мес.

+
+

⚡ {title}

+

Быстрый и надёжный VPN-сервис

-
-👤 Панель управления -❤️ Поддержать проект +
+
{total}
👥 Клиентов
+
{len(servers)}
🌍 Локаций
- +
{servers_html}
+
+

🔧 Технические детали

+

+🔒 Шифрование: VLESS + XTLS Vision / Reality
+ Протоколы: TCP, WebSocket, gRPC
+🛡️ DDoS-защита на всех серверах
+📡 Каналы: 1-10 Gbit/s
+🔐 Zero-log политика — трафик не логируется
+🌐 Поддержка Happ (iOS/Android/Desktop) +

+
+ +
''') + +async def fetch_servers_status() -> list: + results = [] + async with httpx.AsyncClient(timeout=8.0, verify=False) as client: + for srv in servers: + url = srv.get("status_url", "") + entry = {"name": srv["name"], "country": srv.get("country",""), "checks": {}} + if not url: + results.append(entry) + continue + try: + resp = await client.get(url) + if resp.status_code == 200: + data = resp.json() + entry["server_name"] = data.get("server_name", "") + entry["checks"] = data.get("checks", {}) + else: + entry["checks"]["error"] = {"value": f"HTTP {resp.status_code}"} + except Exception as e: + entry["checks"]["error"] = {"value": str(e)[:50]} + results.append(entry) + return results + @app.get("/webhook/tg") async def tg_webhook(): bot_cfg = settings.get("bot", {})