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
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

View File

@ -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

View File

@ -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):

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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