mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2024-12-22 22:45:09 +01:00
Make Filters.command only accept MessageEntity commands (#1744)
* Make Filters.command only accept MessageEntitie commands * Add option to filters.command to allow cmds anywhere in the message * Make codecov happy, also retroactive for #1631
This commit is contained in:
parent
7b3b278c7c
commit
f9a8cd924c
2 changed files with 63 additions and 12 deletions
|
@ -22,7 +22,7 @@ import re
|
||||||
|
|
||||||
from future.utils import string_types
|
from future.utils import string_types
|
||||||
|
|
||||||
from telegram import Chat, Update
|
from telegram import Chat, Update, MessageEntity
|
||||||
|
|
||||||
__all__ = ['Filters', 'BaseFilter', 'InvertedFilter', 'MergedFilter']
|
__all__ = ['Filters', 'BaseFilter', 'InvertedFilter', 'MergedFilter']
|
||||||
|
|
||||||
|
@ -249,9 +249,6 @@ class Filters(object):
|
||||||
|
|
||||||
def __call__(self, update):
|
def __call__(self, update):
|
||||||
if isinstance(update, Update):
|
if isinstance(update, Update):
|
||||||
if self.update_filter:
|
|
||||||
return self.filter(update)
|
|
||||||
else:
|
|
||||||
return self.filter(update.effective_message)
|
return self.filter(update.effective_message)
|
||||||
else:
|
else:
|
||||||
return self._TextIterable(update)
|
return self._TextIterable(update)
|
||||||
|
@ -296,9 +293,6 @@ class Filters(object):
|
||||||
|
|
||||||
def __call__(self, update):
|
def __call__(self, update):
|
||||||
if isinstance(update, Update):
|
if isinstance(update, Update):
|
||||||
if self.update_filter:
|
|
||||||
return self.filter(update)
|
|
||||||
else:
|
|
||||||
return self.filter(update.effective_message)
|
return self.filter(update.effective_message)
|
||||||
else:
|
else:
|
||||||
return self._CaptionIterable(update)
|
return self._CaptionIterable(update)
|
||||||
|
@ -321,11 +315,41 @@ class Filters(object):
|
||||||
class _Command(BaseFilter):
|
class _Command(BaseFilter):
|
||||||
name = 'Filters.command'
|
name = 'Filters.command'
|
||||||
|
|
||||||
|
class _CommandOnlyStart(BaseFilter):
|
||||||
|
|
||||||
|
def __init__(self, only_start):
|
||||||
|
self.only_start = only_start
|
||||||
|
self.name = 'Filters.command({})'.format(only_start)
|
||||||
|
|
||||||
def filter(self, message):
|
def filter(self, message):
|
||||||
return bool(message.text and message.text.startswith('/'))
|
return (message.entities
|
||||||
|
and any([e.type == MessageEntity.BOT_COMMAND for e in message.entities]))
|
||||||
|
|
||||||
|
def __call__(self, update):
|
||||||
|
if isinstance(update, Update):
|
||||||
|
return self.filter(update.effective_message)
|
||||||
|
else:
|
||||||
|
return self._CommandOnlyStart(update)
|
||||||
|
|
||||||
|
def filter(self, message):
|
||||||
|
return (message.entities and message.entities[0].type == MessageEntity.BOT_COMMAND
|
||||||
|
and message.entities[0].offset == 0)
|
||||||
|
|
||||||
command = _Command()
|
command = _Command()
|
||||||
"""Messages starting with ``/``."""
|
"""
|
||||||
|
Messages with a :attr:`telegram.MessageEntity.BOT_COMMAND`. By default only allows
|
||||||
|
messages `starting` with a bot command. Pass ``False`` to also allow messages that contain a
|
||||||
|
bot command `anywhere` in the text.
|
||||||
|
|
||||||
|
Examples::
|
||||||
|
|
||||||
|
MessageHandler(Filters.command, command_at_start_callback)
|
||||||
|
MessageHandler(Filters.command(False), command_anywhere_callback)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
update (:obj:`bool`, optional): Whether to only allow messages that `start` with a bot
|
||||||
|
command. Defaults to ``True``.
|
||||||
|
"""
|
||||||
|
|
||||||
class regex(BaseFilter):
|
class regex(BaseFilter):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -63,12 +63,23 @@ class TestFilters(object):
|
||||||
assert Filters.caption({'test', 'test1'})(update)
|
assert Filters.caption({'test', 'test1'})(update)
|
||||||
assert not Filters.caption(['test1', 'test2'])(update)
|
assert not Filters.caption(['test1', 'test2'])(update)
|
||||||
|
|
||||||
def test_filters_command(self, update):
|
def test_filters_command_default(self, update):
|
||||||
update.message.text = 'test'
|
update.message.text = 'test'
|
||||||
assert not Filters.command(update)
|
assert not Filters.command(update)
|
||||||
update.message.text = '/test'
|
update.message.text = '/test'
|
||||||
|
assert not Filters.command(update)
|
||||||
|
# Only accept commands at the beginning
|
||||||
|
update.message.entities = [MessageEntity(MessageEntity.BOT_COMMAND, 3, 5)]
|
||||||
|
assert not Filters.command(update)
|
||||||
|
update.message.entities = [MessageEntity(MessageEntity.BOT_COMMAND, 0, 5)]
|
||||||
assert Filters.command(update)
|
assert Filters.command(update)
|
||||||
|
|
||||||
|
def test_filters_command_anywhere(self, update):
|
||||||
|
update.message.text = 'test /cmd'
|
||||||
|
assert not (Filters.command(False))(update)
|
||||||
|
update.message.entities = [MessageEntity(MessageEntity.BOT_COMMAND, 5, 4)]
|
||||||
|
assert (Filters.command(False))(update)
|
||||||
|
|
||||||
def test_filters_regex(self, update):
|
def test_filters_regex(self, update):
|
||||||
SRE_TYPE = type(re.match("", ""))
|
SRE_TYPE = type(re.match("", ""))
|
||||||
update.message.text = '/start deep-linked param'
|
update.message.text = '/start deep-linked param'
|
||||||
|
@ -120,6 +131,7 @@ class TestFilters(object):
|
||||||
def test_filters_merged_with_regex(self, update):
|
def test_filters_merged_with_regex(self, update):
|
||||||
SRE_TYPE = type(re.match("", ""))
|
SRE_TYPE = type(re.match("", ""))
|
||||||
update.message.text = '/start deep-linked param'
|
update.message.text = '/start deep-linked param'
|
||||||
|
update.message.entities = [MessageEntity(MessageEntity.BOT_COMMAND, 0, 6)]
|
||||||
result = (Filters.command & Filters.regex(r'linked param'))(update)
|
result = (Filters.command & Filters.regex(r'linked param'))(update)
|
||||||
assert result
|
assert result
|
||||||
assert isinstance(result, dict)
|
assert isinstance(result, dict)
|
||||||
|
@ -216,6 +228,7 @@ class TestFilters(object):
|
||||||
result = filter(update)
|
result = filter(update)
|
||||||
assert not result
|
assert not result
|
||||||
update.message.text = '/start'
|
update.message.text = '/start'
|
||||||
|
update.message.entities = [MessageEntity(MessageEntity.BOT_COMMAND, 0, 6)]
|
||||||
result = filter(update)
|
result = filter(update)
|
||||||
assert result
|
assert result
|
||||||
assert isinstance(result, bool)
|
assert isinstance(result, bool)
|
||||||
|
@ -230,6 +243,7 @@ class TestFilters(object):
|
||||||
|
|
||||||
def test_regex_inverted(self, update):
|
def test_regex_inverted(self, update):
|
||||||
update.message.text = '/start deep-linked param'
|
update.message.text = '/start deep-linked param'
|
||||||
|
update.message.entities = [MessageEntity(MessageEntity.BOT_COMMAND, 0, 5)]
|
||||||
filter = ~Filters.regex(r'deep-linked param')
|
filter = ~Filters.regex(r'deep-linked param')
|
||||||
result = filter(update)
|
result = filter(update)
|
||||||
assert not result
|
assert not result
|
||||||
|
@ -243,6 +257,7 @@ class TestFilters(object):
|
||||||
result = filter(update)
|
result = filter(update)
|
||||||
assert not result
|
assert not result
|
||||||
update.message.text = '/start'
|
update.message.text = '/start'
|
||||||
|
update.message.entities = [MessageEntity(MessageEntity.BOT_COMMAND, 0, 6)]
|
||||||
result = filter(update)
|
result = filter(update)
|
||||||
assert result
|
assert result
|
||||||
update.message.text = '/linked'
|
update.message.text = '/linked'
|
||||||
|
@ -251,15 +266,18 @@ class TestFilters(object):
|
||||||
|
|
||||||
filter = (~Filters.regex('linked') | Filters.command)
|
filter = (~Filters.regex('linked') | Filters.command)
|
||||||
update.message.text = "it's linked"
|
update.message.text = "it's linked"
|
||||||
|
update.message.entities = []
|
||||||
result = filter(update)
|
result = filter(update)
|
||||||
assert not result
|
assert not result
|
||||||
update.message.text = '/start linked'
|
update.message.text = '/start linked'
|
||||||
|
update.message.entities = [MessageEntity(MessageEntity.BOT_COMMAND, 0, 6)]
|
||||||
result = filter(update)
|
result = filter(update)
|
||||||
assert result
|
assert result
|
||||||
update.message.text = '/start'
|
update.message.text = '/start'
|
||||||
result = filter(update)
|
result = filter(update)
|
||||||
assert result
|
assert result
|
||||||
update.message.text = 'nothig'
|
update.message.text = 'nothig'
|
||||||
|
update.message.entities = []
|
||||||
result = filter(update)
|
result = filter(update)
|
||||||
assert result
|
assert result
|
||||||
|
|
||||||
|
@ -664,14 +682,17 @@ class TestFilters(object):
|
||||||
|
|
||||||
def test_inverted_filters(self, update):
|
def test_inverted_filters(self, update):
|
||||||
update.message.text = '/test'
|
update.message.text = '/test'
|
||||||
|
update.message.entities = [MessageEntity(MessageEntity.BOT_COMMAND, 0, 5)]
|
||||||
assert Filters.command(update)
|
assert Filters.command(update)
|
||||||
assert not (~Filters.command)(update)
|
assert not (~Filters.command)(update)
|
||||||
update.message.text = 'test'
|
update.message.text = 'test'
|
||||||
|
update.message.entities = []
|
||||||
assert not Filters.command(update)
|
assert not Filters.command(update)
|
||||||
assert (~Filters.command)(update)
|
assert (~Filters.command)(update)
|
||||||
|
|
||||||
def test_inverted_and_filters(self, update):
|
def test_inverted_and_filters(self, update):
|
||||||
update.message.text = '/test'
|
update.message.text = '/test'
|
||||||
|
update.message.entities = [MessageEntity(MessageEntity.BOT_COMMAND, 0, 5)]
|
||||||
update.message.forward_date = 1
|
update.message.forward_date = 1
|
||||||
assert (Filters.forwarded & Filters.command)(update)
|
assert (Filters.forwarded & Filters.command)(update)
|
||||||
assert not (~Filters.forwarded & Filters.command)(update)
|
assert not (~Filters.forwarded & Filters.command)(update)
|
||||||
|
@ -683,6 +704,7 @@ class TestFilters(object):
|
||||||
assert not (Filters.forwarded & ~Filters.command)(update)
|
assert not (Filters.forwarded & ~Filters.command)(update)
|
||||||
assert (~(Filters.forwarded & Filters.command))(update)
|
assert (~(Filters.forwarded & Filters.command))(update)
|
||||||
update.message.text = 'test'
|
update.message.text = 'test'
|
||||||
|
update.message.entities = []
|
||||||
assert not (Filters.forwarded & Filters.command)(update)
|
assert not (Filters.forwarded & Filters.command)(update)
|
||||||
assert not (~Filters.forwarded & Filters.command)(update)
|
assert not (~Filters.forwarded & Filters.command)(update)
|
||||||
assert not (Filters.forwarded & ~Filters.command)(update)
|
assert not (Filters.forwarded & ~Filters.command)(update)
|
||||||
|
@ -746,6 +768,7 @@ class TestFilters(object):
|
||||||
|
|
||||||
def test_merged_short_circuit_and(self, update):
|
def test_merged_short_circuit_and(self, update):
|
||||||
update.message.text = '/test'
|
update.message.text = '/test'
|
||||||
|
update.message.entities = [MessageEntity(MessageEntity.BOT_COMMAND, 0, 5)]
|
||||||
|
|
||||||
class TestException(Exception):
|
class TestException(Exception):
|
||||||
pass
|
pass
|
||||||
|
@ -760,6 +783,7 @@ class TestFilters(object):
|
||||||
(Filters.command & raising_filter)(update)
|
(Filters.command & raising_filter)(update)
|
||||||
|
|
||||||
update.message.text = 'test'
|
update.message.text = 'test'
|
||||||
|
update.message.entities = []
|
||||||
(Filters.command & raising_filter)(update)
|
(Filters.command & raising_filter)(update)
|
||||||
|
|
||||||
def test_merged_short_circuit_or(self, update):
|
def test_merged_short_circuit_or(self, update):
|
||||||
|
@ -778,10 +802,12 @@ class TestFilters(object):
|
||||||
(Filters.command | raising_filter)(update)
|
(Filters.command | raising_filter)(update)
|
||||||
|
|
||||||
update.message.text = '/test'
|
update.message.text = '/test'
|
||||||
|
update.message.entities = [MessageEntity(MessageEntity.BOT_COMMAND, 0, 5)]
|
||||||
(Filters.command | raising_filter)(update)
|
(Filters.command | raising_filter)(update)
|
||||||
|
|
||||||
def test_merged_data_merging_and(self, update):
|
def test_merged_data_merging_and(self, update):
|
||||||
update.message.text = '/test'
|
update.message.text = '/test'
|
||||||
|
update.message.entities = [MessageEntity(MessageEntity.BOT_COMMAND, 0, 5)]
|
||||||
|
|
||||||
class DataFilter(BaseFilter):
|
class DataFilter(BaseFilter):
|
||||||
data_filter = True
|
data_filter = True
|
||||||
|
@ -799,6 +825,7 @@ class TestFilters(object):
|
||||||
assert result['test'] == ['blah1', 'blah2']
|
assert result['test'] == ['blah1', 'blah2']
|
||||||
|
|
||||||
update.message.text = 'test'
|
update.message.text = 'test'
|
||||||
|
update.message.entities = []
|
||||||
result = (Filters.command & DataFilter('blah'))(update)
|
result = (Filters.command & DataFilter('blah'))(update)
|
||||||
assert not result
|
assert not result
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue