Skip to content

Commit

Permalink
Merge pull request #119 from emxsys/permit-patterns
Browse files Browse the repository at this point in the history
Add ability to permit callers based on name and number regex patterns
  • Loading branch information
emxsys authored Nov 5, 2020
2 parents 96a149e + 99d4dc2 commit 33d25a4
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 9 deletions.
6 changes: 6 additions & 0 deletions callattendant/app.cfg.example
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 3 additions & 0 deletions callattendant/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
"SCREENED_GREETING_FILE": "resources/general_greeting.wav",
"SCREENED_RINGS_BEFORE_ANSWER": 0,

"PERMIT_NAME_PATTERNS": {},
"PERMIT_NUMBER_PATTERNS": {},

"PERMITTED_ACTIONS": (),
"PERMITTED_GREETING_FILE": "resources/general_greeting.wav",
"PERMITTED_RINGS_BEFORE_ANSWER": 4,
Expand Down
25 changes: 24 additions & 1 deletion callattendant/screening/callscreener.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'''
Expand Down
32 changes: 24 additions & 8 deletions tests/test_callscreener.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand All @@ -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
Expand Down Expand Up @@ -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"

0 comments on commit 33d25a4

Please sign in to comment.