2
0
mirror of https://github.com/pyrogram/pyrogram synced 2025-09-03 15:55:37 +00:00

Update filters: Make the name argument optional

This commit is contained in:
Dan
2019-06-28 11:11:59 +02:00
parent 506253e506
commit 155580649a
2 changed files with 92 additions and 96 deletions

View File

@@ -17,190 +17,193 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
import re
from typing import Callable
from .filter import Filter
from ..types.bots_and_keyboards import InlineKeyboardMarkup, ReplyKeyboardMarkup
CUSTOM_FILTER_NAME = "CustomFilter"
def create(name: str, func: callable, **kwargs) -> type:
"""Create a Filter.
def create(func: Callable, name: str = None, **kwargs) -> Filter:
"""Easily create a custom filter.
Custom filters give you extra control over which updates are allowed or not to be processed by your handlers.
Parameters:
name (``str``):
Your filter's name. Can be anything you like.
func (``callable``):
A function that accepts two arguments *(filter, update)* and returns a Boolean: True if the update should be
handled, False otherwise.
The "update" argument type will vary depending on which `Handler <Handlers.html>`_ is coming from.
For example, in a :obj:`MessageHandler` the update type will be
a :obj:`Message`; in a :obj:`CallbackQueryHandler` the
update type will be a :obj:`CallbackQuery`. Your function body can then access the
incoming update and decide whether to allow it or not.
A function that accepts two positional arguments *(filter, update)* and returns a boolean: True if the
update should be handled, False otherwise. The *filter* argument refers to the filter itself and can be used
to access keyword arguments (read below). The *update* argument type will vary depending on which
`Handler <handlers>`_ is coming from. For example, in a :obj:`MessageHandler` the *update* argument will be
a :obj:`Message`; in a :obj:`CallbackQueryHandler` the *update* will be a :obj:`CallbackQuery`. Your
function body can then access the incoming update attributes and decide whether to allow it or not.
name (``str``, *optional*):
Your filter's name. Can be anything you like.
Defaults to "CustomFilter".
**kwargs (``any``, *optional*):
Any keyword argument you would like to pass. Useful for custom filters that accept parameters (e.g.:
:meth:`~Filters.command`, :meth:`~Filters.regex`).
Any keyword argument you would like to pass. Useful when creating parameterized custom filters, such as
:meth:`~Filters.command` or :meth:`~Filters.regex`.
"""
# TODO: unpack kwargs using **kwargs into the dict itself. For Python 3.5+ only
d = {"__call__": func}
d.update(kwargs)
return type(name, (Filter,), d)()
return type(name or CUSTOM_FILTER_NAME, (Filter,), d)()
class Filters:
"""This class provides access to all library-defined Filters available in Pyrogram.
The Filters listed here are intended to be used with the :obj:`MessageHandler` only.
The Filters listed here are currently intended to be used with the :obj:`MessageHandler` only.
At the moment, if you want to filter updates coming from different `Handlers <Handlers.html>`_ you have to create
your own filters with :meth:`~Filters.create` and use them in the same way.
"""
create = create
me = create("Me", lambda _, m: bool(m.from_user and m.from_user.is_self))
me = create(lambda _, m: bool(m.from_user and m.from_user.is_self), "MeFilter")
"""Filter messages generated by you yourself."""
bot = create("Bot", lambda _, m: bool(m.from_user and m.from_user.is_bot))
bot = create(lambda _, m: bool(m.from_user and m.from_user.is_bot), "BotFilter")
"""Filter messages coming from bots."""
incoming = create("Incoming", lambda _, m: not m.outgoing)
incoming = create(lambda _, m: not m.outgoing, "IncomingFilter")
"""Filter incoming messages. Messages sent to your own chat (Saved Messages) are also recognised as incoming."""
outgoing = create("Outgoing", lambda _, m: m.outgoing)
outgoing = create(lambda _, m: m.outgoing, "OutgoingFilter")
"""Filter outgoing messages. Messages sent to your own chat (Saved Messages) are not recognized as outgoing."""
text = create("Text", lambda _, m: bool(m.text))
text = create(lambda _, m: bool(m.text), "TextFilter")
"""Filter text messages."""
reply = create("Reply", lambda _, m: bool(m.reply_to_message))
reply = create(lambda _, m: bool(m.reply_to_message), "ReplyFilter")
"""Filter messages that are replies to other messages."""
forwarded = create("Forwarded", lambda _, m: bool(m.forward_date))
forwarded = create(lambda _, m: bool(m.forward_date), "ForwardedFilter")
"""Filter messages that are forwarded."""
caption = create("Caption", lambda _, m: bool(m.caption))
caption = create(lambda _, m: bool(m.caption), "CaptionFilter")
"""Filter media messages that contain captions."""
edited = create("Edited", lambda _, m: bool(m.edit_date))
edited = create(lambda _, m: bool(m.edit_date), "EditedFilter")
"""Filter edited messages."""
audio = create("Audio", lambda _, m: bool(m.audio))
audio = create(lambda _, m: bool(m.audio), "AudioFilter")
"""Filter messages that contain :obj:`Audio` objects."""
document = create("Document", lambda _, m: bool(m.document))
document = create(lambda _, m: bool(m.document), "DocumentFilter")
"""Filter messages that contain :obj:`Document` objects."""
photo = create("Photo", lambda _, m: bool(m.photo))
photo = create(lambda _, m: bool(m.photo), "PhotoFilter")
"""Filter messages that contain :obj:`Photo` objects."""
sticker = create("Sticker", lambda _, m: bool(m.sticker))
sticker = create(lambda _, m: bool(m.sticker), "StickerFilter")
"""Filter messages that contain :obj:`Sticker` objects."""
animation = create("Animation", lambda _, m: bool(m.animation))
animation = create(lambda _, m: bool(m.animation), "AnimationFilter")
"""Filter messages that contain :obj:`Animation` objects."""
game = create("Game", lambda _, m: bool(m.game))
game = create(lambda _, m: bool(m.game), "GameFilter")
"""Filter messages that contain :obj:`Game` objects."""
video = create("Video", lambda _, m: bool(m.video))
video = create(lambda _, m: bool(m.video), "VideoFilter")
"""Filter messages that contain :obj:`Video` objects."""
media_group = create("MediaGroup", lambda _, m: bool(m.media_group_id))
media_group = create(lambda _, m: bool(m.media_group_id), "MediaGroupFilter")
"""Filter messages containing photos or videos being part of an album."""
voice = create("Voice", lambda _, m: bool(m.voice))
voice = create(lambda _, m: bool(m.voice), "VoiceFilter")
"""Filter messages that contain :obj:`Voice` note objects."""
video_note = create("VideoNote", lambda _, m: bool(m.video_note))
video_note = create(lambda _, m: bool(m.video_note), "VideoNoteFilter")
"""Filter messages that contain :obj:`VideoNote` objects."""
contact = create("Contact", lambda _, m: bool(m.contact))
contact = create(lambda _, m: bool(m.contact), "ContactFilter")
"""Filter messages that contain :obj:`Contact` objects."""
location = create("Location", lambda _, m: bool(m.location))
location = create(lambda _, m: bool(m.location), "LocationFilter")
"""Filter messages that contain :obj:`Location` objects."""
venue = create("Venue", lambda _, m: bool(m.venue))
venue = create(lambda _, m: bool(m.venue), "VenueFilter")
"""Filter messages that contain :obj:`Venue` objects."""
web_page = create("WebPage", lambda _, m: m.web_page)
web_page = create(lambda _, m: m.web_page, "WebPageFilter")
"""Filter messages sent with a webpage preview."""
poll = create("Poll", lambda _, m: m.poll)
poll = create(lambda _, m: m.poll, "PollFilter")
"""Filter messages that contain :obj:`Poll` objects."""
private = create("Private", lambda _, m: bool(m.chat and m.chat.type == "private"))
private = create(lambda _, m: bool(m.chat and m.chat.type == "private"), "PrivateFilter")
"""Filter messages sent in private chats."""
group = create("Group", lambda _, m: bool(m.chat and m.chat.type in {"group", "supergroup"}))
group = create(lambda _, m: bool(m.chat and m.chat.type in {"group", "supergroup"}), "GroupFilter")
"""Filter messages sent in group or supergroup chats."""
channel = create("Channel", lambda _, m: bool(m.chat and m.chat.type == "channel"))
channel = create(lambda _, m: bool(m.chat and m.chat.type == "channel"), "ChannelFilter")
"""Filter messages sent in channels."""
new_chat_members = create("NewChatMembers", lambda _, m: bool(m.new_chat_members))
new_chat_members = create(lambda _, m: bool(m.new_chat_members), "NewChatMembersFilter")
"""Filter service messages for new chat members."""
left_chat_member = create("LeftChatMember", lambda _, m: bool(m.left_chat_member))
left_chat_member = create(lambda _, m: bool(m.left_chat_member), "LeftChatMemberFilter")
"""Filter service messages for members that left the chat."""
new_chat_title = create("NewChatTitle", lambda _, m: bool(m.new_chat_title))
new_chat_title = create(lambda _, m: bool(m.new_chat_title), "NewChatTitleFilter")
"""Filter service messages for new chat titles."""
new_chat_photo = create("NewChatPhoto", lambda _, m: bool(m.new_chat_photo))
new_chat_photo = create(lambda _, m: bool(m.new_chat_photo), "NewChatPhotoFilter")
"""Filter service messages for new chat photos."""
delete_chat_photo = create("DeleteChatPhoto", lambda _, m: bool(m.delete_chat_photo))
delete_chat_photo = create(lambda _, m: bool(m.delete_chat_photo), "DeleteChatPhotoFilter")
"""Filter service messages for deleted photos."""
group_chat_created = create("GroupChatCreated", lambda _, m: bool(m.group_chat_created))
group_chat_created = create(lambda _, m: bool(m.group_chat_created), "GroupChatCreatedFilter")
"""Filter service messages for group chat creations."""
supergroup_chat_created = create("SupergroupChatCreated", lambda _, m: bool(m.supergroup_chat_created))
supergroup_chat_created = create(lambda _, m: bool(m.supergroup_chat_created), "SupergroupChatCreatedFilter")
"""Filter service messages for supergroup chat creations."""
channel_chat_created = create("ChannelChatCreated", lambda _, m: bool(m.channel_chat_created))
channel_chat_created = create(lambda _, m: bool(m.channel_chat_created), "ChannelChatCreatedFilter")
"""Filter service messages for channel chat creations."""
migrate_to_chat_id = create("MigrateToChatId", lambda _, m: bool(m.migrate_to_chat_id))
migrate_to_chat_id = create(lambda _, m: bool(m.migrate_to_chat_id), "MigrateToChatIdFilter")
"""Filter service messages that contain migrate_to_chat_id."""
migrate_from_chat_id = create("MigrateFromChatId", lambda _, m: bool(m.migrate_from_chat_id))
migrate_from_chat_id = create(lambda _, m: bool(m.migrate_from_chat_id), "MigrateFromChatIdFilter")
"""Filter service messages that contain migrate_from_chat_id."""
pinned_message = create("PinnedMessage", lambda _, m: bool(m.pinned_message))
pinned_message = create(lambda _, m: bool(m.pinned_message), "PinnedMessageFilter")
"""Filter service messages for pinned messages."""
game_high_score = create("GameHighScore", lambda _, m: bool(m.game_high_score))
game_high_score = create(lambda _, m: bool(m.game_high_score), "GameHighScoreFilter")
"""Filter service messages for game high scores."""
reply_keyboard = create("ReplyKeyboard", lambda _, m: isinstance(m.reply_markup, ReplyKeyboardMarkup))
reply_keyboard = create(lambda _, m: isinstance(m.reply_markup, ReplyKeyboardMarkup), "ReplyKeyboardFilter")
"""Filter messages containing reply keyboard markups"""
inline_keyboard = create("InlineKeyboard", lambda _, m: isinstance(m.reply_markup, InlineKeyboardMarkup))
inline_keyboard = create(lambda _, m: isinstance(m.reply_markup, InlineKeyboardMarkup), "InlineKeyboardFilter")
"""Filter messages containing inline keyboard markups"""
mentioned = create("Mentioned", lambda _, m: bool(m.mentioned))
mentioned = create(lambda _, m: bool(m.mentioned), "MentionedFilter")
"""Filter messages containing mentions"""
via_bot = create("ViaBot", lambda _, m: bool(m.via_bot))
via_bot = create(lambda _, m: bool(m.via_bot), "ViaBotFilter")
"""Filter messages sent via inline bots"""
service = create("Service", lambda _, m: bool(m.service))
service = create(lambda _, m: bool(m.service), "ServiceFilter")
"""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*, *game_score*.
"""
media = create("Media", lambda _, m: bool(m.media))
media = create(lambda _, m: bool(m.media), "MediaFilter")
"""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*, *poll*.
"""
@@ -253,17 +256,17 @@ class Filters:
commands = {c if case_sensitive else c.lower() for c in commands}
prefixes = set(prefix) if prefix else {""}
return create("Command", func=func, c=commands, p=prefixes, s=separator, cs=case_sensitive)
return create(func, "CommandFilter", c=commands, p=prefixes, s=separator, cs=case_sensitive)
@staticmethod
def regex(pattern, flags: int = 0):
"""Filter messages that match a given RegEx pattern.
"""Filter message texts or captions that match a given regular expression pattern.
Parameters:
pattern (``str``):
The RegEx pattern as string, it will be applied to the text of a message. When a pattern matches,
all the `Match Objects <https://docs.python.org/3/library/re.html#match-objects>`_
are stored in the *matches* field of the :obj:`Message` itself.
The RegEx pattern as string, it will be applied to the text or the caption of a message. When a pattern
matches, all the `Match Objects <https://docs.python.org/3/library/re.html#match-objects>`_ are stored
in the *matches* field of the :obj:`Message` itself.
flags (``int``, *optional*):
RegEx flags.
@@ -273,7 +276,7 @@ class Filters:
m.matches = [i for i in _.p.finditer(m.text or m.caption or "")]
return bool(m.matches)
return create("Regex", f, p=re.compile(pattern, flags))
return create(f, "RegexFilter", p=re.compile(pattern, flags))
# noinspection PyPep8Naming
class user(Filter, set):
@@ -285,7 +288,7 @@ class Filters:
Parameters:
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.
For you yourself, "me" or "self" can be used as well.
Defaults to None (no users).
"""
@@ -342,12 +345,12 @@ class Filters:
@staticmethod
def callback_data(data: str or bytes):
"""Filter callback queries for their data.
Parameters:
data (``str`` | ``bytes``):
Pass the data you want to filter for.
"""
return create("CallbackData", lambda flt, cb: cb.data == flt.data, data=data)
return create(lambda flt, cb: cb.data == flt.data, "CallbackDataFilter", data=data)
dan = create("Dan", lambda _, m: bool(m.from_user and m.from_user.id == 23122162))
dan = create(lambda _, m: bool(m.from_user and m.from_user.id == 23122162), "DanFilter")