Show all inbound nodes with country flags in Remnawave
This commit is contained in:
@@ -29,6 +29,7 @@ from handlers.keys.key_utils import (
|
||||
)
|
||||
from logger import logger
|
||||
from panels.remnawave import RemnawaveAPI
|
||||
from panels.remnawave_time import get_all_nodes_with_online
|
||||
|
||||
from ..panel.keyboard import AdminPanelCallback, build_admin_back_kb
|
||||
from .keyboard import (
|
||||
@@ -391,33 +392,62 @@ async def handle_cluster_availability(
|
||||
result_text += f"🌍 <b>{prefix} {server_name}</b> - {online_inbound_users} онлайн\n"
|
||||
|
||||
elif panel_type == "remnawave":
|
||||
remna = RemnawaveAPI(server["api_url"])
|
||||
if not await remna.login(REMNAWAVE_LOGIN, REMNAWAVE_PASSWORD):
|
||||
raise Exception("Не удалось авторизоваться")
|
||||
# remna = RemnawaveAPI(server["api_url"])
|
||||
# if not await remna.login(REMNAWAVE_LOGIN, REMNAWAVE_PASSWORD):
|
||||
# raise Exception("Не удалось авторизоваться")
|
||||
|
||||
server_inbound_id = server.get("inbound_id")
|
||||
if not server_inbound_id:
|
||||
raise Exception("Не указан inbound_id сервера")
|
||||
|
||||
all_nodes = await remna.get_all_nodes()
|
||||
if not all_nodes:
|
||||
raise Exception("Не удалось получить список нод")
|
||||
# all_nodes = await remna.get_all_nodes()
|
||||
# if not all_nodes:
|
||||
# raise Exception("Не удалось получить список нод")
|
||||
|
||||
matching_node = None
|
||||
for node in all_nodes:
|
||||
excluded_inbounds = node.get("excludedInbounds", [])
|
||||
if server_inbound_id not in excluded_inbounds:
|
||||
matching_node = node
|
||||
break
|
||||
# matching_node = None
|
||||
# for node in all_nodes:
|
||||
# excluded_inbounds = node.get("excludedInbounds", [])
|
||||
# if server_inbound_id not in excluded_inbounds:
|
||||
# matching_node = node
|
||||
# break
|
||||
|
||||
if not matching_node:
|
||||
raise Exception("Нода, обслуживающая этот inbound_id, не найдена")
|
||||
# if not matching_node:
|
||||
# raise Exception("Нода, обслуживающая этот inbound_id, не найдена")
|
||||
|
||||
online_remna_users = matching_node.get("usersOnline", 0)
|
||||
total_online_users += online_remna_users
|
||||
result_text += (
|
||||
f"🌍 <b>{prefix} {server_name}</b> - {online_remna_users} онлайн\n"
|
||||
# online_remna_users = matching_node.get("usersOnline", 0)
|
||||
# total_online_users += online_remna_users
|
||||
# result_text += (
|
||||
# f"🌍 <b>{prefix} {server_name}</b> - {online_remna_users} онлайн\n"
|
||||
# )
|
||||
|
||||
nodes_data = await get_all_nodes_with_online(
|
||||
server["api_url"], REMNAWAVE_LOGIN, REMNAWAVE_PASSWORD, server_inbound_id
|
||||
)
|
||||
|
||||
if nodes_data.get("error"):
|
||||
raise Exception(nodes_data["error"])
|
||||
|
||||
online_remna_users = nodes_data["total_online"]
|
||||
total_online_users += online_remna_users
|
||||
|
||||
nodes_info = nodes_data["nodes"]
|
||||
if len(nodes_info) > 1:
|
||||
result_text += f"🌍 <b>{prefix} {server_name}</b> - {online_remna_users} онлайн\n"
|
||||
for node_info in nodes_info:
|
||||
country_code = node_info.get('country_code', 'Unknown')
|
||||
node_name = node_info.get('name', 'Unknown')
|
||||
online_users = node_info.get('online_users', 0)
|
||||
|
||||
if country_code != 'Unknown' and len(country_code) == 2:
|
||||
flag = ''.join(chr(ord(c) + 127397) for c in country_code.upper())
|
||||
else:
|
||||
flag = country_code
|
||||
|
||||
result_text += f" ↳ {flag} ({node_name}): {online_users} онлайн\n"
|
||||
else:
|
||||
result_text += (
|
||||
f"🌍 <b>{prefix} {server_name}</b> - {online_remna_users} онлайн\n"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
error_text = str(e) or "Сервер недоступен"
|
||||
|
||||
@@ -41,6 +41,69 @@ async def login_remnawave(api_url: str, username: str, password: str) -> str | N
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user