Queer European MD passionate about IT
Эх сурвалжийг харах

Support for multiple languages

Davte 5 жил өмнө
parent
commit
6075e5513b

+ 1 - 1
davtelepot/__init__.py

@@ -14,7 +14,7 @@ __author__ = "Davide Testa"
 __email__ = "davide@davte.it"
 __credits__ = ["Marco Origlia", "Nick Lee @Nickoala"]
 __license__ = "GNU General Public License v3.0"
-__version__ = "2.1.16"
+__version__ = "2.1.17"
 __maintainer__ = "Davide Testa"
 __contact__ = "t.me/davte"
 

+ 0 - 2
davtelepot/administration_tools.py

@@ -491,8 +491,6 @@ async def _talk_button(update, bot):
 
 def init(bot):
     """Assign parsers, commands, buttons and queries to given `bot`."""
-    if not hasattr(bot, 'messages'):
-        bot.messages = dict()
     bot.messages['talk'] = TALK_MESSAGES
     with bot.db as db:
         if 'talking_sessions' not in db.tables:

+ 3 - 1
davtelepot/bot.py

@@ -47,6 +47,7 @@ from aiohttp import web
 # Project modules
 from .api import TelegramBot, TelegramError
 from .database import ObjectWithDatabase
+from .languages import MultiLanguageObject
 from .utilities import (
     escape_html_chars, extract, get_secure_key, make_inline_query_answer,
     make_lines_of_buttons, remove_html_tags
@@ -56,7 +57,7 @@ from .utilities import (
 logging.getLogger('aiohttp').setLevel(logging.WARNING)
 
 
-class Bot(TelegramBot, ObjectWithDatabase):
+class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
     """Simple Bot object, providing methods corresponding to Telegram bot API.
 
     Multiple Bot() instances may be run together, along with a aiohttp web app.
@@ -107,6 +108,7 @@ class Bot(TelegramBot, ObjectWithDatabase):
         # Call superclasses constructors with proper arguments
         TelegramBot.__init__(self, token)
         ObjectWithDatabase.__init__(self, database_url=database_url)
+        MultiLanguageObject.__init__(self)
         self._path = None
         self.preliminary_tasks = []
         self.final_tasks = []

+ 88 - 0
davtelepot/languages.py

@@ -0,0 +1,88 @@
+"""Bot support for multiple languages."""
+
+# Standard library modules
+import logging
+
+# Project modules
+from .utilities import extract
+
+
+class MultiLanguageObject(object):
+    """Make bot inherit from this class to make it support multiple languages.
+
+    Call MultiLanguage().get_message(
+        field1, field2, ...,
+        update, user_record, language,
+        format_kwarg1, format_kwarg2, ...
+    ) to get the corresponding message in the selected language.
+    """
+
+    def __init__(self):
+        """Instantiate MultiLanguage object, setting self.messages."""
+        self.messages = dict()
+
+    def get_message(self, *fields, update=dict(), user_record=dict(),
+                    language=None, **format_kwargs):
+        """Given a list of strings (`fields`), return proper message.
+
+        Language will be selected in this order:
+        - `language` parameter
+        - `user_record['selected_language_code']`: language selected by user
+        - `update['language_code']`: language of incoming telegram update
+        - Fallback to English if none of the above fits
+
+        `format_kwargs` will be passed to format function on the result.
+        """
+        # Choose language
+        if (
+            language is None
+            and 'selected_language_code' in user_record
+        ):
+            language = user_record['selected_language_code']
+        if (
+            language is None
+            and 'from' in update
+            and 'language_code' in update['from']
+        ):
+            language = update['from']['language_code']
+        if language is None:
+            language = 'en'
+        # Find result for `language`
+        result = self.messages
+        for field in fields:
+            if field not in result:
+                logging.error(
+                    "Please define self.message{f}".format(
+                        f=''.join(
+                            '[\'{field}\']'.format(
+                                field=field
+                            )
+                            for field in fields
+                        )
+                    )
+                )
+                return "Invalid message!"
+            result = result[field]
+        if language not in result:
+            # For specific languages, try generic ones
+            language = extract(
+                language,
+                ender='-'
+            )
+            if language not in result:
+                language = 'en'
+                if language not in result:
+                    logging.error(
+                        "Please define self.message{f}['en']".format(
+                            f=''.join(
+                                '[\'{field}\']'.format(
+                                    field=field
+                                )
+                                for field in fields
+                            )
+                        )
+                    )
+                    return "Invalid message!"
+        return result[language].format(
+            **format_kwargs
+        )