diff --git a/telebot/asyncio_middlewares.py b/telebot/asyncio_middlewares.py index cf33280..d5d0e4a 100644 --- a/telebot/asyncio_middlewares.py +++ b/telebot/asyncio_middlewares.py @@ -1,3 +1,15 @@ +import contextvars + +try: + from babel.support import LazyProxy + + babel_imported = True +except ImportError: + babel_imported = False + +from telebot import util + + class BaseMiddleware: """ Base class for middleware. @@ -13,3 +25,85 @@ class BaseMiddleware: async def post_process(self, message, data, exception): raise NotImplementedError + + +class I18N(BaseMiddleware): + """ + This middleware provides high-level tool for internationalization + It is based on gettext util. + """ + + context_lang = contextvars.ContextVar('language', default=None) + + def __init__(self, translations_path, domain_name: str): + super().__init__() + self.update_types = self.process_update_types() + + self.path = translations_path + self.domain = domain_name + self.translations = util.find_translations(self.path, self.domain) + + @property + def available_translations(self): + return list(self.translations) + + def gettext(self, text: str, lang: str = None): + """ + Singular translations + """ + + if lang is None: + lang = self.context_lang.get() + + if lang not in self.translations: + return text + + translator = self.translations[lang] + return translator.gettext(text) + + def ngettext(self, singular: str, plural: str, lang: str = None, n=1): + """ + Plural translations + """ + if lang is None: + lang = self.context_lang.get() + + if lang not in self.translations: + if n == 1: + return singular + return plural + + translator = self.translations[lang] + return translator.ngettext(singular, plural, n) + + def lazy_gettext(self, text: str, lang: str = None): + if not babel_imported: + raise RuntimeError('babel module is not imported. Check that you installed it.') + return LazyProxy(self.gettext, text, lang, enable_cache=False) + + def lazy_ngettext(self, singular: str, plural: str, lang: str = None, n=1): + if not babel_imported: + raise RuntimeError('babel module is not imported. Check that you installed it.') + return LazyProxy(self.ngettext, singular, plural, lang, n, enable_cache=False) + + async def get_user_language(self, obj): + """ + You need to override this method and return user language + """ + raise NotImplementedError + + def process_update_types(self) -> list: + """ + You need to override this method and return any update types which you want to be processed + """ + raise NotImplementedError + + async def pre_process(self, message, data): + """ + context language variable will be set each time when update from 'process_update_types' comes + value is the result of 'get_user_language' method + """ + self.context_lang.set(await self.get_user_language(obj=message)) + + async def post_process(self, message, data, exception): + pass