Support custom-callback filter for all events

This commit is contained in:
Lonami Exo 2018-09-09 15:48:54 +02:00
parent 11ef4ce370
commit 2f09e5c335
7 changed files with 36 additions and 17 deletions

View File

@ -23,8 +23,9 @@ class CallbackQuery(EventBuilder):
instance, to check against ``'data_1'`` and ``'data_2'`` you instance, to check against ``'data_1'`` and ``'data_2'`` you
can use ``re.compile(b'data_')``. can use ``re.compile(b'data_')``.
""" """
def __init__(self, chats=None, *, blacklist_chats=False, data=None): def __init__(
super().__init__(chats=chats, blacklist_chats=blacklist_chats) self, chats=None, *, blacklist_chats=False, func=None, data=None):
super().__init__(chats, blacklist_chats=blacklist_chats, func=func)
if isinstance(data, bytes): if isinstance(data, bytes):
self.data = data self.data = data

View File

@ -1,6 +1,6 @@
from .common import EventBuilder, EventCommon, name_inner_event from .common import EventBuilder, EventCommon, name_inner_event
from .. import utils from .. import utils
from ..tl import types, functions, custom from ..tl import types, functions
@name_inner_event @name_inner_event
@ -139,8 +139,8 @@ class ChatAction(EventBuilder):
self._added_by = None self._added_by = None
self._kicked_by = None self._kicked_by = None
self.user_added, self.user_joined, self.user_left,\ self.user_added = self.user_joined = self.user_left = \
self.user_kicked, self.unpin = (False, False, False, False, False) self.user_kicked = self.unpin = False
if added_by is True: if added_by is True:
self.user_joined = True self.user_joined = True

View File

@ -52,13 +52,26 @@ class EventBuilder(abc.ABC):
as a whitelist (default). This means that every chat as a whitelist (default). This means that every chat
will be handled *except* those specified in ``chats`` will be handled *except* those specified in ``chats``
which will be ignored if ``blacklist_chats=True``. 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 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.chats = chats
self.blacklist_chats = blacklist_chats self.blacklist_chats = blacklist_chats
self.resolved = False self.resolved = False
self.func = func
self._resolve_lock = None self._resolve_lock = None
@classmethod @classmethod
@ -100,7 +113,9 @@ class EventBuilder(abc.ABC):
# If this chat matches but it's a blacklist ignore. # If this chat matches but it's a blacklist ignore.
# If it doesn't match but it's a whitelist ignore. # If it doesn't match but it's a whitelist ignore.
return None return None
return event
if not self.func or self.func(event):
return event
class EventCommon(ChatGetter, abc.ABC): class EventCommon(ChatGetter, abc.ABC):

View File

@ -31,8 +31,9 @@ class InlineQuery(EventBuilder):
against the message, a callable function that returns ``True`` against the message, a callable function that returns ``True``
if a message is acceptable, or a compiled regex pattern. if a message is acceptable, or a compiled regex pattern.
""" """
def __init__(self, users=None, *, blacklist_users=False, pattern=None): def __init__(
super().__init__(chats=users, blacklist_chats=blacklist_users) self, users=None, *, blacklist_users=False, func=None, pattern=None):
super().__init__(users, blacklist_chats=blacklist_users, func=func)
if isinstance(pattern, str): if isinstance(pattern, str):
self.pattern = re.compile(pattern).match self.pattern = re.compile(pattern).match

View File

@ -14,8 +14,9 @@ class MessageRead(EventBuilder):
messages the event will be fired. By default (``False``) only messages the event will be fired. By default (``False``) only
when messages you sent are read by someone else will fire it. when messages you sent are read by someone else will fire it.
""" """
def __init__(self, chats=None, *, blacklist_chats=None, inbox=False): def __init__(
super().__init__(chats, blacklist_chats) self, chats=None, *, blacklist_chats=None, func=None, inbox=False):
super().__init__(chats, blacklist_chats=blacklist_chats, func=func)
self.inbox = inbox self.inbox = inbox
@classmethod @classmethod

View File

@ -38,7 +38,7 @@ class NewMessage(EventBuilder):
against the message, a callable function that returns ``True`` against the message, a callable function that returns ``True``
if a message is acceptable, or a compiled regex pattern. 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, incoming=None, outgoing=None,
from_users=None, forwards=None, pattern=None): from_users=None, forwards=None, pattern=None):
if incoming and outgoing: if incoming and outgoing:
@ -51,7 +51,7 @@ class NewMessage(EventBuilder):
raise ValueError("Don't create an event handler if you " raise ValueError("Don't create an event handler if you "
"don't want neither incoming or outgoing!") "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.incoming = incoming
self.outgoing = outgoing self.outgoing = outgoing
self.from_users = from_users self.from_users = from_users
@ -68,7 +68,7 @@ class NewMessage(EventBuilder):
# Should we short-circuit? E.g. perform no check at all # Should we short-circuit? E.g. perform no check at all
self._no_check = all(x is None for x in ( self._no_check = all(x is None for x in (
self.chats, self.incoming, self.outgoing, self.pattern, 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): async def _resolve(self, client):

View File

@ -11,8 +11,8 @@ class Raw(EventBuilder):
The type or types that the :tl:`Update` instance must be. The type or types that the :tl:`Update` instance must be.
Equivalent to ``if not isinstance(update, types): return``. Equivalent to ``if not isinstance(update, types): return``.
""" """
def __init__(self, types=None): def __init__(self, types=None, *, func=None):
super().__init__() super().__init__(func=func)
if not types: if not types:
self.types = None self.types = None
elif not utils.is_list_like(types): elif not utils.is_list_like(types):
@ -34,5 +34,6 @@ class Raw(EventBuilder):
return update return update
def filter(self, event): 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 return event