Queer European MD passionate about IT
Browse Source

Pass to handlers the parameters they take and preserve update_id

Davte 4 years ago
parent
commit
12cca835b9
3 changed files with 34 additions and 23 deletions
  1. 1 1
      davtelepot/__init__.py
  2. 31 17
      davtelepot/bot.py
  3. 2 5
      davtelepot/useful_tools.py

+ 1 - 1
davtelepot/__init__.py

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

+ 31 - 17
davtelepot/bot.py

@@ -596,11 +596,16 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
 
     async def message_router(self, update, user_record, language):
         """Route Telegram `message` update to appropriate message handler."""
-        for key, value in update.items():
-            if key in self.message_handlers:
-                return await self.message_handlers[key](update=update,
-                                                        user_record=user_record,
-                                                        language=language)
+        bot = self
+        for key in self.message_handlers:
+            if key in update:
+                return await self.message_handlers[key](**{
+                    name: argument
+                    for name, argument in locals().items()
+                    if name in inspect.signature(
+                        self.message_handlers[key]
+                    ).parameters
+                })
         logging.error(
             f"The following message update was received: {update}\n"
             "However, this message type is unknown."
@@ -2933,7 +2938,11 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
         """Set `handler` as router for `event`."""
         self.routing_table[event] = handler
 
-    async def route_update(self, update):
+    def set_message_handler(self, message_type: str, handler: Callable):
+        """Set `handler` for `message_type`."""
+        self.message_handlers[message_type] = handler
+
+    async def route_update(self, raw_update):
         """Pass `update` to proper method.
 
         Update objects have two keys:
@@ -2952,20 +2961,25 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
         """
         if (
             self.under_maintenance
-            and not self.is_allowed_during_maintenance(update)
+            and not self.is_allowed_during_maintenance(raw_update)
         ):
-            return await self.handle_update_during_maintenance(update)
-        for key, value in update.items():
-            if key in self.routing_table:
-                user_record = self.get_user_record(update=value)
+            return await self.handle_update_during_maintenance(raw_update)
+        for key in self.routing_table:
+            if key in raw_update:
+                update = raw_update[key]
+                update['update_id'] = raw_update['update_id']
+                user_record = self.get_user_record(update=update)
                 language = self.get_language(update=update,
                                              user_record=user_record)
-                return await self.routing_table[key](
-                    update=value,
-                    user_record=user_record,
-                    language=language
-                )
-        logging.error(f"Unknown type of update.\n{update}")
+                bot = self
+                return await self.routing_table[key](**{
+                    name: argument
+                    for name, argument in locals().items()
+                    if name in inspect.signature(
+                        self.routing_table[key]
+                    ).parameters
+                })
+        logging.error(f"Unknown type of update.\n{raw_update}")
 
     def additional_task(self, when='BEFORE', *args, **kwargs):
         """Add a task before at app start or cleanup.

+ 2 - 5
davtelepot/useful_tools.py

@@ -381,11 +381,8 @@ async def calculate_session(bot: Bot,
         return
     expression = record['expression'] or ''
     reply_markup = get_calculator_keyboard(additional_data=[record['id']])
-
-    # It would be nice to do:
-    # for update in sorted(queue, key=lambda u: u['id'])
-    # Alas, 'id's are not progressive... Telegram's fault!
-    for i, update in enumerate(queue):
+    # Process updates in order of arrival (according to Telegram servers)
+    for i, update in enumerate(sorted(queue, key=lambda u: u['update_id'])):
         if i % 5 == 0:
             await asyncio.sleep(.1)
         data = update['data']