- Add separate level systems: CEFR (A1-C2) for European languages, JLPT (N5-N1) for Japanese - Store levels per language in new `levels_by_language` JSON field - Add custom scenario option in AI practice mode - Show action buttons after practice ends (new dialogue, tasks, words) - Fix level display across all handlers to use correct level system - Add Alembic migration for levels_by_language field - Update all locale files (ru, en, ja) with new keys 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
99 lines
3.4 KiB
Python
99 lines
3.4 KiB
Python
"""
|
||
Утилиты для работы с уровнями языка (CEFR и JLPT)
|
||
"""
|
||
from database.models import JLPT_LANGUAGES, DEFAULT_CEFR_LEVEL, DEFAULT_JLPT_LEVEL
|
||
|
||
|
||
# Все доступные уровни по системам
|
||
CEFR_LEVELS = ["A1", "A2", "B1", "B2", "C1", "C2"]
|
||
JLPT_LEVELS = ["N5", "N4", "N3", "N2", "N1"]
|
||
|
||
|
||
def get_level_system(learning_language: str) -> str:
|
||
"""Определить систему уровней для языка"""
|
||
return "jlpt" if learning_language in JLPT_LANGUAGES else "cefr"
|
||
|
||
|
||
def get_available_levels(learning_language: str) -> list[str]:
|
||
"""Получить список доступных уровней для языка"""
|
||
if learning_language in JLPT_LANGUAGES:
|
||
return JLPT_LEVELS
|
||
return CEFR_LEVELS
|
||
|
||
|
||
def get_default_level(learning_language: str) -> str:
|
||
"""Получить дефолтный уровень для языка"""
|
||
if learning_language in JLPT_LANGUAGES:
|
||
return DEFAULT_JLPT_LEVEL
|
||
return DEFAULT_CEFR_LEVEL
|
||
|
||
|
||
def get_user_level_for_language(user, language: str = None) -> str:
|
||
"""
|
||
Получить уровень пользователя для конкретного языка.
|
||
|
||
Args:
|
||
user: Объект пользователя
|
||
language: Код языка (если None, берётся learning_language пользователя)
|
||
|
||
Returns:
|
||
Строка уровня (например "B1" или "N4")
|
||
"""
|
||
if language is None:
|
||
language = user.learning_language or "en"
|
||
|
||
# Пытаемся получить из JSON поля
|
||
levels = user.levels_by_language or {}
|
||
if language in levels:
|
||
return levels[language]
|
||
|
||
# Fallback на старое поле level (для CEFR языков)
|
||
if language not in JLPT_LANGUAGES and user.level:
|
||
return user.level.value
|
||
|
||
# Возвращаем дефолт
|
||
return get_default_level(language)
|
||
|
||
|
||
def set_user_level_for_language(user, level: str, language: str = None) -> dict:
|
||
"""
|
||
Установить уровень пользователя для конкретного языка.
|
||
|
||
Args:
|
||
user: Объект пользователя
|
||
level: Уровень (например "B1" или "N4")
|
||
language: Код языка (если None, берётся learning_language пользователя)
|
||
|
||
Returns:
|
||
Обновлённый словарь levels_by_language
|
||
"""
|
||
if language is None:
|
||
language = user.learning_language or "en"
|
||
|
||
# Инициализируем JSON если его нет
|
||
if user.levels_by_language is None:
|
||
user.levels_by_language = {}
|
||
|
||
# Копируем для изменения (SQLAlchemy требует новый объект для JSON)
|
||
levels = dict(user.levels_by_language)
|
||
levels[language] = level
|
||
user.levels_by_language = levels
|
||
|
||
return levels
|
||
|
||
|
||
def get_level_key_for_i18n(learning_language: str, level: str) -> str:
|
||
"""
|
||
Получить ключ локализации для уровня.
|
||
|
||
Args:
|
||
learning_language: Язык изучения
|
||
level: Уровень
|
||
|
||
Returns:
|
||
Ключ для функции t() (например "settings.level.b1" или "settings.jlpt.n4")
|
||
"""
|
||
if learning_language in JLPT_LANGUAGES:
|
||
return f"settings.jlpt.{level.lower()}"
|
||
return f"settings.level.{level.lower()}"
|