From a10dd419d76e2111325525b3ec8c3faba69028cd Mon Sep 17 00:00:00 2001 From: Ling-ex Date: Sat, 24 May 2025 18:01:07 +0000 Subject: [PATCH 1/3] Fix: Register RawUpdateHandler and Refactor Dispatcher for Better Modularity. Signed-off-by: Ling-ex --- pyrogram/dispatcher.py | 122 ++++++++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 50 deletions(-) diff --git a/pyrogram/dispatcher.py b/pyrogram/dispatcher.py index 5cb97b5e..c5f166d5 100644 --- a/pyrogram/dispatcher.py +++ b/pyrogram/dispatcher.py @@ -21,6 +21,7 @@ import asyncio import inspect import logging from collections import OrderedDict +from typing import Any import pyrogram from pyrogram import raw, types, utils @@ -337,59 +338,88 @@ class Dispatcher: async def handler_worker(self, lock: asyncio.Lock): while True: packet = await self.updates_queue.get() + if packet is None: break - await self._process_packet(packet, lock) - async def _process_packet( - self, - packet: tuple[raw.core.TLObject, dict[int, types.Update], dict[int, types.Update]], - lock: asyncio.Lock, + try: + await self._handle_packet(packet, lock) + except pyrogram.StopPropagation: + pass + except Exception as e: + log.exception(e) + finally: + self.updates_queue.task_done() + + async def _handle_packet(self, packet, lock: asyncio.Lock): + update, users, chats = packet + parser = self.update_parsers.get(type(update)) + + parsed_update, handler_type = ( + await parser(update, users, chats) + if parser is not None else (None, type(None)) + ) + async with lock: + await self._dispatch_to_handlers(update, users, chats, parsed_update, handler_type) + + + async def _dispatch_to_handlers( + self, update, users, chats, parsed_update, handler_type, + ): + for group in self.groups.values(): + for handler in group: + args = await self._match_handler( + handler, update, users, chats, parsed_update, handler_type, + ) + if args is None: + continue + + try: + await self._execute_handler(handler, *args) + except pyrogram.StopPropagation: + raise + except pyrogram.ContinuePropagation: + continue + except Exception as error: + if parsed_update is not None: + await self._handle_exception(parsed_update, error) + break + + async def _match_handler( + self, handler, update, users, chats, parsed_update, handler_type, ): try: - update, users, chats = packet - parser = self.update_parsers.get(type(update)) - - if parser is not None: - parsed_result = parser(update, users, chats) - if inspect.isawaitable(parsed_result): - parsed_update, handler_type = await parsed_result - else: - parsed_update, handler_type = parsed_result - else: - parsed_update, handler_type = (None, type(None)) - - async with lock: - for group in self.groups.values(): - for handler in group: - try: - if parsed_update is not None: - if isinstance(handler, handler_type) and await handler.check( - self.client, parsed_update - ): - await self._execute_callback(handler, parsed_update) - break - elif isinstance(handler, RawUpdateHandler): - await self._execute_callback(handler, update, users, chats) - break - except (pyrogram.StopPropagation, pyrogram.ContinuePropagation) as e: - if isinstance(e, pyrogram.StopPropagation): - raise - except Exception as exception: - if parsed_update is not None: - await self._handle_exception(parsed_update, exception) - except pyrogram.StopPropagation: - pass + if isinstance(handler, handler_type): + if await handler.check(self.client, parsed_update): + return (parsed_update,) + elif isinstance(handler, RawUpdateHandler): + if await handler.check(self.client, update): + return (update, users, chats) except Exception as e: log.exception(e) - finally: - self.updates_queue.task_done() - async def _handle_exception(self, parsed_update: types.Update, exception: Exception): + return None + + async def _execute_handler(self, handler, *args: Any): + if inspect.iscoroutinefunction(handler.callback): + await handler.callback(self.client, *args) + else: + await self.loop.run_in_executor( + self.client.executor, + handler.callback, + self.client, + *args + ) + + async def _handle_exception( + self, parsed_update: types.Update, exception: Exception, + ): handled_error = False for error_handler in self.error_handlers: try: - if await error_handler.check(self.client, parsed_update, exception): + if await error_handler.check( + self.client, parsed_update, exception, + ): handled_error = True break except pyrogram.StopPropagation: @@ -401,11 +431,3 @@ class Dispatcher: if not handled_error: log.exception("Unhandled exception: %s", exception) - - async def _execute_callback(self, handler: Handler, *args): - if inspect.iscoroutinefunction(handler.callback): - await handler.callback(self.client, *args) - else: - await self.client.loop.run_in_executor( - self.client.executor, handler.callback, self.client, *args - ) \ No newline at end of file From b2ca66bb9e835df9010e7d8aa5383814bfba8221 Mon Sep 17 00:00:00 2001 From: Ling-ex Date: Sat, 24 May 2025 18:01:40 +0000 Subject: [PATCH 2/3] Update Gift class: add ton_address and clarify owner info. Signed-off-by: Ling-ex --- pyrogram/types/payments/gift.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/pyrogram/types/payments/gift.py b/pyrogram/types/payments/gift.py index 348a937d..2af51f66 100644 --- a/pyrogram/types/payments/gift.py +++ b/pyrogram/types/payments/gift.py @@ -77,13 +77,16 @@ class Gift(Object): User who sent the star gift. owner (:obj:`~pyrogram.types.Chat`, *optional*): - Current gift owner. + Only available if the nfts is in telegram. owner_name (``str``, *optional*): Name of the user who received the star gift. owner_address (``str``, *optional*): - Address of the gift owner in TON blockchain. + Only available if the nfts is in ton network. + + ton_address (``str``, *optional*): + Only available if the nfts is in ton network. price (``int``, *optional*): Price of this gift in stars. @@ -141,7 +144,7 @@ class Gift(Object): raw (:obj:`~pyrogram.raw.base.StarGift`, *optional*): The raw object as received from the server. - + link (``str``, *property*): A link to the gift. For unique gifts only. @@ -163,6 +166,7 @@ class Gift(Object): owner: Optional["types.Chat"] = None, owner_name: Optional[str] = None, owner_address: Optional[str] = None, + ton_address: Optional[str] = None, price: Optional[int] = None, convert_price: Optional[int] = None, upgrade_price: Optional[int] = None, @@ -201,6 +205,7 @@ class Gift(Object): self.owner = owner self.owner_name = owner_name self.owner_address = owner_address + self.ton_address = ton_address self.price = price self.convert_price = convert_price self.upgrade_price = upgrade_price @@ -233,7 +238,7 @@ class Gift(Object): return await Gift._parse_unique(client, gift, users, chats) elif isinstance(gift, raw.types.StarGiftSaved): return await Gift._parse_saved(client, gift, users, chats) - + @staticmethod async def _parse_regular( client, @@ -277,9 +282,15 @@ class Gift(Object): ) or None, available_amount=getattr(star_gift, "availability_issued", None), total_amount=getattr(star_gift, "availability_total", None), - owner=types.Chat._parse_chat(client, users.get(owner_id) or chats.get(owner_id)), + owner=( + types.Chat._parse_chat(client, users.get(owner_id) or + chats.get(owner_id)) + if owner_id is not None + else None + ), owner_name=getattr(star_gift, "owner_name", None), owner_address=getattr(star_gift, "owner_address", None), + ton_address=getattr(star_gift, "gift_address", None), is_upgraded=True, raw=star_gift, client=client From 38cde8d556328698d06c60945f3749209b70d190 Mon Sep 17 00:00:00 2001 From: Ling-ex Date: Sat, 24 May 2025 18:02:07 +0000 Subject: [PATCH 3/3] Fix: typo enums.MessageServiceType.ChatShared in pyrogram/types/messages_and_media/message. Signed-off-by: Ling-ex --- pyrogram/types/messages_and_media/message.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyrogram/types/messages_and_media/message.py b/pyrogram/types/messages_and_media/message.py index df9ccb62..dd8cf711 100644 --- a/pyrogram/types/messages_and_media/message.py +++ b/pyrogram/types/messages_and_media/message.py @@ -305,7 +305,7 @@ class Message(Object, Update): views (``int``, *optional*): Channel post views. - + forwards (``int``, *optional*): Channel post forwards. @@ -808,7 +808,7 @@ class Message(Object, Update): service_type = enums.MessageServiceType.BOT_ALLOWED elif isinstance(action, raw.types.MessageActionRequestedPeer) or isinstance(action, raw.types.MessageActionRequestedPeerSentMe): chats_shared = await types.RequestedChats._parse(client, action) - service_type = enums.MessageServiceType.ChatShared + service_type = enums.MessageServiceType.CHAT_SHARED elif isinstance(action, raw.types.MessageActionTopicCreate): forum_topic_created = types.ForumTopicCreated._parse(message) service_type = enums.MessageServiceType.FORUM_TOPIC_CREATED