import json from aiogram import types from aiogram.enums import ParseMode from pyxui.errors import BadLogin from bot.services.client import ClientService from bot.utils.logging import logger class ClientHandlers: """Обработчики команд для работы с клиентами.""" def __init__(self, client_service: ClientService): self.client_service = client_service async def cmd_create(self, message: types.Message): """Обработчик команды /create.""" args = (message.text or "").strip().split(maxsplit=1) if len(args) < 2: await message.answer( "❌ Укажи Telegram ID или username после команды.\n" "Пример:\n/create udochudo" ) return telegram_id = args[1].lstrip("@").strip() try: success, result_message = await self.client_service.create_client_profile(telegram_id) if success: await message.answer(result_message, parse_mode=ParseMode.HTML) else: await message.answer(f"❌ {result_message}") except BadLogin: await message.answer("❌ Ошибка: неверный логин или пароль XUI.") except Exception as e: logger.error(f"Неожиданная ошибка при создании профиля: {e}") await message.answer(f"❌ Произошла ошибка при создании профиля. Попробуйте позже.\n {e}") async def cmd_info(self, message: types.Message): """Обработчик команды /info с выводом конфига и статистики.""" args = (message.text or "").strip().split(maxsplit=1) if len(args) < 2: await message.answer( "❌ Укажи Telegram ID или username после команды.\n" "Пример:\n/info udochudo" ) return telegram_id = args[1].lstrip("@").strip() try: (vless_client, vless_stats), (ss_client, ss_stats) = \ self.client_service.get_client_info_with_stats(telegram_id) def format_info(client, stats, name): if not client: return f"❌ Клиент {name} не найден.\n" # Конфиг клиента json_info = json.dumps(client, ensure_ascii=False, indent=2) text = f"🔹 {name}:\n
{json_info}
" # Статистика if stats: up = stats.get("up", 0) down = stats.get("down", 0) total = up + down def human_size(num): for unit in ["B", "KB", "MB", "GB", "TB"]: if num < 1024: return f"{num:.2f} {unit}" num /= 1024 return f"{num:.2f} PB" text += ( f"\n📊 Трафик: ↑ {human_size(up)} / ↓ {human_size(down)}" f" (Σ {human_size(total)})" ) else: text += "\n📊 Статистика не найдена." return text response = ( format_info(vless_client, vless_stats, "VLESS") + "\n\n" + format_info(ss_client, ss_stats, "Shadowsocks") ) await message.answer(response, parse_mode=ParseMode.HTML) except BadLogin: await message.answer("❌ Ошибка входа в панель XUI.") except Exception as e: logger.error(f"Ошибка получения информации: {e}") await message.answer("❌ Ошибка при получении информации. Проверь лог.")