diff --git a/.env.example b/.env.example index 4ccc38b0..d9589826 100644 --- a/.env.example +++ b/.env.example @@ -340,6 +340,8 @@ MAINTENANCE_MESSAGE=Ведутся технические работы. Серв # Укажите язык из AVAILABLE_LANGUAGES. При некорректном значении используется ru. DEFAULT_LANGUAGE=ru AVAILABLE_LANGUAGES=ru,en +# Включить выбор языка при старте и отображение кнопки в меню +LANGUAGE_SELECTION_ENABLED=true # ===== ДОПОЛНИТЕЛЬНЫЕ НАСТРОЙКИ ===== # Конфигурация приложений для гайда подключения diff --git a/README.md b/README.md index 2a23b022..189ad150 100644 --- a/README.md +++ b/README.md @@ -584,6 +584,8 @@ MAINTENANCE_MESSAGE=Ведутся технические работы. Серв # Укажите язык из AVAILABLE_LANGUAGES. При некорректном значении используется ru. DEFAULT_LANGUAGE=ru AVAILABLE_LANGUAGES=ru,en +# Включить выбор языка при старте и отображение кнопки в меню +LANGUAGE_SELECTION_ENABLED=true # ===== ДОПОЛНИТЕЛЬНЫЕ НАСТРОЙКИ ===== # Конфигурация приложений для гайда подключения diff --git a/app/config.py b/app/config.py index b098201b..286434d3 100644 --- a/app/config.py +++ b/app/config.py @@ -226,6 +226,7 @@ class Settings(BaseSettings): DEFAULT_LANGUAGE: str = "ru" AVAILABLE_LANGUAGES: str = "ru,en" + LANGUAGE_SELECTION_ENABLED: bool = True LOG_LEVEL: str = "INFO" LOG_FILE: str = "logs/bot.log" @@ -452,7 +453,10 @@ class Settings(BaseSettings): return ["ru", "en"] except AttributeError: return ["ru", "en"] - + + def is_language_selection_enabled(self) -> bool: + return bool(getattr(self, "LANGUAGE_SELECTION_ENABLED", True)) + def format_price(self, price_kopeks: int) -> str: rubles = price_kopeks // 100 return f"{rubles} ₽" diff --git a/app/handlers/menu.py b/app/handlers/menu.py index 8b25b4e6..7c8d56d4 100644 --- a/app/handlers/menu.py +++ b/app/handlers/menu.py @@ -105,6 +105,16 @@ async def show_language_menu( ): texts = get_texts(db_user.language) + if not settings.is_language_selection_enabled(): + await callback.answer( + texts.t( + "LANGUAGE_SELECTION_DISABLED", + "⚙️ Выбор языка временно недоступен.", + ), + show_alert=True, + ) + return + await edit_or_answer_photo( callback=callback, caption=texts.t("LANGUAGE_PROMPT", "🌐 Выберите язык интерфейса:"), @@ -123,6 +133,18 @@ async def process_language_change( db_user: User, db: AsyncSession, ): + texts = get_texts(db_user.language) + + if not settings.is_language_selection_enabled(): + await callback.answer( + texts.t( + "LANGUAGE_SELECTION_DISABLED", + "⚙️ Выбор языка временно недоступен.", + ), + show_alert=True, + ) + return + selected_raw = (callback.data or "").split(":", 1)[-1] normalized_selected = selected_raw.strip().lower() @@ -139,7 +161,6 @@ async def process_language_change( resolved_language = available_map[normalized_selected].lower() if db_user.language.lower() == normalized_selected: - texts = get_texts(db_user.language) await show_main_menu( callback, db_user, diff --git a/app/handlers/start.py b/app/handlers/start.py index b4d3bfa1..780f44c3 100644 --- a/app/handlers/start.py +++ b/app/handlers/start.py @@ -404,8 +404,22 @@ async def cmd_start(message: types.Message, state: FSMContext, db: AsyncSession, data = await state.get_data() or {} if not data.get('language'): - await _prompt_language_selection(message, state) - return + if settings.is_language_selection_enabled(): + await _prompt_language_selection(message, state) + return + + default_language = ( + (settings.DEFAULT_LANGUAGE or DEFAULT_LANGUAGE) + if isinstance(settings.DEFAULT_LANGUAGE, str) + else DEFAULT_LANGUAGE + ) + normalized_default = default_language.split("-")[0].lower() + data['language'] = normalized_default + await state.set_data(data) + logger.info( + "🌐 LANGUAGE: выбор языка отключен, устанавливаем язык по умолчанию '%s'", + normalized_default, + ) await _continue_registration_after_language( message=message, @@ -424,6 +438,44 @@ async def process_language_selection( f"🌐 LANGUAGE: Пользователь {callback.from_user.id} выбрал язык ({callback.data})" ) + if not settings.is_language_selection_enabled(): + data = await state.get_data() or {} + default_language = ( + (settings.DEFAULT_LANGUAGE or DEFAULT_LANGUAGE) + if isinstance(settings.DEFAULT_LANGUAGE, str) + else DEFAULT_LANGUAGE + ) + normalized_default = default_language.split("-")[0].lower() + data['language'] = normalized_default + await state.set_data(data) + + texts = get_texts(normalized_default) + + try: + await callback.message.edit_text( + texts.t( + "LANGUAGE_SELECTION_DISABLED", + "⚙️ Выбор языка временно недоступен. Используем язык по умолчанию.", + ) + ) + except Exception: + await callback.message.answer( + texts.t( + "LANGUAGE_SELECTION_DISABLED", + "⚙️ Выбор языка временно недоступен. Используем язык по умолчанию.", + ) + ) + + await callback.answer() + + await _continue_registration_after_language( + message=None, + callback=callback, + state=state, + db=db, + ) + return + selected_raw = (callback.data or "").split(":", 1)[-1] normalized_selected = selected_raw.strip().lower() diff --git a/app/keyboards/inline.py b/app/keyboards/inline.py index b8033c70..f2f89624 100644 --- a/app/keyboards/inline.py +++ b/app/keyboards/inline.py @@ -273,9 +273,10 @@ def get_main_menu_keyboard( support_row.append(InlineKeyboardButton(text=texts.MENU_RULES, callback_data="menu_rules")) keyboard.append(support_row) - keyboard.append([ - InlineKeyboardButton(text=texts.MENU_LANGUAGE, callback_data="menu_language") - ]) + if settings.is_language_selection_enabled(): + keyboard.append([ + InlineKeyboardButton(text=texts.MENU_LANGUAGE, callback_data="menu_language") + ]) if settings.DEBUG: print(f"DEBUG KEYBOARD: is_admin={is_admin}, добавляем админ кнопку: {is_admin}") diff --git a/app/services/system_settings_service.py b/app/services/system_settings_service.py index 9f2bec98..8238179b 100644 --- a/app/services/system_settings_service.py +++ b/app/services/system_settings_service.py @@ -161,6 +161,7 @@ class BotConfigurationService: "PAYMENT_BALANCE_TEMPLATE": "PAYMENT", "PAYMENT_SUBSCRIPTION_TEMPLATE": "PAYMENT", "INACTIVE_USER_DELETE_MONTHS": "MONITORING", + "LANGUAGE_SELECTION_ENABLED": "LOCALIZATION", } CATEGORY_PREFIX_OVERRIDES: Dict[str, str] = {