forked from FOSS/ASF-Control-Bot
269 lines
8.6 KiB
Python
269 lines
8.6 KiB
Python
import html
|
||
|
||
from aiogram import Router
|
||
from aiogram.types import Message
|
||
from aiogram.fsm.context import FSMContext
|
||
|
||
from bot.filters import AdminFilter
|
||
from bot.api.asf import get_all_bots, send_command
|
||
from bot.logging_utils import describe_user, get_logger
|
||
from bot.services.redeem import (
|
||
extract_keys,
|
||
redeem_all_bots_keys,
|
||
redeem_single_bot_keys,
|
||
)
|
||
|
||
from bot.states import ConsoleFlow, RedeemFlow
|
||
|
||
from bot.ui.formatters import format_bot_ui, get_asf_status_text
|
||
from bot.ui.keyboards import (
|
||
main_keyboard,
|
||
bot_details_keyboard,
|
||
delete_message_keyboard,
|
||
)
|
||
|
||
router = Router()
|
||
logger = get_logger(__name__)
|
||
|
||
|
||
@router.message(ConsoleFlow.waiting_command, AdminFilter())
|
||
async def handle_console_message(message: Message, state: FSMContext):
|
||
if not message.text:
|
||
await message.answer("Отправьте текстовую команду.")
|
||
return
|
||
|
||
command = message.text.strip()
|
||
if not command:
|
||
await message.answer("Команда не может быть пустой.")
|
||
return
|
||
|
||
logger.info(
|
||
"Пользователь %s отправил консольную команду: %s",
|
||
describe_user(message.from_user),
|
||
command,
|
||
)
|
||
|
||
try:
|
||
await message.delete()
|
||
|
||
except Exception:
|
||
logger.debug(
|
||
"Не удалось удалить сообщение с консольной командой от %s",
|
||
describe_user(message.from_user),
|
||
exc_info=True,
|
||
)
|
||
|
||
try:
|
||
response = send_command(f"!{command}")
|
||
if response.status_code != 200:
|
||
logger.warning(
|
||
"ASF вернул HTTP %s на консольную команду '%s' от %s",
|
||
response.status_code,
|
||
command,
|
||
describe_user(message.from_user),
|
||
)
|
||
|
||
text = f"Ошибка HTTP {response.status_code}"
|
||
|
||
else:
|
||
data = response.json()
|
||
|
||
if not data.get("Success"):
|
||
logger.warning(
|
||
"ASF вернул неуспешный ответ на консольную команду '%s' от %s",
|
||
command,
|
||
describe_user(message.from_user),
|
||
)
|
||
text = "Ошибка ASF"
|
||
|
||
else:
|
||
logger.info(
|
||
"Консольная команда '%s' от %s выполнена успешно",
|
||
command,
|
||
describe_user(message.from_user),
|
||
)
|
||
result = html.escape(str(data.get("Result", "Нет ответа")))
|
||
text = f"<b>Команда:</b> <code>{command}</code>\n\n<b>Ответ:</b>\n<code>{result}</code>"
|
||
|
||
await message.answer(text, reply_markup=delete_message_keyboard())
|
||
|
||
except Exception as error:
|
||
logger.exception(
|
||
"Ошибка при выполнении консольной команды '%s' от %s",
|
||
command,
|
||
describe_user(message.from_user),
|
||
)
|
||
|
||
await message.answer(f"Ошибка: {error}")
|
||
|
||
|
||
@router.message(RedeemFlow.waiting_bot_keys, AdminFilter())
|
||
async def handle_single_bot_redeem(message: Message, state: FSMContext):
|
||
state_data = await state.get_data()
|
||
|
||
bot_name = state_data.get("bot_name")
|
||
if not isinstance(bot_name, str) or not bot_name:
|
||
await message.answer("Контекст потерян, попробуйте еще раз.")
|
||
await state.clear()
|
||
|
||
return
|
||
|
||
chat_id = message.chat.id
|
||
menu_message_id = state_data.get("menu_message_id")
|
||
|
||
logger.info(
|
||
"Пользователь %s отправил ключи для бота %s",
|
||
describe_user(message.from_user),
|
||
bot_name,
|
||
)
|
||
|
||
if menu_message_id:
|
||
try:
|
||
response = get_all_bots()
|
||
bot_data = response.json().get("Result", {}).get(bot_name)
|
||
|
||
if bot_data:
|
||
await message.bot.edit_message_text(
|
||
text=format_bot_ui(bot_data),
|
||
reply_markup=bot_details_keyboard(
|
||
bot_name, bool(bot_data.get("HasMobileAuthenticator"))
|
||
),
|
||
disable_web_page_preview=True,
|
||
chat_id=chat_id,
|
||
message_id=menu_message_id,
|
||
)
|
||
|
||
except Exception:
|
||
logger.debug(
|
||
"Не удалось восстановить меню бота %s после ввода ключей от %s",
|
||
bot_name,
|
||
describe_user(message.from_user),
|
||
exc_info=True,
|
||
)
|
||
|
||
try:
|
||
await message.bot.delete_message(
|
||
chat_id=message.chat.id, message_id=message.message_id
|
||
)
|
||
|
||
except Exception:
|
||
logger.debug(
|
||
"Не удалось удалить сообщение с ключами для бота %s от %s",
|
||
bot_name,
|
||
describe_user(message.from_user),
|
||
exc_info=True,
|
||
)
|
||
|
||
keys = extract_keys(message.text or "")
|
||
if not keys:
|
||
logger.info(
|
||
"В сообщении от %s для бота %s не найдено ключей",
|
||
describe_user(message.from_user),
|
||
bot_name,
|
||
)
|
||
await message.answer("Ключи не найдены")
|
||
await state.clear()
|
||
|
||
return
|
||
|
||
logger.info(
|
||
"Для бота %s получено %s ключ(ей) от %s",
|
||
bot_name,
|
||
len(keys),
|
||
describe_user(message.from_user),
|
||
)
|
||
checking = await message.answer(
|
||
f"Аккаунт: <code>{bot_name}</code>\nНайдено ключей: {len(keys)}\nНачинаю активацию..."
|
||
)
|
||
|
||
try:
|
||
await checking.edit_text(await redeem_single_bot_keys(bot_name, keys))
|
||
|
||
except Exception as error:
|
||
logger.exception(
|
||
"Не удалось активировать ключи для бота %s от %s",
|
||
bot_name,
|
||
describe_user(message.from_user),
|
||
)
|
||
try:
|
||
await checking.edit_text(f"Ошибка: {error}")
|
||
|
||
except Exception:
|
||
await message.answer(f"Ошибка: {error}")
|
||
|
||
finally:
|
||
await state.clear()
|
||
|
||
|
||
@router.message(RedeemFlow.waiting_all_keys, AdminFilter())
|
||
async def handle_all_bots_redeem(message: Message, state: FSMContext):
|
||
state_data = await state.get_data()
|
||
|
||
chat_id = message.chat.id
|
||
menu_message_id = state_data.get("menu_message_id")
|
||
|
||
logger.info(
|
||
"Пользователь %s отправил ключи для активации на всех ботах",
|
||
describe_user(message.from_user),
|
||
)
|
||
|
||
if menu_message_id:
|
||
try:
|
||
await message.bot.edit_message_text(
|
||
text=get_asf_status_text(),
|
||
reply_markup=main_keyboard(),
|
||
chat_id=chat_id,
|
||
message_id=menu_message_id,
|
||
)
|
||
|
||
except Exception:
|
||
logger.debug(
|
||
"Не удалось восстановить главное меню после массовой активации для %s",
|
||
describe_user(message.from_user),
|
||
exc_info=True,
|
||
)
|
||
|
||
try:
|
||
await message.bot.delete_message(
|
||
chat_id=message.chat.id, message_id=message.message_id
|
||
)
|
||
|
||
except Exception:
|
||
logger.debug(
|
||
"Не удалось удалить сообщение с массовой активацией от %s",
|
||
describe_user(message.from_user),
|
||
exc_info=True,
|
||
)
|
||
|
||
keys = extract_keys(message.text or "")
|
||
if not keys:
|
||
logger.info(
|
||
"В сообщении от %s для массовой активации не найдено ключей",
|
||
describe_user(message.from_user),
|
||
)
|
||
await message.answer("Ключи не найдены")
|
||
await state.clear()
|
||
|
||
return
|
||
|
||
logger.info(
|
||
"Для массовой активации получено %s ключ(ей) от %s",
|
||
len(keys),
|
||
describe_user(message.from_user),
|
||
)
|
||
checking = await message.answer(
|
||
f"Найдено ключей: {len(keys)}\nНачинаю активацию..."
|
||
)
|
||
|
||
try:
|
||
await checking.edit_text(await redeem_all_bots_keys(keys))
|
||
|
||
except Exception as error:
|
||
logger.exception(
|
||
"Ошибка при массовой активации ключей от %s",
|
||
describe_user(message.from_user),
|
||
)
|
||
await checking.edit_text(f"Ошибка: {error}")
|
||
|
||
await state.clear()
|