From a315c30336814c2cb9b3bcc2a2e8342f48410391 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 17 Oct 2018 20:37:53 +0200 Subject: [PATCH 01/32] Optimize dispatcher.py code --- pyrogram/client/dispatcher/dispatcher.py | 159 +++++++++-------------- 1 file changed, 61 insertions(+), 98 deletions(-) diff --git a/pyrogram/client/dispatcher/dispatcher.py b/pyrogram/client/dispatcher/dispatcher.py index a0c5e365..4366b56d 100644 --- a/pyrogram/client/dispatcher/dispatcher.py +++ b/pyrogram/client/dispatcher/dispatcher.py @@ -25,7 +25,7 @@ from threading import Thread import pyrogram from pyrogram.api import types from ..ext import utils -from ..handlers import RawUpdateHandler, CallbackQueryHandler, MessageHandler, DeletedMessagesHandler, UserStatusHandler +from ..handlers import CallbackQueryHandler, MessageHandler, DeletedMessagesHandler, UserStatusHandler, RawUpdateHandler log = logging.getLogger(__name__) @@ -88,56 +88,6 @@ class Dispatcher: "Handler was not removed.".format(group)) self.groups[group].remove(handler) - def dispatch(self, update, users: dict = None, chats: dict = None, is_raw: bool = False): - for group in self.groups.values(): - try: - for handler in group: - if is_raw: - if not isinstance(handler, RawUpdateHandler): - continue - - args = (self.client, update, users, chats) - else: - message = (update.message - or update.channel_post - or update.edited_message - or update.edited_channel_post) - - deleted_messages = (update.deleted_channel_posts - or update.deleted_messages) - - callback_query = update.callback_query - - user_status = update.user_status - - if message and isinstance(handler, MessageHandler): - if not handler.check(message): - continue - - args = (self.client, message) - elif deleted_messages and isinstance(handler, DeletedMessagesHandler): - if not handler.check(deleted_messages): - continue - - args = (self.client, deleted_messages) - elif callback_query and isinstance(handler, CallbackQueryHandler): - if not handler.check(callback_query): - continue - - args = (self.client, callback_query) - elif user_status and isinstance(handler, UserStatusHandler): - if not handler.check(user_status): - continue - - args = (self.client, user_status) - else: - continue - - handler.callback(*args) - break - except Exception as e: - log.error(e, exc_info=True) - def update_worker(self): name = threading.current_thread().name log.debug("{} started".format(name)) @@ -153,80 +103,93 @@ class Dispatcher: chats = {i.id: i for i in update[2]} update = update[0] - self.dispatch(update, users=users, chats=chats, is_raw=True) + self.dispatch_raw(update, users=users, chats=chats, handler_class=RawUpdateHandler) if isinstance(update, Dispatcher.MESSAGE_UPDATES): if isinstance(update.message, types.MessageEmpty): continue - message = utils.parse_messages( - self.client, - update.message, - users, - chats - ) + message = utils.parse_messages(self.client, update.message, users, chats) + is_edited = isinstance(update, Dispatcher.EDIT_MESSAGE_UPDATES) + is_channel = message.chat.type == "channel" - is_edited_message = isinstance(update, Dispatcher.EDIT_MESSAGE_UPDATES) - - self.dispatch( - pyrogram.Update( - message=((message if message.chat.type != "channel" - else None) if not is_edited_message - else None), - edited_message=((message if message.chat.type != "channel" - else None) if is_edited_message - else None), - channel_post=((message if message.chat.type == "channel" - else None) if not is_edited_message - else None), - edited_channel_post=((message if message.chat.type == "channel" - else None) if is_edited_message - else None) - ) + update = pyrogram.Update( + message=message if not is_channel and not is_edited else None, + edited_message=message if not is_channel and is_edited else None, + channel_post=message if is_channel and not is_edited else None, + edited_channel_post=message if is_channel and is_edited else None ) elif isinstance(update, Dispatcher.DELETE_MESSAGE_UPDATES): - is_channel = hasattr(update, 'channel_id') - + is_channel = hasattr(update, "channel_id") messages = utils.parse_deleted_messages( update.messages, - (update.channel_id if is_channel else None) + update.channel_id if is_channel else None ) - self.dispatch( - pyrogram.Update( - deleted_messages=(messages if not is_channel else None), - deleted_channel_posts=(messages if is_channel else None) - ) + update = pyrogram.Update( + deleted_messages=messages if not is_channel else None, + deleted_channel_posts=messages if is_channel else None ) elif isinstance(update, types.UpdateBotCallbackQuery): - self.dispatch( - pyrogram.Update( - callback_query=utils.parse_callback_query( - self.client, update, users - ) + update = pyrogram.Update( + callback_query=utils.parse_callback_query( + self.client, update, users ) ) elif isinstance(update, types.UpdateInlineBotCallbackQuery): - self.dispatch( - pyrogram.Update( - callback_query=utils.parse_inline_callback_query( - self.client, update, users - ) + update = pyrogram.Update( + callback_query=utils.parse_inline_callback_query( + self.client, update, users ) ) elif isinstance(update, types.UpdateUserStatus): - self.dispatch( - pyrogram.Update( - user_status=utils.parse_user_status( - update.status, update.user_id - ) + update = pyrogram.Update( + user_status=utils.parse_user_status( + update.status, update.user_id ) ) else: continue + + self.dispatch(update) except Exception as e: log.error(e, exc_info=True) log.debug("{} stopped".format(name)) + + def dispatch_raw(self, update, users: dict, chats: dict, handler_class): + for group in self.groups.values(): + for handler in group: + if isinstance(handler, handler_class): + try: + handler.callback(self.client, update, users, chats) + except Exception as e: + log.error(e, exc_info=True) + + # noinspection PyShadowingBuiltins + def dispatch(self, update): + message = update.message or update.channel_post or update.edited_message or update.edited_channel_post + deleted_messages = update.deleted_channel_posts or update.deleted_messages + callback_query = update.callback_query + user_status = update.user_status + + update = message or deleted_messages or callback_query or user_status + + type = ( + MessageHandler if message + else DeletedMessagesHandler if deleted_messages + else CallbackQueryHandler if callback_query + else UserStatusHandler if user_status + else None + ) + + for group in self.groups.values(): + for handler in group: + if isinstance(handler, type): + if handler.check(update): + try: + handler.callback(self.client, update) + except Exception as e: + log.error(e, exc_info=True) From 426cdbbcb86f983e2ed74f60fea73cf91821b325 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 17 Oct 2018 20:59:33 +0200 Subject: [PATCH 02/32] Don't make use of Update objects when dispatching updates The Update type is used nowhere, adds costly abstraction and makes the code uglier. If I ever need it again (unlikely) I can just revert this. --- pyrogram/client/dispatcher/dispatcher.py | 60 ++++-------------------- 1 file changed, 10 insertions(+), 50 deletions(-) diff --git a/pyrogram/client/dispatcher/dispatcher.py b/pyrogram/client/dispatcher/dispatcher.py index 4366b56d..53448252 100644 --- a/pyrogram/client/dispatcher/dispatcher.py +++ b/pyrogram/client/dispatcher/dispatcher.py @@ -22,7 +22,6 @@ from collections import OrderedDict from queue import Queue from threading import Thread -import pyrogram from pyrogram.api import types from ..ext import utils from ..handlers import CallbackQueryHandler, MessageHandler, DeletedMessagesHandler, UserStatusHandler, RawUpdateHandler @@ -110,50 +109,26 @@ class Dispatcher: continue message = utils.parse_messages(self.client, update.message, users, chats) - is_edited = isinstance(update, Dispatcher.EDIT_MESSAGE_UPDATES) - is_channel = message.chat.type == "channel" - - update = pyrogram.Update( - message=message if not is_channel and not is_edited else None, - edited_message=message if not is_channel and is_edited else None, - channel_post=message if is_channel and not is_edited else None, - edited_channel_post=message if is_channel and is_edited else None - ) + update = message, MessageHandler elif isinstance(update, Dispatcher.DELETE_MESSAGE_UPDATES): - is_channel = hasattr(update, "channel_id") - messages = utils.parse_deleted_messages( + deleted_messages = utils.parse_deleted_messages( update.messages, - update.channel_id if is_channel else None + update.channel_id if hasattr(update, "channel_id") else None ) - update = pyrogram.Update( - deleted_messages=messages if not is_channel else None, - deleted_channel_posts=messages if is_channel else None - ) + update = deleted_messages, DeletedMessagesHandler elif isinstance(update, types.UpdateBotCallbackQuery): - update = pyrogram.Update( - callback_query=utils.parse_callback_query( - self.client, update, users - ) - ) + update = utils.parse_callback_query(self.client, update, users), CallbackQueryHandler elif isinstance(update, types.UpdateInlineBotCallbackQuery): - update = pyrogram.Update( - callback_query=utils.parse_inline_callback_query( - self.client, update, users - ) - ) + update = utils.parse_inline_callback_query(self.client, update, users), CallbackQueryHandler elif isinstance(update, types.UpdateUserStatus): - update = pyrogram.Update( - user_status=utils.parse_user_status( - update.status, update.user_id - ) - ) + update = utils.parse_user_status(update.status, update.user_id), UserStatusHandler else: continue - self.dispatch(update) + self.dispatch(*update) except Exception as e: log.error(e, exc_info=True) @@ -169,25 +144,10 @@ class Dispatcher: log.error(e, exc_info=True) # noinspection PyShadowingBuiltins - def dispatch(self, update): - message = update.message or update.channel_post or update.edited_message or update.edited_channel_post - deleted_messages = update.deleted_channel_posts or update.deleted_messages - callback_query = update.callback_query - user_status = update.user_status - - update = message or deleted_messages or callback_query or user_status - - type = ( - MessageHandler if message - else DeletedMessagesHandler if deleted_messages - else CallbackQueryHandler if callback_query - else UserStatusHandler if user_status - else None - ) - + def dispatch(self, update, handler_class): for group in self.groups.values(): for handler in group: - if isinstance(handler, type): + if isinstance(handler, handler_class): if handler.check(update): try: handler.callback(self.client, update) From 38ff950d0160e93f710e9c0886f0feb706eb9a00 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 17 Oct 2018 21:00:14 +0200 Subject: [PATCH 03/32] Remove useless #noinspection --- pyrogram/client/dispatcher/dispatcher.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyrogram/client/dispatcher/dispatcher.py b/pyrogram/client/dispatcher/dispatcher.py index 53448252..2989d9fa 100644 --- a/pyrogram/client/dispatcher/dispatcher.py +++ b/pyrogram/client/dispatcher/dispatcher.py @@ -143,7 +143,6 @@ class Dispatcher: except Exception as e: log.error(e, exc_info=True) - # noinspection PyShadowingBuiltins def dispatch(self, update, handler_class): for group in self.groups.values(): for handler in group: From 09e0345868d3d28a46df6a0e79463199c260e8f9 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 18 Oct 2018 21:18:22 +0200 Subject: [PATCH 04/32] Small dispatcher clean ups --- pyrogram/client/dispatcher/dispatcher.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pyrogram/client/dispatcher/dispatcher.py b/pyrogram/client/dispatcher/dispatcher.py index 2989d9fa..cbfb59e4 100644 --- a/pyrogram/client/dispatcher/dispatcher.py +++ b/pyrogram/client/dispatcher/dispatcher.py @@ -50,6 +50,7 @@ class Dispatcher: def __init__(self, client, workers): self.client = client self.workers = workers + self.workers_list = [] self.updates = Queue() self.groups = OrderedDict() @@ -69,8 +70,8 @@ class Dispatcher: for _ in range(self.workers): self.updates.put(None) - for i in self.workers_list: - i.join() + for worker in self.workers_list: + worker.join() self.workers_list.clear() @@ -83,8 +84,8 @@ class Dispatcher: def remove_handler(self, handler, group: int): if group not in self.groups: - raise ValueError("Group {} does not exist. " - "Handler was not removed.".format(group)) + raise ValueError("Group {} does not exist. Handler was not removed.".format(group)) + self.groups[group].remove(handler) def update_worker(self): @@ -108,8 +109,7 @@ class Dispatcher: if isinstance(update.message, types.MessageEmpty): continue - message = utils.parse_messages(self.client, update.message, users, chats) - update = message, MessageHandler + update = utils.parse_messages(self.client, update.message, users, chats), MessageHandler elif isinstance(update, Dispatcher.DELETE_MESSAGE_UPDATES): deleted_messages = utils.parse_deleted_messages( From 3f0a355f7eff8eaf623759b9bcb5d25f074ae744 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 19 Oct 2018 11:54:27 +0200 Subject: [PATCH 05/32] Further optimize and simplify the Dispatcher --- pyrogram/client/dispatcher/dispatcher.py | 88 ++++++++++++------------ pyrogram/client/ext/utils.py | 64 +++++++++-------- 2 files changed, 76 insertions(+), 76 deletions(-) diff --git a/pyrogram/client/dispatcher/dispatcher.py b/pyrogram/client/dispatcher/dispatcher.py index cbfb59e4..f1c14fbe 100644 --- a/pyrogram/client/dispatcher/dispatcher.py +++ b/pyrogram/client/dispatcher/dispatcher.py @@ -45,9 +45,16 @@ class Dispatcher: types.UpdateDeleteChannelMessages ) + CALLBACK_QUERY_UPDATES = ( + types.UpdateBotCallbackQuery, + types.UpdateInlineBotCallbackQuery + ) + MESSAGE_UPDATES = NEW_MESSAGE_UPDATES + EDIT_MESSAGE_UPDATES - def __init__(self, client, workers): + UPDATES = None + + def __init__(self, client, workers: int): self.client = client self.workers = workers @@ -55,6 +62,22 @@ class Dispatcher: self.updates = Queue() self.groups = OrderedDict() + Dispatcher.UPDATES = { + Dispatcher.MESSAGE_UPDATES: + lambda upd, usr, cht: (utils.parse_messages(self.client, upd.message, usr, cht), MessageHandler), + + Dispatcher.DELETE_MESSAGE_UPDATES: + lambda upd, usr, cht: (utils.parse_deleted_messages(upd), DeletedMessagesHandler), + + Dispatcher.CALLBACK_QUERY_UPDATES: + lambda upd, usr, cht: (utils.parse_callback_query(self.client, upd, usr), CallbackQueryHandler), + + (types.UpdateUserStatus,): + lambda upd, usr, cht: (utils.parse_user_status(upd.status, upd.user_id), UserStatusHandler) + } + + Dispatcher.UPDATES = {key: value for key_tuple, value in Dispatcher.UPDATES.items() for key in key_tuple} + def start(self): for i in range(self.workers): self.workers_list.append( @@ -103,52 +126,31 @@ class Dispatcher: chats = {i.id: i for i in update[2]} update = update[0] - self.dispatch_raw(update, users=users, chats=chats, handler_class=RawUpdateHandler) + parser = Dispatcher.UPDATES.get(type(update), None) - if isinstance(update, Dispatcher.MESSAGE_UPDATES): - if isinstance(update.message, types.MessageEmpty): - continue - - update = utils.parse_messages(self.client, update.message, users, chats), MessageHandler - - elif isinstance(update, Dispatcher.DELETE_MESSAGE_UPDATES): - deleted_messages = utils.parse_deleted_messages( - update.messages, - update.channel_id if hasattr(update, "channel_id") else None - ) - - update = deleted_messages, DeletedMessagesHandler - - elif isinstance(update, types.UpdateBotCallbackQuery): - update = utils.parse_callback_query(self.client, update, users), CallbackQueryHandler - elif isinstance(update, types.UpdateInlineBotCallbackQuery): - update = utils.parse_inline_callback_query(self.client, update, users), CallbackQueryHandler - elif isinstance(update, types.UpdateUserStatus): - update = utils.parse_user_status(update.status, update.user_id), UserStatusHandler - else: + if parser is None: continue - self.dispatch(*update) + update, handler_type = parser(update, users, chats) + + for group in self.groups.values(): + for handler in group: + args = None + + if isinstance(handler, RawUpdateHandler): + args = (update, users, chats) + elif isinstance(handler, handler_type): + if handler.check(update): + args = (update,) + + if args is not None: + try: + handler.callback(self.client, *args) + except Exception as e: + log.error(e, exc_info=True) + finally: + break except Exception as e: log.error(e, exc_info=True) log.debug("{} stopped".format(name)) - - def dispatch_raw(self, update, users: dict, chats: dict, handler_class): - for group in self.groups.values(): - for handler in group: - if isinstance(handler, handler_class): - try: - handler.callback(self.client, update, users, chats) - except Exception as e: - log.error(e, exc_info=True) - - def dispatch(self, update, handler_class): - for group in self.groups.values(): - for handler in group: - if isinstance(handler, handler_class): - if handler.check(update): - try: - handler.callback(self.client, update) - except Exception as e: - log.error(e, exc_info=True) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index c7a10db9..fdf7693c 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -764,10 +764,10 @@ def parse_messages( return parsed_messages if is_list else parsed_messages[0] -def parse_deleted_messages( - messages: list, - channel_id: int -) -> pyrogram_types.Messages: +def parse_deleted_messages(update) -> pyrogram_types.Messages: + messages = update.messages + channel_id = getattr(update, "channel_id", None) + parsed_messages = [] for message in messages: @@ -874,42 +874,40 @@ def parse_profile_photos(photos): ) -def parse_callback_query(client, callback_query, users): - peer = callback_query.peer +def parse_callback_query(client, update, users): + message = None + inline_message_id = None - if isinstance(peer, types.PeerUser): - peer_id = peer.user_id - elif isinstance(peer, types.PeerChat): - peer_id = -peer.chat_id - else: - peer_id = int("-100" + str(peer.channel_id)) + if isinstance(update, types.UpdateBotCallbackQuery): + peer = update.peer - return pyrogram_types.CallbackQuery( - id=str(callback_query.query_id), - from_user=parse_user(users[callback_query.user_id]), - message=client.get_messages(peer_id, callback_query.msg_id), - chat_instance=str(callback_query.chat_instance), - data=callback_query.data.decode(), - game_short_name=callback_query.game_short_name, - client=client - ) + if isinstance(peer, types.PeerUser): + peer_id = peer.user_id + elif isinstance(peer, types.PeerChat): + peer_id = -peer.chat_id + else: + peer_id = int("-100" + str(peer.channel_id)) - -def parse_inline_callback_query(client, callback_query, users): - return pyrogram_types.CallbackQuery( - id=str(callback_query.query_id), - from_user=parse_user(users[callback_query.user_id]), - chat_instance=str(callback_query.chat_instance), - inline_message_id=b64encode( + message = client.get_messages(peer_id, update.msg_id) + elif isinstance(update, types.UpdateInlineBotCallbackQuery): + inline_message_id = b64encode( pack( " Date: Mon, 5 Nov 2018 17:32:11 +0100 Subject: [PATCH 06/32] Update dev version --- pyrogram/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index 4f9866e0..a98ac672 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -23,7 +23,7 @@ __copyright__ = "Copyright (C) 2017-2018 Dan Tès Date: Mon, 5 Nov 2018 17:33:12 +0100 Subject: [PATCH 07/32] Use TCPAbridgedO as default connection mode --- pyrogram/connection/connection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/connection/connection.py b/pyrogram/connection/connection.py index 8020bc71..41f64a40 100644 --- a/pyrogram/connection/connection.py +++ b/pyrogram/connection/connection.py @@ -37,7 +37,7 @@ class Connection: 4: TCPIntermediateO } - def __init__(self, dc_id: int, test_mode: bool, ipv6: bool, proxy: dict, mode: int = 1): + def __init__(self, dc_id: int, test_mode: bool, ipv6: bool, proxy: dict, mode: int = 3): self.dc_id = dc_id self.ipv6 = ipv6 self.proxy = proxy From 91beb214e9cd3ff4cf71425f245b3fd327536bbb Mon Sep 17 00:00:00 2001 From: Furoin Date: Tue, 6 Nov 2018 17:11:35 +0300 Subject: [PATCH 08/32] added message.mentioned --- pyrogram/client/ext/utils.py | 3 +++ pyrogram/client/types/messages_and_media/message.py | 2 ++ 2 files changed, 5 insertions(+) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index bc908165..0d0c5abf 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -591,6 +591,8 @@ def parse_messages( else: reply_markup = None + mentioned = message.mentioned + m = pyrogram_types.Message( message_id=message.id, date=message.date, @@ -606,6 +608,7 @@ def parse_messages( forward_from_message_id=forward_from_message_id, forward_signature=forward_signature, forward_date=forward_date, + mentioned=mentioned, edit_date=message.edit_date, media_group_id=message.grouped_id, photo=photo, diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index 86bb57bc..59776859 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -206,6 +206,7 @@ class Message(Object): forward_signature: str = None, forward_date: int = None, reply_to_message=None, + mentioned=None, edit_date: int = None, media_group_id: str = None, author_signature: str = None, @@ -253,6 +254,7 @@ class Message(Object): self.forward_signature = forward_signature # flags.4?string self.forward_date = forward_date # flags.5?int self.reply_to_message = reply_to_message # flags.6?Message + self.mentioned = mentioned self.edit_date = edit_date # flags.7?int self.media_group_id = media_group_id # flags.8?string self.author_signature = author_signature # flags.9?string From 2d0ffcb0f48117af882213da8f056056f2cfa59b Mon Sep 17 00:00:00 2001 From: Furoin Date: Tue, 6 Nov 2018 17:13:37 +0300 Subject: [PATCH 09/32] added Filters.mentioned --- pyrogram/client/filters/filters.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index aeb730a7..6b9e9fd2 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -168,6 +168,8 @@ class Filters: dan = create("Dan", lambda _, m: bool(m.from_user and m.from_user.id == 23122162)) + mentioned = create("Mentioned", lambda _, m: bool(m.mentioned)) + @staticmethod def command(command: str or list, prefix: str or list = "/", From 1adc8121080ff71f247cee6afac52647cf9c42d9 Mon Sep 17 00:00:00 2001 From: Furoin Date: Tue, 6 Nov 2018 18:36:40 +0300 Subject: [PATCH 10/32] added Filters.chat("me") --- pyrogram/client/filters/filters.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index aeb730a7..037e6bb9 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -287,9 +287,9 @@ class Filters: def __init__(self, chats: int or str or list = None): chats = [] if chats is None else chats if type(chats) is list else [chats] super().__init__( - {i.lower().strip("@") if type(i) is str else i for i in chats} + {"me" if i in ["me", "self"] else i.lower().strip("@") if type(i) is str else i for i in chats} if type(chats) is list else - {chats.lower().strip("@") if type(chats) is str else chats} + {"me" if chats in ["me", "self"] else chats.lower().strip("@") if type(chats) is str else chats} ) def __call__(self, message): @@ -297,7 +297,10 @@ class Filters: message.chat and (message.chat.id in self or (message.chat.username - and message.chat.username.lower() in self)) + and message.chat.username.lower() in self) + or ("me" in self and message.from_user + and message.from_user.is_self + and not message.outgoing)) ) service = create( From 5da5cabf4ca708f5aeb067f76f9528ff6acc3131 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 6 Nov 2018 17:31:04 +0100 Subject: [PATCH 11/32] Remove useless variable --- pyrogram/client/ext/utils.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index 0d0c5abf..6fc2552a 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -591,8 +591,6 @@ def parse_messages( else: reply_markup = None - mentioned = message.mentioned - m = pyrogram_types.Message( message_id=message.id, date=message.date, @@ -608,7 +606,7 @@ def parse_messages( forward_from_message_id=forward_from_message_id, forward_signature=forward_signature, forward_date=forward_date, - mentioned=mentioned, + mentioned=message.mentioned, edit_date=message.edit_date, media_group_id=message.grouped_id, photo=photo, From 0943761a911ae2a0f29127f1b29860ff8b308ddd Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 6 Nov 2018 17:32:46 +0100 Subject: [PATCH 12/32] Update filters.py --- pyrogram/client/filters/filters.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index 6b9e9fd2..48f0965d 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -169,6 +169,7 @@ class Filters: dan = create("Dan", lambda _, m: bool(m.from_user and m.from_user.id == 23122162)) mentioned = create("Mentioned", lambda _, m: bool(m.mentioned)) + """Filter messages containing mentions""" @staticmethod def command(command: str or list, From 5571888143dc310168b3383a8718209510f103e0 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 6 Nov 2018 17:37:32 +0100 Subject: [PATCH 13/32] Add mentioned docstrings --- pyrogram/client/types/messages_and_media/message.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index 59776859..d224a9c6 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -55,6 +55,9 @@ class Message(Object): For replies, the original message. Note that the Message object in this field will not contain further reply_to_message fields even if it itself is a reply. + mentioned (``bool``, *optional*): + The message contains a mention. + edit_date (``int``, *optional*): Date the message was last edited in Unix time. From 5efd608487f454efaf7a6939355eefd3f49acc10 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 6 Nov 2018 17:40:37 +0100 Subject: [PATCH 14/32] Update Filters.chat docstrings --- pyrogram/client/filters/filters.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index 037e6bb9..77ebb771 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -281,6 +281,7 @@ class Filters: Args: chats (``int`` | ``str`` | ``list``): Pass one or more chat ids/usernames to filter chats. + For your personal cloud (Saved Messages) you can simply use “me” or “self”. Defaults to None (no chats). """ From b3737fc6ef2d9047a7054c87fb7dec679de883ad Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 6 Nov 2018 17:42:01 +0100 Subject: [PATCH 15/32] Add MESSAGE_DELETE_FORBIDDEN error --- compiler/error/source/403_FORBIDDEN.tsv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/error/source/403_FORBIDDEN.tsv b/compiler/error/source/403_FORBIDDEN.tsv index a2d06832..34433da7 100644 --- a/compiler/error/source/403_FORBIDDEN.tsv +++ b/compiler/error/source/403_FORBIDDEN.tsv @@ -1,4 +1,5 @@ id message CHAT_WRITE_FORBIDDEN You don't have rights to send messages in this chat RIGHT_FORBIDDEN One or more admin rights can't be applied to this kind of chat (channel/supergroup) -CHAT_ADMIN_INVITE_REQUIRED You don't have rights to invite other users \ No newline at end of file +CHAT_ADMIN_INVITE_REQUIRED You don't have rights to invite other users +MESSAGE_DELETE_FORBIDDEN You don't have rights to delete messages in this chat \ No newline at end of file From 648eb809287e526ae3b17e936bbacac06e12e7e3 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 7 Nov 2018 12:03:57 +0100 Subject: [PATCH 16/32] Add Message.edit() bound method --- .../types/messages_and_media/message.py | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index d224a9c6..2dce5dfb 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -369,6 +369,54 @@ class Message(Object): reply_markup=reply_markup ) + def edit(self, text: str, parse_mode: str = "", disable_web_page_preview: bool = None, reply_markup=None): + """Bound method *edit* of :obj:`Message + + Use as a shortcut for: + + .. code-block:: python + + client.edit_message_text( + chat_id=message.chat.id, + message_id=message.message_id, + text="hello", + ) + + Example: + .. code-block:: python + + message.edit("hello") + + Args: + text (``str``): + New text of the message. + + parse_mode (``str``, *optional*): + Use :obj:`MARKDOWN ` or :obj:`HTML ` + if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your message. + Defaults to Markdown. + + disable_web_page_preview (``bool``, *optional*): + Disables link previews for links in this message. + + reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): + An InlineKeyboardMarkup object. + + Returns: + On success, the edited :obj:`Message ` is returned. + + Raises: + :class:`Error ` in case of a Telegram RPC error. + """ + return self._client.edit_message_text( + chat_id=self.chat.id, + message_id=self.message_id, + text=text, + parse_mode=parse_mode, + disable_web_page_preview=disable_web_page_preview, + reply_markup=reply_markup + ) + def forward(self, chat_id: int or str, disable_notification: bool = None): From f8844d60ab43707d0d924207cadd39bc83643ee4 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Wed, 7 Nov 2018 13:11:33 +0100 Subject: [PATCH 17/32] Handle possible MESSAGE_IDS_EMPTY errors in case of pinned messages --- pyrogram/client/ext/utils.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index 6fc2552a..123dfabf 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -641,7 +641,7 @@ def parse_messages( replies=replies - 1 ) except MessageIdsEmpty: - m.reply_to_message = None + pass elif isinstance(message, types.MessageService): action = message.action @@ -742,11 +742,14 @@ def parse_messages( ) if isinstance(action, types.MessageActionPinMessage): - m.pinned_message = client.get_messages( - m.chat.id, - reply_to_message_ids=message.id, - replies=0 - ) + try: + m.pinned_message = client.get_messages( + m.chat.id, + reply_to_message_ids=message.id, + replies=0 + ) + except MessageIdsEmpty: + pass else: m = pyrogram_types.Message(message_id=message.id, client=proxy(client)) From 32a09ffc4cb17a3595ab2ada4167f297f57e623c Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 8 Nov 2018 10:28:11 +0100 Subject: [PATCH 18/32] Add Message.empty field --- pyrogram/client/ext/utils.py | 2 +- pyrogram/client/types/messages_and_media/message.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index 123dfabf..6d6fe828 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -751,7 +751,7 @@ def parse_messages( except MessageIdsEmpty: pass else: - m = pyrogram_types.Message(message_id=message.id, client=proxy(client)) + m = pyrogram_types.Message(message_id=message.id, client=proxy(client), empty=True) parsed_messages.append(m) diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index 2dce5dfb..b20c2c3f 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -58,6 +58,10 @@ class Message(Object): mentioned (``bool``, *optional*): The message contains a mention. + empty (``bool``, *optional*): + The message is empty. + A message can be empty in case it was deleted or you tried to retrieve a message that doesn't exist yet. + edit_date (``int``, *optional*): Date the message was last edited in Unix time. @@ -210,6 +214,7 @@ class Message(Object): forward_date: int = None, reply_to_message=None, mentioned=None, + empty=None, edit_date: int = None, media_group_id: str = None, author_signature: str = None, @@ -258,6 +263,7 @@ class Message(Object): self.forward_date = forward_date # flags.5?int self.reply_to_message = reply_to_message # flags.6?Message self.mentioned = mentioned + self.empty = empty self.edit_date = edit_date # flags.7?int self.media_group_id = media_group_id # flags.8?string self.author_signature = author_signature # flags.9?string From fc7b77e2b9a433dc7ef97c2e00d0d81165319332 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 8 Nov 2018 10:40:35 +0100 Subject: [PATCH 19/32] Add Message.service field --- pyrogram/client/ext/utils.py | 1 + pyrogram/client/types/messages_and_media/message.py | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index 6d6fe828..3df2a450 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -728,6 +728,7 @@ def parse_messages( date=message.date, chat=parse_chat(message, users, chats), from_user=parse_user(users.get(message.from_id, None)), + service=True, new_chat_members=new_chat_members, left_chat_member=left_chat_member, new_chat_title=new_chat_title, diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index b20c2c3f..12f3116a 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -62,6 +62,12 @@ class Message(Object): The message is empty. A message can be empty in case it was deleted or you tried to retrieve a message that doesn't exist yet. + service (``bool``, *optional*): + The message is a service message. + A service message has one and only one of these fields set: left_chat_member, new_chat_title, + new_chat_photo, delete_chat_photo, group_chat_created, supergroup_chat_created, channel_chat_created, + migrate_to_chat_id, migrate_from_chat_id, pinned_message. + edit_date (``int``, *optional*): Date the message was last edited in Unix time. @@ -215,6 +221,7 @@ class Message(Object): reply_to_message=None, mentioned=None, empty=None, + service=None, edit_date: int = None, media_group_id: str = None, author_signature: str = None, @@ -264,6 +271,7 @@ class Message(Object): self.reply_to_message = reply_to_message # flags.6?Message self.mentioned = mentioned self.empty = empty + self.service = service self.edit_date = edit_date # flags.7?int self.media_group_id = media_group_id # flags.8?string self.author_signature = author_signature # flags.9?string From f26e20d30e43138aaed1f8edb34f86c44c6a3ede Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 8 Nov 2018 10:44:32 +0100 Subject: [PATCH 20/32] Update Filters.service --- pyrogram/client/filters/filters.py | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index ff06b327..b847543a 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -166,11 +166,14 @@ class Filters: inline_keyboard = create("InlineKeyboard", lambda _, m: isinstance(m.reply_markup, InlineKeyboardMarkup)) """Filter messages containing inline keyboard markups""" - dan = create("Dan", lambda _, m: bool(m.from_user and m.from_user.id == 23122162)) - mentioned = create("Mentioned", lambda _, m: bool(m.mentioned)) """Filter messages containing mentions""" + service = create("Service", lambda _, m: bool(m.service)) + """Filter messages containing any of these fields set: left_chat_member, new_chat_title, new_chat_photo, + delete_chat_photo, group_chat_created, supergroup_chat_created, channel_chat_created, migrate_to_chat_id, + migrate_from_chat_id, pinned_message""" + @staticmethod def command(command: str or list, prefix: str or list = "/", @@ -307,24 +310,6 @@ class Filters: and not message.outgoing)) ) - service = create( - "Service", - lambda _, m: bool( - Filters.new_chat_members(m) - or Filters.left_chat_member(m) - or Filters.new_chat_title(m) - or Filters.new_chat_photo(m) - or Filters.delete_chat_photo(m) - or Filters.group_chat_created(m) - or Filters.supergroup_chat_created(m) - or Filters.channel_chat_created(m) - or Filters.migrate_to_chat_id(m) - or Filters.migrate_from_chat_id(m) - or Filters.pinned_message(m) - ) - ) - """Filter all service messages.""" - media = create( "Media", lambda _, m: bool( @@ -342,3 +327,5 @@ class Filters: ) ) """Filter all media messages.""" + + dan = create("Dan", lambda _, m: bool(m.from_user and m.from_user.id == 23122162)) From e760550f8b443cf67289d11106eab3bff940593d Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 8 Nov 2018 10:49:32 +0100 Subject: [PATCH 21/32] Add Message.media field --- pyrogram/client/ext/utils.py | 1 + pyrogram/client/types/messages_and_media/message.py | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index 3df2a450..218655f4 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -607,6 +607,7 @@ def parse_messages( forward_signature=forward_signature, forward_date=forward_date, mentioned=message.mentioned, + media=bool(media) or None, edit_date=message.edit_date, media_group_id=message.grouped_id, photo=photo, diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index 12f3116a..ffcab6f3 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -68,6 +68,11 @@ class Message(Object): new_chat_photo, delete_chat_photo, group_chat_created, supergroup_chat_created, channel_chat_created, migrate_to_chat_id, migrate_from_chat_id, pinned_message. + media (``bool``` *optional*): + The message is a media message. + A media message has one and only one of these fields set: audio, document, photo, sticker, video, animation, + voice, video_note, contact, location, venue. + edit_date (``int``, *optional*): Date the message was last edited in Unix time. @@ -222,6 +227,7 @@ class Message(Object): mentioned=None, empty=None, service=None, + media=None, edit_date: int = None, media_group_id: str = None, author_signature: str = None, @@ -272,6 +278,7 @@ class Message(Object): self.mentioned = mentioned self.empty = empty self.service = service + self.media = media self.edit_date = edit_date # flags.7?int self.media_group_id = media_group_id # flags.8?string self.author_signature = author_signature # flags.9?string From b747f87319080d084c201fa46aad753c9b484f9e Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 8 Nov 2018 10:50:52 +0100 Subject: [PATCH 22/32] Update Filters.media --- pyrogram/client/filters/filters.py | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index b847543a..f3d2ec56 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -174,6 +174,10 @@ class Filters: delete_chat_photo, group_chat_created, supergroup_chat_created, channel_chat_created, migrate_to_chat_id, migrate_from_chat_id, pinned_message""" + media = create("Media", lambda _, m: bool(m.media)) + """Filter messages containing any of these fields set: audio, document, photo, sticker, video, animation, voice, + video_note, contact, location, venue""" + @staticmethod def command(command: str or list, prefix: str or list = "/", @@ -310,22 +314,4 @@ class Filters: and not message.outgoing)) ) - media = create( - "Media", - lambda _, m: bool( - Filters.audio(m) - or Filters.document(m) - or Filters.photo(m) - or Filters.sticker(m) - or Filters.video(m) - or Filters.animation(m) - or Filters.voice(m) - or Filters.video_note(m) - or Filters.contact(m) - or Filters.location(m) - or Filters.venue(m) - ) - ) - """Filter all media messages.""" - dan = create("Dan", lambda _, m: bool(m.from_user and m.from_user.id == 23122162)) From f6d3db366240603f7c52017d0113117693712588 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 8 Nov 2018 11:03:47 +0100 Subject: [PATCH 23/32] Update docstring style --- pyrogram/client/filters/filters.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index f3d2ec56..d470e993 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -170,13 +170,13 @@ class Filters: """Filter messages containing mentions""" service = create("Service", lambda _, m: bool(m.service)) - """Filter messages containing any of these fields set: left_chat_member, new_chat_title, new_chat_photo, - delete_chat_photo, group_chat_created, supergroup_chat_created, channel_chat_created, migrate_to_chat_id, - migrate_from_chat_id, pinned_message""" + """Filter messages containing any of these fields set: *left_chat_member*, *new_chat_title*, *new_chat_photo*, + *delete_chat_photo*, *group_chat_created*, *supergroup_chat_created*, *channel_chat_created*, *migrate_to_chat_id*, + *migrate_from_chat_id*, *pinned_message*""" media = create("Media", lambda _, m: bool(m.media)) - """Filter messages containing any of these fields set: audio, document, photo, sticker, video, animation, voice, - video_note, contact, location, venue""" + """Filter messages containing any of these fields set: *audio*, *document*, *photo*, *sticker*, *video*, + *animation*, *voice*, *video_note*, *contact*, *location*, *venue*""" @staticmethod def command(command: str or list, From 774462283ec1487c630ceb5d2b8e45b840df9b8d Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 8 Nov 2018 11:10:24 +0100 Subject: [PATCH 24/32] Update service and media filter docstrings --- pyrogram/client/filters/filters.py | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index d470e993..57e48948 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -170,13 +170,33 @@ class Filters: """Filter messages containing mentions""" service = create("Service", lambda _, m: bool(m.service)) - """Filter messages containing any of these fields set: *left_chat_member*, *new_chat_title*, *new_chat_photo*, - *delete_chat_photo*, *group_chat_created*, *supergroup_chat_created*, *channel_chat_created*, *migrate_to_chat_id*, - *migrate_from_chat_id*, *pinned_message*""" + """Filter service messages. A service message contains any of the following fields set + + - left_chat_member + - new_chat_title + - new_chat_photo + - delete_chat_photo + - group_chat_created + - supergroup_chat_created + - channel_chat_created + - migrate_to_chat_id + - migrate_from_chat_id + - pinned_message""" media = create("Media", lambda _, m: bool(m.media)) - """Filter messages containing any of these fields set: *audio*, *document*, *photo*, *sticker*, *video*, - *animation*, *voice*, *video_note*, *contact*, *location*, *venue*""" + """Filter media messages. A media message contains any of the following fields set + + - audio + - document + - photo + - sticker + - video + - animation + - voice + - video_note + - contact + - location + - venue""" @staticmethod def command(command: str or list, From cdabf3e7e06afacc7e217a45013cc2fa6b3cc86b Mon Sep 17 00:00:00 2001 From: Vankineeni Tawrun Date: Thu, 8 Nov 2018 19:08:56 +0530 Subject: [PATCH 25/32] added args to Message.download bound method --- .../client/types/messages_and_media/message.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/pyrogram/client/types/messages_and_media/message.py b/pyrogram/client/types/messages_and_media/message.py index ffcab6f3..ee812c3a 100644 --- a/pyrogram/client/types/messages_and_media/message.py +++ b/pyrogram/client/types/messages_and_media/message.py @@ -634,7 +634,7 @@ class Message(Object): else: raise ValueError("The message doesn't contain any keyboard") - def download(self, file_name: str = "", block: bool = True): + def download(self, file_name: str = "", block: bool = True, progress: callable = None, progress_args: tuple = None): """Bound method *download* of :obj:`Message `. Use as a shortcut for: @@ -659,6 +659,15 @@ class Message(Object): Blocks the code execution until the file has been downloaded. Defaults to True. + progress (``callable``): + Pass a callback function to view the download progress. + The function must take *(client, current, total, \*args)* as positional arguments (look at the section + below for a detailed description). + + progress_args (``tuple``): + Extra custom arguments for the progress callback function. Useful, for example, if you want to pass + a chat_id and a message_id in order to edit a message with the updated progress. + Returns: On success, the absolute path of the downloaded file as string is returned, None otherwise. @@ -669,5 +678,7 @@ class Message(Object): return self._client.download_media( message=self, file_name=file_name, - block=block + block=block, + progress=progress, + progress_args=progress_args, ) From b4bc7deba0de5e21101542473315e671a08ccc44 Mon Sep 17 00:00:00 2001 From: Furoin Date: Thu, 8 Nov 2018 17:11:43 +0300 Subject: [PATCH 26/32] added Filters.user("me") --- pyrogram/client/filters/filters.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index 57e48948..9105543c 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -288,9 +288,9 @@ class Filters: def __init__(self, users: int or str or list = None): users = [] if users is None else users if type(users) is list else [users] super().__init__( - {i.lower().strip("@") if type(i) is str else i for i in users} + {"me" if i in ["me", "self"] else i.lower().strip("@") if type(i) is str else i for i in users} if type(users) is list else - {users.lower().strip("@") if type(users) is str else users} + {"me" if users in ["me", "self"] else users.lower().strip("@") if type(users) is str else users} ) def __call__(self, message): @@ -298,7 +298,9 @@ class Filters: message.from_user and (message.from_user.id in self or (message.from_user.username - and message.from_user.username.lower() in self)) + and message.from_user.username.lower() in self) + or ("me" in self + and message.from_user.is_self)) ) # noinspection PyPep8Naming From 803f36412f1f4b34cbfe713ffff0ec3f5fb8569c Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 8 Nov 2018 20:24:54 +0100 Subject: [PATCH 27/32] Update Filters.user docstrings --- pyrogram/client/filters/filters.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index 9105543c..53081a04 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -282,6 +282,7 @@ class Filters: Args: users (``int`` | ``str`` | ``list``): Pass one or more user ids/usernames to filter users. + For you yourself, "me" or "self" can be used as well. Defaults to None (no users). """ From 80726784e57a4e424a84eb0745a3e44b6364bf0a Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 8 Nov 2018 20:25:35 +0100 Subject: [PATCH 28/32] Fix Filters.chat docstrings using unusual double quotes --- pyrogram/client/filters/filters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/filters/filters.py b/pyrogram/client/filters/filters.py index 53081a04..6042173f 100644 --- a/pyrogram/client/filters/filters.py +++ b/pyrogram/client/filters/filters.py @@ -314,7 +314,7 @@ class Filters: Args: chats (``int`` | ``str`` | ``list``): Pass one or more chat ids/usernames to filter chats. - For your personal cloud (Saved Messages) you can simply use “me” or “self”. + For your personal cloud (Saved Messages) you can simply use "me" or "self". Defaults to None (no chats). """ From 23fd39e2c8234c9b5532a1c8e8de387922108e4b Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 9 Nov 2018 09:21:01 +0100 Subject: [PATCH 29/32] Update dispatcher.py --- pyrogram/client/dispatcher/dispatcher.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/pyrogram/client/dispatcher/dispatcher.py b/pyrogram/client/dispatcher/dispatcher.py index f1c14fbe..fa65f987 100644 --- a/pyrogram/client/dispatcher/dispatcher.py +++ b/pyrogram/client/dispatcher/dispatcher.py @@ -143,13 +143,15 @@ class Dispatcher: if handler.check(update): args = (update,) - if args is not None: - try: - handler.callback(self.client, *args) - except Exception as e: - log.error(e, exc_info=True) - finally: - break + if args is None: + continue + + try: + handler.callback(self.client, *args) + except Exception as e: + log.error(e, exc_info=True) + finally: + break except Exception as e: log.error(e, exc_info=True) From fafa3b513168c4b3ace7528a7fc6207f4776d66d Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 10 Nov 2018 15:15:58 +0100 Subject: [PATCH 30/32] Fix some decorators not working when used in plugins --- pyrogram/client/methods/decorators/on_callback_query.py | 2 +- pyrogram/client/methods/decorators/on_deleted_messages.py | 2 +- pyrogram/client/methods/decorators/on_disconnect.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyrogram/client/methods/decorators/on_callback_query.py b/pyrogram/client/methods/decorators/on_callback_query.py index 8413515d..a79cbd10 100644 --- a/pyrogram/client/methods/decorators/on_callback_query.py +++ b/pyrogram/client/methods/decorators/on_callback_query.py @@ -22,7 +22,7 @@ from ...ext import BaseClient class OnCallbackQuery(BaseClient): - def on_callback_query(self, filters=None, group: int = 0): + def on_callback_query(self=None, filters=None, group: int = 0): """Use this decorator to automatically register a function for handling callback queries. This does the same thing as :meth:`add_handler` using the :class:`CallbackQueryHandler`. diff --git a/pyrogram/client/methods/decorators/on_deleted_messages.py b/pyrogram/client/methods/decorators/on_deleted_messages.py index e4b2bc97..347deaf9 100644 --- a/pyrogram/client/methods/decorators/on_deleted_messages.py +++ b/pyrogram/client/methods/decorators/on_deleted_messages.py @@ -22,7 +22,7 @@ from ...ext import BaseClient class OnDeletedMessages(BaseClient): - def on_deleted_messages(self, filters=None, group: int = 0): + def on_deleted_messages(self=None, filters=None, group: int = 0): """Use this decorator to automatically register a function for handling deleted messages. This does the same thing as :meth:`add_handler` using the :class:`DeletedMessagesHandler`. diff --git a/pyrogram/client/methods/decorators/on_disconnect.py b/pyrogram/client/methods/decorators/on_disconnect.py index a639471b..e2288619 100644 --- a/pyrogram/client/methods/decorators/on_disconnect.py +++ b/pyrogram/client/methods/decorators/on_disconnect.py @@ -21,7 +21,7 @@ from ...ext import BaseClient class OnDisconnect(BaseClient): - def on_disconnect(self): + def on_disconnect(self=None): """Use this decorator to automatically register a function for handling disconnections. This does the same thing as :meth:`add_handler` using the :class:`DisconnectHandler`. From 2e164993693fe70c36c7cf41b22b95ecd22738ce Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 10 Nov 2018 15:21:52 +0100 Subject: [PATCH 31/32] Allow decorators to be stacked E.g: app1.on_message(...) app2.on_message(...) app3.on_message(...) def on_message(client, message): ... --- pyrogram/client/methods/decorators/on_callback_query.py | 3 +++ pyrogram/client/methods/decorators/on_deleted_messages.py | 3 +++ pyrogram/client/methods/decorators/on_message.py | 3 +++ pyrogram/client/methods/decorators/on_raw_update.py | 3 +++ pyrogram/client/methods/decorators/on_user_status.py | 3 +++ 5 files changed, 15 insertions(+) diff --git a/pyrogram/client/methods/decorators/on_callback_query.py b/pyrogram/client/methods/decorators/on_callback_query.py index a79cbd10..a7079236 100644 --- a/pyrogram/client/methods/decorators/on_callback_query.py +++ b/pyrogram/client/methods/decorators/on_callback_query.py @@ -37,6 +37,9 @@ class OnCallbackQuery(BaseClient): """ def decorator(func): + if isinstance(func, tuple): + func = func[0].callback + handler = pyrogram.CallbackQueryHandler(func, filters) if isinstance(self, Filter): diff --git a/pyrogram/client/methods/decorators/on_deleted_messages.py b/pyrogram/client/methods/decorators/on_deleted_messages.py index 347deaf9..2fd8f298 100644 --- a/pyrogram/client/methods/decorators/on_deleted_messages.py +++ b/pyrogram/client/methods/decorators/on_deleted_messages.py @@ -37,6 +37,9 @@ class OnDeletedMessages(BaseClient): """ def decorator(func): + if isinstance(func, tuple): + func = func[0].callback + handler = pyrogram.DeletedMessagesHandler(func, filters) if isinstance(self, Filter): diff --git a/pyrogram/client/methods/decorators/on_message.py b/pyrogram/client/methods/decorators/on_message.py index 7a0d54a0..690f8368 100644 --- a/pyrogram/client/methods/decorators/on_message.py +++ b/pyrogram/client/methods/decorators/on_message.py @@ -37,6 +37,9 @@ class OnMessage(BaseClient): """ def decorator(func): + if isinstance(func, tuple): + func = func[0].callback + handler = pyrogram.MessageHandler(func, filters) if isinstance(self, Filter): diff --git a/pyrogram/client/methods/decorators/on_raw_update.py b/pyrogram/client/methods/decorators/on_raw_update.py index 7675a4f0..1391482f 100644 --- a/pyrogram/client/methods/decorators/on_raw_update.py +++ b/pyrogram/client/methods/decorators/on_raw_update.py @@ -32,6 +32,9 @@ class OnRawUpdate(BaseClient): """ def decorator(func): + if isinstance(func, tuple): + func = func[0].callback + handler = pyrogram.RawUpdateHandler(func) if isinstance(self, int): diff --git a/pyrogram/client/methods/decorators/on_user_status.py b/pyrogram/client/methods/decorators/on_user_status.py index b49e63a8..5aa6f783 100644 --- a/pyrogram/client/methods/decorators/on_user_status.py +++ b/pyrogram/client/methods/decorators/on_user_status.py @@ -36,6 +36,9 @@ class OnUserStatus(BaseClient): """ def decorator(func): + if isinstance(func, tuple): + func = func[0].callback + handler = pyrogram.UserStatusHandler(func, filters) if isinstance(self, Filter): From 87fca98035c7e6428356ca60e5cfc75f76e8a394 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Tue, 13 Nov 2018 13:16:31 +0100 Subject: [PATCH 32/32] Update to v0.9.2 --- pyrogram/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index a98ac672..8471dd82 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -23,7 +23,7 @@ __copyright__ = "Copyright (C) 2017-2018 Dan Tès