From 5a6225567505d24054f906b7b2ef6b968a6e0f3c Mon Sep 17 00:00:00 2001 From: evgfilim1 Date: Mon, 19 Jun 2017 22:50:44 +0500 Subject: [PATCH 1/7] Added new filters for handling specific chat id and user id --- telegram/ext/filters.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/telegram/ext/filters.py b/telegram/ext/filters.py index 1942fa8593d..ba7f09aad83 100644 --- a/telegram/ext/filters.py +++ b/telegram/ext/filters.py @@ -324,6 +324,32 @@ def filter(self, message): group = _Group() + class user(BaseFilter): + """Filters messages to allow only those which are from specified user ID + + Args: + user_id(int): which user ID to allow through + """ + + def __init__(self, user_id): + self.user_id = user_id + + def filter(self, message): + return bool(message.from_user and message.from_user.id == self.user_id) + + class chat(BaseFilter): + """Filters messages to allow only those which are from specified chat ID + + Args: + chat_id(int): which chat ID to allow through + """ + + def __init__(self, chat_id): + self.chat_id = chat_id + + def filter(self, message): + return bool(message.chat_id == self.chat_id) + class _Invoice(BaseFilter): def filter(self, message): From e18ebd035c07762c0e633f8e5496d16c6a2b7237 Mon Sep 17 00:00:00 2001 From: evgfilim1 Date: Mon, 19 Jun 2017 22:53:44 +0500 Subject: [PATCH 2/7] Added tests --- tests/test_filters.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/test_filters.py b/tests/test_filters.py index e8c4c6637d2..674042de1f4 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -213,6 +213,20 @@ def test_group_fileter(self): self.message.chat.type = "supergroup" self.assertTrue(Filters.group(self.message)) + def test_filters_chat(self): + self.assertFalse(Filters.chat(-1)(self.message)) + self.message.chat.id = -1 + self.assertTrue(Filters.chat(-1)(self.message)) + self.message.chat.id = -2 + self.assertFalse(Filters.chat(-1)(self.message)) + + def test_filters_user(self): + self.assertFalse(Filters.user(1)(self.message)) + self.message.from_user.id = 1 + self.assertTrue(Filters.user(1)(self.message)) + self.message.from_user.id = 2 + self.assertFalse(Filters.user(1)(self.message)) + def test_and_filters(self): self.message.text = 'test' self.message.forward_date = True From 9bccbdab2adafea46727bae8c406014a02f699e8 Mon Sep 17 00:00:00 2001 From: evgfilim1 Date: Tue, 20 Jun 2017 12:43:07 +0500 Subject: [PATCH 3/7] Added ability to filter by username --- telegram/ext/filters.py | 45 +++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/telegram/ext/filters.py b/telegram/ext/filters.py index ba7f09aad83..be63ba473bf 100644 --- a/telegram/ext/filters.py +++ b/telegram/ext/filters.py @@ -328,27 +328,60 @@ class user(BaseFilter): """Filters messages to allow only those which are from specified user ID Args: - user_id(int): which user ID to allow through + user_id(Optional[int]): which user ID to allow through. Required if username is not + specified + username(Optional[str]): which username to allow through. Required if user_id is not + specified + + Raises: + ValueError """ - def __init__(self, user_id): + def __init__(self, user_id=None, username=None): + if (user_id is None and username is None) or (bool(user_id) and bool(username)): + raise ValueError('You must specify either user_id or username') + if username is not None and username.startswith('@'): + self.username = username[1:] + else: + self.username = username self.user_id = user_id def filter(self, message): - return bool(message.from_user and message.from_user.id == self.user_id) + if self.user_id is not None: + return bool(message.from_user and message.from_user.id == self.user_id) + else: + # self.username is not None + return bool(message.from_user and message.from_user.username and + message.from_user.username == self.username) class chat(BaseFilter): """Filters messages to allow only those which are from specified chat ID Args: - chat_id(int): which chat ID to allow through + chat_id(Optional[int]): which chat ID to allow through. Required if username is not + specified + username(Optional[str]): which username to allow through. Required if chat_id is not + specified + + Raises: + ValueError """ - def __init__(self, chat_id): + def __init__(self, chat_id=None, username=None): + if (chat_id is None and username is None) or (bool(chat_id) and bool(username)): + raise ValueError('You must specify either chat_id or username') + if username is not None and username.startswith('@'): + self.username = username[1:] + else: + self.username = username self.chat_id = chat_id def filter(self, message): - return bool(message.chat_id == self.chat_id) + if self.chat_id is not None: + return message.chat_id == self.chat_id + else: + # self.username is not None + return bool(message.chat.username and message.chat.username == self.username) class _Invoice(BaseFilter): From 3bf4399a4fabdfdb339b80b03addca21915792ae Mon Sep 17 00:00:00 2001 From: evgfilim1 Date: Tue, 20 Jun 2017 12:49:01 +0500 Subject: [PATCH 4/7] Fixed tests --- tests/test_filters.py | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/tests/test_filters.py b/tests/test_filters.py index 674042de1f4..0911d066795 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -214,18 +214,43 @@ def test_group_fileter(self): self.assertTrue(Filters.group(self.message)) def test_filters_chat(self): - self.assertFalse(Filters.chat(-1)(self.message)) + with self.assertRaisesRegexp(ValueError, 'either chat_id or username'): + Filters.chat(chat_id=0, username='chat') + Filters.chat() + + def test_filters_chat_id(self): + self.assertFalse(Filters.chat(chat_id=-1)(self.message)) self.message.chat.id = -1 - self.assertTrue(Filters.chat(-1)(self.message)) + self.assertTrue(Filters.chat(chat_id=-1)(self.message)) self.message.chat.id = -2 - self.assertFalse(Filters.chat(-1)(self.message)) + self.assertFalse(Filters.chat(chat_id=-1)(self.message)) + + def test_filters_chat_username(self): + self.assertFalse(Filters.chat(username='chat')(self.message)) + self.message.chat.username = 'chat' + self.assertTrue(Filters.chat(username='@chat')(self.message)) + self.assertTrue(Filters.chat(username='chat')(self.message)) + self.assertFalse(Filters.chat(username='@chat_username')(self.message)) def test_filters_user(self): - self.assertFalse(Filters.user(1)(self.message)) + with self.assertRaisesRegexp(ValueError, 'either user_id or username'): + Filters.user(user_id=0, username='user') + Filters.user() + + def test_filters_user_id(self): + self.assertFalse(Filters.user(user_id=1)(self.message)) self.message.from_user.id = 1 - self.assertTrue(Filters.user(1)(self.message)) + self.assertTrue(Filters.user(user_id=1)(self.message)) self.message.from_user.id = 2 - self.assertFalse(Filters.user(1)(self.message)) + self.assertFalse(Filters.user(user_id=1)(self.message)) + + def test_filters_username(self): + self.assertFalse(Filters.user(username='user')(self.message)) + self.assertFalse(Filters.user(username='Testuser')(self.message)) + self.message.from_user.username = 'user' + self.assertTrue(Filters.user(username='@user')(self.message)) + self.assertTrue(Filters.user(username='user')(self.message)) + self.assertFalse(Filters.user(username='@username')(self.message)) def test_and_filters(self): self.message.text = 'test' From ca9068f2b50da258ada1afb7aabb361cf1d839f6 Mon Sep 17 00:00:00 2001 From: evgfilim1 Date: Thu, 22 Jun 2017 13:35:59 +0500 Subject: [PATCH 5/7] Simplified if statement, fixed docs --- telegram/ext/filters.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/telegram/ext/filters.py b/telegram/ext/filters.py index be63ba473bf..3571dab74d8 100644 --- a/telegram/ext/filters.py +++ b/telegram/ext/filters.py @@ -325,21 +325,23 @@ def filter(self, message): group = _Group() class user(BaseFilter): - """Filters messages to allow only those which are from specified user ID + """Filters messages to allow only those which are from specified user ID. + + Notes: + Only one of chat_id or username must be used here. Args: - user_id(Optional[int]): which user ID to allow through. Required if username is not - specified - username(Optional[str]): which username to allow through. Required if user_id is not - specified + user_id(Optional[int]): which user ID to allow through. + username(Optional[str]): which username to allow through. If username starts with '@' + symbol, it will be ignored. Raises: ValueError """ def __init__(self, user_id=None, username=None): - if (user_id is None and username is None) or (bool(user_id) and bool(username)): - raise ValueError('You must specify either user_id or username') + if not (bool(user_id) ^ bool(username)): + raise ValueError('One and only one of user_id or username must be used') if username is not None and username.startswith('@'): self.username = username[1:] else: @@ -355,21 +357,23 @@ def filter(self, message): message.from_user.username == self.username) class chat(BaseFilter): - """Filters messages to allow only those which are from specified chat ID + """Filters messages to allow only those which are from specified chat ID. + + Notes: + Only one of chat_id or username must be used here. Args: - chat_id(Optional[int]): which chat ID to allow through. Required if username is not - specified - username(Optional[str]): which username to allow through. Required if chat_id is not - specified + chat_id(Optional[int]): which chat ID to allow through. + username(Optional[str]): which username to allow through. If username starts with '@' + symbol, it will be ignored. Raises: ValueError """ def __init__(self, chat_id=None, username=None): - if (chat_id is None and username is None) or (bool(chat_id) and bool(username)): - raise ValueError('You must specify either chat_id or username') + if not (bool(chat_id) ^ bool(username)): + raise ValueError('One and only one of user_id or username must be used') if username is not None and username.startswith('@'): self.username = username[1:] else: From 7e81a1510d143ff7cfb5264dc0909192ac67cae5 Mon Sep 17 00:00:00 2001 From: evgfilim1 Date: Thu, 22 Jun 2017 15:19:49 +0500 Subject: [PATCH 6/7] Added ability to process list of ids/usernames --- telegram/ext/filters.py | 56 ++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/telegram/ext/filters.py b/telegram/ext/filters.py index 3571dab74d8..28b15ee070e 100644 --- a/telegram/ext/filters.py +++ b/telegram/ext/filters.py @@ -331,9 +331,9 @@ class user(BaseFilter): Only one of chat_id or username must be used here. Args: - user_id(Optional[int]): which user ID to allow through. - username(Optional[str]): which username to allow through. If username starts with '@' - symbol, it will be ignored. + user_id(Optional[int|list]): which user ID(s) to allow through. + username(Optional[str|list]): which username(s) to allow through. If username starts + with '@' symbol, it will be ignored. Raises: ValueError @@ -342,19 +342,24 @@ class user(BaseFilter): def __init__(self, user_id=None, username=None): if not (bool(user_id) ^ bool(username)): raise ValueError('One and only one of user_id or username must be used') - if username is not None and username.startswith('@'): - self.username = username[1:] + if user_id is not None and isinstance(user_id, int): + self.user_ids = [user_id] else: - self.username = username - self.user_id = user_id + self.user_ids = user_id + if username is None: + self.usernames = username + elif isinstance(username, str_type): + self.usernames = [username.replace('@', '')] + else: + self.usernames = [user.replace('@', '') for user in username] def filter(self, message): - if self.user_id is not None: - return bool(message.from_user and message.from_user.id == self.user_id) + if self.user_ids is not None: + return bool(message.from_user and message.from_user.id in self.user_ids) else: - # self.username is not None + # self.usernames is not None return bool(message.from_user and message.from_user.username and - message.from_user.username == self.username) + message.from_user.username in self.usernames) class chat(BaseFilter): """Filters messages to allow only those which are from specified chat ID. @@ -363,9 +368,9 @@ class chat(BaseFilter): Only one of chat_id or username must be used here. Args: - chat_id(Optional[int]): which chat ID to allow through. - username(Optional[str]): which username to allow through. If username starts with '@' - symbol, it will be ignored. + chat_id(Optional[int|list]): which chat ID(s) to allow through. + username(Optional[str|list]): which username(s) to allow through. If username starts + with '@' symbol, it will be ignored. Raises: ValueError @@ -373,19 +378,24 @@ class chat(BaseFilter): def __init__(self, chat_id=None, username=None): if not (bool(chat_id) ^ bool(username)): - raise ValueError('One and only one of user_id or username must be used') - if username is not None and username.startswith('@'): - self.username = username[1:] + raise ValueError('One and only one of chat_id or username must be used') + if chat_id is not None and isinstance(chat_id, int): + self.chat_ids = [chat_id] + else: + self.chat_ids = chat_id + if username is None: + self.usernames = username + elif isinstance(username, str_type): + self.usernames = [username.replace('@', '')] else: - self.username = username - self.chat_id = chat_id + self.usernames = [chat.replace('@', '') for chat in username] def filter(self, message): - if self.chat_id is not None: - return message.chat_id == self.chat_id + if self.chat_ids is not None: + return bool(message.chat_id in self.chat_ids) else: - # self.username is not None - return bool(message.chat.username and message.chat.username == self.username) + # self.usernames is not None + return bool(message.chat.username and message.chat.username in self.usernames) class _Invoice(BaseFilter): From ecfcc69cf93411f49f964eccbf86ddb4a0f0314e Mon Sep 17 00:00:00 2001 From: evgfilim1 Date: Thu, 22 Jun 2017 15:20:11 +0500 Subject: [PATCH 7/7] Fixed tests --- tests/test_filters.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/test_filters.py b/tests/test_filters.py index 0911d066795..2fcded4bc9b 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -214,8 +214,9 @@ def test_group_fileter(self): self.assertTrue(Filters.group(self.message)) def test_filters_chat(self): - with self.assertRaisesRegexp(ValueError, 'either chat_id or username'): - Filters.chat(chat_id=0, username='chat') + with self.assertRaisesRegexp(ValueError, 'chat_id or username'): + Filters.chat(chat_id=-1, username='chat') + with self.assertRaisesRegexp(ValueError, 'chat_id or username'): Filters.chat() def test_filters_chat_id(self): @@ -223,6 +224,7 @@ def test_filters_chat_id(self): self.message.chat.id = -1 self.assertTrue(Filters.chat(chat_id=-1)(self.message)) self.message.chat.id = -2 + self.assertTrue(Filters.chat(chat_id=[-1, -2])(self.message)) self.assertFalse(Filters.chat(chat_id=-1)(self.message)) def test_filters_chat_username(self): @@ -230,11 +232,13 @@ def test_filters_chat_username(self): self.message.chat.username = 'chat' self.assertTrue(Filters.chat(username='@chat')(self.message)) self.assertTrue(Filters.chat(username='chat')(self.message)) - self.assertFalse(Filters.chat(username='@chat_username')(self.message)) + self.assertTrue(Filters.chat(username=['chat1', 'chat', 'chat2'])(self.message)) + self.assertFalse(Filters.chat(username=['@chat1', 'chat_2'])(self.message)) def test_filters_user(self): - with self.assertRaisesRegexp(ValueError, 'either user_id or username'): - Filters.user(user_id=0, username='user') + with self.assertRaisesRegexp(ValueError, 'user_id or username'): + Filters.user(user_id=1, username='user') + with self.assertRaisesRegexp(ValueError, 'user_id or username'): Filters.user() def test_filters_user_id(self): @@ -242,6 +246,7 @@ def test_filters_user_id(self): self.message.from_user.id = 1 self.assertTrue(Filters.user(user_id=1)(self.message)) self.message.from_user.id = 2 + self.assertTrue(Filters.user(user_id=[1, 2])(self.message)) self.assertFalse(Filters.user(user_id=1)(self.message)) def test_filters_username(self): @@ -250,7 +255,8 @@ def test_filters_username(self): self.message.from_user.username = 'user' self.assertTrue(Filters.user(username='@user')(self.message)) self.assertTrue(Filters.user(username='user')(self.message)) - self.assertFalse(Filters.user(username='@username')(self.message)) + self.assertTrue(Filters.user(username=['user1', 'user', 'user2'])(self.message)) + self.assertFalse(Filters.user(username=['@username', '@user_2'])(self.message)) def test_and_filters(self): self.message.text = 'test'