From 38f3b1ad743a4259ab2540a877581abfa8ce46b7 Mon Sep 17 00:00:00 2001 From: machka-pasla Date: Wed, 3 Sep 2025 16:28:02 +0300 Subject: [PATCH] Enhance localization and fallback logic in i18n middleware - Improved the effective language determination process by adding robust fallbacks to ensure a valid language is always used. - Updated the gettext method to include explicit fallback to English if the requested language data is unavailable. - Corrected a typo in the Russian localization for auto-renewal messaging to ensure clarity in user notifications. --- bot/middlewares/i18n.py | 19 ++++++++++++++++++- locales/ru.json | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/bot/middlewares/i18n.py b/bot/middlewares/i18n.py index 80bb2b8..7140bb5 100644 --- a/bot/middlewares/i18n.py +++ b/bot/middlewares/i18n.py @@ -45,10 +45,27 @@ class JsonI18n: exc_info=True) def gettext(self, lang_code: Optional[str], key: str, **kwargs) -> str: - effective_lang_code = lang_code if lang_code and lang_code in self.locales_data else self.default_lang + # Determine effective language with robust fallback + if lang_code and lang_code in self.locales_data: + effective_lang_code = lang_code + elif self.default_lang in self.locales_data: + effective_lang_code = self.default_lang + elif 'en' in self.locales_data: + effective_lang_code = 'en' + else: + effective_lang_code = lang_code or self.default_lang lang_data = self.locales_data.get(effective_lang_code) if lang_data is None: + # Try explicit fallback to English if available + fallback_data = self.locales_data.get('en') + if fallback_data is not None: + text = fallback_data.get(key) + if text is not None: + try: + return text.format(**kwargs) if kwargs else text + except Exception: + return text logging.warning( f"No language data for '{effective_lang_code}' (default '{self.default_lang}' also missing). Key '{key}' will be returned as is." ) diff --git a/locales/ru.json b/locales/ru.json index 651b26d..53a60b8 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -140,7 +140,7 @@ "subscription_expired_notification": "πŸ‘‹ ΠŸΡ€ΠΈΠ²Π΅Ρ‚, {user_name}!\n\nβ›” Π‘Ρ€ΠΎΠΊ вашСй подписки Π½Π° VPN истСк ({end_date}).\n\nΠŸΡ€ΠΎΠ΄Π»ΠΈΡ‚Π΅ Π΅Ρ‘ ΠΏΠΎ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π½ΠΈΠΆΠ΅.", "subscription_expired_yesterday_notification": "πŸ‘‹ ΠŸΡ€ΠΈΠ²Π΅Ρ‚, {user_name}!\n\n⏳ Π’Π°ΡˆΠ° подписка Π½Π° VPN истСкла сутки Π½Π°Π·Π°Π΄ ({end_date}).\n\nΠŸΡ€ΠΎΠ΄Π»ΠΈΡ‚Π΅ Π΅Ρ‘ ΠΏΠΎ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π½ΠΈΠΆΠ΅.", "tribute_subscription_cancelled": "🚨 Подписка ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Π°\n\nΠ’Π°ΡˆΠ° подписка Tribute Π±Ρ‹Π»Π° ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Π°. Π£ вас Π΅ΡΡ‚ΡŒ 24 часа для восстановлСния доступа, послС Ρ‡Π΅Π³ΠΎ подписка Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π°.\n\nДля продлСния подписки Π½Π°ΠΆΠΌΠΈΡ‚Π΅ ΠΊΠ½ΠΎΠΏΠΊΡƒ Π½ΠΈΠΆΠ΅.", - "yookassa_auto_renewal": "πŸ”„ Подписка автоматичСски ΠΏΡ€ΠΎΠ΄Π»Π΅Π½Π°\n\nΠ’Π°ΡˆΠ° подписка Π±Ρ‹Π»Π° автоматичСскΠΈ ΠΏΡ€ΠΎΠ΄Π»Π΅Π½Π° Π½Π° {months} мСс.\nНовая Π΄Π°Ρ‚Π° окончания: {end_date}", + "yookassa_auto_renewal": "πŸ”„ Подписка автоматичСски ΠΏΡ€ΠΎΠ΄Π»Π΅Π½Π°\n\nΠ’Π°ΡˆΠ° подписка Π±Ρ‹Π»Π° автоматичСски ΠΏΡ€ΠΎΠ΄Π»Π΅Π½Π° Π½Π° {months} мСс.\nНовая Π΄Π°Ρ‚Π° окончания: {end_date}", "admin_promo_set_validity_days": "⏰ Π£ΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ срок (Π΄Π½ΠΈ)", "admin_back_to_panel": "⬅️ Π’ панСль", "admin_promo_unlimited": "♾️ НСограничСнно",