mirror of https://github.com/caronc/apprise
PEP E501 (file length) fix applied
parent
2d4ad01829
commit
8a18e6b6e4
|
@ -25,6 +25,7 @@
|
||||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import contextlib
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
|
@ -286,13 +287,10 @@ class AttachHTTP(AttachBase):
|
||||||
self.logger.trace("Attachment cleanup of %s", self._temp_file.name)
|
self.logger.trace("Attachment cleanup of %s", self._temp_file.name)
|
||||||
self._temp_file.close()
|
self._temp_file.close()
|
||||||
|
|
||||||
try:
|
with contextlib.suppress(OSError):
|
||||||
# Ensure our file is removed (if it exists)
|
# Ensure our file is removed (if it exists)
|
||||||
os.unlink(self._temp_file.name)
|
os.unlink(self._temp_file.name)
|
||||||
|
|
||||||
except OSError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Reset our temporary file to prevent from entering
|
# Reset our temporary file to prevent from entering
|
||||||
# this block again
|
# this block again
|
||||||
self._temp_file = None
|
self._temp_file = None
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import contextlib
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
@ -186,12 +187,8 @@ class LogCapture:
|
||||||
self.__buffer_ptr.close()
|
self.__buffer_ptr.close()
|
||||||
self.__handler.close()
|
self.__handler.close()
|
||||||
if self.__delete:
|
if self.__delete:
|
||||||
try:
|
with contextlib.suppress(OSError):
|
||||||
# Always remove file afterwards
|
# Always remove file afterwards
|
||||||
os.unlink(self.__path)
|
os.unlink(self.__path)
|
||||||
|
|
||||||
except OSError:
|
|
||||||
# It's okay if the file does not exist
|
|
||||||
pass
|
|
||||||
|
|
||||||
return exc_type is None
|
return exc_type is None
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
# THE SOFTWARE.
|
# THE SOFTWARE.
|
||||||
import base64
|
import base64
|
||||||
import binascii
|
import binascii
|
||||||
|
import contextlib
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
import glob
|
import glob
|
||||||
import gzip
|
import gzip
|
||||||
|
@ -52,13 +53,9 @@ def _ntf_tidy(ntf):
|
||||||
"""Reusable NamedTemporaryFile cleanup."""
|
"""Reusable NamedTemporaryFile cleanup."""
|
||||||
if ntf:
|
if ntf:
|
||||||
# Cleanup
|
# Cleanup
|
||||||
try:
|
with contextlib.suppress(OSError):
|
||||||
ntf.close()
|
ntf.close()
|
||||||
|
|
||||||
except OSError:
|
|
||||||
# Already closed
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.unlink(ntf.name)
|
os.unlink(ntf.name)
|
||||||
logger.trace("Persistent temporary file removed: %s", ntf.name)
|
logger.trace("Persistent temporary file removed: %s", ntf.name)
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
# http://www.aprs.org/doc/APRS101.PDF
|
# http://www.aprs.org/doc/APRS101.PDF
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import contextlib
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
|
@ -321,13 +322,8 @@ class NotifyAprs(NotifyBase):
|
||||||
def socket_close(self):
|
def socket_close(self):
|
||||||
"""Closes the socket connection whereas present."""
|
"""Closes the socket connection whereas present."""
|
||||||
if self.sock:
|
if self.sock:
|
||||||
try:
|
with contextlib.suppress(Exception):
|
||||||
self.sock.close()
|
self.sock.close()
|
||||||
|
|
||||||
except Exception:
|
|
||||||
# No worries if socket exception thrown on close()
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.sock = None
|
self.sock = None
|
||||||
|
|
||||||
def socket_open(self):
|
def socket_open(self):
|
||||||
|
|
|
@ -187,10 +187,11 @@ class NotifyBase(URLBase):
|
||||||
"default": overflow_mode,
|
"default": overflow_mode,
|
||||||
# look up default using the following parent class value at
|
# look up default using the following parent class value at
|
||||||
# runtime. The variable name identified here (in this case
|
# runtime. The variable name identified here (in this case
|
||||||
# overflow_mode) is checked and it's result is placed over-top of
|
# overflow_mode) is checked and it's result is placed over-top
|
||||||
# the 'default'. This is done because once a parent class inherits
|
# of the 'default'. This is done because once a parent class
|
||||||
# this one, the overflow_mode already set as a default 'could' be
|
# inherits this one, the overflow_mode already set as a default
|
||||||
# potentially over-ridden and changed to a different value.
|
# 'could' be potentially over-ridden and changed to a different
|
||||||
|
# value.
|
||||||
"_lookup_default": "overflow_mode",
|
"_lookup_default": "overflow_mode",
|
||||||
},
|
},
|
||||||
"format": {
|
"format": {
|
||||||
|
|
|
@ -133,10 +133,11 @@ class NotifyD7Networks(NotifyBase):
|
||||||
"alias_of": "targets",
|
"alias_of": "targets",
|
||||||
},
|
},
|
||||||
"source": {
|
"source": {
|
||||||
# Originating address,In cases where the rewriting of the sender's
|
# Originating address,In cases where the rewriting of the
|
||||||
# address is supported or permitted by the SMS-C. This is used to
|
# sender's address is supported or permitted by the SMS-C.
|
||||||
# transmit the message, this number is transmitted as the
|
# This is used to transmit the message, this number is
|
||||||
# originating address and is completely optional.
|
# transmitted as the originating address and is completely
|
||||||
|
# optional.
|
||||||
"name": _("Originating Address"),
|
"name": _("Originating Address"),
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"map_to": "source",
|
"map_to": "source",
|
||||||
|
|
|
@ -144,9 +144,9 @@ class NotifyGnome(NotifyBase):
|
||||||
"default": GnomeUrgency.NORMAL,
|
"default": GnomeUrgency.NORMAL,
|
||||||
},
|
},
|
||||||
"priority": {
|
"priority": {
|
||||||
# Apprise uses 'priority' everywhere; it's just a nice consistent
|
# Apprise uses 'priority' everywhere; it's just a nice
|
||||||
# feel to be able to use it here as well. Just map the
|
# consistent feel to be able to use it here as well. Just map
|
||||||
# value back to 'priority'
|
# the value back to 'priority'
|
||||||
"alias_of": "urgency",
|
"alias_of": "urgency",
|
||||||
},
|
},
|
||||||
"image": {
|
"image": {
|
||||||
|
|
|
@ -86,6 +86,7 @@
|
||||||
# - https://developer.lametric.com/icons
|
# - https://developer.lametric.com/icons
|
||||||
|
|
||||||
|
|
||||||
|
import contextlib
|
||||||
from json import dumps
|
from json import dumps
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
@ -1103,13 +1104,9 @@ class NotifyLametric(NotifyBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set cycles
|
# Set cycles
|
||||||
try:
|
with contextlib.suppress(TypeError, ValueError):
|
||||||
results["cycles"] = abs(int(results["qsd"].get("cycles")))
|
results["cycles"] = abs(int(results["qsd"].get("cycles")))
|
||||||
|
|
||||||
except (TypeError, ValueError):
|
|
||||||
# Not a valid integer; ignore entry
|
|
||||||
pass
|
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -96,7 +96,9 @@ class NotifyLark(NotifyBase):
|
||||||
"""Returns the URL built dynamically based on specified arguments."""
|
"""Returns the URL built dynamically based on specified arguments."""
|
||||||
params = self.url_parameters(privacy=privacy, *args, **kwargs)
|
params = self.url_parameters(privacy=privacy, *args, **kwargs)
|
||||||
return (
|
return (
|
||||||
f"{self.secure_protocol}://{self.pprint(self.token, privacy, mode=PrivacyMode.Secret)}/?{NotifyLark.urlencode(params)}"
|
f"{self.secure_protocol}://"
|
||||||
|
f"{self.pprint(self.token, privacy, mode=PrivacyMode.Secret)}/"
|
||||||
|
f"?{NotifyLark.urlencode(params)}"
|
||||||
)
|
)
|
||||||
|
|
||||||
def send(self, body, title="", notify_type=NotifyType.INFO, **kwargs):
|
def send(self, body, title="", notify_type=NotifyType.INFO, **kwargs):
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import contextlib
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from json import dumps, loads
|
from json import dumps, loads
|
||||||
|
@ -828,13 +829,10 @@ class NotifyMastodon(NotifyBase):
|
||||||
# 'emojis': [],
|
# 'emojis': [],
|
||||||
# 'fields': []
|
# 'fields': []
|
||||||
# }
|
# }
|
||||||
try:
|
with contextlib.suppress(TypeError, KeyError):
|
||||||
# Cache our response for future references
|
# Cache our response for future references
|
||||||
self._whoami_cache = {response["username"]: response["id"]}
|
self._whoami_cache = {response["username"]: response["id"]}
|
||||||
|
|
||||||
except (TypeError, KeyError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
elif response and "authorized scopes" in response.get("error", ""):
|
elif response and "authorized scopes" in response.get("error", ""):
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
"Failed to lookup Mastodon Auth details; "
|
"Failed to lookup Mastodon Auth details; "
|
||||||
|
|
|
@ -108,8 +108,8 @@ class NotifyNextcloud(NotifyBase):
|
||||||
NotifyBase.template_args,
|
NotifyBase.template_args,
|
||||||
**{
|
**{
|
||||||
# Nextcloud uses different API end points depending on the version
|
# Nextcloud uses different API end points depending on the version
|
||||||
# being used however the (API) payload remains the same. Allow users
|
# being used however the (API) payload remains the same. Allow
|
||||||
# to specify the version they are using:
|
# users to specify the version they are using:
|
||||||
"version": {
|
"version": {
|
||||||
"name": _("Version"),
|
"name": _("Version"),
|
||||||
"type": "int",
|
"type": "int",
|
||||||
|
|
|
@ -454,7 +454,8 @@ class NotifyOneSignal(NotifyBase):
|
||||||
|
|
||||||
self.logger.debug(
|
self.logger.debug(
|
||||||
"OneSignal POST URL:"
|
"OneSignal POST URL:"
|
||||||
f" {self.notify_url} (cert_verify={self.verify_certificate!r})"
|
f" {self.notify_url} "
|
||||||
|
f"(cert_verify={self.verify_certificate!r})"
|
||||||
)
|
)
|
||||||
self.logger.debug(f"OneSignal Payload: {payload!s}")
|
self.logger.debug(f"OneSignal Payload: {payload!s}")
|
||||||
|
|
||||||
|
|
|
@ -179,8 +179,8 @@ class NotifyPagerDuty(NotifyBase):
|
||||||
"default": PagerDutyRegion.US,
|
"default": PagerDutyRegion.US,
|
||||||
"map_to": "region_name",
|
"map_to": "region_name",
|
||||||
},
|
},
|
||||||
# The severity is automatically determined, however you can optionally
|
# The severity is automatically determined, however you can
|
||||||
# over-ride its value and force it to be what you want
|
# optionally over-ride its value and force it to be what you want
|
||||||
"severity": {
|
"severity": {
|
||||||
"name": _("Severity"),
|
"name": _("Severity"),
|
||||||
"type": "choice:string",
|
"type": "choice:string",
|
||||||
|
@ -276,8 +276,9 @@ class NotifyPagerDuty(NotifyBase):
|
||||||
|
|
||||||
if self.region_name not in PAGERDUTY_REGIONS:
|
if self.region_name not in PAGERDUTY_REGIONS:
|
||||||
# allow the outer except to handle this common response
|
# allow the outer except to handle this common response
|
||||||
raise
|
raise IndexError()
|
||||||
except:
|
|
||||||
|
except (AttributeError, IndexError, TypeError):
|
||||||
# Invalid region specified
|
# Invalid region specified
|
||||||
msg = f"The PagerDuty region specified ({region_name}) is invalid."
|
msg = f"The PagerDuty region specified ({region_name}) is invalid."
|
||||||
self.logger.warning(msg)
|
self.logger.warning(msg)
|
||||||
|
|
|
@ -240,8 +240,8 @@ class NotifyPopcornNotify(NotifyBase):
|
||||||
except requests.RequestException as e:
|
except requests.RequestException as e:
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
"A Connection error occured sending"
|
"A Connection error occured sending"
|
||||||
f" {len(self.targets[index:index + batch_size])} PopcornNotify"
|
f" {len(self.targets[index:index + batch_size])} "
|
||||||
" notification(s)."
|
"PopcornNotify notification(s)."
|
||||||
)
|
)
|
||||||
self.logger.debug(f"Socket Exception: {e!s}")
|
self.logger.debug(f"Socket Exception: {e!s}")
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import contextlib
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
@ -339,19 +340,15 @@ class NotifyPushover(NotifyBase):
|
||||||
|
|
||||||
# How often to resend notification, in seconds
|
# How often to resend notification, in seconds
|
||||||
self.retry = self.template_args["retry"]["default"]
|
self.retry = self.template_args["retry"]["default"]
|
||||||
try:
|
with contextlib.suppress(ValueError, TypeError):
|
||||||
|
# Get our retry value
|
||||||
self.retry = int(retry)
|
self.retry = int(retry)
|
||||||
except (ValueError, TypeError):
|
|
||||||
# Do nothing
|
|
||||||
pass
|
|
||||||
|
|
||||||
# How often to resend notification, in seconds
|
# How often to resend notification, in seconds
|
||||||
self.expire = self.template_args["expire"]["default"]
|
self.expire = self.template_args["expire"]["default"]
|
||||||
try:
|
with contextlib.suppress(ValueError, TypeError):
|
||||||
|
# Acquire our expiry value
|
||||||
self.expire = int(expire)
|
self.expire = int(expire)
|
||||||
except (ValueError, TypeError):
|
|
||||||
# Do nothing
|
|
||||||
pass
|
|
||||||
|
|
||||||
if self.retry < 30:
|
if self.retry < 30:
|
||||||
msg = "Pushover retry must be at least 30 seconds."
|
msg = "Pushover retry must be at least 30 seconds."
|
||||||
|
|
|
@ -90,7 +90,9 @@ class NotifyPushplus(NotifyBase):
|
||||||
"""Returns the URL built dynamically based on specified arguments."""
|
"""Returns the URL built dynamically based on specified arguments."""
|
||||||
params = self.url_parameters(privacy=privacy, *args, **kwargs)
|
params = self.url_parameters(privacy=privacy, *args, **kwargs)
|
||||||
return (
|
return (
|
||||||
f"{self.secure_protocol}://{self.pprint(self.token, privacy, mode=PrivacyMode.Secret)}/?{self.urlencode(params)}"
|
f"{self.secure_protocol}://"
|
||||||
|
f"{self.pprint(self.token, privacy, mode=PrivacyMode.Secret)}/"
|
||||||
|
f"?{self.urlencode(params)}"
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -94,7 +94,9 @@ class NotifyQQ(NotifyBase):
|
||||||
"""Returns the URL built dynamically based on specified arguments."""
|
"""Returns the URL built dynamically based on specified arguments."""
|
||||||
params = self.url_parameters(privacy=privacy, *args, **kwargs)
|
params = self.url_parameters(privacy=privacy, *args, **kwargs)
|
||||||
return (
|
return (
|
||||||
f"{self.secure_protocol}://{self.pprint(self.token, privacy, mode=PrivacyMode.Secret)}/?{self.urlencode(params)}"
|
f"{self.secure_protocol}://"
|
||||||
|
f"{self.pprint(self.token, privacy, mode=PrivacyMode.Secret)}/"
|
||||||
|
f"?{self.urlencode(params)}"
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -692,7 +692,8 @@ class NotifySES(NotifyBase):
|
||||||
# Our Authorization header
|
# Our Authorization header
|
||||||
headers["Authorization"] = ", ".join([
|
headers["Authorization"] = ", ".join([
|
||||||
(
|
(
|
||||||
f"{self.aws_auth_algorithm} Credential={self.aws_access_key_id}/{scope}"
|
f"{self.aws_auth_algorithm} "
|
||||||
|
f"Credential={self.aws_access_key_id}/{scope}"
|
||||||
),
|
),
|
||||||
"SignedHeaders={signed_headers}".format(
|
"SignedHeaders={signed_headers}".format(
|
||||||
signed_headers=";".join(signed_headers.keys()),
|
signed_headers=";".join(signed_headers.keys()),
|
||||||
|
|
|
@ -99,10 +99,11 @@ class NotifySeven(NotifyBase):
|
||||||
"alias_of": "targets",
|
"alias_of": "targets",
|
||||||
},
|
},
|
||||||
"source": {
|
"source": {
|
||||||
# Originating address,In cases where the rewriting of the sender's
|
# Originating address,In cases where the rewriting of the
|
||||||
# address is supported or permitted by the SMS-C. This is used to
|
# sender's address is supported or permitted by the SMS-C.
|
||||||
# transmit the message, this number is transmitted as the
|
# This is used to transmit the message, this number is
|
||||||
# originating address and is completely optional.
|
# transmitted as the originating address and is completely
|
||||||
|
# optional.
|
||||||
"name": _("Originating Address"),
|
"name": _("Originating Address"),
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"map_to": "source",
|
"map_to": "source",
|
||||||
|
|
|
@ -71,6 +71,7 @@
|
||||||
# - You will be able to select the Bot App you previously created
|
# - You will be able to select the Bot App you previously created
|
||||||
# - Your bot will join your channel.
|
# - Your bot will join your channel.
|
||||||
|
|
||||||
|
import contextlib
|
||||||
from json import dumps, loads
|
from json import dumps, loads
|
||||||
import re
|
import re
|
||||||
from time import time
|
from time import time
|
||||||
|
@ -815,14 +816,13 @@ class NotifySlack(NotifyBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Attachment posts return a JSON string
|
# Attachment posts return a JSON string
|
||||||
try:
|
with contextlib.suppress(AttributeError, TypeError, ValueError):
|
||||||
response = loads(r.content)
|
# Load our JSON object if we can
|
||||||
|
|
||||||
except (AttributeError, TypeError, ValueError):
|
|
||||||
# ValueError = r.content is Unparsable
|
# ValueError = r.content is Unparsable
|
||||||
# TypeError = r.content is None
|
# TypeError = r.content is None
|
||||||
# AttributeError = r is None
|
# AttributeError = r is None
|
||||||
pass
|
response = loads(r.content)
|
||||||
|
|
||||||
# We can get a 200 response, but still fail. A failure message
|
# We can get a 200 response, but still fail. A failure message
|
||||||
# might look like this (missing bot permissions):
|
# might look like this (missing bot permissions):
|
||||||
|
@ -980,14 +980,12 @@ class NotifySlack(NotifyBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Posts return a JSON string
|
# Posts return a JSON string
|
||||||
try:
|
with contextlib.suppress(AttributeError, TypeError, ValueError):
|
||||||
response = loads(r.content)
|
# Load our JSON object if we can
|
||||||
|
|
||||||
except (AttributeError, TypeError, ValueError):
|
|
||||||
# ValueError = r.content is Unparsable
|
# ValueError = r.content is Unparsable
|
||||||
# TypeError = r.content is None
|
# TypeError = r.content is None
|
||||||
# AttributeError = r is None
|
# AttributeError = r is None
|
||||||
pass
|
response = loads(r.content)
|
||||||
|
|
||||||
# Another response type is:
|
# Another response type is:
|
||||||
# {
|
# {
|
||||||
|
|
|
@ -419,7 +419,8 @@ class NotifySNS(NotifyBase):
|
||||||
("content-type", headers["Content-Type"]),
|
("content-type", headers["Content-Type"]),
|
||||||
(
|
(
|
||||||
"host",
|
"host",
|
||||||
f"{self.aws_service_name}.{self.aws_region_name}.amazonaws.com",
|
f"{self.aws_service_name}"
|
||||||
|
f".{self.aws_region_name}.amazonaws.com",
|
||||||
),
|
),
|
||||||
("x-amz-date", headers["X-Amz-Date"]),
|
("x-amz-date", headers["X-Amz-Date"]),
|
||||||
])
|
])
|
||||||
|
@ -455,7 +456,8 @@ class NotifySNS(NotifyBase):
|
||||||
# Our Authorization header
|
# Our Authorization header
|
||||||
headers["Authorization"] = ", ".join([
|
headers["Authorization"] = ", ".join([
|
||||||
(
|
(
|
||||||
f"{self.aws_auth_algorithm} Credential={self.aws_access_key_id}/{scope}"
|
f"{self.aws_auth_algorithm} "
|
||||||
|
f"Credential={self.aws_access_key_id}/{scope}"
|
||||||
),
|
),
|
||||||
"SignedHeaders={signed_headers}".format(
|
"SignedHeaders={signed_headers}".format(
|
||||||
signed_headers=";".join(signed_headers.keys()),
|
signed_headers=";".join(signed_headers.keys()),
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#
|
#
|
||||||
# API Documentation: https://developers.sparkpost.com/api/
|
# API Documentation: https://developers.sparkpost.com/api/
|
||||||
# Specifically: https://developers.sparkpost.com/api/transmissions/
|
# Specifically: https://developers.sparkpost.com/api/transmissions/
|
||||||
|
import contextlib
|
||||||
from email.utils import formataddr
|
from email.utils import formataddr
|
||||||
from json import dumps, loads
|
from json import dumps, loads
|
||||||
|
|
||||||
|
@ -273,8 +274,9 @@ class NotifySparkPost(NotifyBase):
|
||||||
|
|
||||||
if self.region_name not in SPARKPOST_REGIONS:
|
if self.region_name not in SPARKPOST_REGIONS:
|
||||||
# allow the outer except to handle this common response
|
# allow the outer except to handle this common response
|
||||||
raise
|
raise IndexError()
|
||||||
except:
|
|
||||||
|
except (AttributeError, IndexError, TypeError):
|
||||||
# Invalid region specified
|
# Invalid region specified
|
||||||
msg = f"The SparkPost region specified ({region_name}) is invalid."
|
msg = f"The SparkPost region specified ({region_name}) is invalid."
|
||||||
self.logger.warning(msg)
|
self.logger.warning(msg)
|
||||||
|
@ -448,18 +450,13 @@ class NotifySparkPost(NotifyBase):
|
||||||
# ]
|
# ]
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
try:
|
with contextlib.suppress(
|
||||||
# Update our status response if we can
|
AttributeError, TypeError, ValueError):
|
||||||
json_response = loads(r.content)
|
# Load our JSON Object if we can
|
||||||
|
|
||||||
except (AttributeError, TypeError, ValueError):
|
|
||||||
# ValueError = r.content is Unparsable
|
# ValueError = r.content is Unparsable
|
||||||
# TypeError = r.content is None
|
# TypeError = r.content is None
|
||||||
# AttributeError = r is None
|
# AttributeError = r is None
|
||||||
|
json_response = loads(r.content)
|
||||||
# We could not parse JSON response.
|
|
||||||
# We will just use the status we already have.
|
|
||||||
pass
|
|
||||||
|
|
||||||
status_code = r.status_code
|
status_code = r.status_code
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,9 @@ class NotifySpike(NotifyBase):
|
||||||
"""Returns the URL built dynamically based on specified arguments."""
|
"""Returns the URL built dynamically based on specified arguments."""
|
||||||
params = self.url_parameters(privacy=privacy, *args, **kwargs)
|
params = self.url_parameters(privacy=privacy, *args, **kwargs)
|
||||||
return (
|
return (
|
||||||
f"{self.secure_protocol}://{self.pprint(self.token, privacy, mode=PrivacyMode.Secret)}/?{self.urlencode(params)}"
|
f"{self.secure_protocol}://"
|
||||||
|
f"{self.pprint(self.token, privacy, mode=PrivacyMode.Secret)}/"
|
||||||
|
f"?{self.urlencode(params)}"
|
||||||
)
|
)
|
||||||
|
|
||||||
def send(self, body, title="", notify_type=NotifyType.INFO, **kwargs):
|
def send(self, body, title="", notify_type=NotifyType.INFO, **kwargs):
|
||||||
|
|
|
@ -92,7 +92,9 @@ class NotifySpugpush(NotifyBase):
|
||||||
"""Returns the URL built dynamically based on specified arguments."""
|
"""Returns the URL built dynamically based on specified arguments."""
|
||||||
params = self.url_parameters(privacy=privacy, *args, **kwargs)
|
params = self.url_parameters(privacy=privacy, *args, **kwargs)
|
||||||
return (
|
return (
|
||||||
f"{self.secure_protocol}://{self.pprint(self.token, privacy, mode=PrivacyMode.Secret)}/?{self.urlencode(params)}"
|
f"{self.secure_protocol}://"
|
||||||
|
f"{self.pprint(self.token, privacy, mode=PrivacyMode.Secret)}/"
|
||||||
|
f"?{self.urlencode(params)}"
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import contextlib
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from json import dumps
|
from json import dumps
|
||||||
import os
|
import os
|
||||||
|
@ -172,7 +173,8 @@ class NotifyVapid(NotifyBase):
|
||||||
"map_to": "mode",
|
"map_to": "mode",
|
||||||
},
|
},
|
||||||
# Default Time To Live (defined in seconds)
|
# Default Time To Live (defined in seconds)
|
||||||
# 0 (Zero) - message will be delivered only if the device is reacheable
|
# 0 (Zero) - message will be delivered only if the device is
|
||||||
|
# reacheable
|
||||||
"ttl": {
|
"ttl": {
|
||||||
"name": _("ttl"),
|
"name": _("ttl"),
|
||||||
"type": "int",
|
"type": "int",
|
||||||
|
@ -241,13 +243,10 @@ class NotifyVapid(NotifyBase):
|
||||||
# Set our Time to Live Flag
|
# Set our Time to Live Flag
|
||||||
self.ttl = self.template_args["ttl"]["default"]
|
self.ttl = self.template_args["ttl"]["default"]
|
||||||
if ttl is not None:
|
if ttl is not None:
|
||||||
try:
|
with contextlib.suppress(ValueError, TypeError):
|
||||||
|
# Store our TTL (Time To live) if it is a valid integer
|
||||||
self.ttl = int(ttl)
|
self.ttl = int(ttl)
|
||||||
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
# Do nothing
|
|
||||||
pass
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
self.ttl < self.template_args["ttl"]["min"]
|
self.ttl < self.template_args["ttl"]["min"]
|
||||||
or self.ttl > self.template_args["ttl"]["max"]
|
or self.ttl > self.template_args["ttl"]["max"]
|
||||||
|
@ -280,8 +279,9 @@ class NotifyVapid(NotifyBase):
|
||||||
|
|
||||||
if self.mode not in VAPID_PUSH_MODES:
|
if self.mode not in VAPID_PUSH_MODES:
|
||||||
# allow the outer except to handle this common response
|
# allow the outer except to handle this common response
|
||||||
raise
|
raise IndexError()
|
||||||
except:
|
|
||||||
|
except (AttributeError, IndexError, TypeError):
|
||||||
# Invalid region specified
|
# Invalid region specified
|
||||||
msg = f"The Vapid mode specified ({mode}) is invalid."
|
msg = f"The Vapid mode specified ({mode}) is invalid."
|
||||||
self.logger.warning(msg)
|
self.logger.warning(msg)
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
# Read more about VoIP.ms API here:
|
# Read more about VoIP.ms API here:
|
||||||
# - https://voip.ms/m/apidocs.php
|
# - https://voip.ms/m/apidocs.php
|
||||||
|
|
||||||
|
import contextlib
|
||||||
from json import loads
|
from json import loads
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
@ -250,14 +251,13 @@ class NotifyVoipms(NotifyBase):
|
||||||
timeout=self.request_timeout,
|
timeout=self.request_timeout,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
with contextlib.suppress(
|
||||||
response = loads(r.content)
|
AttributeError, TypeError, ValueError):
|
||||||
|
# Load our JSON object if valid
|
||||||
except (AttributeError, TypeError, ValueError):
|
|
||||||
# ValueError = r.content is Unparsable
|
# ValueError = r.content is Unparsable
|
||||||
# TypeError = r.content is None
|
# TypeError = r.content is None
|
||||||
# AttributeError = r is None
|
# AttributeError = r is None
|
||||||
pass
|
response = loads(r.content)
|
||||||
|
|
||||||
if r.status_code != requests.codes.ok:
|
if r.status_code != requests.codes.ok:
|
||||||
# We had a problem
|
# We had a problem
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
# Get your (api) key and secret here:
|
# Get your (api) key and secret here:
|
||||||
# - https://dashboard.nexmo.com/getting-started-guide
|
# - https://dashboard.nexmo.com/getting-started-guide
|
||||||
#
|
#
|
||||||
|
import contextlib
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from ..common import NotifyType
|
from ..common import NotifyType
|
||||||
|
@ -126,10 +128,10 @@ class NotifyVonage(NotifyBase):
|
||||||
"alias_of": "secret",
|
"alias_of": "secret",
|
||||||
},
|
},
|
||||||
# Default Time To Live
|
# Default Time To Live
|
||||||
# By default Vonage attempt delivery for 72 hours, however the maximum
|
# By default Vonage attempt delivery for 72 hours, however the
|
||||||
# effective value depends on the operator and is typically 24 - 48
|
# maximum effective value depends on the operator and is typically
|
||||||
# hours. We recommend this value should be kept at its default or at
|
# 24 - 48 hours. We recommend this value should be kept at its
|
||||||
# least 30 minutes.
|
# default or at least 30 minutes.
|
||||||
"ttl": {
|
"ttl": {
|
||||||
"name": _("ttl"),
|
"name": _("ttl"),
|
||||||
"type": "int",
|
"type": "int",
|
||||||
|
@ -166,13 +168,10 @@ class NotifyVonage(NotifyBase):
|
||||||
|
|
||||||
# Set our Time to Live Flag
|
# Set our Time to Live Flag
|
||||||
self.ttl = self.template_args["ttl"]["default"]
|
self.ttl = self.template_args["ttl"]["default"]
|
||||||
try:
|
with contextlib.suppress(ValueError, TypeError):
|
||||||
|
# update our ttl if we're dealing with an integer
|
||||||
self.ttl = int(ttl)
|
self.ttl = int(ttl)
|
||||||
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
# Do nothing
|
|
||||||
pass
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
self.ttl < self.template_args["ttl"]["min"]
|
self.ttl < self.template_args["ttl"]["min"]
|
||||||
or self.ttl > self.template_args["ttl"]["max"]
|
or self.ttl > self.template_args["ttl"]["max"]
|
||||||
|
|
|
@ -93,7 +93,8 @@ class NotifyWeComBot(NotifyBase):
|
||||||
template_tokens = dict(
|
template_tokens = dict(
|
||||||
NotifyBase.template_tokens,
|
NotifyBase.template_tokens,
|
||||||
**{
|
**{
|
||||||
# The Bot Key can be found at the end of the webhook provided (?key=)
|
# The Bot Key can be found at the end of the webhook provided
|
||||||
|
# (?key=)
|
||||||
"key": {
|
"key": {
|
||||||
"name": _("Bot Webhook Key"),
|
"name": _("Bot Webhook Key"),
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import contextlib
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
from ..common import NotifyImageSize, NotifyType
|
from ..common import NotifyImageSize, NotifyType
|
||||||
|
@ -276,12 +277,9 @@ class NotifyWindows(NotifyBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set duration
|
# Set duration
|
||||||
try:
|
with contextlib.suppress(TypeError, ValueError):
|
||||||
|
# Update our duration if we're dealing with an integer
|
||||||
results["duration"] = int(results["qsd"].get("duration"))
|
results["duration"] = int(results["qsd"].get("duration"))
|
||||||
|
|
||||||
except (TypeError, ValueError):
|
|
||||||
# Not a valid integer; ignore entry
|
|
||||||
pass
|
|
||||||
|
|
||||||
# return results
|
# return results
|
||||||
return results
|
return results
|
||||||
|
|
|
@ -467,13 +467,13 @@ def parse_qsd(qs, simple=False, plus_to_space=False, sanitize=True):
|
||||||
# Our return result set:
|
# Our return result set:
|
||||||
result = (
|
result = (
|
||||||
{
|
{
|
||||||
# The arguments passed in (the parsed query). This is in a dictionary
|
# The arguments passed in (the parsed query). This is in a
|
||||||
# of {'key': 'val', etc }. Keys are all made lowercase before storing
|
# dictionary of {'key': 'val', etc }. Keys are all made lowercase
|
||||||
# to simplify access to them.
|
# before storing to simplify access to them.
|
||||||
"qsd": {},
|
"qsd": {},
|
||||||
# Detected Entries that start with + or - are additionally stored in
|
# Detected Entries that start with + or - are additionally stored
|
||||||
# these values (un-touched). The :,+,- however are stripped from their
|
# in these values (un-touched). The :,+,- however are stripped
|
||||||
# name before they are stored here.
|
# from their name before they are stored here.
|
||||||
"qsd+": {},
|
"qsd+": {},
|
||||||
"qsd-": {},
|
"qsd-": {},
|
||||||
"qsd:": {},
|
"qsd:": {},
|
||||||
|
@ -624,14 +624,14 @@ def parse_url(
|
||||||
"schema": None,
|
"schema": None,
|
||||||
# The schema
|
# The schema
|
||||||
"url": None,
|
"url": None,
|
||||||
# The arguments passed in (the parsed query). This is in a dictionary
|
# The arguments passed in (the parsed query). This is in a
|
||||||
# of {'key': 'val', etc }. Keys are all made lowercase before storing
|
# dictionary of {'key': 'val', etc }. Keys are all made lowercase
|
||||||
# to simplify access to them.
|
# before storing to simplify access to them.
|
||||||
# qsd = Query String Dictionary
|
# qsd = Query String Dictionary
|
||||||
"qsd": {},
|
"qsd": {},
|
||||||
# Detected Entries that start with +, - or : are additionally stored in
|
# Detected Entries that start with +, - or : are additionally
|
||||||
# these values (un-touched). The +, -, and : however are stripped
|
# stored in these values (un-touched). The +, -, and : however
|
||||||
# from their name before they are stored here.
|
# are stripped from their name before they are stored here.
|
||||||
"qsd+": {},
|
"qsd+": {},
|
||||||
"qsd-": {},
|
"qsd-": {},
|
||||||
"qsd:": {},
|
"qsd:": {},
|
||||||
|
|
|
@ -518,8 +518,8 @@ class ApprisePEMController:
|
||||||
if (
|
if (
|
||||||
self.load_public_key(path)
|
self.load_public_key(path)
|
||||||
or
|
or
|
||||||
# Try to see if we can load a private key (which we can generate a
|
# Try to see if we can load a private key (which we ca
|
||||||
# public from)
|
# generate a public from)
|
||||||
self.private_key(*names, autogen=autogen)
|
self.private_key(*names, autogen=autogen)
|
||||||
)
|
)
|
||||||
else None
|
else None
|
||||||
|
|
|
@ -323,11 +323,6 @@ ignore = [
|
||||||
|
|
||||||
# The following needs to be supported at some point and is of great value
|
# The following needs to be supported at some point and is of great value
|
||||||
"RUF012", # typing.ClassVar implimentation
|
"RUF012", # typing.ClassVar implimentation
|
||||||
"E501", # Enforcing wordrap at 79 characters per BSD should be enforced
|
|
||||||
# it broke when ruff-autofixed over 600+ entries to accomodate
|
|
||||||
# other PEP styles.
|
|
||||||
"SIM105", # leverage contextlib.supress() so signifigantly simply the
|
|
||||||
# readability of the code
|
|
||||||
"UP032", # This is a massive undertaking and requires a massive rewrite
|
"UP032", # This is a massive undertaking and requires a massive rewrite
|
||||||
# of test cases; this will take a while to fix, so turning off
|
# of test cases; this will take a while to fix, so turning off
|
||||||
# for now
|
# for now
|
||||||
|
@ -340,6 +335,8 @@ inline-quotes = "double"
|
||||||
known-first-party = ["apprise"]
|
known-first-party = ["apprise"]
|
||||||
force-sort-within-sections = true
|
force-sort-within-sections = true
|
||||||
combine-as-imports = true
|
combine-as-imports = true
|
||||||
|
order-by-type = true
|
||||||
|
section-order = ["future", "standard-library", "third-party", "first-party", "local-folder"]
|
||||||
|
|
||||||
[tool.ruff.lint.flake8-builtins]
|
[tool.ruff.lint.flake8-builtins]
|
||||||
builtins-ignorelist = ["_"]
|
builtins-ignorelist = ["_"]
|
||||||
|
|
|
@ -90,7 +90,8 @@ apprise_url_tests = (
|
||||||
"a" * 5, "b" * 10, "3" * 11
|
"a" * 5, "b" * 10, "3" * 11
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
# included phone, short number (123) and garbage string (abcd) dropped
|
# included phone, short number (123) and garbage string (abcd)
|
||||||
|
# dropped
|
||||||
"instance": NotifyBulkVS,
|
"instance": NotifyBulkVS,
|
||||||
"privacy_url": "bulkvs://a...a:****@9876543210/33333333333",
|
"privacy_url": "bulkvs://a...a:****@9876543210/33333333333",
|
||||||
},
|
},
|
||||||
|
|
|
@ -136,7 +136,8 @@ apprise_url_tests = (
|
||||||
(
|
(
|
||||||
"d7sms://token@{}?batch=yes&source=apprise".format("3" * 14),
|
"d7sms://token@{}?batch=yes&source=apprise".format("3" * 14),
|
||||||
{
|
{
|
||||||
# valid number, utilizing the optional source= variable (same as from)
|
# valid number, utilizing the optional source= variable (same as
|
||||||
|
# from)
|
||||||
"instance": NotifyD7Networks,
|
"instance": NotifyD7Networks,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -900,7 +900,8 @@ def test_plugin_email_smtplib_internationalization(mock_smtp):
|
||||||
# Further test encoding through the message content as well
|
# Further test encoding through the message content as well
|
||||||
assert (
|
assert (
|
||||||
obj.notify(
|
obj.notify(
|
||||||
# Google Translated to Arabic: "Let's make the world a better place."
|
# Google Translated to Arabic:
|
||||||
|
# "Let's make the world a better place."
|
||||||
title="دعونا نجعل العالم مكانا أفضل.",
|
title="دعونا نجعل العالم مكانا أفضل.",
|
||||||
# Google Translated to Hungarian: "One line of code at a time.'
|
# Google Translated to Hungarian: "One line of code at a time.'
|
||||||
body="Egy sor kódot egyszerre.",
|
body="Egy sor kódot egyszerre.",
|
||||||
|
|
|
@ -59,7 +59,8 @@ apprise_url_tests = (
|
||||||
"enigma2://localhost",
|
"enigma2://localhost",
|
||||||
{
|
{
|
||||||
"instance": NotifyEnigma2,
|
"instance": NotifyEnigma2,
|
||||||
# This will fail because we're also expecting a server acknowledgement
|
# This will fail because we're also expecting a server
|
||||||
|
# acknowledgement
|
||||||
"notify_response": False,
|
"notify_response": False,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -81,7 +81,8 @@ apprise_url_tests = (
|
||||||
(
|
(
|
||||||
"httpsms://{}@9876543210/{}/abcd/".format("b" * 10, "3" * 11),
|
"httpsms://{}@9876543210/{}/abcd/".format("b" * 10, "3" * 11),
|
||||||
{
|
{
|
||||||
# included phone, short number (123) and garbage string (abcd) dropped
|
# included phone, short number (123) and garbage string (abcd)
|
||||||
|
# dropped
|
||||||
"instance": NotifyHttpSMS,
|
"instance": NotifyHttpSMS,
|
||||||
"privacy_url": "httpsms://b...b@9876543210/33333333333",
|
"privacy_url": "httpsms://b...b@9876543210/33333333333",
|
||||||
},
|
},
|
||||||
|
|
|
@ -144,8 +144,8 @@ apprise_url_tests = (
|
||||||
"mastodon://access_token@hostname/?key=My%20Idempotency%20Key",
|
"mastodon://access_token@hostname/?key=My%20Idempotency%20Key",
|
||||||
{
|
{
|
||||||
# Prevent duplicate submissions of the same status. Idempotency
|
# Prevent duplicate submissions of the same status. Idempotency
|
||||||
# keys are stored for up to 1 hour, and can be any arbitrary string.
|
# keys are stored for up to 1 hour, and can be any arbitrary
|
||||||
# Consider using a hash or UUID generated client-side.
|
# string. Consider using a hash or UUID generated client-side.
|
||||||
"instance": NotifyMastodon,
|
"instance": NotifyMastodon,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -68,7 +68,8 @@ apprise_url_tests = (
|
||||||
"psafer://{}".format("a" * 20),
|
"psafer://{}".format("a" * 20),
|
||||||
{
|
{
|
||||||
"instance": NotifyPushSafer,
|
"instance": NotifyPushSafer,
|
||||||
# This will fail because we're also expecting a server acknowledgement
|
# This will fail because we're also expecting a server
|
||||||
|
# acknowledgement
|
||||||
"notify_response": False,
|
"notify_response": False,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -95,7 +95,8 @@ apprise_url_tests = (
|
||||||
{
|
{
|
||||||
# Invalid topic specified
|
# Invalid topic specified
|
||||||
"instance": NotifyPushy,
|
"instance": NotifyPushy,
|
||||||
# Expected notify() response False because there is no one to notify
|
# Expected notify() response False because there is no one to
|
||||||
|
# notify
|
||||||
"notify_response": False,
|
"notify_response": False,
|
||||||
"requests_response_text": GOOD_RESPONSE,
|
"requests_response_text": GOOD_RESPONSE,
|
||||||
},
|
},
|
||||||
|
|
|
@ -108,7 +108,8 @@ apprise_url_tests = (
|
||||||
(
|
(
|
||||||
"seven://{}/15551232000?source=apprise".format("3" * 14),
|
"seven://{}/15551232000?source=apprise".format("3" * 14),
|
||||||
{
|
{
|
||||||
# valid number, utilizing the optional source= variable (same as from)
|
# valid number, utilizing the optional source= variable (same as
|
||||||
|
# from)
|
||||||
"instance": NotifySeven,
|
"instance": NotifySeven,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -122,14 +123,16 @@ apprise_url_tests = (
|
||||||
(
|
(
|
||||||
"seven://{}/15551232000?source=apprise&flash=true".format("3" * 14),
|
"seven://{}/15551232000?source=apprise&flash=true".format("3" * 14),
|
||||||
{
|
{
|
||||||
# valid number, utilizing the optional source= variable (same as from)
|
# valid number, utilizing the optional source= variable (same as
|
||||||
|
# from)
|
||||||
"instance": NotifySeven,
|
"instance": NotifySeven,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"seven://{}/15551232000?source=AR&flash=1&label=123".format("3" * 14),
|
"seven://{}/15551232000?source=AR&flash=1&label=123".format("3" * 14),
|
||||||
{
|
{
|
||||||
# valid number, utilizing the optional source= variable (same as from)
|
# valid number, utilizing the optional source= variable (same as
|
||||||
|
# from)
|
||||||
"instance": NotifySeven,
|
"instance": NotifySeven,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -157,21 +157,24 @@ apprise_url_tests = (
|
||||||
"1" * 11, "2" * 11, "3" * 11
|
"1" * 11, "2" * 11, "3" * 11
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
# If we have from= specified, then all elements take on the to= value
|
# If we have from= specified, then all elements take on the to=
|
||||||
|
# value
|
||||||
"instance": NotifySignalAPI,
|
"instance": NotifySignalAPI,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"signals://user@localhost/{}/{}".format("1" * 11, "3" * 11),
|
"signals://user@localhost/{}/{}".format("1" * 11, "3" * 11),
|
||||||
{
|
{
|
||||||
# use get args to acomplish the same thing (use source instead of from)
|
# use get args to acomplish the same thing (use source instead of
|
||||||
|
# from)
|
||||||
"instance": NotifySignalAPI,
|
"instance": NotifySignalAPI,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"signals://user:password@localhost/{}/{}".format("1" * 11, "3" * 11),
|
"signals://user:password@localhost/{}/{}".format("1" * 11, "3" * 11),
|
||||||
{
|
{
|
||||||
# use get args to acomplish the same thing (use source instead of from)
|
# use get args to acomplish the same thing (use source instead of
|
||||||
|
# from)
|
||||||
"instance": NotifySignalAPI,
|
"instance": NotifySignalAPI,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -147,7 +147,8 @@ apprise_url_tests = (
|
||||||
"a" * 32, "b" * 32, "5" * 11
|
"a" * 32, "b" * 32, "5" * 11
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
# use get args to acomplish the same thing (use source instead of from)
|
# use get args to acomplish the same thing (use source instead of
|
||||||
|
# from)
|
||||||
"instance": NotifySinch,
|
"instance": NotifySinch,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -77,7 +77,8 @@ apprise_url_tests = (
|
||||||
"slack://T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#hmm/#-invalid-",
|
"slack://T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#hmm/#-invalid-",
|
||||||
{
|
{
|
||||||
# No username specified; this is still okay as we sub in
|
# No username specified; this is still okay as we sub in
|
||||||
# default; The one invalid channel is skipped when sending a message
|
# default; The one invalid channel is skipped when sending a
|
||||||
|
# message
|
||||||
"instance": NotifySlack,
|
"instance": NotifySlack,
|
||||||
# There is an invalid channel that we will fail to deliver to
|
# There is an invalid channel that we will fail to deliver to
|
||||||
# as a result the response type will be false
|
# as a result the response type will be false
|
||||||
|
@ -92,7 +93,8 @@ apprise_url_tests = (
|
||||||
"slack://T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#channel",
|
"slack://T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#channel",
|
||||||
{
|
{
|
||||||
# No username specified; this is still okay as we sub in
|
# No username specified; this is still okay as we sub in
|
||||||
# default; The one invalid channel is skipped when sending a message
|
# default; The one invalid channel is skipped when sending a
|
||||||
|
# message
|
||||||
"instance": NotifySlack,
|
"instance": NotifySlack,
|
||||||
# don't include an image by default
|
# don't include an image by default
|
||||||
"include_image": False,
|
"include_image": False,
|
||||||
|
@ -121,7 +123,8 @@ apprise_url_tests = (
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"slack://username@T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#nuxref",
|
("slack://username@T1JJ3T3L2/A1BRTD4JD/"
|
||||||
|
"TIiajkdnlazkcOXrIdevi7FQ/#nuxref"),
|
||||||
{
|
{
|
||||||
"instance": NotifySlack,
|
"instance": NotifySlack,
|
||||||
"requests_response_text": "ok",
|
"requests_response_text": "ok",
|
||||||
|
@ -147,7 +150,8 @@ apprise_url_tests = (
|
||||||
),
|
),
|
||||||
# Specify Token and channels on argument string (no username)
|
# Specify Token and channels on argument string (no username)
|
||||||
(
|
(
|
||||||
"slack://?token=T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/&to=#chan",
|
("slack://?token=T1JJ3T3L2/A1BRTD4JD"
|
||||||
|
"/TIiajkdnlazkcOXrIdevi7FQ/&to=#chan"),
|
||||||
{
|
{
|
||||||
"instance": NotifySlack,
|
"instance": NotifySlack,
|
||||||
"requests_response_text": "ok",
|
"requests_response_text": "ok",
|
||||||
|
@ -155,7 +159,8 @@ apprise_url_tests = (
|
||||||
),
|
),
|
||||||
# Test webhook that doesn't have a proper response
|
# Test webhook that doesn't have a proper response
|
||||||
(
|
(
|
||||||
"slack://username@T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#nuxref",
|
("slack://username@T1JJ3T3L2/A1BRTD4JD/"
|
||||||
|
"TIiajkdnlazkcOXrIdevi7FQ/#nuxref"),
|
||||||
{
|
{
|
||||||
"instance": NotifySlack,
|
"instance": NotifySlack,
|
||||||
"requests_response_text": "fail",
|
"requests_response_text": "fail",
|
||||||
|
@ -244,8 +249,8 @@ apprise_url_tests = (
|
||||||
"ok": True,
|
"ok": True,
|
||||||
"message": "",
|
"message": "",
|
||||||
},
|
},
|
||||||
# we'll fail to send attachments because we had no 'file' response in
|
# we'll fail to send attachments because we had no 'file' response
|
||||||
# our object
|
# in our object
|
||||||
"response": False,
|
"response": False,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -270,7 +270,8 @@ apprise_url_tests = (
|
||||||
(
|
(
|
||||||
"smseagle://token@localhost:8088/{}/{}/".format("2" * 11, "3" * 11),
|
"smseagle://token@localhost:8088/{}/{}/".format("2" * 11, "3" * 11),
|
||||||
{
|
{
|
||||||
# If we have from= specified, then all elements take on the to= value
|
# If we have from= specified, then all elements take on the
|
||||||
|
# to= value
|
||||||
"instance": NotifySMSEagle,
|
"instance": NotifySMSEagle,
|
||||||
# Our response expected server response
|
# Our response expected server response
|
||||||
"requests_response_text": SMSEAGLE_GOOD_RESPONSE,
|
"requests_response_text": SMSEAGLE_GOOD_RESPONSE,
|
||||||
|
@ -279,7 +280,8 @@ apprise_url_tests = (
|
||||||
(
|
(
|
||||||
"smseagles://token@localhost/{}".format("3" * 11),
|
"smseagles://token@localhost/{}".format("3" * 11),
|
||||||
{
|
{
|
||||||
# use get args to acomplish the same thing (use source instead of from)
|
# use get args to acomplish the same thing (use source instead of
|
||||||
|
# from)
|
||||||
"instance": NotifySMSEagle,
|
"instance": NotifySMSEagle,
|
||||||
# Our response expected server response
|
# Our response expected server response
|
||||||
"requests_response_text": SMSEAGLE_GOOD_RESPONSE,
|
"requests_response_text": SMSEAGLE_GOOD_RESPONSE,
|
||||||
|
|
|
@ -165,7 +165,8 @@ apprise_url_tests = (
|
||||||
"a" * 32, "b" * 32, "5" * 11
|
"a" * 32, "b" * 32, "5" * 11
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
# use get args to acomplish the same thing (use source instead of from)
|
# use get args to acomplish the same thing (use source instead of
|
||||||
|
# from)
|
||||||
"instance": NotifyTwilio,
|
"instance": NotifyTwilio,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -258,7 +259,8 @@ def test_plugin_twilio_auth(mock_post):
|
||||||
assert (
|
assert (
|
||||||
first_call[0][0]
|
first_call[0][0]
|
||||||
== second_call[0][0]
|
== second_call[0][0]
|
||||||
== f"https://api.twilio.com/2010-04-01/Accounts/{account_sid}/Messages.json"
|
== ("https://api.twilio.com/2010-04-01/Accounts"
|
||||||
|
f"/{account_sid}/Messages.json")
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
first_call[1]["data"]["Body"]
|
first_call[1]["data"]["Body"]
|
||||||
|
|
|
@ -80,8 +80,8 @@ apprise_url_tests = (
|
||||||
(
|
(
|
||||||
"vapid://user@example.com",
|
"vapid://user@example.com",
|
||||||
{
|
{
|
||||||
# bare bone requirements met, but we don't have our subscription file
|
# bare bone requirements met, but we don't have our subscription
|
||||||
# or our private key (pem)
|
# file or our private key (pem)
|
||||||
"instance": NotifyVapid,
|
"instance": NotifyVapid,
|
||||||
# We'll fail to respond because we would not have found any
|
# We'll fail to respond because we would not have found any
|
||||||
# configuration to load
|
# configuration to load
|
||||||
|
|
|
@ -116,7 +116,8 @@ apprise_url_tests = (
|
||||||
"a" * 8, "b" * 16, "5" * 11
|
"a" * 8, "b" * 16, "5" * 11
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
# use get args to acomplish the same thing (use source instead of from)
|
# use get args to acomplish the same thing (use source instead
|
||||||
|
# of from)
|
||||||
"instance": NotifyVonage,
|
"instance": NotifyVonage,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -223,7 +224,8 @@ apprise_url_tests = (
|
||||||
"a" * 8, "b" * 16, "5" * 11
|
"a" * 8, "b" * 16, "5" * 11
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
# use get args to acomplish the same thing (use source instead of from)
|
# use get args to acomplish the same thing (use source instead of
|
||||||
|
# from)
|
||||||
"instance": NotifyVonage,
|
"instance": NotifyVonage,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -157,7 +157,8 @@ apprise_url_tests = (
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
# template with kwarg assignments
|
# template with kwarg assignments
|
||||||
# Invalid keyword specified; cna only be a digit OR `body' or 'type'
|
# Invalid keyword specified; cna only be a digit OR `body'
|
||||||
|
# or 'type'
|
||||||
"instance": TypeError,
|
"instance": TypeError,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -200,7 +201,8 @@ apprise_url_tests = (
|
||||||
"d" * 32, "5" * 11, "6" * 11
|
"d" * 32, "5" * 11, "6" * 11
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
# use get args to acomplish the same thing (use source instead of from)
|
# use get args to acomplish the same thing (use source instead
|
||||||
|
# of from)
|
||||||
"instance": NotifyWhatsApp,
|
"instance": NotifyWhatsApp,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -218,7 +218,8 @@ apprise_url_tests = (
|
||||||
(
|
(
|
||||||
"wxpusher://AT_appid/{}/{}/".format("2" * 11, "3" * 11),
|
"wxpusher://AT_appid/{}/{}/".format("2" * 11, "3" * 11),
|
||||||
{
|
{
|
||||||
# If we have from= specified, then all elements take on the to= value
|
# If we have from= specified, then all elements take on the
|
||||||
|
# to= value
|
||||||
"instance": NotifyWxPusher,
|
"instance": NotifyWxPusher,
|
||||||
# Our response expected server response
|
# Our response expected server response
|
||||||
"requests_response_text": WXPUSHER_GOOD_RESPONSE,
|
"requests_response_text": WXPUSHER_GOOD_RESPONSE,
|
||||||
|
@ -227,7 +228,8 @@ apprise_url_tests = (
|
||||||
(
|
(
|
||||||
"wxpusher://AT_appid/{}".format("3" * 11),
|
"wxpusher://AT_appid/{}".format("3" * 11),
|
||||||
{
|
{
|
||||||
# use get args to acomplish the same thing (use source instead of from)
|
# use get args to acomplish the same thing (use source instead
|
||||||
|
# of from)
|
||||||
"instance": NotifyWxPusher,
|
"instance": NotifyWxPusher,
|
||||||
# Our response expected server response
|
# Our response expected server response
|
||||||
"requests_response_text": WXPUSHER_GOOD_RESPONSE,
|
"requests_response_text": WXPUSHER_GOOD_RESPONSE,
|
||||||
|
|
Loading…
Reference in New Issue