Files
tg_bot_language/bot/handlers/wordofday.py

157 lines
5.4 KiB
Python
Raw Normal View History

"""Handler для функции 'Слово дня'."""
from datetime import datetime
from aiogram import Router, F
from aiogram.filters import Command
from aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
from database.db import async_session_maker
from database.models import WordOfDay, WordSource
from services.user_service import UserService
from services.vocabulary_service import VocabularyService
from services.wordofday_service import wordofday_service
from utils.i18n import t, get_user_lang, get_user_translation_lang
from utils.levels import get_user_level_for_language
router = Router()
def format_word_of_day(wod: WordOfDay, lang: str) -> str:
"""Форматировать слово дня для отображения."""
date_str = wod.date.strftime("%d.%m.%Y")
text = f"🌅 <b>{t(lang, 'wod.title')}</b> — {date_str}\n\n"
text += f"📝 <b>{wod.word}</b>\n"
if wod.transcription:
text += f"🔊 [{wod.transcription}]\n"
text += f"\n💬 {wod.translation}\n"
# Примеры
if wod.examples:
text += f"\n📖 <b>{t(lang, 'wod.examples')}:</b>\n"
for ex in wod.examples[:2]:
sentence = ex.get('sentence', '')
translation = ex.get('translation', '')
text += f"• <i>{sentence}</i>\n"
if translation:
text += f" ({translation})\n"
# Синонимы
if wod.synonyms:
text += f"\n🔗 <b>{t(lang, 'wod.synonyms')}:</b> {wod.synonyms}\n"
# Этимология/интересный факт
if wod.etymology:
text += f"\n💡 {wod.etymology}\n"
return text
@router.message(Command("wordofday"))
async def cmd_wordofday(message: Message):
"""Обработчик команды /wordofday."""
async with async_session_maker() as session:
user = await UserService.get_user_by_telegram_id(session, message.from_user.id)
if not user:
await message.answer(t('ru', 'common.start_first'))
return
lang = get_user_lang(user)
learning_lang = user.learning_language or 'en'
level = get_user_level_for_language(user)
# Получаем слово дня из глобальной таблицы
wod = await wordofday_service.get_word_of_day(
learning_lang=learning_lang,
level=level
)
if not wod:
# Слово ещё не сгенерировано - показываем сообщение
await message.answer(t(lang, 'wod.not_available'))
return
# Форматируем и отправляем
text = format_word_of_day(wod, lang)
# Кнопка добавления в словарь
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(
text=t(lang, 'wod.add_btn'),
callback_data=f"wod_add_{wod.id}"
)]
])
await message.answer(text, reply_markup=keyboard)
@router.callback_query(F.data.startswith("wod_add_"))
async def wod_add_callback(callback: CallbackQuery):
"""Добавить слово дня в словарь."""
await callback.answer()
wod_id = int(callback.data.replace("wod_add_", ""))
async with async_session_maker() as session:
user = await UserService.get_user_by_telegram_id(session, callback.from_user.id)
lang = get_user_lang(user)
# Получаем слово дня
wod = await session.get(WordOfDay, wod_id)
if not wod:
await callback.answer(t(lang, 'wod.not_found'), show_alert=True)
return
# Проверяем, нет ли уже в словаре
existing = await VocabularyService.get_word_by_original(
session, user.id, wod.word, source_lang=wod.learning_lang
)
if existing:
await callback.answer(t(lang, 'words.already_exists', word=wod.word), show_alert=True)
return
# Добавляем в словарь
translation_lang = get_user_translation_lang(user)
new_word = await VocabularyService.add_word(
session=session,
user_id=user.id,
word_original=wod.word,
word_translation=wod.translation,
source_lang=wod.learning_lang,
translation_lang=translation_lang,
transcription=wod.transcription,
difficulty_level=wod.level,
source=WordSource.SUGGESTED
)
# Добавляем переводы в word_translations (разбиваем по запятой)
# Берём первый пример из examples если есть
example = None
example_translation = None
if wod.examples and len(wod.examples) > 0:
example = wod.examples[0].get('sentence')
example_translation = wod.examples[0].get('translation')
await VocabularyService.add_translation_split(
session=session,
vocabulary_id=new_word.id,
translation=wod.translation,
context=example,
context_translation=example_translation,
is_primary=True
)
await session.commit()
# Обновляем сообщение
text = format_word_of_day(wod, lang)
text += f"\n✅ <i>{t(lang, 'wod.added')}</i>"
await callback.message.edit_text(text, reply_markup=None)