import html from typing import Optional from aiogram import types from aiogram.fsm.context import FSMContext from helper_bot.handlers.admin.exceptions import AdminError from helper_bot.keyboards.keyboards import get_reply_keyboard_admin from logs.custom_logger import logger def escape_html(text: str) -> str: """Экранирование HTML для безопасного использования в сообщениях""" return html.escape(str(text)) if text else "" async def return_to_admin_menu( message: types.Message, state: FSMContext, additional_message: Optional[str] = None ) -> None: """Универсальная функция для возврата в админ-меню""" logger.info( f"return_to_admin_menu: Возврат в админ-меню для пользователя {message.from_user.id}" ) await state.set_data({}) await state.set_state("ADMIN") markup = get_reply_keyboard_admin() if additional_message: logger.info( f"return_to_admin_menu: Отправка дополнительного сообщения: {additional_message}" ) await message.answer(additional_message) await message.answer("Вернулись в меню", reply_markup=markup) logger.info( f"return_to_admin_menu: Пользователь {message.from_user.id} успешно возвращен в админ-меню" ) async def handle_admin_error( message: types.Message, error: Exception, state: FSMContext, error_context: str = "" ) -> None: """Централизованная обработка ошибок административных операций""" logger.error(f"Ошибка в {error_context}: {error}") if isinstance(error, AdminError): await message.answer(f"Ошибка: {str(error)}") else: await message.answer("Произошла внутренняя ошибка. Попробуйте позже.") await return_to_admin_menu(message, state) def format_user_info(user_id: int, username: str, full_name: str) -> str: """Форматирование информации о пользователе для отображения""" safe_username = escape_html(username) safe_full_name = escape_html(full_name) return ( f"Выбран пользователь:\n" f"ID: {user_id}\n" f"Username: {safe_username}\n" f"Имя: {safe_full_name}" ) def format_ban_confirmation(user_id: int, reason: str, ban_days: Optional[int]) -> str: """Форматирование подтверждения бана""" safe_reason = escape_html(reason) ban_text = "Навсегда" if ban_days is None else f"{ban_days} дней" return ( f"Необходимо подтверждение:\n" f"Пользователь: {user_id}\n" f"Причина бана: {safe_reason}\n" f"Срок бана: {ban_text}" )