mirror of
https://github.com/caronc/apprise.git
synced 2024-11-26 01:53:10 +01:00
Better handling of multiple URLs delimited by space/comma
This commit is contained in:
parent
25f5066e27
commit
28b67d42f3
@ -33,6 +33,7 @@ from .common import NotifyType
|
|||||||
from .common import NotifyFormat
|
from .common import NotifyFormat
|
||||||
from .utils import is_exclusive_match
|
from .utils import is_exclusive_match
|
||||||
from .utils import parse_list
|
from .utils import parse_list
|
||||||
|
from .utils import split_urls
|
||||||
from .utils import GET_SCHEMA_RE
|
from .utils import GET_SCHEMA_RE
|
||||||
from .logger import logger
|
from .logger import logger
|
||||||
|
|
||||||
@ -161,7 +162,9 @@ class Apprise(object):
|
|||||||
|
|
||||||
if isinstance(servers, six.string_types):
|
if isinstance(servers, six.string_types):
|
||||||
# build our server list
|
# build our server list
|
||||||
servers = parse_list(servers)
|
servers = split_urls(servers)
|
||||||
|
if len(servers) == 0:
|
||||||
|
return False
|
||||||
|
|
||||||
elif isinstance(servers, (ConfigBase, NotifyBase, AppriseConfig)):
|
elif isinstance(servers, (ConfigBase, NotifyBase, AppriseConfig)):
|
||||||
# Go ahead and just add our plugin into our list
|
# Go ahead and just add our plugin into our list
|
||||||
|
@ -107,6 +107,10 @@ GET_EMAIL_RE = re.compile(
|
|||||||
re.IGNORECASE,
|
re.IGNORECASE,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Regular expression used to destinguish between multiple URLs
|
||||||
|
URL_DETECTION_RE = re.compile(
|
||||||
|
r'([a-z0-9]+?:\/\/.*?)[\s,]*(?=$|[a-z0-9]+?:\/\/)', re.I)
|
||||||
|
|
||||||
|
|
||||||
def is_hostname(hostname):
|
def is_hostname(hostname):
|
||||||
"""
|
"""
|
||||||
@ -463,6 +467,28 @@ def parse_bool(arg, default=False):
|
|||||||
return bool(arg)
|
return bool(arg)
|
||||||
|
|
||||||
|
|
||||||
|
def split_urls(urls):
|
||||||
|
"""
|
||||||
|
Takes a string containing URLs separated by comma's and/or spaces and
|
||||||
|
returns a list.
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
results = URL_DETECTION_RE.findall(urls)
|
||||||
|
|
||||||
|
except TypeError:
|
||||||
|
results = []
|
||||||
|
|
||||||
|
if len(results) > 0 and results[len(results) - 1][-1] != urls[-1]:
|
||||||
|
# we always want to save the end of url URL if we can; This handles
|
||||||
|
# cases where there is actually a comma (,) at the end of a single URL
|
||||||
|
# that would have otherwise got lost when our regex passed over it.
|
||||||
|
results[len(results) - 1] += \
|
||||||
|
re.match(r'.*?([\s,]+)?$', urls).group(1).rstrip()
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
def parse_list(*args):
|
def parse_list(*args):
|
||||||
"""
|
"""
|
||||||
Take a string list and break it into a delimited
|
Take a string list and break it into a delimited
|
||||||
|
@ -318,6 +318,9 @@ def test_apprise_tagging(mock_post, mock_get):
|
|||||||
# Create our object
|
# Create our object
|
||||||
a = Apprise()
|
a = Apprise()
|
||||||
|
|
||||||
|
# An invalid addition can't add the tag
|
||||||
|
assert(a.add('averyinvalidschema://localhost', tag='uhoh') is False)
|
||||||
|
|
||||||
# Add entry and assign it to a tag called 'awesome'
|
# Add entry and assign it to a tag called 'awesome'
|
||||||
assert(a.add('json://localhost/path1/', tag='awesome') is True)
|
assert(a.add('json://localhost/path1/', tag='awesome') is True)
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
# THE SOFTWARE.
|
# THE SOFTWARE.
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
import re
|
||||||
try:
|
try:
|
||||||
# Python 2.7
|
# Python 2.7
|
||||||
from urllib import unquote
|
from urllib import unquote
|
||||||
@ -406,8 +407,104 @@ def test_is_email():
|
|||||||
assert utils.is_email(None) is False
|
assert utils.is_email(None) is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_split_urls():
|
||||||
|
"""utils: split_urls() testing """
|
||||||
|
# A simple single array entry (As str)
|
||||||
|
results = utils.split_urls('')
|
||||||
|
assert isinstance(results, list)
|
||||||
|
assert len(results) == 0
|
||||||
|
|
||||||
|
# just delimeters
|
||||||
|
results = utils.split_urls(', ,, , ,,, ')
|
||||||
|
assert isinstance(results, list)
|
||||||
|
assert len(results) == 0
|
||||||
|
|
||||||
|
results = utils.split_urls(',')
|
||||||
|
assert isinstance(results, list)
|
||||||
|
assert len(results) == 0
|
||||||
|
|
||||||
|
results = utils.split_urls(None)
|
||||||
|
assert isinstance(results, list)
|
||||||
|
assert len(results) == 0
|
||||||
|
|
||||||
|
results = utils.split_urls(42)
|
||||||
|
assert isinstance(results, list)
|
||||||
|
assert len(results) == 0
|
||||||
|
|
||||||
|
results = utils.split_urls('this is not a parseable url at all')
|
||||||
|
assert isinstance(results, list)
|
||||||
|
assert len(results) == 0
|
||||||
|
|
||||||
|
# Now test valid URLs
|
||||||
|
results = utils.split_urls('windows://')
|
||||||
|
assert isinstance(results, list)
|
||||||
|
assert len(results) == 1
|
||||||
|
assert 'windows://' in results
|
||||||
|
|
||||||
|
results = utils.split_urls('windows:// gnome://')
|
||||||
|
assert isinstance(results, list)
|
||||||
|
assert len(results) == 2
|
||||||
|
assert 'windows://' in results
|
||||||
|
assert 'gnome://' in results
|
||||||
|
|
||||||
|
# Commas and spaces found inside URLs are ignored
|
||||||
|
urls = [
|
||||||
|
'mailgun://noreply@sandbox.mailgun.org/apikey/?to=test@example.com,'
|
||||||
|
'test2@example.com,, abcd@example.com',
|
||||||
|
'mailgun://noreply@sandbox.another.mailgun.org/apikey/'
|
||||||
|
'?to=hello@example.com,,hmmm@example.com,, abcd@example.com, ,',
|
||||||
|
'windows://',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Since comma's and whitespace are the delimiters; they won't be
|
||||||
|
# present at the end of the URL; so we just need to write a special
|
||||||
|
# rstrip() as a regular exression to handle whitespace (\s) and comma
|
||||||
|
# delimiter
|
||||||
|
rstrip_re = re.compile(r'[\s,]+$')
|
||||||
|
|
||||||
|
# Since a comma acts as a delimiter, we run a risk of a problem where the
|
||||||
|
# comma exists as part of the URL and is therefore lost if it was found
|
||||||
|
# at the end of it.
|
||||||
|
|
||||||
|
results = utils.split_urls(', '.join(urls))
|
||||||
|
assert isinstance(results, list)
|
||||||
|
assert len(results) == len(urls)
|
||||||
|
for url in urls:
|
||||||
|
assert rstrip_re.sub('', url) in results
|
||||||
|
|
||||||
|
# However if a comma is found at the end of a single url without a new
|
||||||
|
# match to hit, it is saved and not lost
|
||||||
|
|
||||||
|
# The comma at the end of the password will not be lost if we're
|
||||||
|
# dealing with a single entry:
|
||||||
|
url = 'http://hostname?password=,abcd,'
|
||||||
|
results = utils.split_urls(url)
|
||||||
|
assert isinstance(results, list)
|
||||||
|
assert len(results) == 1
|
||||||
|
assert url in results
|
||||||
|
|
||||||
|
# however if we have multiple entries, commas and spaces between
|
||||||
|
# URLs will be lost, however the last URL will not lose the comma
|
||||||
|
urls = [
|
||||||
|
'schema1://hostname?password=,abcd,',
|
||||||
|
'schema2://hostname?password=,abcd,',
|
||||||
|
]
|
||||||
|
results = utils.split_urls(', '.join(urls))
|
||||||
|
assert isinstance(results, list)
|
||||||
|
assert len(results) == len(urls)
|
||||||
|
|
||||||
|
# No match because the comma is gone in the results entry
|
||||||
|
# schema1://hostname?password=,abcd
|
||||||
|
assert urls[0] not in results
|
||||||
|
assert urls[0][:-1] in results
|
||||||
|
|
||||||
|
# However we wouldn't have lost the comma in the second one:
|
||||||
|
# schema2://hostname?password=,abcd,
|
||||||
|
assert urls[1] in results
|
||||||
|
|
||||||
|
|
||||||
def test_parse_list():
|
def test_parse_list():
|
||||||
"utils: parse_list() testing """
|
"""utils: parse_list() testing """
|
||||||
|
|
||||||
# A simple single array entry (As str)
|
# A simple single array entry (As str)
|
||||||
results = utils.parse_list(
|
results = utils.parse_list(
|
||||||
|
Loading…
Reference in New Issue
Block a user