mirror of
https://github.com/caronc/apprise.git
synced 2025-01-05 21:49:02 +01:00
Return target count from len(Service) calls (#874)
This commit is contained in:
parent
e83cba66a6
commit
c542ab23bf
@ -685,6 +685,15 @@ class URLBase:
|
||||
|
||||
return response
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Should be over-ridden and allows the tracking of how many targets
|
||||
are associated with each URLBase object.
|
||||
|
||||
Default is always 1
|
||||
"""
|
||||
return 1
|
||||
|
||||
def schemas(self):
|
||||
"""A simple function that returns a set of all schemas associated
|
||||
with this object based on the object.protocol and
|
||||
|
@ -280,7 +280,7 @@ class NotifyBark(NotifyBase):
|
||||
# error tracking (used for function return)
|
||||
has_error = False
|
||||
|
||||
if not len(self.targets):
|
||||
if not self.targets:
|
||||
# We have nothing to notify; we're done
|
||||
self.logger.warning('There are no Bark devices to notify')
|
||||
return False
|
||||
@ -456,6 +456,12 @@ class NotifyBark(NotifyBase):
|
||||
params=NotifyBark.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -46,6 +46,7 @@ except ImportError:
|
||||
from .NotifyBase import NotifyBase
|
||||
from ..URLBase import PrivacyMode
|
||||
from ..utils import parse_bool
|
||||
from ..utils import parse_list
|
||||
from ..utils import validate_regex
|
||||
from ..common import NotifyType
|
||||
from ..common import NotifyImageSize
|
||||
@ -58,7 +59,7 @@ DEFAULT_TAG = '@all'
|
||||
# list of tagged devices that the notification need to be send to, and a
|
||||
# boolean operator (‘and’ / ‘or’) that defines the criteria to match devices
|
||||
# against those tags.
|
||||
IS_TAG = re.compile(r'^[@](?P<name>[A-Z0-9]{1,63})$', re.I)
|
||||
IS_TAG = re.compile(r'^[@]?(?P<name>[A-Z0-9]{1,63})$', re.I)
|
||||
|
||||
# Device tokens are only referenced when developing.
|
||||
# It's not likely you'll send a message directly to a device, but if you do;
|
||||
@ -160,7 +161,7 @@ class NotifyBoxcar(NotifyBase):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
# Initialize tag list
|
||||
self.tags = list()
|
||||
self._tags = list()
|
||||
|
||||
# Initialize device_token list
|
||||
self.device_tokens = list()
|
||||
@ -184,29 +185,27 @@ class NotifyBoxcar(NotifyBase):
|
||||
raise TypeError(msg)
|
||||
|
||||
if not targets:
|
||||
self.tags.append(DEFAULT_TAG)
|
||||
self._tags.append(DEFAULT_TAG)
|
||||
targets = []
|
||||
|
||||
elif isinstance(targets, str):
|
||||
targets = [x for x in filter(bool, TAGS_LIST_DELIM.split(
|
||||
targets,
|
||||
))]
|
||||
|
||||
# Validate targets and drop bad ones:
|
||||
for target in targets:
|
||||
if IS_TAG.match(target):
|
||||
for target in parse_list(targets):
|
||||
result = IS_TAG.match(target)
|
||||
if result:
|
||||
# store valid tag/alias
|
||||
self.tags.append(IS_TAG.match(target).group('name'))
|
||||
self._tags.append(result.group('name'))
|
||||
continue
|
||||
|
||||
elif IS_DEVICETOKEN.match(target):
|
||||
result = IS_DEVICETOKEN.match(target)
|
||||
if result:
|
||||
# store valid device
|
||||
self.device_tokens.append(target)
|
||||
continue
|
||||
|
||||
else:
|
||||
self.logger.warning(
|
||||
'Dropped invalid tag/alias/device_token '
|
||||
'({}) specified.'.format(target),
|
||||
)
|
||||
self.logger.warning(
|
||||
'Dropped invalid tag/alias/device_token '
|
||||
'({}) specified.'.format(target),
|
||||
)
|
||||
|
||||
# Track whether or not we want to send an image with our notification
|
||||
# or not.
|
||||
@ -238,8 +237,8 @@ class NotifyBoxcar(NotifyBase):
|
||||
if body:
|
||||
payload['aps']['alert'] = body
|
||||
|
||||
if self.tags:
|
||||
payload['tags'] = {'or': self.tags}
|
||||
if self._tags:
|
||||
payload['tags'] = {'or': self._tags}
|
||||
|
||||
if self.device_tokens:
|
||||
payload['device_tokens'] = self.device_tokens
|
||||
@ -341,10 +340,18 @@ class NotifyBoxcar(NotifyBase):
|
||||
self.secret, privacy, mode=PrivacyMode.Secret, safe=''),
|
||||
targets='/'.join([
|
||||
NotifyBoxcar.quote(x, safe='') for x in chain(
|
||||
self.tags, self.device_tokens) if x != DEFAULT_TAG]),
|
||||
self._tags, self.device_tokens) if x != DEFAULT_TAG]),
|
||||
params=NotifyBoxcar.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self._tags) + len(self.device_tokens)
|
||||
# DEFAULT_TAG is set if no tokens/tags are otherwise set
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -414,6 +414,24 @@ class NotifyBulkSMS(NotifyBase):
|
||||
for x in self.groups])),
|
||||
params=NotifyBulkSMS.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
# Note: Groups always require a separate request (and can not be
|
||||
# included in batch calculations)
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
targets = len(self.targets)
|
||||
if batch_size > 1:
|
||||
targets = int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
|
||||
return targets + len(self.groups)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -288,6 +288,21 @@ class NotifyClickSend(NotifyBase):
|
||||
params=NotifyClickSend.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
targets = len(self.targets)
|
||||
if batch_size > 1:
|
||||
targets = int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
|
||||
return targets
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -357,6 +357,15 @@ class NotifyD7Networks(NotifyBase):
|
||||
[NotifyD7Networks.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifyD7Networks.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
return len(self.targets) if not self.batch else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -350,6 +350,21 @@ class NotifyDapnet(NotifyBase):
|
||||
params=NotifyDapnet.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
targets = len(self.targets)
|
||||
if batch_size > 1:
|
||||
targets = int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
|
||||
return targets
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -309,6 +309,13 @@ class NotifyDingTalk(NotifyBase):
|
||||
[NotifyDingTalk.quote(x, safe='') for x in self.targets]),
|
||||
args=NotifyDingTalk.urlencode(args))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -999,6 +999,13 @@ class NotifyEmail(NotifyBase):
|
||||
params=NotifyEmail.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -555,6 +555,12 @@ class NotifyFCM(NotifyBase):
|
||||
params=NotifyFCM.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -334,6 +334,13 @@ class NotifyFlock(NotifyBase):
|
||||
params=NotifyFlock.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -389,6 +389,12 @@ class NotifyGitter(NotifyBase):
|
||||
[NotifyGitter.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifyGitter.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -312,6 +312,12 @@ class NotifyIFTTT(NotifyBase):
|
||||
params=NotifyIFTTT.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.events)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -373,6 +373,12 @@ class NotifyJoin(NotifyBase):
|
||||
for x in self.targets]),
|
||||
params=NotifyJoin.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -324,6 +324,12 @@ class NotifyKavenegar(NotifyBase):
|
||||
[NotifyKavenegar.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifyKavenegar.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -267,6 +267,12 @@ class NotifyLine(NotifyBase):
|
||||
params=NotifyLine.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -476,6 +476,12 @@ class NotifyMQTT(NotifyBase):
|
||||
params=NotifyMQTT.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.topics)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -329,6 +329,12 @@ class NotifyMSG91(NotifyBase):
|
||||
[NotifyMSG91.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifyMSG91.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -627,6 +627,20 @@ class NotifyMailgun(NotifyBase):
|
||||
safe='') for e in self.targets]),
|
||||
params=NotifyMailgun.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
targets = len(self.targets)
|
||||
if batch_size > 1:
|
||||
targets = int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -378,6 +378,13 @@ class NotifyMastodon(NotifyBase):
|
||||
params=NotifyMastodon.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
def send(self, body, title='', notify_type=NotifyType.INFO, attach=None,
|
||||
**kwargs):
|
||||
"""
|
||||
|
@ -1196,6 +1196,13 @@ class NotifyMatrix(NotifyBase):
|
||||
params=NotifyMatrix.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.rooms)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -311,6 +311,13 @@ class NotifyMessageBird(NotifyBase):
|
||||
[NotifyMessageBird.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifyMessageBird.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -312,6 +312,12 @@ class NotifyNextcloud(NotifyBase):
|
||||
params=NotifyNextcloud.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -263,6 +263,12 @@ class NotifyNextcloudTalk(NotifyBase):
|
||||
for x in self.targets]),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -698,6 +698,12 @@ class NotifyNtfy(NotifyBase):
|
||||
params=NotifyNtfy.urlencode(params)
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.topics)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -596,6 +596,12 @@ class NotifyOffice365(NotifyBase):
|
||||
safe='') for e in self.targets]),
|
||||
params=NotifyOffice365.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -51,7 +51,7 @@ from ..utils import is_email
|
||||
from ..AppriseLocale import gettext_lazy as _
|
||||
|
||||
|
||||
class OneSignalCategory(NotifyBase):
|
||||
class OneSignalCategory:
|
||||
"""
|
||||
We define the different category types that we can notify via OneSignal
|
||||
"""
|
||||
@ -92,7 +92,7 @@ class NotifyOneSignal(NotifyBase):
|
||||
image_size = NotifyImageSize.XY_72
|
||||
|
||||
# The maximum allowable batch sizes per message
|
||||
maximum_batch_size = 2000
|
||||
default_batch_size = 2000
|
||||
|
||||
# Define object templates
|
||||
templates = (
|
||||
@ -121,7 +121,7 @@ class NotifyOneSignal(NotifyBase):
|
||||
'private': True,
|
||||
'required': True,
|
||||
},
|
||||
'target_device': {
|
||||
'target_player': {
|
||||
'name': _('Target Player ID'),
|
||||
'type': 'string',
|
||||
'map_to': 'targets',
|
||||
@ -204,7 +204,7 @@ class NotifyOneSignal(NotifyBase):
|
||||
raise TypeError(msg)
|
||||
|
||||
# Prepare Batch Mode Flag
|
||||
self.batch_size = self.maximum_batch_size if batch else 1
|
||||
self.batch_size = self.default_batch_size if batch else 1
|
||||
|
||||
# Place a thumbnail image inline with the message body
|
||||
self.include_image = include_image
|
||||
@ -432,6 +432,26 @@ class NotifyOneSignal(NotifyBase):
|
||||
params=NotifyOneSignal.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
if self.batch_size > 1:
|
||||
# Batches can only be sent by group (you can't combine groups into
|
||||
# a single batch)
|
||||
total_targets = 0
|
||||
for k, m in self.targets.items():
|
||||
targets = len(m)
|
||||
total_targets += int(targets / self.batch_size) + \
|
||||
(1 if targets % self.batch_size else 0)
|
||||
return total_targets
|
||||
|
||||
# Normal batch count; just count the targets
|
||||
return sum([len(m) for _, m in self.targets.items()])
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -172,7 +172,7 @@ class NotifyOpsgenie(NotifyBase):
|
||||
opsgenie_default_region = OpsgenieRegion.US
|
||||
|
||||
# The maximum allowable targets within a notification
|
||||
maximum_batch_size = 50
|
||||
default_batch_size = 50
|
||||
|
||||
# Define object templates
|
||||
templates = (
|
||||
@ -308,7 +308,7 @@ class NotifyOpsgenie(NotifyBase):
|
||||
self.details.update(details)
|
||||
|
||||
# Prepare Batch Mode Flag
|
||||
self.batch_size = self.maximum_batch_size if batch else 1
|
||||
self.batch_size = self.default_batch_size if batch else 1
|
||||
|
||||
# Assign our tags (if defined)
|
||||
self.__tags = parse_list(tags)
|
||||
@ -536,6 +536,20 @@ class NotifyOpsgenie(NotifyBase):
|
||||
for x in self.targets]),
|
||||
params=NotifyOpsgenie.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
targets = len(self.targets)
|
||||
if self.batch_size > 1:
|
||||
targets = int(targets / self.batch_size) + \
|
||||
(1 if targets % self.batch_size else 0)
|
||||
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -265,6 +265,21 @@ class NotifyPopcornNotify(NotifyBase):
|
||||
[NotifyPopcornNotify.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifyPopcornNotify.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
targets = len(self.targets)
|
||||
if batch_size > 1:
|
||||
targets = int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
|
||||
return targets
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -406,6 +406,12 @@ class NotifyPushBullet(NotifyBase):
|
||||
targets=targets,
|
||||
params=NotifyPushBullet.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -794,6 +794,12 @@ class NotifyPushSafer(NotifyBase):
|
||||
targets=targets,
|
||||
params=NotifyPushSafer.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -329,6 +329,13 @@ class NotifyPushed(NotifyBase):
|
||||
)]),
|
||||
params=NotifyPushed.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.channels) + len(self.users)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -577,6 +577,12 @@ class NotifyPushover(NotifyBase):
|
||||
devices=devices,
|
||||
params=NotifyPushover.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -367,6 +367,12 @@ class NotifyReddit(NotifyBase):
|
||||
params=NotifyReddit.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.subreddits)
|
||||
|
||||
def login(self):
|
||||
"""
|
||||
A simple wrapper to authenticate with the Reddit Server
|
||||
|
@ -348,6 +348,13 @@ class NotifyRocketChat(NotifyBase):
|
||||
params=NotifyRocketChat.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.channels) + len(self.rooms) + len(self.users)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
|
||||
"""
|
||||
wrapper to _send since we can alert more then one channel
|
||||
|
@ -816,6 +816,13 @@ class NotifySES(NotifyBase):
|
||||
params=NotifySES.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -73,6 +73,22 @@ SMSEAGLE_PRIORITY_MAP = {
|
||||
}
|
||||
|
||||
|
||||
class SMSEagleCategory:
|
||||
"""
|
||||
We define the different category types that we can notify via SMS Eagle
|
||||
"""
|
||||
PHONE = 'phone'
|
||||
GROUP = 'group'
|
||||
CONTACT = 'contact'
|
||||
|
||||
|
||||
SMSEAGLE_CATEGORIES = (
|
||||
SMSEagleCategory.PHONE,
|
||||
SMSEagleCategory.GROUP,
|
||||
SMSEagleCategory.CONTACT,
|
||||
)
|
||||
|
||||
|
||||
class NotifySMSEagle(NotifyBase):
|
||||
"""
|
||||
A wrapper for SMSEagle Notifications
|
||||
@ -403,15 +419,15 @@ class NotifySMSEagle(NotifyBase):
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
|
||||
notify_by = {
|
||||
'phone': {
|
||||
SMSEagleCategory.PHONE: {
|
||||
"method": "sms.send_sms",
|
||||
'target': 'to',
|
||||
},
|
||||
'group': {
|
||||
SMSEagleCategory.GROUP: {
|
||||
"method": "sms.send_togroup",
|
||||
'target': 'groupname',
|
||||
},
|
||||
'contact': {
|
||||
SMSEagleCategory.CONTACT: {
|
||||
"method": "sms.send_tocontact",
|
||||
'target': 'contactname',
|
||||
},
|
||||
@ -420,7 +436,7 @@ class NotifySMSEagle(NotifyBase):
|
||||
# categories separated into a tuple since notify_by.keys()
|
||||
# returns an unpredicable list in Python 2.7 which causes
|
||||
# tests to fail every so often
|
||||
for category in ('phone', 'group', 'contact'):
|
||||
for category in SMSEAGLE_CATEGORIES:
|
||||
# Create a copy of our template
|
||||
payload = {
|
||||
'method': notify_by[category]['method'],
|
||||
@ -596,6 +612,28 @@ class NotifySMSEagle(NotifyBase):
|
||||
params=NotifySMSEagle.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
if batch_size > 1:
|
||||
# Batches can only be sent by group (you can't combine groups into
|
||||
# a single batch)
|
||||
total_targets = 0
|
||||
for c in SMSEAGLE_CATEGORIES:
|
||||
targets = len(getattr(self, f'target_{c}s'))
|
||||
total_targets += int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
return total_targets
|
||||
|
||||
# Normal batch count; just count the targets
|
||||
return len(self.target_phones) + len(self.target_contacts) + \
|
||||
len(self.target_groups)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -513,6 +513,21 @@ class NotifySMTP2Go(NotifyBase):
|
||||
safe='') for e in self.targets]),
|
||||
params=NotifySMTP2Go.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
targets = len(self.targets)
|
||||
if batch_size > 1:
|
||||
targets = int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -600,6 +600,12 @@ class NotifySNS(NotifyBase):
|
||||
params=NotifySNS.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.phone) + len(self.topics)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -287,6 +287,12 @@ class NotifySendGrid(NotifyBase):
|
||||
params=NotifySendGrid.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
|
||||
"""
|
||||
Perform SendGrid Notification
|
||||
|
@ -431,6 +431,21 @@ class NotifySignalAPI(NotifyBase):
|
||||
params=NotifySignalAPI.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
targets = len(self.targets)
|
||||
if batch_size > 1:
|
||||
targets = int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
|
||||
return targets
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -408,6 +408,13 @@ class NotifySinch(NotifyBase):
|
||||
[NotifySinch.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifySinch.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -1015,6 +1015,12 @@ class NotifySlack(NotifyBase):
|
||||
params=NotifySlack.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.channels)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -722,6 +722,21 @@ class NotifySparkPost(NotifyBase):
|
||||
safe='') for e in self.targets]),
|
||||
params=NotifySparkPost.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
#
|
||||
# Factor batch into calculation
|
||||
#
|
||||
batch_size = 1 if not self.batch else self.default_batch_size
|
||||
targets = len(self.targets)
|
||||
if batch_size > 1:
|
||||
targets = int(targets / batch_size) + \
|
||||
(1 if targets % batch_size else 0)
|
||||
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -350,6 +350,13 @@ class NotifySpontit(NotifyBase):
|
||||
[NotifySpontit.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifySpontit.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -819,6 +819,12 @@ class NotifyTelegram(NotifyBase):
|
||||
[NotifyTelegram.quote('@{}'.format(x)) for x in self.targets]),
|
||||
params=NotifyTelegram.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -385,6 +385,13 @@ class NotifyTwilio(NotifyBase):
|
||||
[NotifyTwilio.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifyTwilio.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -256,6 +256,12 @@ class NotifyTwist(NotifyBase):
|
||||
params=NotifyTwist.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.channels) + len(self.channel_ids)
|
||||
|
||||
def login(self):
|
||||
"""
|
||||
A simple wrapper to authenticate with the Twist Server
|
||||
|
@ -793,10 +793,6 @@ class NotifyTwitter(NotifyBase):
|
||||
# Extend our parameters
|
||||
params.update(self.url_parameters(privacy=privacy, *args, **kwargs))
|
||||
|
||||
if len(self.targets) > 0:
|
||||
params['to'] = ','.join(
|
||||
[NotifyTwitter.quote(x, safe='') for x in self.targets])
|
||||
|
||||
return '{schema}://{ckey}/{csecret}/{akey}/{asecret}' \
|
||||
'/{targets}/?{params}'.format(
|
||||
schema=self.secure_protocol[0],
|
||||
@ -811,6 +807,13 @@ class NotifyTwitter(NotifyBase):
|
||||
for target in self.targets]),
|
||||
params=NotifyTwitter.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
@ -823,28 +826,22 @@ class NotifyTwitter(NotifyBase):
|
||||
# We're done early as we couldn't load the results
|
||||
return results
|
||||
|
||||
# The first token is stored in the hostname
|
||||
consumer_key = NotifyTwitter.unquote(results['host'])
|
||||
|
||||
# Acquire remaining tokens
|
||||
tokens = NotifyTwitter.split_path(results['fullpath'])
|
||||
|
||||
# The consumer token is stored in the hostname
|
||||
results['ckey'] = NotifyTwitter.unquote(results['host'])
|
||||
|
||||
#
|
||||
# Now fetch the remaining tokens
|
||||
try:
|
||||
consumer_secret, access_token_key, access_token_secret = \
|
||||
tokens[0:3]
|
||||
#
|
||||
|
||||
except (ValueError, AttributeError, IndexError):
|
||||
# Force some bad values that will get caught
|
||||
# in parsing later
|
||||
consumer_secret = None
|
||||
access_token_key = None
|
||||
access_token_secret = None
|
||||
|
||||
results['ckey'] = consumer_key
|
||||
results['csecret'] = consumer_secret
|
||||
results['akey'] = access_token_key
|
||||
results['asecret'] = access_token_secret
|
||||
# Consumer Secret
|
||||
results['csecret'] = tokens.pop(0) if tokens else None
|
||||
# Access Token Key
|
||||
results['akey'] = tokens.pop(0) if tokens else None
|
||||
# Access Token Secret
|
||||
results['asecret'] = tokens.pop(0) if tokens else None
|
||||
|
||||
# The defined twitter mode
|
||||
if 'mode' in results['qsd'] and len(results['qsd']['mode']):
|
||||
@ -861,7 +858,7 @@ class NotifyTwitter(NotifyBase):
|
||||
results['targets'].append(results.get('user'))
|
||||
|
||||
# Store any remaining items as potential targets
|
||||
results['targets'].extend(tokens[3:])
|
||||
results['targets'].extend(tokens)
|
||||
|
||||
# Get Cache Flag (reduces lookup hits)
|
||||
if 'cache' in results['qsd'] and len(results['qsd']['cache']):
|
||||
|
@ -329,6 +329,13 @@ class NotifyVoipms(NotifyBase):
|
||||
['1' + NotifyVoipms.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifyVoipms.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -334,6 +334,13 @@ class NotifyVonage(NotifyBase):
|
||||
[NotifyVonage.quote(x, safe='') for x in self.targets]),
|
||||
params=NotifyVonage.urlencode(params))
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
targets = len(self.targets)
|
||||
return targets if targets > 0 else 1
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -359,6 +359,12 @@ class NotifyZulip(NotifyBase):
|
||||
params=NotifyZulip.urlencode(params),
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Returns the number of targets associated with this notification
|
||||
"""
|
||||
return len(self.targets)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url):
|
||||
"""
|
||||
|
@ -203,6 +203,9 @@ class AppriseURLTester:
|
||||
# this url
|
||||
assert isinstance(obj.url(), str) is True
|
||||
|
||||
# Verify we can acquire a target count as an integer
|
||||
assert isinstance(len(obj), int)
|
||||
|
||||
# Test url() with privacy=True
|
||||
assert isinstance(
|
||||
obj.url(privacy=True), str) is True
|
||||
@ -240,6 +243,14 @@ class AppriseURLTester:
|
||||
url, obj.url()))
|
||||
assert False
|
||||
|
||||
# Verify there is no change from the old and the new
|
||||
if len(obj) != len(obj_cmp):
|
||||
print('%d targets found in %s' % (
|
||||
len(obj), obj.url(privacy=True)))
|
||||
print('But %d targets found in %s' % (
|
||||
len(obj_cmp), obj_cmp.url(privacy=True)))
|
||||
raise AssertionError("Target miscount %d != %d")
|
||||
|
||||
# Tidy our object
|
||||
del obj_cmp
|
||||
|
||||
@ -371,11 +382,19 @@ class AppriseURLTester:
|
||||
try:
|
||||
if test_requests_exceptions is False:
|
||||
|
||||
# Verify we can acquire a target count as an integer
|
||||
targets = len(obj)
|
||||
|
||||
# check that we're as expected
|
||||
assert obj.notify(
|
||||
body=self.body, title=self.title,
|
||||
notify_type=notify_type) == notify_response
|
||||
|
||||
if notify_response:
|
||||
# If we successfully got a response, there must have been
|
||||
# at least 1 target present
|
||||
assert targets > 0
|
||||
|
||||
# check that this doesn't change using different overflow
|
||||
# methods
|
||||
assert obj.notify(
|
||||
@ -447,6 +466,7 @@ class AppriseURLTester:
|
||||
os.path.join(self.__test_var_dir, 'apprise-test.png'),
|
||||
os.path.join(self.__test_var_dir, 'apprise-test.jpeg'),
|
||||
))
|
||||
|
||||
assert obj.notify(
|
||||
body=self.body, title=self.title,
|
||||
notify_type=notify_type,
|
||||
|
@ -168,8 +168,14 @@ def test_plugin_boxcar_edge_cases(mock_post, mock_get):
|
||||
|
||||
# Test comma, separate values
|
||||
device = 'a' * 64
|
||||
|
||||
p = NotifyBoxcar(
|
||||
access=access, secret=secret,
|
||||
targets=','.join([device, device, device]))
|
||||
# unique entries are colapsed into 1
|
||||
assert len(p.device_tokens) == 1
|
||||
|
||||
p = NotifyBoxcar(
|
||||
access=access, secret=secret,
|
||||
targets=','.join(['a' * 64, 'b' * 64, 'c' * 64]))
|
||||
# not unique, so we get the same data here
|
||||
assert len(p.device_tokens) == 3
|
||||
|
@ -173,6 +173,9 @@ def test_plugin_bulksms_edge_cases(mock_post):
|
||||
assert obj.notify(
|
||||
body='body', title='title', notify_type=NotifyType.INFO) is True
|
||||
|
||||
# We know there are 4 targets
|
||||
assert len(obj) == 4
|
||||
|
||||
# Test our call count
|
||||
assert mock_post.call_count == 4
|
||||
|
||||
@ -205,3 +208,9 @@ def test_plugin_bulksms_edge_cases(mock_post):
|
||||
['+15551231234', '+15555555555', '@group', '@12'])))
|
||||
|
||||
assert 'batch=no' in obj.url()
|
||||
|
||||
# With our batch in place, our calculations are different
|
||||
obj = Apprise.instantiate(
|
||||
'bulksms://{}:{}@{}?batch=y'.format(user, pwd, '/'.join(targets)))
|
||||
# 2 groups and 2 phones are lumped together
|
||||
assert len(obj) == 3
|
||||
|
@ -36,6 +36,7 @@ from unittest import mock
|
||||
import apprise
|
||||
from apprise.plugins.NotifyDapnet import DapnetPriority, NotifyDapnet
|
||||
from helpers import AppriseURLTester
|
||||
from apprise import NotifyType
|
||||
|
||||
# Disable logging for a cleaner testing output
|
||||
import logging
|
||||
@ -141,6 +142,35 @@ def test_plugin_dapnet_urls():
|
||||
AppriseURLTester(tests=apprise_url_tests).run_all()
|
||||
|
||||
|
||||
@mock.patch('requests.post')
|
||||
def test_plugin_dapnet_edge_cases(mock_post):
|
||||
"""
|
||||
NotifyDapnet() Edge Cases
|
||||
"""
|
||||
# Prepare Mock
|
||||
mock_post.return_value = requests.Request()
|
||||
mock_post.return_value.status_code = requests.codes.created
|
||||
|
||||
# test the handling of our batch modes
|
||||
obj = apprise.Apprise.instantiate(
|
||||
'dapnet://user:pass@{}?batch=yes'.format(
|
||||
'/'.join(['DF1ABC', 'DF1DEF'])))
|
||||
assert isinstance(obj, NotifyDapnet)
|
||||
|
||||
# objects will be combined into a single post in batch mode
|
||||
assert len(obj) == 1
|
||||
|
||||
# Force our batch to break into separate messages
|
||||
obj.default_batch_size = 1
|
||||
|
||||
# We'll send 2 messages now
|
||||
assert len(obj) == 2
|
||||
|
||||
assert obj.notify(
|
||||
body='body', title='title', notify_type=NotifyType.INFO) is True
|
||||
assert mock_post.call_count == 2
|
||||
|
||||
|
||||
@mock.patch('requests.post')
|
||||
def test_plugin_dapnet_config_files(mock_post):
|
||||
"""
|
||||
|
@ -342,6 +342,9 @@ def test_plugin_email(mock_smtp, mock_smtpssl):
|
||||
# We loaded okay; now lets make sure we can reverse this url
|
||||
assert isinstance(obj.url(), str) is True
|
||||
|
||||
# Verify we can acquire a target count as an integer
|
||||
assert isinstance(len(obj), int)
|
||||
|
||||
# Test url() with privacy=True
|
||||
assert isinstance(
|
||||
obj.url(privacy=True), str) is True
|
||||
@ -369,6 +372,14 @@ def test_plugin_email(mock_smtp, mock_smtpssl):
|
||||
url, obj.url()))
|
||||
assert False
|
||||
|
||||
# Verify there is no change from the old and the new
|
||||
if len(obj) != len(obj_cmp):
|
||||
print('%d targets found in %s' % (
|
||||
len(obj), obj.url(privacy=True)))
|
||||
print('But %d targets found in %s' % (
|
||||
len(obj_cmp), obj_cmp.url(privacy=True)))
|
||||
raise AssertionError("Target miscount %d != %d")
|
||||
|
||||
if self:
|
||||
# Iterate over our expected entries inside of our object
|
||||
for key, val in self.items():
|
||||
@ -378,11 +389,19 @@ def test_plugin_email(mock_smtp, mock_smtpssl):
|
||||
|
||||
try:
|
||||
if test_smtplib_exceptions is False:
|
||||
# Verify we can acquire a target count as an integer
|
||||
targets = len(obj)
|
||||
|
||||
# check that we're as expected
|
||||
assert obj.notify(
|
||||
title='test', body='body',
|
||||
notify_type=NotifyType.INFO) == response
|
||||
|
||||
if response:
|
||||
# If we successfully got a response, there must have
|
||||
# been at least 1 target present
|
||||
assert targets > 0
|
||||
|
||||
else:
|
||||
for exception in test_smtplib_exceptions:
|
||||
mock_socket.sendmail.side_effect = exception
|
||||
|
@ -288,9 +288,15 @@ def test_plugin_mailgun_attachments(mock_post):
|
||||
'user1@example.com/user2@example.com?batch=yes'.format(apikey))
|
||||
assert isinstance(obj, NotifyMailgun)
|
||||
|
||||
# objects will be combined into a single post in batch mode
|
||||
assert len(obj) == 1
|
||||
|
||||
# Force our batch to break into separate messages
|
||||
obj.default_batch_size = 1
|
||||
# We'll send 2 messages
|
||||
|
||||
# We'll send 2 messages now
|
||||
assert len(obj) == 2
|
||||
|
||||
mock_post.reset_mock()
|
||||
|
||||
assert obj.notify(
|
||||
|
@ -96,6 +96,8 @@ def test_plugin_mqtt_default_success(mqtt_client_mock):
|
||||
obj = apprise.Apprise.instantiate(
|
||||
'mqtt://localhost:1234/my/topic', suppress_exceptions=False)
|
||||
assert isinstance(obj, NotifyMQTT)
|
||||
# We only loaded 1 topic
|
||||
assert len(obj) == 1
|
||||
assert obj.url().startswith('mqtt://localhost:1234/my/topic')
|
||||
|
||||
# Verify default settings.
|
||||
@ -135,6 +137,9 @@ def test_plugin_mqtt_multiple_topics_success(mqtt_client_mock):
|
||||
'mqtt://localhost/my/topic,my/other/topic',
|
||||
suppress_exceptions=False)
|
||||
|
||||
# Verify we have loaded 2 topics
|
||||
assert len(obj) == 2
|
||||
|
||||
assert isinstance(obj, NotifyMQTT)
|
||||
assert obj.url().startswith('mqtt://localhost')
|
||||
assert re.search(r'my/topic', obj.url())
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
from apprise.plugins.NotifyOneSignal import NotifyOneSignal
|
||||
from helpers import AppriseURLTester
|
||||
from apprise import Apprise
|
||||
|
||||
# Disable logging for a cleaner testing output
|
||||
import logging
|
||||
@ -131,3 +132,119 @@ def test_plugin_onesignal_urls():
|
||||
|
||||
# Run our general tests
|
||||
AppriseURLTester(tests=apprise_url_tests).run_all()
|
||||
|
||||
|
||||
def test_plugin_onesignal_edge_cases():
|
||||
"""
|
||||
NotifyOneSignal() Batch Validation
|
||||
|
||||
"""
|
||||
obj = Apprise.instantiate(
|
||||
'onesignal://appid@apikey/#segment/@user/playerid/user@email.com'
|
||||
'/?batch=yes')
|
||||
# Validate that it loaded okay
|
||||
assert isinstance(obj, NotifyOneSignal)
|
||||
|
||||
# all 4 types defined; but even in a batch mode, they can not be
|
||||
# sent in one submission
|
||||
assert len(obj) == 4
|
||||
|
||||
#
|
||||
# Users
|
||||
#
|
||||
obj = Apprise.instantiate(
|
||||
'onesignal://appid@apikey/@user1/@user2/@user3/@user4/?batch=yes')
|
||||
assert isinstance(obj, NotifyOneSignal)
|
||||
|
||||
# We can lump these together - no problem
|
||||
assert len(obj) == 1
|
||||
|
||||
# Same query, but no batch mode set
|
||||
obj = Apprise.instantiate(
|
||||
'onesignal://appid@apikey/@user1/@user2/@user3/@user4/?batch=no')
|
||||
assert isinstance(obj, NotifyOneSignal)
|
||||
|
||||
# Individual queries
|
||||
assert len(obj) == 4
|
||||
|
||||
#
|
||||
# Segments
|
||||
#
|
||||
obj = Apprise.instantiate(
|
||||
'onesignal://appid@apikey/#segment1/#seg2/#seg3/#seg4/?batch=yes')
|
||||
assert isinstance(obj, NotifyOneSignal)
|
||||
|
||||
# We can lump these together - no problem
|
||||
assert len(obj) == 1
|
||||
|
||||
# Same query, but no batch mode set
|
||||
obj = Apprise.instantiate(
|
||||
'onesignal://appid@apikey/#segment1/#seg2/#seg3/#seg4/?batch=no')
|
||||
assert isinstance(obj, NotifyOneSignal)
|
||||
|
||||
# Individual queries
|
||||
assert len(obj) == 4
|
||||
|
||||
#
|
||||
# Player ID's
|
||||
#
|
||||
obj = Apprise.instantiate(
|
||||
'onesignal://appid@apikey/pid1/pid2/pid3/pid4/?batch=yes')
|
||||
assert isinstance(obj, NotifyOneSignal)
|
||||
|
||||
# We can lump these together - no problem
|
||||
assert len(obj) == 1
|
||||
|
||||
# Same query, but no batch mode set
|
||||
obj = Apprise.instantiate(
|
||||
'onesignal://appid@apikey/pid1/pid2/pid3/pid4/?batch=no')
|
||||
assert isinstance(obj, NotifyOneSignal)
|
||||
|
||||
# Individual queries
|
||||
assert len(obj) == 4
|
||||
|
||||
#
|
||||
# Emails
|
||||
#
|
||||
emails = ('abc@yahoo.ca', 'def@yahoo.ca', 'ghi@yahoo.ca', 'jkl@yahoo.ca')
|
||||
obj = Apprise.instantiate(
|
||||
'onesignal://appid@apikey/{}/?batch=yes'.format('/'.join(emails)))
|
||||
assert isinstance(obj, NotifyOneSignal)
|
||||
|
||||
# We can lump these together - no problem
|
||||
assert len(obj) == 1
|
||||
|
||||
# Same query, but no batch mode set
|
||||
obj = Apprise.instantiate(
|
||||
'onesignal://appid@apikey/{}/?batch=no'.format('/'.join(emails)))
|
||||
assert isinstance(obj, NotifyOneSignal)
|
||||
|
||||
# Individual queries
|
||||
assert len(obj) == 4
|
||||
|
||||
#
|
||||
# Mixed
|
||||
#
|
||||
emails = ('abc@yahoo.ca', 'def@yahoo.ca', 'ghi@yahoo.ca', 'jkl@yahoo.ca')
|
||||
users = ('@user1', '@user2', '@user3', '@user4')
|
||||
players = ('player1', 'player2', 'player3', 'player4')
|
||||
segments = ('#seg1', '#seg2', '#seg3', '#seg4')
|
||||
|
||||
path = '{}/{}/{}/{}'.format(
|
||||
'/'.join(emails), '/'.join(users),
|
||||
'/'.join(players), '/'.join(segments))
|
||||
|
||||
obj = Apprise.instantiate(
|
||||
'onesignal://appid@apikey/{}/?batch=yes'.format(path))
|
||||
assert isinstance(obj, NotifyOneSignal)
|
||||
|
||||
# We can lump these together - no problem
|
||||
assert len(obj) == 4
|
||||
|
||||
# Same query, but no batch mode set
|
||||
obj = Apprise.instantiate(
|
||||
'onesignal://appid@apikey/{}/?batch=no'.format(path))
|
||||
assert isinstance(obj, NotifyOneSignal)
|
||||
|
||||
# Individual queries
|
||||
assert len(obj) == 16
|
||||
|
@ -101,8 +101,15 @@ apprise_url_tests = (
|
||||
# an invalid entry (%20), and too short of an entry (a)
|
||||
'instance': NotifyOpsgenie,
|
||||
}),
|
||||
('opsgenie://apikey/{}/@{}/#{}/*{}/^{}/'.format(
|
||||
UUID4, UUID4, UUID4, UUID4, UUID4), {
|
||||
('opsgenie://apikey/@{}/#{}/*{}/^{}/'.format(
|
||||
UUID4, UUID4, UUID4, UUID4), {
|
||||
# similar to the above, except we use the UUID's
|
||||
'instance': NotifyOpsgenie,
|
||||
}),
|
||||
# Same link as before but @ missing at the front causing an ambigious
|
||||
# lookup however the entry is treated a though a @ was in front (user)
|
||||
('opsgenie://apikey/{}/#{}/*{}/^{}/'.format(
|
||||
UUID4, UUID4, UUID4, UUID4), {
|
||||
# similar to the above, except we use the UUID's
|
||||
'instance': NotifyOpsgenie,
|
||||
}),
|
||||
|
@ -299,8 +299,8 @@ def test_plugin_smseagle_edge_cases(mock_post):
|
||||
aobj = Apprise()
|
||||
assert aobj.add(
|
||||
"smseagles://token@localhost:231/{}".format(target))
|
||||
assert len(aobj) == 1
|
||||
assert aobj.notify(title=title, body=body)
|
||||
|
||||
assert mock_post.call_count == 1
|
||||
|
||||
details = mock_post.call_args_list[0]
|
||||
@ -315,8 +315,8 @@ def test_plugin_smseagle_edge_cases(mock_post):
|
||||
assert aobj.add(
|
||||
"smseagles://token@localhost:231/{}?status=Yes".format(
|
||||
target))
|
||||
assert len(aobj) == 1
|
||||
assert aobj.notify(title=title, body=body)
|
||||
|
||||
assert mock_post.call_count == 1
|
||||
|
||||
details = mock_post.call_args_list[0]
|
||||
@ -348,6 +348,8 @@ def test_plugin_smseagle_result_set(mock_post):
|
||||
aobj.add(
|
||||
'smseagle://token@10.0.0.112:8080/+12512222222/+12513333333/'
|
||||
'12514444444?batch=yes')
|
||||
# In a batch mode we can shove them all into 1 call
|
||||
assert len(aobj[0]) == 1
|
||||
|
||||
assert aobj.notify(title=title, body=body)
|
||||
|
||||
@ -386,6 +388,7 @@ def test_plugin_smseagle_result_set(mock_post):
|
||||
aobj.add(
|
||||
'smseagle://token@10.0.0.112:8080/#group/Contact/'
|
||||
'123456789?batch=no')
|
||||
assert len(aobj[0]) == 3
|
||||
|
||||
assert aobj.notify(title=title, body=body)
|
||||
|
||||
@ -463,6 +466,8 @@ def test_plugin_smseagle_result_set(mock_post):
|
||||
'smseagle://token@10.0.0.112:8080/513333333/#group1/@contact1/'
|
||||
'contact2/12514444444?batch=yes')
|
||||
|
||||
# contacts and numbers can be combined and is calculated in batch response
|
||||
assert len(aobj[0]) == 3
|
||||
assert aobj.notify(title=title, body=body)
|
||||
|
||||
# There is a unique post to each (group, contact x2, and phone x2)
|
||||
|
@ -225,9 +225,15 @@ def test_plugin_smtp2go_attachments(mock_post):
|
||||
'user1@example.com/user2@example.com?batch=yes'.format(apikey))
|
||||
assert isinstance(obj, NotifySMTP2Go)
|
||||
|
||||
# objects will be combined into a single post in batch mode
|
||||
assert len(obj) == 1
|
||||
|
||||
# Force our batch to break into separate messages
|
||||
obj.default_batch_size = 1
|
||||
# We'll send 2 messages
|
||||
|
||||
# We'll send 2 messages now
|
||||
assert len(obj) == 2
|
||||
|
||||
mock_post.reset_mock()
|
||||
|
||||
assert obj.notify(
|
||||
|
@ -391,9 +391,14 @@ def test_plugin_sparkpost_attachments(mock_post):
|
||||
'user1@example.com/user2@example.com?batch=yes'.format(apikey))
|
||||
assert isinstance(obj, NotifySparkPost)
|
||||
|
||||
# As a batch mode, both emails can be lumped into 1
|
||||
assert len(obj) == 1
|
||||
|
||||
# Force our batch to break into separate messages
|
||||
obj.default_batch_size = 1
|
||||
# We'll send 2 messages
|
||||
|
||||
# We'll send 2 messages no
|
||||
assert len(obj) == 2
|
||||
mock_post.reset_mock()
|
||||
|
||||
assert obj.notify(
|
||||
|
Loading…
Reference in New Issue
Block a user