Мини-игры (/games): - Speed Round: 10 раундов, 10 секунд на ответ, очки за скорость - Match Pairs: 5 слов + 5 переводов, соединить пары Premium-функции: - Поля is_premium и premium_until для пользователей - AI режим проверки ответов (учитывает синонимы) - Batch проверка всех ответов одним запросом Улучшения: - Примеры использования для всех добавляемых слов - Разбиение переводов по запятой на отдельные записи - Полные предложения в контекстах (без ___) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
114 lines
4.1 KiB
Python
114 lines
4.1 KiB
Python
"""
|
||
Скрипт для обновления контекстов слов через AI.
|
||
|
||
Запуск:
|
||
python scripts/update_word_contexts.py
|
||
|
||
Что делает:
|
||
1. Находит слова в word_translations без контекста или с пропуском ___
|
||
2. Генерирует примеры использования через AI
|
||
3. Обновляет записи в БД
|
||
"""
|
||
import asyncio
|
||
import sys
|
||
import os
|
||
|
||
# Добавляем корень проекта в путь
|
||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||
|
||
from sqlalchemy import select, or_
|
||
from database.db import async_session_maker
|
||
from database.models import WordTranslation, Vocabulary
|
||
from services.ai_service import AIService
|
||
|
||
|
||
async def update_contexts():
|
||
"""Обновить контексты для слов"""
|
||
ai_service = AIService()
|
||
|
||
async with async_session_maker() as session:
|
||
# Находим переводы без контекста или с пропуском
|
||
result = await session.execute(
|
||
select(WordTranslation, Vocabulary)
|
||
.join(Vocabulary, WordTranslation.vocabulary_id == Vocabulary.id)
|
||
.where(
|
||
or_(
|
||
WordTranslation.context.is_(None),
|
||
WordTranslation.context == '',
|
||
WordTranslation.context.contains('___')
|
||
)
|
||
)
|
||
.limit(50) # Обрабатываем по 50 за раз
|
||
)
|
||
|
||
rows = result.all()
|
||
|
||
if not rows:
|
||
print("Нет слов для обновления")
|
||
return
|
||
|
||
print(f"Найдено {len(rows)} слов для обновления контекста")
|
||
|
||
# Группируем по языку
|
||
words_by_lang = {}
|
||
for word_translation, vocabulary in rows:
|
||
lang = vocabulary.source_lang or 'en'
|
||
trans_lang = vocabulary.translation_lang or 'ru'
|
||
key = (lang, trans_lang)
|
||
|
||
if key not in words_by_lang:
|
||
words_by_lang[key] = []
|
||
|
||
words_by_lang[key].append({
|
||
'translation_id': word_translation.id,
|
||
'word': vocabulary.word_original,
|
||
'translation': word_translation.translation
|
||
})
|
||
|
||
# Генерируем контексты для каждой группы
|
||
for (learning_lang, translation_lang), words in words_by_lang.items():
|
||
print(f"\nОбработка {len(words)} слов ({learning_lang} -> {translation_lang})...")
|
||
|
||
# Формируем список слов для batch запроса
|
||
words_list = [w['word'] for w in words]
|
||
|
||
# Генерируем примеры через AI
|
||
results = await ai_service.translate_words_batch(
|
||
words=words_list,
|
||
source_lang=learning_lang,
|
||
translation_lang=translation_lang
|
||
)
|
||
|
||
# Обновляем записи
|
||
updated = 0
|
||
for word_data, ai_result in zip(words, results):
|
||
example = ai_result.get('example', '')
|
||
example_translation = ai_result.get('example_translation', '')
|
||
|
||
if example and '___' not in example:
|
||
# Обновляем запись
|
||
word_translation = await session.get(WordTranslation, word_data['translation_id'])
|
||
if word_translation:
|
||
word_translation.context = example
|
||
word_translation.context_translation = example_translation
|
||
updated += 1
|
||
print(f" ✓ {word_data['word']}: {example}")
|
||
|
||
await session.commit()
|
||
print(f"Обновлено {updated} из {len(words)} слов")
|
||
|
||
|
||
async def main():
|
||
print("=== Обновление контекстов слов ===\n")
|
||
|
||
try:
|
||
await update_contexts()
|
||
print("\n✅ Готово!")
|
||
except Exception as e:
|
||
print(f"\n❌ Ошибка: {e}")
|
||
raise
|
||
|
||
|
||
if __name__ == "__main__":
|
||
asyncio.run(main())
|