Files
tg_bot_language/services/vocabulary_service.py

144 lines
4.8 KiB
Python
Raw Normal View History

from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from database.models import Vocabulary, WordSource, LanguageLevel
from typing import List, Optional
class VocabularyService:
"""Сервис для работы со словарным запасом"""
@staticmethod
async def add_word(
session: AsyncSession,
user_id: int,
word_original: str,
word_translation: str,
transcription: Optional[str] = None,
examples: Optional[dict] = None,
category: Optional[str] = None,
difficulty_level: Optional[str] = None,
source: WordSource = WordSource.MANUAL,
notes: Optional[str] = None
) -> Vocabulary:
"""
Добавить слово в словарь пользователя
Args:
session: Сессия базы данных
user_id: ID пользователя
word_original: Оригинальное слово
word_translation: Перевод
transcription: Транскрипция
examples: Примеры использования
category: Категория слова
difficulty_level: Уровень сложности
source: Источник добавления
notes: Заметки пользователя
Returns:
Созданный объект слова
"""
# Преобразование difficulty_level в enum
difficulty_enum = None
if difficulty_level:
try:
difficulty_enum = LanguageLevel[difficulty_level]
except KeyError:
difficulty_enum = None
new_word = Vocabulary(
user_id=user_id,
word_original=word_original,
word_translation=word_translation,
transcription=transcription,
examples=examples,
category=category,
difficulty_level=difficulty_enum,
source=source,
notes=notes
)
session.add(new_word)
await session.commit()
await session.refresh(new_word)
return new_word
@staticmethod
async def get_user_words(session: AsyncSession, user_id: int, limit: int = 50) -> List[Vocabulary]:
"""
Получить все слова пользователя
Args:
session: Сессия базы данных
user_id: ID пользователя
limit: Максимальное количество слов
Returns:
Список слов пользователя
"""
result = await session.execute(
select(Vocabulary)
.where(Vocabulary.user_id == user_id)
.order_by(Vocabulary.created_at.desc())
.limit(limit)
)
return list(result.scalars().all())
@staticmethod
async def get_words_count(session: AsyncSession, user_id: int) -> int:
"""
Получить количество слов в словаре пользователя
Args:
session: Сессия базы данных
user_id: ID пользователя
Returns:
Количество слов
"""
result = await session.execute(
select(Vocabulary).where(Vocabulary.user_id == user_id)
)
return len(list(result.scalars().all()))
@staticmethod
async def find_word(session: AsyncSession, user_id: int, word: str) -> Optional[Vocabulary]:
"""
Найти слово в словаре пользователя
Args:
session: Сессия базы данных
user_id: ID пользователя
word: Слово для поиска
Returns:
Объект слова или None
"""
result = await session.execute(
select(Vocabulary)
.where(Vocabulary.user_id == user_id)
.where(Vocabulary.word_original.ilike(f"%{word}%"))
)
return result.scalar_one_or_none()
Добавлены основные функции MVP: тематические подборки, импорт слов, диалоговая практика, напоминания и тест уровня Новые команды: - /words [тема] - AI-генерация тематических подборок слов (10 слов по теме с учётом уровня) - /import - извлечение до 15 ключевых слов из текста (книги, статьи, песни) - /practice - диалоговая практика с AI в 6 сценариях (ресторан, магазин, путешествие, работа, врач, общение) - /reminder - настройка ежедневных напоминаний по расписанию - /level_test - тест из 7 вопросов для определения уровня английского (A1-C2) Основные изменения: - AI сервис: добавлены методы generate_thematic_words, extract_words_from_text, start_conversation, continue_conversation, generate_level_test - Диалоговая практика: исправление ошибок в реальном времени, подсказки, перевод реплик - Напоминания: APScheduler для ежедневной отправки напоминаний в выбранное время - Тест уровня: автоматическое определение уровня при регистрации, можно пропустить - База данных: добавлены поля reminders_enabled, last_reminder_sent - Vocabulary service: метод get_word_by_original для проверки дубликатов - Зависимости: apscheduler==3.10.4 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 15:46:02 +03:00
@staticmethod
async def get_word_by_original(session: AsyncSession, user_id: int, word: str) -> Optional[Vocabulary]:
"""
Получить слово по точному совпадению
Args:
session: Сессия базы данных
user_id: ID пользователя
word: Слово для поиска (точное совпадение)
Returns:
Объект слова или None
"""
result = await session.execute(
select(Vocabulary)
.where(Vocabulary.user_id == user_id)
.where(Vocabulary.word_original == word.lower())
)
return result.scalar_one_or_none()