Enhance admin handlers with improved logging and error handling

- Added detailed logging for user ban processing in `process_ban_target` and `process_ban_reason` functions, including user data and error messages.
- Improved error handling for user input validation and database interactions.
- Updated `return_to_admin_menu` function to log user return actions.
- Enhanced media group handling in `PostPublishService` with better error logging and author ID retrieval.
- Added new button options in voice handlers and updated keyboard layouts for improved user interaction.
- Refactored album middleware to better handle media group messages and added documentation for clarity.
This commit is contained in:
2025-09-02 22:20:34 +03:00
parent 1c6a37bc12
commit 1ab427a7ba
12 changed files with 340 additions and 232 deletions

View File

@@ -13,7 +13,7 @@ except ImportError:
_emoji_lib_available = False
from aiogram import types
from aiogram.types import InputMediaPhoto, FSInputFile, InputMediaVideo, InputMediaAudio
from aiogram.types import InputMediaPhoto, FSInputFile, InputMediaVideo, InputMediaAudio, InputMediaDocument
from helper_bot.utils.base_dependency_factory import BaseDependencyFactory, get_global_instance
from logs.custom_logger import logger
@@ -145,14 +145,14 @@ async def download_file(message: types.Message, file_id: str):
async def prepare_media_group_from_middlewares(album, post_caption: str = ''):
"""
Создает MediaGroup.
Создает MediaGroup согласно best practices aiogram 3.x.
Args:
album: Album объект из Telegram API.
post_caption: Текст подписи к первому фото.
album: Album объект из Telegram API (список сообщений).
post_caption: Текст подписи к первому медиа файлу.
Returns:
Список InputMediaPhoto (MediaGroup).
Список InputMedia объектов для MediaGroup.
"""
# Экранируем post_caption для безопасного использования в HTML
safe_post_caption = html.escape(str(post_caption)) if post_caption else ""
@@ -162,34 +162,37 @@ async def prepare_media_group_from_middlewares(album, post_caption: str = ''):
for i, message in enumerate(album):
if message.photo:
file_id = message.photo[-1].file_id
media_type = 'photo'
# Для фото используем InputMediaPhoto
if i == 0: # Первое фото получает подпись
media_group.append(InputMediaPhoto(media=file_id, caption=safe_post_caption))
else:
media_group.append(InputMediaPhoto(media=file_id))
elif message.video:
file_id = message.video.file_id
media_type = 'video'
# Для видео используем InputMediaVideo
if i == 0: # Первое видео получает подпись
media_group.append(InputMediaVideo(media=file_id, caption=safe_post_caption))
else:
media_group.append(InputMediaVideo(media=file_id))
elif message.audio:
file_id = message.audio.file_id
media_type = 'audio'
# Для аудио используем InputMediaAudio
if i == 0: # Первое аудио получает подпись
media_group.append(InputMediaAudio(media=file_id, caption=safe_post_caption))
else:
media_group.append(InputMediaAudio(media=file_id))
elif message.document:
file_id = message.document.file_id
# Для документов используем InputMediaDocument (если поддерживается)
if i == 0: # Первый документ получает подпись
media_group.append(InputMediaDocument(media=file_id, caption=safe_post_caption))
else:
media_group.append(InputMediaDocument(media=file_id))
else:
# Если нет фото, видео или аудио, пропускаем сообщение
# Если нет поддерживаемого медиа, пропускаем сообщение
continue
# Формируем объект MediaGroup с учетом типа медиа
if i == len(album) - 1:
if media_type == 'photo':
media_group.append(InputMediaPhoto(media=file_id, caption=safe_post_caption))
elif media_type == 'video':
media_group.append(InputMediaVideo(media=file_id, caption=safe_post_caption))
elif media_type == 'audio':
media_group.append(InputMediaAudio(media=file_id, caption=safe_post_caption))
else:
if media_type == 'photo':
media_group.append(InputMediaPhoto(media=file_id))
elif media_type == 'video':
media_group.append(InputMediaVideo(media=file_id))
elif media_type == 'audio':
media_group.append(InputMediaAudio(media=file_id))
return media_group # Возвращаем MediaGroup
return media_group
async def add_in_db_media_mediagroup(sent_message, bot_db):
@@ -280,26 +283,43 @@ async def send_media_group_to_channel(bot, chat_id: int, post_content: List, pos
post_content: Список кортежей с путями к файлам.
post_text: Текст подписи.
"""
logger.info(f"Начинаю отправку медиа-группы в чат {chat_id}, количество файлов: {len(post_content)}")
media = []
for file_path in post_content:
for i, file_path in enumerate(post_content):
try:
file = FSInputFile(path=file_path[0])
type = file_path[1]
logger.debug(f"Обрабатываю файл {i+1}/{len(post_content)}: {file_path[0]} (тип: {type})")
if type == 'video':
media.append(types.InputMediaVideo(media=file))
if type == 'photo':
elif type == 'photo':
media.append(types.InputMediaPhoto(media=file))
else:
logger.warning(f"Неизвестный тип файла: {type} для {file_path[0]}")
except FileNotFoundError:
logger.error(f"Файл не найден: {file_path[0]}")
return
except Exception as e:
logger.error(f"Ошибка при обработке файла {file_path[0]}: {e}")
return
logger.info(f"Подготовлено {len(media)} медиа-файлов для отправки")
# Добавляем подпись к последнему файлу
if media:
# Экранируем post_text для безопасного использования в HTML
safe_post_text = html.escape(str(post_text)) if post_text else ""
media[-1].caption = safe_post_text
logger.debug(f"Добавлена подпись к последнему файлу: {safe_post_text[:50]}{'...' if len(safe_post_text) > 50 else ''}")
await bot.send_media_group(chat_id=chat_id, media=media)
try:
await bot.send_media_group(chat_id=chat_id, media=media)
logger.info(f"Медиа-группа успешно отправлена в чат {chat_id}")
except Exception as e:
logger.error(f"Ошибка при отправке медиа-группы в чат {chat_id}: {e}")
raise
async def send_text_message(chat_id, message: types.Message, post_text: str, markup: types.ReplyKeyboardMarkup = None):
@@ -599,7 +619,7 @@ async def update_user_info(source: str, message: types.Message):
@db_query_time("check_emoji_for_user", "users", "select")
async def check_user_emoji(message: types.Message):
user_id = message.from_user.id
user_emoji = await BotDB.get_stickers_info(user_id=user_id)
user_emoji = await BotDB.get_user_emoji(user_id=user_id)
if user_emoji is None or user_emoji in ("Смайл еще не определен", "Эмоджи не определен", ""):
user_emoji = await get_random_emoji()
await BotDB.update_user_emoji(user_id=user_id, emoji=user_emoji)