diff --git a/telegram/ext/filters.py b/telegram/ext/filters.py index f10b66f8772..d88015da2fe 100644 --- a/telegram/ext/filters.py +++ b/telegram/ext/filters.py @@ -19,6 +19,7 @@ """This module contains the Filters for use with the MessageHandler class.""" import re +import time from abc import ABC, abstractmethod from future.utils import string_types @@ -1397,3 +1398,33 @@ def filter(self, update): channel_posts: Updates with either :attr:`telegram.Update.channel_post` or :attr:`telegram.Update.edited_channel_post` """ + + class date(BaseFilter): + """Filters messages to allow only those which are not older than a specified number + of sec ago. + + Examples: + ``MessageHandler(Filters.date(seconds_ago=15), callback_method)`` + + Args: + seconds_ago(:obj:`int`, optional): Max time diff between when the message was sent + (message.date) and 'now' for message to be allowed through, in seconds. + + Raises: + ValueError: If seconds_ago not set or smaller than 2. + """ + + def __init__(self, seconds_ago=None): + if not bool(seconds_ago): + raise ValueError('seconds_ago must be used') + elif seconds_ago is not None and isinstance(seconds_ago, int) and seconds_ago < 2: + raise ValueError('seconds_ago must be 2 at minimum') + elif seconds_ago is not None and isinstance(seconds_ago, int) and seconds_ago >= 2: + self.seconds_ago = seconds_ago + else: + # should never end up here + raise ValueError('Unknown error!') + + def filter(self, message): + # msg.date > (now - seconds_ago) + return bool(int(message.date.timestamp()) > (int(time.time()) - int(self.seconds_ago))) diff --git a/tests/test_filters.py b/tests/test_filters.py index 6d8917d8727..e1175d49100 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -47,6 +47,18 @@ def test_filters_text(self, update): update.message.text = '/test' assert (Filters.text)(update) + def test_filters_date_init(self): + with pytest.raises(ValueError, match='must be used'): + Filters.date(seconds_ago=0) + with pytest.raises(ValueError, match='at minimum'): + Filters.date(seconds_ago=1) + + def test_filters_date(self, update): + update.message.date = datetime.datetime.utcnow() + assert Filters.date(seconds_ago=10)(update) + update.message.date = datetime.datetime.utcnow() - datetime.timedelta(seconds=100) + assert not Filters.date(seconds_ago=10)(update) + def test_filters_text_strings(self, update): update.message.text = '/test' assert Filters.text({'/test', 'test1'})(update)