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

@@ -30,7 +30,10 @@ BTN_LISTEN = "🎧Послушать"
# Button to command mapping for metrics
BUTTON_COMMAND_MAPPING: Final[Dict[str, str]] = {
"🎤Высказаться": "voice_speak",
"🎧Послушать": "voice_listen"
"🎧Послушать": "voice_listen",
"Отменить": "voice_cancel",
"🔄Сбросить прослушивания": "voice_refresh_listen",
"😊Узнать эмодзи": "voice_emoji"
}
# Callback data

View File

@@ -1,5 +1,6 @@
import random
import asyncio
import traceback
from datetime import datetime
from pathlib import Path
from typing import List, Optional, Tuple
@@ -255,22 +256,40 @@ class AudioFileService:
async def download_and_save_audio(self, bot, message, file_name: str) -> None:
"""Скачать и сохранить аудио файл"""
try:
logger.info(f"Начинаем скачивание и сохранение аудио: {file_name}")
# Проверяем наличие голосового сообщения
if not message or not message.voice:
logger.error("Сообщение или голосовое сообщение не найдено")
raise FileOperationError("Сообщение или голосовое сообщение не найдено")
file_id = message.voice.file_id
logger.info(f"Получен file_id: {file_id}")
file_info = await bot.get_file(file_id=file_id)
logger.info(f"Получена информация о файле: {file_info.file_path}")
downloaded_file = await bot.download_file(file_path=file_info.file_path)
logger.info(f"Файл скачан, размер: {len(downloaded_file.read()) if downloaded_file else 'None'} bytes")
# Сбрасываем позицию в файле
downloaded_file.seek(0)
# Создаем директорию если она не существует
import os
os.makedirs(VOICE_USERS_DIR, exist_ok=True)
logger.info(f"Директория {VOICE_USERS_DIR} создана/проверена")
file_path = f'{VOICE_USERS_DIR}/{file_name}.ogg'
logger.info(f"Сохраняем файл по пути: {file_path}")
# Сохраняем файл
with open(f'{VOICE_USERS_DIR}/{file_name}.ogg', 'wb') as new_file:
with open(file_path, 'wb') as new_file:
new_file.write(downloaded_file.read())
logger.info(f"Файл успешно сохранен: {file_path}")
except Exception as e:
logger.error(f"Ошибка при скачивании и сохранении аудио: {e}")
logger.error(f"Traceback: {traceback.format_exc()}")
raise FileOperationError(f"Не удалось скачать и сохранить аудио: {e}")

View File

@@ -18,12 +18,14 @@ from helper_bot.handlers.voice.constants import *
from helper_bot.handlers.voice.services import VoiceBotService
from helper_bot.handlers.voice.utils import get_last_message_text, validate_voice_message, get_user_emoji_safe
from helper_bot.keyboards.keyboards import get_main_keyboard, get_reply_keyboard_for_voice
from helper_bot.keyboards import get_reply_keyboard
from helper_bot.handlers.private.constants import FSM_STATES
from helper_bot.handlers.private.constants import BUTTON_TEXTS
class VoiceHandlers:
def __init__(self, db, settings):
self.db = db
self.db = db.get_db() if hasattr(db, 'get_db') else db
self.settings = settings
self.router = Router()
self._setup_handlers()
@@ -93,6 +95,25 @@ class VoiceHandlers:
ChatTypeFilter(chat_type=["private"]),
F.text == BTN_LISTEN
)
# Новые обработчики кнопок
self.router.message.register(
self.cancel_handler,
ChatTypeFilter(chat_type=["private"]),
F.text == "Отменить"
)
self.router.message.register(
self.refresh_listen_function,
ChatTypeFilter(chat_type=["private"]),
F.text == "🔄Сбросить прослушивания"
)
self.router.message.register(
self.handle_emoji_message,
ChatTypeFilter(chat_type=["private"]),
F.text == "😊Узнать эмодзи"
)
async def voice_bot_button_handler(self, message: types.Message, state: FSMContext, bot_db: MagicData("bot_db"), settings: MagicData("settings")):
"""Обработчик кнопки 'Голосовой бот' из основной клавиатуры"""
@@ -180,6 +201,19 @@ class VoiceHandlers:
except Exception as e:
logger.error(f"Ошибка при отметке получения приветствия: {e}")
async def cancel_handler(
self,
message: types.Message,
state: FSMContext,
bot_db: MagicData("bot_db"),
settings: MagicData("settings")
):
"""Обработчик кнопки 'Отменить' - возвращает в начальное состояние"""
await message.forward(chat_id=settings['Telegram']['group_for_logs'])
await update_user_info(VOICE_BOT_NAME, message)
markup = await get_reply_keyboard(self.db, message.from_user.id)
await message.answer(text='Добро пожаловать в меню!', reply_markup=markup, parse_mode='HTML')
await state.set_state(FSM_STATES["START"])
async def refresh_listen_function(
self,
@@ -334,7 +368,7 @@ class VoiceHandlers:
await voice_service.mark_audio_as_listened(audio_for_user, message.from_user.id)
# Получаем количество оставшихся аудио только после успешной отправки
remaining_count = await voice_service.get_remaining_audio_count(message.from_user.id) - 1
remaining_count = await voice_service.get_remaining_audio_count(message.from_user.id)
await message.answer(
text=f'Осталось непрослушанных: <b>{remaining_count}</b>',
reply_markup=markup