From 1eec919b88e8966c6344f193cb70eccd122f7b4e Mon Sep 17 00:00:00 2001 From: Egor Date: Thu, 6 Nov 2025 03:17:08 +0300 Subject: [PATCH] Update main.py --- app/handlers/admin/main.py | 164 +++++++++++++++++++++++++++---------- 1 file changed, 122 insertions(+), 42 deletions(-) diff --git a/app/handlers/admin/main.py b/app/handlers/admin/main.py index fbc9bf13..c18aad2c 100644 --- a/app/handlers/admin/main.py +++ b/app/handlers/admin/main.py @@ -2,6 +2,7 @@ import logging from aiogram import Dispatcher, types, F from aiogram.filters import Command from sqlalchemy.ext.asyncio import AsyncSession +from aiogram.exceptions import TelegramBadRequest from app.config import settings from app.database.models import User @@ -26,6 +27,55 @@ from app.database.crud.ticket import TicketCRUD logger = logging.getLogger(__name__) +async def safe_edit_message( + callback: types.CallbackQuery, + text: str, + reply_markup: types.InlineKeyboardMarkup, + parse_mode: str = "HTML" +): + """ + Безопасное редактирование сообщений, которое корректно обрабатывает + как обычные текстовые сообщения, так и сообщения с фото + """ + if callback.message.photo: + try: + await callback.message.edit_caption( + caption=text, + reply_markup=reply_markup, + parse_mode=parse_mode + ) + except TelegramBadRequest as e: + if "there is no text in the message to edit" in str(e) or "message is not modified" in str(e): + try: + await callback.message.delete() + await callback.message.answer( + text=text, + reply_markup=reply_markup, + parse_mode=parse_mode + ) + except Exception: + try: + await callback.message.edit_text( + text, + reply_markup=reply_markup, + parse_mode=parse_mode + ) + except TelegramBadRequest: + await callback.message.answer( + text=text, + reply_markup=reply_markup, + parse_mode=parse_mode + ) + else: + raise + else: + await callback.message.edit_text( + text, + reply_markup=reply_markup, + parse_mode=parse_mode + ) + + @admin_required @error_handler async def show_admin_panel( @@ -56,9 +106,11 @@ async def show_admin_panel( except Exception as e: logger.error(f"Не удалось получить статистику Remnawave для админ-панели: {e}") - await callback.message.edit_text( + await safe_edit_message( + callback, admin_text, - reply_markup=get_admin_main_keyboard(db_user.language) + get_admin_main_keyboard(db_user.language), + "HTML" ) await callback.answer() @@ -71,12 +123,15 @@ async def show_users_submenu( db: AsyncSession ): texts = get_texts(db_user.language) + + message_text = (texts.t("ADMIN_USERS_SUBMENU_TITLE", "👥 **Управление пользователями и подписками**\n\n") + + texts.t("ADMIN_SUBMENU_SELECT_SECTION", "Выберите нужный раздел:")) - await callback.message.edit_text( - texts.t("ADMIN_USERS_SUBMENU_TITLE", "👥 **Управление пользователями и подписками**\n\n") + - texts.t("ADMIN_SUBMENU_SELECT_SECTION", "Выберите нужный раздел:"), - reply_markup=get_admin_users_submenu_keyboard(db_user.language), - parse_mode="Markdown" + await safe_edit_message( + callback, + message_text, + get_admin_users_submenu_keyboard(db_user.language), + "Markdown" ) await callback.answer() @@ -89,12 +144,15 @@ async def show_promo_submenu( db: AsyncSession ): texts = get_texts(db_user.language) + + message_text = (texts.t("ADMIN_PROMO_SUBMENU_TITLE", "💰 **Промокоды и статистика**\n\n") + + texts.t("ADMIN_SUBMENU_SELECT_SECTION", "Выберите нужный раздел:")) - await callback.message.edit_text( - texts.t("ADMIN_PROMO_SUBMENU_TITLE", "💰 **Промокоды и статистика**\n\n") + - texts.t("ADMIN_SUBMENU_SELECT_SECTION", "Выберите нужный раздел:"), - reply_markup=get_admin_promo_submenu_keyboard(db_user.language), - parse_mode="Markdown" + await safe_edit_message( + callback, + message_text, + get_admin_promo_submenu_keyboard(db_user.language), + "Markdown" ) await callback.answer() @@ -107,12 +165,15 @@ async def show_communications_submenu( db: AsyncSession ): texts = get_texts(db_user.language) + + message_text = (texts.t("ADMIN_COMMUNICATIONS_SUBMENU_TITLE", "📨 **Коммуникации**\n\n") + + texts.t("ADMIN_COMMUNICATIONS_SUBMENU_DESCRIPTION", "Управление рассылками и текстами интерфейса:")) - await callback.message.edit_text( - texts.t("ADMIN_COMMUNICATIONS_SUBMENU_TITLE", "📨 **Коммуникации**\n\n") + - texts.t("ADMIN_COMMUNICATIONS_SUBMENU_DESCRIPTION", "Управление рассылками и текстами интерфейса:"), - reply_markup=get_admin_communications_submenu_keyboard(db_user.language), - parse_mode="Markdown" + await safe_edit_message( + callback, + message_text, + get_admin_communications_submenu_keyboard(db_user.language), + "Markdown" ) await callback.answer() @@ -135,14 +196,18 @@ async def show_support_submenu( [InlineKeyboardButton(text=texts.t("ADMIN_SUPPORT_TICKETS", "🎫 Тикеты поддержки"), callback_data="admin_tickets")], [InlineKeyboardButton(text=texts.BACK, callback_data="back_to_menu")] ]) - await callback.message.edit_text( - texts.t("ADMIN_SUPPORT_SUBMENU_TITLE", "🛟 **Поддержка**\n\n") + ( - texts.t("ADMIN_SUPPORT_SUBMENU_DESCRIPTION_MODERATOR", "Доступ к тикетам.") - if is_moderator_only - else texts.t("ADMIN_SUPPORT_SUBMENU_DESCRIPTION", "Управление тикетами и настройками поддержки:") - ), - reply_markup=kb, - parse_mode="Markdown" + + message_text = (texts.t("ADMIN_SUPPORT_SUBMENU_TITLE", "🛟 **Поддержка**\n\n") + ( + texts.t("ADMIN_SUPPORT_SUBMENU_DESCRIPTION_MODERATOR", "Доступ к тикетам.") + if is_moderator_only + else texts.t("ADMIN_SUPPORT_SUBMENU_DESCRIPTION", "Управление тикетами и настройками поддержки:") + )) + + await safe_edit_message( + callback, + message_text, + kb, + "Markdown" ) await callback.answer() @@ -158,11 +223,15 @@ async def show_moderator_panel( [InlineKeyboardButton(text=texts.t("ADMIN_SUPPORT_TICKETS", "🎫 Тикеты поддержки"), callback_data="admin_tickets")], [InlineKeyboardButton(text=texts.t("BACK_TO_MAIN_MENU_BUTTON", "⬅️ В главное меню"), callback_data="back_to_menu")] ]) - await callback.message.edit_text( - texts.t("ADMIN_SUPPORT_MODERATION_TITLE", "🧑‍⚖️ Модерация поддержки") + "\n\n" + - texts.t("ADMIN_SUPPORT_MODERATION_DESCRIPTION", "Доступ к тикетам поддержки."), - parse_mode="HTML", - reply_markup=kb + + message_text = (texts.t("ADMIN_SUPPORT_MODERATION_TITLE", "🧑‍⚖️ Модерация поддержки") + "\n\n" + + texts.t("ADMIN_SUPPORT_MODERATION_DESCRIPTION", "Доступ к тикетам поддержки.")) + + await safe_edit_message( + callback, + message_text, + kb, + "HTML" ) await callback.answer() @@ -235,7 +304,12 @@ async def show_support_audit( kb_rows.append([InlineKeyboardButton(text=texts.BACK, callback_data="admin_submenu_support")]) kb = InlineKeyboardMarkup(inline_keyboard=kb_rows) - await callback.message.edit_text("\n".join(lines), parse_mode="HTML", reply_markup=kb) + await safe_edit_message( + callback, + "\n".join(lines), + kb, + "HTML" + ) await callback.answer() @@ -247,12 +321,15 @@ async def show_settings_submenu( db: AsyncSession ): texts = get_texts(db_user.language) + + message_text = (texts.t("ADMIN_SETTINGS_SUBMENU_TITLE", "⚙️ **Настройки системы**\n\n") + + texts.t("ADMIN_SETTINGS_SUBMENU_DESCRIPTION", "Управление Remnawave, мониторингом и другими настройками:")) - await callback.message.edit_text( - texts.t("ADMIN_SETTINGS_SUBMENU_TITLE", "⚙️ **Настройки системы**\n\n") + - texts.t("ADMIN_SETTINGS_SUBMENU_DESCRIPTION", "Управление Remnawave, мониторингом и другими настройками:"), - reply_markup=get_admin_settings_submenu_keyboard(db_user.language), - parse_mode="Markdown" + await safe_edit_message( + callback, + message_text, + get_admin_settings_submenu_keyboard(db_user.language), + "Markdown" ) await callback.answer() @@ -265,12 +342,15 @@ async def show_system_submenu( db: AsyncSession ): texts = get_texts(db_user.language) + + message_text = (texts.t("ADMIN_SYSTEM_SUBMENU_TITLE", "🛠️ **Системные функции**\n\n") + + texts.t("ADMIN_SYSTEM_SUBMENU_DESCRIPTION", "Отчеты, обновления, логи, резервные копии и системные операции:")) - await callback.message.edit_text( - texts.t("ADMIN_SYSTEM_SUBMENU_TITLE", "🛠️ **Системные функции**\n\n") + - texts.t("ADMIN_SYSTEM_SUBMENU_DESCRIPTION", "Отчеты, обновления, логи, резервные копии и системные операции:"), - reply_markup=get_admin_system_submenu_keyboard(db_user.language), - parse_mode="Markdown" + await safe_edit_message( + callback, + message_text, + get_admin_system_submenu_keyboard(db_user.language), + "Markdown" ) await callback.answer() @@ -449,4 +529,4 @@ def register_handlers(dp: Dispatcher): dp.message.register( admin_commands_help, Command("admin_help") - ) \ No newline at end of file + )