remove table connections/token and cookies 3x-ui/bug fixes
This commit is contained in:
+44
-65
@@ -3,8 +3,17 @@ from typing import Any
|
||||
|
||||
import httpx
|
||||
import py3xui
|
||||
from py3xui import AsyncApi
|
||||
import time
|
||||
|
||||
from config import LIMIT_IP, SUPERNODE
|
||||
from config import (
|
||||
LIMIT_IP,
|
||||
SUPERNODE,
|
||||
XUI_TOKEN,
|
||||
USE_XUI_TOKEN,
|
||||
ADMIN_PASSWORD,
|
||||
ADMIN_USERNAME,
|
||||
)
|
||||
from logger import logger
|
||||
|
||||
|
||||
@@ -24,20 +33,38 @@ class ClientConfig:
|
||||
sub_id: str
|
||||
|
||||
|
||||
_xui_instance_cache: dict[str, tuple[AsyncApi, float]] = {}
|
||||
SESSION_TTL = 1800
|
||||
|
||||
async def get_xui_instance(api_url: str) -> AsyncApi:
|
||||
key = f"{api_url}|{ADMIN_USERNAME}"
|
||||
current_time = time.time()
|
||||
|
||||
xui_entry = _xui_instance_cache.get(key)
|
||||
if xui_entry:
|
||||
xui, last_login = xui_entry
|
||||
if current_time - last_login < SESSION_TTL:
|
||||
return xui
|
||||
else:
|
||||
logger.info(f"[XUI Cache] Сессия устарела (>30 минут), переподключение...")
|
||||
await xui.login()
|
||||
_xui_instance_cache[key] = (xui, current_time)
|
||||
return xui
|
||||
|
||||
xui = AsyncApi(
|
||||
api_url,
|
||||
ADMIN_USERNAME,
|
||||
ADMIN_PASSWORD,
|
||||
token=XUI_TOKEN if USE_XUI_TOKEN else None,
|
||||
logger=logger,
|
||||
)
|
||||
await xui.login()
|
||||
_xui_instance_cache[key] = (xui, current_time)
|
||||
return xui
|
||||
|
||||
|
||||
async def add_client(xui: py3xui.AsyncApi, config: ClientConfig) -> dict[str, Any]:
|
||||
"""
|
||||
Добавляет клиента на сервер через 3x-ui.
|
||||
|
||||
Args:
|
||||
xui: Экземпляр API клиента
|
||||
config: Конфигурация клиента
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: Результат операции в формате
|
||||
{'status': 'success'|'failed'|'duplicate', 'error': str, 'email': str}
|
||||
"""
|
||||
try:
|
||||
await xui.login()
|
||||
|
||||
client = py3xui.Client(
|
||||
id=config.client_id,
|
||||
@@ -53,7 +80,6 @@ async def add_client(xui: py3xui.AsyncApi, config: ClientConfig) -> dict[str, An
|
||||
|
||||
response = await xui.client.add(config.inbound_id, [client])
|
||||
logger.info(f"Клиент {config.email} успешно добавлен с ID {config.client_id}")
|
||||
|
||||
return response if response else {"status": "failed"}
|
||||
|
||||
except httpx.ConnectTimeout as e:
|
||||
@@ -80,31 +106,11 @@ async def extend_client_key(
|
||||
sub_id: str,
|
||||
tg_id: int,
|
||||
) -> bool | None:
|
||||
"""
|
||||
Обновляет срок действия ключа клиента.
|
||||
|
||||
Args:
|
||||
xui: Экземпляр API клиента
|
||||
inbound_id: ID входящего соединения
|
||||
email: Email клиента
|
||||
new_expiry_time: Новое время истечения
|
||||
client_id: ID клиента
|
||||
total_gb: Общий объем трафика
|
||||
sub_id: ID подписки
|
||||
|
||||
Returns:
|
||||
Optional[bool]: True если успешно, False если ошибка, None если клиент не найден
|
||||
"""
|
||||
try:
|
||||
await xui.login()
|
||||
|
||||
client = await xui.client.get_by_email(email)
|
||||
|
||||
if not client:
|
||||
logger.warning(f"Клиент с email {email} не найден.")
|
||||
return None
|
||||
|
||||
if not client.id:
|
||||
logger.warning(f"Ошибка: клиент {email} не имеет действительного ID.")
|
||||
if not client or not client.id:
|
||||
logger.warning(f"Клиент с email {email} не найден или не имеет ID.")
|
||||
return None
|
||||
|
||||
logger.info(f"Обновление ключа клиента {email} с ID {client.id} до {new_expiry_time}")
|
||||
@@ -152,7 +158,6 @@ async def delete_client(
|
||||
bool: True если удаление успешно, False в противном случае
|
||||
"""
|
||||
try:
|
||||
await xui.login()
|
||||
|
||||
if SUPERNODE:
|
||||
await xui.client.delete(inbound_id, client_id)
|
||||
@@ -179,20 +184,9 @@ async def delete_client(
|
||||
|
||||
|
||||
async def get_client_traffic(xui: py3xui.AsyncApi, client_id: str) -> dict[str, Any]:
|
||||
"""
|
||||
Получает информацию о трафике пользователя по client_id.
|
||||
|
||||
Args:
|
||||
xui: Экземпляр API клиента
|
||||
client_id: UUID клиента
|
||||
|
||||
Returns:
|
||||
dict[str, Any]: Информация о трафике пользователя или ошибка
|
||||
"""
|
||||
try:
|
||||
await xui.login()
|
||||
traffic_data = await xui.client.get_traffic_by_id(client_id)
|
||||
|
||||
traffic_data = await xui.client.get_traffic_by_id(client_id)
|
||||
if not traffic_data:
|
||||
logger.warning(f"Трафик для клиента {client_id} не найден.")
|
||||
return {"status": "not_found", "client_id": client_id}
|
||||
@@ -210,24 +204,9 @@ async def get_client_traffic(xui: py3xui.AsyncApi, client_id: str) -> dict[str,
|
||||
|
||||
|
||||
async def toggle_client(xui: py3xui.AsyncApi, inbound_id: int, email: str, client_id: str, enable: bool = True) -> bool:
|
||||
"""
|
||||
Функция для включения/отключения клиента на сервере 3x-ui.
|
||||
|
||||
Args:
|
||||
xui: Экземпляр API клиента
|
||||
inbound_id: ID инбаунда
|
||||
email: Email клиента
|
||||
client_id: UUID клиента
|
||||
enable: True для включения, False для отключения
|
||||
|
||||
Returns:
|
||||
bool: True при успешном выполнении, False при ошибке
|
||||
"""
|
||||
try:
|
||||
await xui.login()
|
||||
|
||||
client = await xui.client.get_by_email(email)
|
||||
|
||||
if not client:
|
||||
logger.warning(f"Клиент с email {email} и ID {client_id} не найден.")
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user