feat: мини-истории, слово дня, меню практики
- Добавлены мини-истории для чтения с выбором жанра и вопросами - Кнопка показа/скрытия перевода истории - Количество вопросов берётся из настроек пользователя - Слово дня генерируется глобально в 00:00 UTC - Кнопка "Практика" открывает меню выбора режима - Убран автоматический create_all при запуске (только миграции) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
from typing import List
|
||||
from typing import List, Optional
|
||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||
from apscheduler.triggers.cron import CronTrigger
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from database.models import User
|
||||
from database.models import User, JLPT_LANGUAGES
|
||||
from database.db import async_session_maker
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -30,9 +30,26 @@ class ReminderService:
|
||||
replace_existing=True
|
||||
)
|
||||
|
||||
# Генерация слов дня в 00:00 UTC
|
||||
self.scheduler.add_job(
|
||||
self.generate_daily_words,
|
||||
trigger=CronTrigger(hour=0, minute=0, timezone='UTC'),
|
||||
id='generate_words_of_day',
|
||||
replace_existing=True
|
||||
)
|
||||
|
||||
self.scheduler.start()
|
||||
logger.info("Планировщик напоминаний запущен")
|
||||
|
||||
async def generate_daily_words(self):
|
||||
"""Генерация слов дня для всех уровней"""
|
||||
try:
|
||||
from services.wordofday_service import wordofday_service
|
||||
results = await wordofday_service.generate_all_words_for_today()
|
||||
logger.info(f"Слова дня сгенерированы: {results}")
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка генерации слов дня: {e}")
|
||||
|
||||
def shutdown(self):
|
||||
"""Остановить планировщик"""
|
||||
self.scheduler.shutdown()
|
||||
@@ -97,6 +114,17 @@ class ReminderService:
|
||||
|
||||
return time_diff < 300 # 5 минут в секундах
|
||||
|
||||
async def _get_user_level(self, user: User) -> str:
|
||||
"""Получить уровень пользователя для текущего языка изучения"""
|
||||
# Сначала проверяем levels_by_language
|
||||
if user.levels_by_language and user.learning_language in user.levels_by_language:
|
||||
return user.levels_by_language[user.learning_language]
|
||||
|
||||
# Иначе используем общий уровень
|
||||
if user.learning_language in JLPT_LANGUAGES:
|
||||
return "N5" # Дефолтный JLPT уровень
|
||||
return user.level.value if user.level else "A1"
|
||||
|
||||
async def _send_reminder(self, user: User, session: AsyncSession):
|
||||
"""
|
||||
Отправить напоминание пользователю
|
||||
@@ -106,18 +134,37 @@ class ReminderService:
|
||||
session: Сессия базы данных
|
||||
"""
|
||||
try:
|
||||
message_text = (
|
||||
"⏰ <b>Время для практики!</b>\n\n"
|
||||
"Не забудь потренироваться сегодня:\n"
|
||||
"• /task - выполни задания\n"
|
||||
"• /practice - попрактикуй диалог\n"
|
||||
"• /words - добавь новые слова\n\n"
|
||||
"💪 Регулярная практика - ключ к успеху!"
|
||||
from services.wordofday_service import wordofday_service
|
||||
from utils.i18n import t
|
||||
|
||||
lang = user.language_interface or "ru"
|
||||
|
||||
# Получаем слово дня для пользователя
|
||||
level = await self._get_user_level(user)
|
||||
word_of_day = await wordofday_service.get_word_of_day(
|
||||
learning_lang=user.learning_language,
|
||||
level=level
|
||||
)
|
||||
|
||||
# Формируем сообщение
|
||||
message_parts = [t(lang, "reminder.daily_title") + "\n"]
|
||||
|
||||
# Добавляем слово дня если есть
|
||||
if word_of_day:
|
||||
word_text = await wordofday_service.format_word_for_user(
|
||||
word_of_day,
|
||||
translation_lang=user.translation_language or user.language_interface,
|
||||
ui_lang=lang
|
||||
)
|
||||
message_parts.append(f"{t(lang, 'reminder.daily_wod')}\n{word_text}\n")
|
||||
|
||||
message_parts.append(t(lang, "reminder.daily_tips"))
|
||||
message_parts.append(f"\n{t(lang, 'reminder.daily_motivation')}")
|
||||
|
||||
await self.bot.send_message(
|
||||
chat_id=user.telegram_id,
|
||||
text=message_text
|
||||
text="\n".join(message_parts),
|
||||
parse_mode="HTML"
|
||||
)
|
||||
|
||||
# Обновляем время последнего напоминания
|
||||
|
||||
Reference in New Issue
Block a user