- Deleted the Makefile, `README_TESTING.md`, and several deployment scripts to streamline the project. - Updated `.dockerignore` to exclude unnecessary development files. - Adjusted database schema comments for clarity. - Refactored metrics handling in middleware for improved command extraction and logging. - Enhanced command mappings for buttons and callbacks in constants for better maintainability. - Start refactor voice bot
216 lines
8.4 KiB
Python
216 lines
8.4 KiB
Python
import asyncio
|
||
from datetime import datetime
|
||
from pathlib import Path
|
||
|
||
from aiogram import Router, types, F
|
||
from aiogram.filters import Command, StateFilter
|
||
from aiogram.fsm.context import FSMContext
|
||
from aiogram.types import FSInputFile
|
||
|
||
from helper_bot.filters.main import ChatTypeFilter
|
||
from helper_bot.middlewares.blacklist_middleware import BlacklistMiddleware
|
||
from helper_bot.utils.helper_func import update_user_info, check_user_emoji, send_voice_message
|
||
from logs.custom_logger import logger
|
||
from voice_bot.handlers.constants import *
|
||
from voice_bot.handlers.dependencies import VoiceBotMiddleware, BotDB, Settings
|
||
from voice_bot.handlers.services import VoiceBotService
|
||
from voice_bot.handlers.utils import get_last_message_text, validate_voice_message, get_user_emoji_safe
|
||
from voice_bot.keyboards.keyboards import get_main_keyboard, get_reply_keyboard_for_voice
|
||
|
||
voice_router = Router()
|
||
|
||
# Middleware
|
||
voice_router.message.middleware(VoiceBotMiddleware())
|
||
voice_router.message.middleware(BlacklistMiddleware())
|
||
|
||
|
||
@voice_router.message(
|
||
ChatTypeFilter(chat_type=["private"]),
|
||
Command(CMD_RESTART)
|
||
)
|
||
async def restart_function(message: types.Message, state: FSMContext, bot_db: BotDB):
|
||
await message.forward(chat_id=bot_db.settings['Telegram']['group_for_logs'])
|
||
await update_user_info(VOICE_BOT_NAME, message)
|
||
check_user_emoji(message)
|
||
markup = get_main_keyboard()
|
||
await message.answer(text='Я перезапущен!', reply_markup=markup)
|
||
await state.set_state(STATE_START)
|
||
|
||
|
||
@voice_router.message(
|
||
ChatTypeFilter(chat_type=["private"]),
|
||
Command(CMD_EMOJI)
|
||
)
|
||
async def handle_emoji_message(message: types.Message, state: FSMContext, bot_db: BotDB):
|
||
await message.forward(chat_id=bot_db.settings['Telegram']['group_for_logs'])
|
||
user_emoji = check_user_emoji(message)
|
||
await state.set_state(STATE_START)
|
||
if user_emoji is not None:
|
||
await message.answer(f'Твоя эмодзя - {user_emoji}', parse_mode='HTML')
|
||
|
||
|
||
@voice_router.message(
|
||
ChatTypeFilter(chat_type=["private"]),
|
||
Command(CMD_HELP)
|
||
)
|
||
async def help_function(message: types.Message, state: FSMContext, bot_db: BotDB):
|
||
await message.forward(chat_id=bot_db.settings['Telegram']['group_for_logs'])
|
||
await update_user_info(VOICE_BOT_NAME, message)
|
||
await message.answer(
|
||
text=HELP_MESSAGE,
|
||
disable_web_page_preview=not bot_db.settings['Telegram']['preview_link']
|
||
)
|
||
await state.set_state(STATE_START)
|
||
|
||
|
||
@voice_router.message(
|
||
ChatTypeFilter(chat_type=["private"]),
|
||
Command(CMD_START)
|
||
)
|
||
async def start(message: types.Message, state: FSMContext, bot_db: BotDB, settings: Settings):
|
||
await state.set_state(STATE_START)
|
||
await message.forward(chat_id=settings['Telegram']['group_for_logs'])
|
||
await update_user_info(VOICE_BOT_NAME, message)
|
||
user_emoji = get_user_emoji_safe(bot_db, message.from_user.id)
|
||
|
||
# Создаем сервис и отправляем приветственные сообщения
|
||
voice_service = VoiceBotService(bot_db, settings)
|
||
await voice_service.send_welcome_messages(message, user_emoji)
|
||
|
||
|
||
@voice_router.message(
|
||
ChatTypeFilter(chat_type=["private"]),
|
||
Command(CMD_REFRESH)
|
||
)
|
||
async def refresh_listen_function(message: types.Message, state: FSMContext, bot_db: BotDB):
|
||
await message.forward(chat_id=bot_db.settings['Telegram']['group_for_logs'])
|
||
await update_user_info(VOICE_BOT_NAME, message)
|
||
markup = get_main_keyboard()
|
||
|
||
# Очищаем прослушивания через сервис
|
||
voice_service = VoiceBotService(bot_db, bot_db.settings)
|
||
voice_service.clear_user_listenings(message.from_user.id)
|
||
|
||
await message.answer(
|
||
text=LISTENINGS_CLEARED_MESSAGE,
|
||
disable_web_page_preview=not bot_db.settings['Telegram']['preview_link'],
|
||
reply_markup=markup
|
||
)
|
||
await state.set_state(STATE_START)
|
||
|
||
|
||
@voice_router.message(
|
||
StateFilter(STATE_START),
|
||
ChatTypeFilter(chat_type=["private"]),
|
||
F.text == BTN_SPEAK
|
||
)
|
||
async def standup_write(message: types.Message, state: FSMContext, bot_db: BotDB):
|
||
await message.forward(chat_id=bot_db.settings['Telegram']['group_for_logs'])
|
||
markup = types.ReplyKeyboardRemove()
|
||
await message.answer(text=RECORD_VOICE_MESSAGE, reply_markup=markup)
|
||
|
||
try:
|
||
message_with_date = get_last_message_text(bot_db)
|
||
if message_with_date:
|
||
await message.answer(text=message_with_date, parse_mode="html")
|
||
except Exception as e:
|
||
logger.error(f'Не удалось получить дату последнего сообщения - {e}')
|
||
|
||
await state.set_state(STATE_STANDUP_WRITE)
|
||
|
||
|
||
@voice_router.message(
|
||
StateFilter(STATE_STANDUP_WRITE),
|
||
ChatTypeFilter(chat_type=["private"]),
|
||
)
|
||
async def suggest_voice(message: types.Message, state: FSMContext, bot_db: BotDB):
|
||
logger.info(
|
||
f"Вызов функции suggest_voice. Пользователь: {message.from_user.id} Имя автора сообщения: {message.from_user.full_name}"
|
||
)
|
||
await message.forward(chat_id=bot_db.settings['Telegram']['group_for_logs'])
|
||
markup = get_main_keyboard()
|
||
|
||
if validate_voice_message(message):
|
||
markup_for_voice = get_reply_keyboard_for_voice()
|
||
|
||
# Отправляем аудио в приватный канал
|
||
sent_message = await send_voice_message(
|
||
bot_db.settings['Telegram']['group_for_posts'],
|
||
message,
|
||
message.voice.file_id,
|
||
markup_for_voice
|
||
)
|
||
|
||
# Сохраняем в базу инфо о посте
|
||
bot_db.set_user_id_and_message_id_for_voice_bot(sent_message.message_id, message.from_user.id)
|
||
|
||
# Отправляем юзеру ответ и возвращаем его в меню
|
||
await message.answer(text=VOICE_SAVED_MESSAGE, reply_markup=markup)
|
||
await state.set_state(STATE_START)
|
||
else:
|
||
await message.forward(chat_id=bot_db.settings['Telegram']['group_for_logs'])
|
||
await message.answer(text=UNKNOWN_CONTENT_MESSAGE, reply_markup=markup)
|
||
await state.set_state(STATE_STANDUP_WRITE)
|
||
|
||
|
||
@voice_router.message(
|
||
StateFilter(STATE_START),
|
||
ChatTypeFilter(chat_type=["private"]),
|
||
F.text == BTN_LISTEN
|
||
)
|
||
async def standup_listen_audio(message: types.Message, bot_db: BotDB):
|
||
markup = get_main_keyboard()
|
||
|
||
# Создаем сервис для работы с аудио
|
||
voice_service = VoiceBotService(bot_db, bot_db.settings)
|
||
|
||
try:
|
||
# Получаем случайное аудио
|
||
audio_data = voice_service.get_random_audio(message.from_user.id)
|
||
|
||
if not audio_data:
|
||
await message.answer(text=NO_AUDIO_MESSAGE, reply_markup=markup)
|
||
try:
|
||
message_with_date = get_last_message_text(bot_db)
|
||
if message_with_date:
|
||
await message.answer(text=message_with_date, parse_mode="html")
|
||
except Exception as e:
|
||
logger.error(f'Не удалось получить последнюю дату {e}')
|
||
return
|
||
|
||
audio_for_user, date_added, user_emoji = audio_data
|
||
|
||
# Получаем путь к файлу
|
||
path = Path(f'{VOICE_USERS_DIR}/{audio_for_user}.ogg')
|
||
voice = FSInputFile(path)
|
||
|
||
# Маркируем сообщение как прослушанное
|
||
voice_service.mark_audio_as_listened(audio_for_user, message.from_user.id)
|
||
|
||
# Формируем подпись
|
||
if user_emoji:
|
||
caption = f'{user_emoji}\nДата записи: {date_added}'
|
||
else:
|
||
caption = f'Дата записи: {date_added}'
|
||
|
||
await message.bot.send_voice(
|
||
chat_id=message.chat.id,
|
||
voice=voice,
|
||
caption=caption,
|
||
reply_markup=markup
|
||
)
|
||
|
||
# Получаем количество оставшихся аудио
|
||
remaining_count = voice_service.get_remaining_audio_count(message.from_user.id) - 1
|
||
await message.answer(
|
||
text=f'Осталось непрослушанных: <b>{remaining_count}</b>',
|
||
reply_markup=markup
|
||
)
|
||
|
||
except Exception as e:
|
||
logger.error(f"Ошибка при прослушивании аудио: {e}")
|
||
await message.answer(
|
||
text="Произошла ошибка при получении аудио. Попробуйте позже.",
|
||
reply_markup=markup
|
||
)
|