From 2f09e5c335c9bf7e652ea06e6c7c69292e931425 Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Sun, 9 Sep 2018 15:48:54 +0200 Subject: [PATCH] Support custom-callback filter for all events --- telethon/events/callbackquery.py | 5 +++-- telethon/events/chataction.py | 6 +++--- telethon/events/common.py | 19 +++++++++++++++++-- telethon/events/inlinequery.py | 5 +++-- telethon/events/messageread.py | 5 +++-- telethon/events/newmessage.py | 6 +++--- telethon/events/raw.py | 7 ++++--- 7 files changed, 36 insertions(+), 17 deletions(-) diff --git a/telethon/events/callbackquery.py b/telethon/events/callbackquery.py index ef01a341..798f2ac3 100644 --- a/telethon/events/callbackquery.py +++ b/telethon/events/callbackquery.py @@ -23,8 +23,9 @@ class CallbackQuery(EventBuilder): instance, to check against ``'data_1'`` and ``'data_2'`` you can use ``re.compile(b'data_')``. """ - def __init__(self, chats=None, *, blacklist_chats=False, data=None): - super().__init__(chats=chats, blacklist_chats=blacklist_chats) + def __init__( + self, chats=None, *, blacklist_chats=False, func=None, data=None): + super().__init__(chats, blacklist_chats=blacklist_chats, func=func) if isinstance(data, bytes): self.data = data diff --git a/telethon/events/chataction.py b/telethon/events/chataction.py index 3bf92b1b..7828f2fd 100644 --- a/telethon/events/chataction.py +++ b/telethon/events/chataction.py @@ -1,6 +1,6 @@ from .common import EventBuilder, EventCommon, name_inner_event from .. import utils -from ..tl import types, functions, custom +from ..tl import types, functions @name_inner_event @@ -139,8 +139,8 @@ class ChatAction(EventBuilder): self._added_by = None self._kicked_by = None - self.user_added, self.user_joined, self.user_left,\ - self.user_kicked, self.unpin = (False, False, False, False, False) + self.user_added = self.user_joined = self.user_left = \ + self.user_kicked = self.unpin = False if added_by is True: self.user_joined = True diff --git a/telethon/events/common.py b/telethon/events/common.py index 8c3d3360..f5fdc11f 100644 --- a/telethon/events/common.py +++ b/telethon/events/common.py @@ -52,13 +52,26 @@ class EventBuilder(abc.ABC): as a whitelist (default). This means that every chat will be handled *except* those specified in ``chats`` which will be ignored if ``blacklist_chats=True``. + + func (`callable`, optional): + A callable function that should accept the event as input + parameter, and return a value indicating whether the event + should be dispatched or not (any truthy value will do, it + does not need to be a `bool`). It works like a custom filter: + + .. code-block:: python + + @client.on(events.NewMessage(func=lambda e: e.is_private)) + async def handler(event): + pass # code here """ self_id = None - def __init__(self, chats=None, blacklist_chats=False): + def __init__(self, chats=None, *, blacklist_chats=False, func=None): self.chats = chats self.blacklist_chats = blacklist_chats self.resolved = False + self.func = func self._resolve_lock = None @classmethod @@ -100,7 +113,9 @@ class EventBuilder(abc.ABC): # If this chat matches but it's a blacklist ignore. # If it doesn't match but it's a whitelist ignore. return None - return event + + if not self.func or self.func(event): + return event class EventCommon(ChatGetter, abc.ABC): diff --git a/telethon/events/inlinequery.py b/telethon/events/inlinequery.py index 8f6e4f54..75e991a6 100644 --- a/telethon/events/inlinequery.py +++ b/telethon/events/inlinequery.py @@ -31,8 +31,9 @@ class InlineQuery(EventBuilder): against the message, a callable function that returns ``True`` if a message is acceptable, or a compiled regex pattern. """ - def __init__(self, users=None, *, blacklist_users=False, pattern=None): - super().__init__(chats=users, blacklist_chats=blacklist_users) + def __init__( + self, users=None, *, blacklist_users=False, func=None, pattern=None): + super().__init__(users, blacklist_chats=blacklist_users, func=func) if isinstance(pattern, str): self.pattern = re.compile(pattern).match diff --git a/telethon/events/messageread.py b/telethon/events/messageread.py index 1788add0..48f478be 100644 --- a/telethon/events/messageread.py +++ b/telethon/events/messageread.py @@ -14,8 +14,9 @@ class MessageRead(EventBuilder): messages the event will be fired. By default (``False``) only when messages you sent are read by someone else will fire it. """ - def __init__(self, chats=None, *, blacklist_chats=None, inbox=False): - super().__init__(chats, blacklist_chats) + def __init__( + self, chats=None, *, blacklist_chats=None, func=None, inbox=False): + super().__init__(chats, blacklist_chats=blacklist_chats, func=func) self.inbox = inbox @classmethod diff --git a/telethon/events/newmessage.py b/telethon/events/newmessage.py index 12d3e7cb..0612931a 100644 --- a/telethon/events/newmessage.py +++ b/telethon/events/newmessage.py @@ -38,7 +38,7 @@ class NewMessage(EventBuilder): against the message, a callable function that returns ``True`` if a message is acceptable, or a compiled regex pattern. """ - def __init__(self, chats=None, *, blacklist_chats=False, + def __init__(self, chats=None, *, blacklist_chats=False, func=None, incoming=None, outgoing=None, from_users=None, forwards=None, pattern=None): if incoming and outgoing: @@ -51,7 +51,7 @@ class NewMessage(EventBuilder): raise ValueError("Don't create an event handler if you " "don't want neither incoming or outgoing!") - super().__init__(chats=chats, blacklist_chats=blacklist_chats) + super().__init__(chats, blacklist_chats=blacklist_chats, func=func) self.incoming = incoming self.outgoing = outgoing self.from_users = from_users @@ -68,7 +68,7 @@ class NewMessage(EventBuilder): # Should we short-circuit? E.g. perform no check at all self._no_check = all(x is None for x in ( self.chats, self.incoming, self.outgoing, self.pattern, - self.from_users, self.forwards, self.from_users + self.from_users, self.forwards, self.from_users, self.func )) async def _resolve(self, client): diff --git a/telethon/events/raw.py b/telethon/events/raw.py index 5bd11721..4f25e769 100644 --- a/telethon/events/raw.py +++ b/telethon/events/raw.py @@ -11,8 +11,8 @@ class Raw(EventBuilder): The type or types that the :tl:`Update` instance must be. Equivalent to ``if not isinstance(update, types): return``. """ - def __init__(self, types=None): - super().__init__() + def __init__(self, types=None, *, func=None): + super().__init__(func=func) if not types: self.types = None elif not utils.is_list_like(types): @@ -34,5 +34,6 @@ class Raw(EventBuilder): return update def filter(self, event): - if not self.types or isinstance(event, self.types): + if ((not self.types or isinstance(event, self.types)) + and (not self.func or self.func(event))): return event