diff --git a/davtelepot/__init__.py b/davtelepot/__init__.py index 4565090..87201a2 100644 --- a/davtelepot/__init__.py +++ b/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" diff --git a/davtelepot/bot.py b/davtelepot/bot.py index fa4ca7e..8ec5f6f 100644 --- a/davtelepot/bot.py +++ b/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. diff --git a/davtelepot/useful_tools.py b/davtelepot/useful_tools.py index 28cf048..922e0b6 100644 --- a/davtelepot/useful_tools.py +++ b/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']