Expand and Adjust filters.{Document, Sticker} (#2922)

Co-authored-by: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com>
This commit is contained in:
Harshil 2022-04-24 17:17:35 +05:30 committed by Hinrich Mahler
parent 42eaa67fd5
commit 7c113f5c75
2 changed files with 104 additions and 26 deletions

View file

@ -52,7 +52,6 @@ __all__ = (
'Chat', 'Chat',
'ChatType', 'ChatType',
'Command', 'Command',
'DOCUMENT',
'Dice', 'Dice',
'Document', 'Document',
'Entity', 'Entity',
@ -70,7 +69,7 @@ __all__ = (
'POLL', 'POLL',
'REPLY', 'REPLY',
'Regex', 'Regex',
'STICKER', 'Sticker',
'SUCCESSFUL_PAYMENT', 'SUCCESSFUL_PAYMENT',
'SenderChat', 'SenderChat',
'StatusUpdate', 'StatusUpdate',
@ -819,7 +818,7 @@ class ChatType: # A convenience namespace for Chat types.
Use these filters like: ``filters.ChatType.CHANNEL`` or Use these filters like: ``filters.ChatType.CHANNEL`` or
``filters.ChatType.SUPERGROUP`` etc. ``filters.ChatType.SUPERGROUP`` etc.
Note: Caution:
``filters.ChatType`` itself is *not* a filter, but just a convenience namespace. ``filters.ChatType`` itself is *not* a filter, but just a convenience namespace.
""" """
@ -1084,18 +1083,30 @@ class Dice(_Dice):
"""Dice messages with the emoji 🎰. Matches any dice value.""" """Dice messages with the emoji 🎰. Matches any dice value."""
class Document(MessageFilter): class Document:
""" """
Subset for messages containing a document/file. Subset for messages containing a document/file.
Examples: Examples:
Use these filters like: ``filters.Document.MP3``, Use these filters like: ``filters.Document.MP3``,
``filters.Document.MimeType("text/plain")`` etc. Or use just ``filters.DOCUMENT`` for all ``filters.Document.MimeType("text/plain")`` etc. Or just use ``filters.Document.ALL`` for
document messages. all document messages.
Caution:
``filters.Document`` itself is *not* a filter, but just a convenience namespace.
""" """
__slots__ = () __slots__ = ()
class _All(MessageFilter):
__slots__ = ()
def filter(self, message: Message) -> bool:
return bool(message.document)
ALL = _All(name="filters.Document.ALL")
"""Messages that contain a :attr:`telegram.Message.document`."""
class Category(MessageFilter): class Category(MessageFilter):
"""Filters documents by their category in the mime-type attribute. """Filters documents by their category in the mime-type attribute.
@ -1252,13 +1263,6 @@ class Document(MessageFilter):
ZIP = MimeType(mimetypes.types_map['.zip']) ZIP = MimeType(mimetypes.types_map['.zip'])
"""Use as ``filters.Document.ZIP``.""" """Use as ``filters.Document.ZIP``."""
def filter(self, message: Message) -> bool:
return bool(message.document)
DOCUMENT = Document(name="filters.DOCUMENT")
"""Shortcut for :class:`telegram.ext.filters.Document()`."""
class Entity(MessageFilter): class Entity(MessageFilter):
""" """
@ -1665,7 +1669,7 @@ class StatusUpdate:
Use these filters like: ``filters.StatusUpdate.NEW_CHAT_MEMBERS`` etc. Or use just Use these filters like: ``filters.StatusUpdate.NEW_CHAT_MEMBERS`` etc. Or use just
``filters.StatusUpdate.ALL`` for all status update messages. ``filters.StatusUpdate.ALL`` for all status update messages.
Note: Caution:
``filters.StatusUpdate`` itself is *not* a filter, but just a convenience namespace. ``filters.StatusUpdate`` itself is *not* a filter, but just a convenience namespace.
""" """
@ -1860,15 +1864,69 @@ class StatusUpdate:
""" """
class _Sticker(MessageFilter): class Sticker:
"""Filters messages which contain a sticker.
Examples:
Use this filter like: ``filters.Sticker.VIDEO``. Or, just use ``filters.Sticker.ALL`` for
any type of sticker.
Caution:
``filters.Sticker`` itself is *not* a filter, but just a convenience namespace.
"""
__slots__ = () __slots__ = ()
def filter(self, message: Message) -> bool: class _All(MessageFilter):
return bool(message.sticker) __slots__ = ()
def filter(self, message: Message) -> bool:
return bool(message.sticker)
STICKER = _Sticker(name="filters.STICKER") ALL = _All(name="filters.Sticker.ALL")
"""Messages that contain :attr:`telegram.Message.sticker`.""" """Messages that contain :attr:`telegram.Message.sticker`."""
class _Animated(MessageFilter):
__slots__ = ()
def filter(self, message: Message) -> bool:
return bool(message.sticker) and bool(message.sticker.is_animated) # type: ignore
ANIMATED = _Animated(name="filters.Sticker.ANIMATED")
"""Messages that contain :attr:`telegram.Message.sticker` and
:attr:`is animated <telegram.Sticker.is_animated>`.
.. versionadded:: 14.0
"""
class _Static(MessageFilter):
__slots__ = ()
def filter(self, message: Message) -> bool:
return bool(message.sticker) and (
not bool(message.sticker.is_animated) # type: ignore[union-attr]
and not bool(message.sticker.is_video) # type: ignore[union-attr]
)
STATIC = _Static(name="filters.Sticker.STATIC")
"""Messages that contain :attr:`telegram.Message.sticker` and is a static sticker, i.e. does
not contain :attr:`telegram.Sticker.is_animated` or :attr:`telegram.Sticker.is_video`.
.. versionadded:: 14.0
"""
class _Video(MessageFilter):
__slots__ = ()
def filter(self, message: Message) -> bool:
return bool(message.sticker) and bool(message.sticker.is_video) # type: ignore
VIDEO = _Video(name="filters.Sticker.VIDEO")
"""Messages that contain :attr:`telegram.Message.sticker` and is a
:attr:`video sticker <telegram.Sticker.is_video>`.
.. versionadded:: 14.0
"""
class _SuccessfulPayment(MessageFilter): class _SuccessfulPayment(MessageFilter):
@ -1940,7 +1998,7 @@ class UpdateType:
Use these filters like: ``filters.UpdateType.MESSAGE`` or Use these filters like: ``filters.UpdateType.MESSAGE`` or
``filters.UpdateType.CHANNEL_POSTS`` etc. ``filters.UpdateType.CHANNEL_POSTS`` etc.
Note: Caution:
``filters.UpdateType`` itself is *not* a filter, but just a convenience namespace. ``filters.UpdateType`` itself is *not* a filter, but just a convenience namespace.
""" """

View file

@ -20,7 +20,17 @@ import datetime
import pytest import pytest
from telegram import Message, User, Chat, MessageEntity, Document, Update, Dice, CallbackQuery from telegram import (
Message,
User,
Chat,
MessageEntity,
Document,
Update,
Dice,
CallbackQuery,
Sticker,
)
from telegram.ext import filters from telegram.ext import filters
import inspect import inspect
import re import re
@ -583,9 +593,9 @@ class TestFilters:
assert filters.AUDIO.check_update(update) assert filters.AUDIO.check_update(update)
def test_filters_document(self, update): def test_filters_document(self, update):
assert not filters.DOCUMENT.check_update(update) assert not filters.Document.ALL.check_update(update)
update.message.document = 'test' update.message.document = 'test'
assert filters.DOCUMENT.check_update(update) assert filters.Document.ALL.check_update(update)
def test_filters_document_type(self, update): def test_filters_document_type(self, update):
update.message.document = Document( update.message.document = Document(
@ -816,9 +826,19 @@ class TestFilters:
assert filters.PHOTO.check_update(update) assert filters.PHOTO.check_update(update)
def test_filters_sticker(self, update): def test_filters_sticker(self, update):
assert not filters.STICKER.check_update(update) assert not filters.Sticker.ALL.check_update(update)
update.message.sticker = 'test' update.message.sticker = Sticker('1', 'uniq', 1, 2, False, False)
assert filters.STICKER.check_update(update) assert filters.Sticker.ALL.check_update(update)
assert filters.Sticker.STATIC.check_update(update)
update.message.sticker.is_animated = True
assert filters.Sticker.ANIMATED.check_update(update)
assert not filters.Sticker.VIDEO.check_update(update)
assert not filters.Sticker.STATIC.check_update(update)
update.message.sticker.is_animated = False
update.message.sticker.is_video = True
assert not filters.Sticker.ANIMATED.check_update(update)
assert not filters.Sticker.STATIC.check_update(update)
assert filters.Sticker.VIDEO.check_update(update)
def test_filters_video(self, update): def test_filters_video(self, update):
assert not filters.VIDEO.check_update(update) assert not filters.VIDEO.check_update(update)