Skip to content

Commit

Permalink
better handling of email/urls; added test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
caronc committed Aug 18, 2020
1 parent 353864b commit ebed0fa
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 33 deletions.
11 changes: 6 additions & 5 deletions apprise/plugins/NotifyEmail.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,11 +465,6 @@ def __init__(self, timeout=15, smtp_host=None, from_name=None,
'({}) specified.'.format(recipient),
)

if not self.targets:
msg = 'There were no valid target emails to send to.'
self.logger.warning(msg)
raise TypeError(msg)

else:
# If our target email list is empty we want to add ourselves to it
self.targets.append(
Expand Down Expand Up @@ -593,6 +588,12 @@ def send(self, body, title='', notify_type=NotifyType.INFO, attach=None,
# error tracking (used for function return)
has_error = False

if not self.targets:
# There is no one to email; we're done
self.logger.warning(
'There are no Email recipients to notify')
return False

# Create a copy of the targets list
emails = list(self.targets)
while len(emails):
Expand Down
7 changes: 1 addition & 6 deletions apprise/plugins/NotifyOffice365.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,11 +238,6 @@ def __init__(self, tenant, email, client_id, secret,
'Dropped invalid To email ({}) specified.'
.format(recipient))

if not self.targets:
msg = 'There were no valid target emails to send to.'
self.logger.warning(msg)
raise TypeError(msg)

else:
# If our target email list is empty we want to add ourselves to it
self.targets.append((False, self.email))
Expand Down Expand Up @@ -298,7 +293,7 @@ def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
if not self.targets:
# There is no one to email; we're done
self.logger.warning(
'There are no Office 365 recipients to notify')
'There are no Email recipients to notify')
return False

# Setup our Content Type
Expand Down
44 changes: 36 additions & 8 deletions apprise/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,36 +572,64 @@ def parse_bool(arg, default=False):
return bool(arg)


def parse_emails(*args):
def parse_emails(*args, store_unparseable=True):
"""
Takes a string containing URLs separated by comma's and/or spaces and
returns a list.
"""

result = []
for arg in args:
if isinstance(arg, six.string_types):
result += EMAIL_DETECTION_RE.findall(arg)
if isinstance(arg, six.string_types) and arg:
_result = EMAIL_DETECTION_RE.findall(arg)
if _result:
result += _result

elif not _result and store_unparseable:
# we had content passed into us that was lost because it was
# so poorly formatted that it didn't even come close to
# meeting the regular expression we defined. We intentially
# keep it as part of our result set so that parsing done
# at a higher level can at least report this to the end user
# and hopefully give them some indication as to what they
# may have done wrong.
result += \
[x for x in filter(bool, re.split(STRING_DELIMITERS, arg))]

elif isinstance(arg, (set, list, tuple)):
result += parse_emails(*arg)
# Use recursion to handle the list of Emails
result += parse_emails(*arg, store_unparseable=store_unparseable)

return result


def parse_urls(*args):
def parse_urls(*args, store_unparseable=True):
"""
Takes a string containing URLs separated by comma's and/or spaces and
returns a list.
"""

result = []
for arg in args:
if isinstance(arg, six.string_types):
result += URL_DETECTION_RE.findall(arg)
if isinstance(arg, six.string_types) and arg:
_result = URL_DETECTION_RE.findall(arg)
if _result:
result += _result

elif not _result and store_unparseable:
# we had content passed into us that was lost because it was
# so poorly formatted that it didn't even come close to
# meeting the regular expression we defined. We intentially
# keep it as part of our result set so that parsing done
# at a higher level can at least report this to the end user
# and hopefully give them some indication as to what they
# may have done wrong.
result += \
[x for x in filter(bool, re.split(STRING_DELIMITERS, arg))]

elif isinstance(arg, (set, list, tuple)):
result += parse_urls(*arg)
# Use recursion to handle the list of URLs
result += parse_urls(*arg, store_unparseable=store_unparseable)

return result

Expand Down
6 changes: 4 additions & 2 deletions test/test_email_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,11 @@
('mailtos://nuxref.com?user=&pass=.', {
'instance': TypeError,
}),
# Invalid To Address
# Invalid To Address is accepted, but we won't be able to properly email
# using the notify() call
('mailtos://user:pass@nuxref.com?to=@', {
'instance': TypeError,
'instance': plugins.NotifyEmail,
'response': False,
}),
# Valid URL, but can't structure a proper email
('mailtos://nuxref.com?user=%20!&pass=.', {
Expand Down
31 changes: 19 additions & 12 deletions test/test_office365.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ def test_office365_general(mock_post):

assert isinstance(obj, plugins.NotifyOffice365)

# Test our URL generation
assert isinstance(obj.url(), six.string_types)

# Test our notification
assert obj.notify(title='title', body='test') is True

Expand All @@ -89,8 +92,8 @@ def test_office365_general(mock_post):
secret=secret,
targets=targets,
# Test the cc and bcc list (use good and bad email)
cc='Chuck Norris cnorris@yahoo.ca, invalid@!',
bcc='Bruce Willis bwillis@hotmail.com, invalid@!',
cc='Chuck Norris cnorris@yahoo.ca, Sauron@lotr.me, invalid@!',
bcc='Bruce Willis bwillis@hotmail.com, Frodo@lotr.me invalid@!',
))

assert isinstance(obj, plugins.NotifyOffice365)
Expand Down Expand Up @@ -132,23 +135,27 @@ def test_office365_general(mock_post):
)

# One of the targets are invalid
plugins.NotifyOffice365(
obj = plugins.NotifyOffice365(
email=email,
client_id=client_id,
tenant=tenant,
secret=secret,
targets=('abc@gmail.com', 'garbage'),
targets=('Management abc@gmail.com', 'garbage'),
)
# Test our notification (this will work and only notify abc@gmail.com)
assert obj.notify(title='title', body='test') is True

# all of the targets are invalid
with pytest.raises(TypeError):
plugins.NotifyOffice365(
email=email,
client_id=client_id,
tenant=tenant,
secret=secret,
targets=('invalid', 'garbage'),
)
obj = plugins.NotifyOffice365(
email=email,
client_id=client_id,
tenant=tenant,
secret=secret,
targets=('invalid', 'garbage'),
)

# Test our notification (which will fail because of no entries)
assert obj.notify(title='title', body='test') is False


@mock.patch('requests.post')
Expand Down
20 changes: 20 additions & 0 deletions test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,11 @@ def test_parse_emails():

results = utils.parse_emails('this is not a parseable email at all')
assert isinstance(results, list)
assert len(results) == 8
# Now we do it again with the store_unparsable flag set to False
results = utils.parse_emails(
'this is not a parseable email at all', store_unparseable=False)
assert isinstance(results, list)
assert len(results) == 0

# Now test valid URLs
Expand Down Expand Up @@ -742,6 +747,15 @@ def test_parse_emails():
for email in emails:
assert email in results

# Pass in some unparseables
results = utils.parse_emails('garbage')
assert isinstance(results, list)
assert len(results) == 1

results = utils.parse_emails('garbage', store_unparseable=False)
assert isinstance(results, list)
assert len(results) == 0

# Pass in garbage
results = utils.parse_emails(object)
assert isinstance(results, list)
Expand Down Expand Up @@ -782,6 +796,12 @@ def test_parse_urls():

results = utils.parse_urls('this is not a parseable url at all')
assert isinstance(results, list)
# we still end up returning this
assert len(results) == 8

results = utils.parse_urls(
'this is not a parseable url at all', store_unparseable=False)
assert isinstance(results, list)
assert len(results) == 0

# Now test valid URLs
Expand Down

0 comments on commit ebed0fa

Please sign in to comment.