From 0ea302b1f0dc367be78c4485d8b180eff982065a Mon Sep 17 00:00:00 2001 From: Bruce Schubert <bruce@emxsys.com> Date: Wed, 4 Nov 2020 16:26:51 -0800 Subject: [PATCH 1/2] Added ability to permit callers based on permitted name/number regex patterns. - Added PERMIT_NAME_PATTERNS and PERMIT_NUMBER_PATTERNS configuration settings. - Re: #117 --- callattendant/app.cfg.example | 6 +++++ callattendant/config.py | 3 +++ callattendant/screening/callscreener.py | 25 ++++++++++++++++++- tests/test_callscreener.py | 32 ++++++++++++++++++------- 4 files changed, 57 insertions(+), 9 deletions(-) diff --git a/callattendant/app.cfg.example b/callattendant/app.cfg.example index baad0b4..9ac72b7 100644 --- a/callattendant/app.cfg.example +++ b/callattendant/app.cfg.example @@ -89,7 +89,13 @@ SCREENED_GREETING_FILE = "resources/general_greeting.wav" # Example: 0 to act immediately, possibly before your local phone rings. SCREENED_RINGS_BEFORE_ANSWER = 0 +# PERMIT_NAME_PATTERNS: A regex expression dict applied to the CID names +# Example: {".*DOE": "Family maybe", "O": "Unknown caller", } +PERMIT_NAME_PATTERNS = {} +# PERMIT_NUMBER_PATTERNS: A regx expression dict applied to the CID numbers +# Example: {"01628": "My area", } +PERMIT_NUMBER_PATTERNS = {} # PERMITTED_ACTIONS: A tuple containing a combination of the following actions: # "greeting", "record_message", "voice_mail". See BLOCKED_ACTIONS for more info. diff --git a/callattendant/config.py b/callattendant/config.py index 392efa5..9b34242 100644 --- a/callattendant/config.py +++ b/callattendant/config.py @@ -40,6 +40,9 @@ "SCREENED_GREETING_FILE": "resources/general_greeting.wav", "SCREENED_RINGS_BEFORE_ANSWER": 0, + "PERMIT_NAME_PATTERNS": {}, + "PERMT_NUMBER_PATTERNS": {}, + "PERMITTED_ACTIONS": (), "PERMITTED_GREETING_FILE": "resources/general_greeting.wav", "PERMITTED_RINGS_BEFORE_ANSWER": 4, diff --git a/callattendant/screening/callscreener.py b/callattendant/screening/callscreener.py index f81d444..2fb6048 100644 --- a/callattendant/screening/callscreener.py +++ b/callattendant/screening/callscreener.py @@ -37,7 +37,30 @@ class CallScreener(object): def is_whitelisted(self, callerid): '''Returns true if the number is on a whitelist''' - return self._whitelist.check_number(callerid['NMBR']) + number = callerid['NMBR'] + name = callerid["NAME"] + permit = self.config.get_namespace("PERMIT_") + try: + is_whitelisted, reason = self._whitelist.check_number(callerid['NMBR']) + if is_whitelisted: + return True, reason + else: + print(">> Checking permitted patterns...") + for key in permit["name_patterns"].keys(): + match = re.search(key, name) + if match: + reason = permit["name_patterns"][key] + print(reason) + return True, reason + for key in permit["number_patterns"].keys(): + match = re.search(key, number) + if match: + reason = permit["number_patterns"][key] + print(reason) + return True, reason + return False, "Not found" + finally: + sys.stdout.flush() def is_blacklisted(self, callerid): '''Returns true if the number is on a blacklist''' diff --git a/tests/test_callscreener.py b/tests/test_callscreener.py index 5036020..d1b72c4 100644 --- a/tests/test_callscreener.py +++ b/tests/test_callscreener.py @@ -35,16 +35,19 @@ # Create a blocked caller -caller1 = {"NAME": "caller1", "NMBR": "1234567890", "DATE": "1012", "TIME": "0600"} +caller1 = {"NAME": "CALLER1", "NMBR": "1234567890", "DATE": "1012", "TIME": "0600"} # Create a permitted caller -caller2 = {"NAME": "caller2", "NMBR": "1111111111", "DATE": "1012", "TIME": "0600"} -# Create a V123456789012345 Telemarketer caller +caller2 = {"NAME": "CALLER2", "NMBR": "1111111111", "DATE": "1012", "TIME": "0600"} +# Create a V123456789012345 Telemarketer caller (blocked name pattern match) caller3 = {"NAME": "V123456789012345", "NMBR": "80512345678", "DATE": "1012", "TIME": "0600"} # Create a robocaller -caller4 = {"NAME": "caller4", "NMBR": "3105241189", "DATE": "1012", "TIME": "0600"} -# Create a Private Number -caller5 = {"NAME": "caller5", "NMBR": "P", "DATE": "1012", "TIME": "0600"} - +caller4 = {"NAME": "CALLER4", "NMBR": "3105241189", "DATE": "1012", "TIME": "0600"} +# Create a Private Number (blocked number pattern match) +caller5 = {"NAME": "CALLER5", "NMBR": "P", "DATE": "1012", "TIME": "0600"} +# Create a John Doe name (permitted name pattern match) +caller6 = {"NAME": "JOHN DOE", "NMBR": "0987654321", "DATE": "1012", "TIME": "0600"} +# Create a unique number (permitted number pattern match) +caller7 = {"NAME": "CALLER7", "NMBR": "09876543210", "DATE": "1012", "TIME": "0600"} @pytest.fixture(scope='module') def screener(): @@ -62,7 +65,12 @@ def screener(): config['BLOCK_NUMBER_PATTERNS'] = { "P": "Private number", } - + config['PERMIT_NAME_PATTERNS'] = { + ".*DOE": "Anyone", + } + config['PERMIT_NUMBER_PATTERNS'] = { + "987654": "Anyone", + } # Create the blacklist to be tested screener = CallScreener(db, config) # Add a record to the blacklist @@ -106,3 +114,11 @@ def test_is_blacklisted_by_nomorobo(screener): def test_blocked_number_pattern(screener): is_blacklisted, reason = screener.is_blacklisted(caller5) assert is_blacklisted, "caller1 should be blocked by number pattern" + +def test_permitted_name_pattern(screener): + is_whitelisted, reason = screener.is_whitelisted(caller6) + assert is_whitelisted, "caller6 should be permiteed by name pattern" + +def test_permitted_number_pattern(screener): + is_whitelisted, reason = screener.is_whitelisted(caller7) + assert is_whitelisted, "caller7 should be permiteed by number pattern" From 99d4dc23e4f402c8d934764cab4ac2bd41e1b909 Mon Sep 17 00:00:00 2001 From: Bruce Schubert <bruce@emxsys.com> Date: Wed, 4 Nov 2020 16:39:21 -0800 Subject: [PATCH 2/2] Fixed typo in config. --- callattendant/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/callattendant/config.py b/callattendant/config.py index 9b34242..772e119 100644 --- a/callattendant/config.py +++ b/callattendant/config.py @@ -41,7 +41,7 @@ "SCREENED_RINGS_BEFORE_ANSWER": 0, "PERMIT_NAME_PATTERNS": {}, - "PERMT_NUMBER_PATTERNS": {}, + "PERMIT_NUMBER_PATTERNS": {}, "PERMITTED_ACTIONS": (), "PERMITTED_GREETING_FILE": "resources/general_greeting.wav",