161 lines
6.1 KiB
Python
161 lines
6.1 KiB
Python
import aiohttp
|
|
from typing import List, Dict, Any
|
|
from logger import logger
|
|
from config import REMNAWAVE_TOKEN_LOGIN_ENABLED, REMNAWAVE_ACCESS_TOKEN, REMNAWAVE_LOGIN, REMNAWAVE_PASSWORD
|
|
|
|
|
|
async def login_remnawave(api_url: str, username: str, password: str) -> str | None:
|
|
if REMNAWAVE_TOKEN_LOGIN_ENABLED and REMNAWAVE_ACCESS_TOKEN:
|
|
logger.info("[Remnawave API] Используется авторизация по токену")
|
|
return REMNAWAVE_ACCESS_TOKEN
|
|
|
|
async with aiohttp.ClientSession() as session:
|
|
auth_data = {
|
|
"username": username,
|
|
"password": password
|
|
}
|
|
|
|
try:
|
|
auth_response = await session.post(f"{api_url}/auth/login", json=auth_data)
|
|
|
|
if auth_response.status != 200:
|
|
logger.error(f"[Remnawave API] Ошибка HTTP статуса: {auth_response.status}")
|
|
return None
|
|
|
|
auth_result = await auth_response.json()
|
|
token = None
|
|
if auth_result.get("success") and auth_result.get("data", {}).get("token"):
|
|
token = auth_result.get("data", {}).get("token")
|
|
elif auth_result.get("response", {}).get("accessToken"):
|
|
token = auth_result.get("response", {}).get("accessToken")
|
|
elif auth_result.get("token"):
|
|
token = auth_result.get("token")
|
|
|
|
if not token:
|
|
logger.error(f"[Remnawave API] Токен не найден в ответе")
|
|
|
|
return token
|
|
|
|
except Exception as e:
|
|
logger.error(f"[Remnawave API] Ошибка при авторизации: {e}")
|
|
return None
|
|
|
|
|
|
async def get_all_nodes_with_online(api_url: str, username: str, password: str, inbound_id: str) -> Dict[str, Any]:
|
|
token = await login_remnawave(api_url, username, password)
|
|
if not token:
|
|
logger.error("[Remnawave API] Не удалось получить токен авторизации")
|
|
return {"total_online": 0, "nodes": [], "error": "Не удалось авторизоваться"}
|
|
|
|
headers = {"Authorization": f"Bearer {token}"}
|
|
|
|
async with aiohttp.ClientSession() as session:
|
|
try:
|
|
nodes_response = await session.get(f"{api_url}/nodes", headers=headers)
|
|
|
|
if nodes_response.status != 200:
|
|
logger.error(f"[Remnawave API] Ошибка получения нод: {nodes_response.status}")
|
|
return {"total_online": 0, "nodes": [], "error": f"HTTP {nodes_response.status}"}
|
|
|
|
nodes_result = await nodes_response.json()
|
|
|
|
all_nodes = []
|
|
if nodes_result.get("success") and "data" in nodes_result:
|
|
all_nodes = nodes_result["data"]
|
|
elif nodes_result.get("response"):
|
|
all_nodes = nodes_result["response"]
|
|
elif isinstance(nodes_result, list):
|
|
all_nodes = nodes_result
|
|
|
|
if not all_nodes:
|
|
logger.warning("[Remnawave API] Список нод пуст")
|
|
return {"total_online": 0, "nodes": [], "error": "Список нод пуст"}
|
|
|
|
matching_nodes = []
|
|
total_online = 0
|
|
|
|
|
|
|
|
for node in all_nodes:
|
|
excluded_inbounds = node.get("excludedInbounds", [])
|
|
if inbound_id not in excluded_inbounds:
|
|
node_online = node.get("usersOnline", 0)
|
|
node_name = node.get("name", "Unknown Node")
|
|
node_id = node.get("id", "Unknown ID")
|
|
|
|
matching_nodes.append({
|
|
"name": node_name,
|
|
"online_users": node_online,
|
|
"country_code": node.get("countryCode", "Unknown")
|
|
})
|
|
|
|
total_online += node_online
|
|
|
|
logger.info(f"[Remnawave API] Найдено {len(matching_nodes)} нод для inbound {inbound_id}, общий онлайн: {total_online}")
|
|
|
|
return {
|
|
"total_online": total_online,
|
|
"nodes": matching_nodes,
|
|
"inbound_id": inbound_id
|
|
}
|
|
|
|
except Exception as e:
|
|
logger.error(f"[Remnawave API] Ошибка при получении нод: {e}")
|
|
return {"total_online": 0, "nodes": [], "error": str(e)}
|
|
|
|
|
|
async def get_all_users_time(api_url: str, username: str, password: str) -> List[Dict[str, Any]]:
|
|
all_users = []
|
|
page_size = 250
|
|
start = 0
|
|
|
|
token = await login_remnawave(api_url, username, password)
|
|
if not token:
|
|
logger.error("[Remnawave API] Не удалось получить токен авторизации")
|
|
return []
|
|
|
|
headers = {"Authorization": f"Bearer {token}"}
|
|
|
|
async with aiohttp.ClientSession() as session:
|
|
while True:
|
|
params = {
|
|
"size": page_size,
|
|
"start": start
|
|
}
|
|
|
|
users_endpoint = f"{api_url}/users"
|
|
|
|
users_response = await session.get(users_endpoint, params=params, headers=headers)
|
|
|
|
if users_response.status != 200:
|
|
break
|
|
|
|
users_result = await users_response.json()
|
|
|
|
if users_result.get("success") is False:
|
|
break
|
|
|
|
users_data = None
|
|
if "response" in users_result:
|
|
users_data = users_result.get("response", {})
|
|
elif "data" in users_result:
|
|
users_data = users_result.get("data", {})
|
|
else:
|
|
users_data = users_result
|
|
|
|
if not users_data:
|
|
break
|
|
|
|
users = users_data.get("users", [])
|
|
total = users_data.get("total", 0)
|
|
|
|
if not users:
|
|
break
|
|
|
|
all_users.extend(users)
|
|
start += len(users)
|
|
|
|
if len(users) < page_size or start >= total:
|
|
break
|
|
|
|
return all_users |