diff --git a/apprise/attachment/http.py b/apprise/attachment/http.py index a97a8fd4..3de8fbfa 100644 --- a/apprise/attachment/http.py +++ b/apprise/attachment/http.py @@ -25,6 +25,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +import contextlib import os import re from tempfile import NamedTemporaryFile @@ -286,13 +287,10 @@ class AttachHTTP(AttachBase): self.logger.trace("Attachment cleanup of %s", self._temp_file.name) self._temp_file.close() - try: + with contextlib.suppress(OSError): # Ensure our file is removed (if it exists) os.unlink(self._temp_file.name) - except OSError: - pass - # Reset our temporary file to prevent from entering # this block again self._temp_file = None diff --git a/apprise/logger.py b/apprise/logger.py index 0e5605f6..ac8a51be 100644 --- a/apprise/logger.py +++ b/apprise/logger.py @@ -25,6 +25,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +import contextlib from io import StringIO import logging import os @@ -186,12 +187,8 @@ class LogCapture: self.__buffer_ptr.close() self.__handler.close() if self.__delete: - try: + with contextlib.suppress(OSError): # Always remove file afterwards os.unlink(self.__path) - except OSError: - # It's okay if the file does not exist - pass - return exc_type is None diff --git a/apprise/persistent_store.py b/apprise/persistent_store.py index ee484952..cb72181c 100644 --- a/apprise/persistent_store.py +++ b/apprise/persistent_store.py @@ -23,6 +23,7 @@ # THE SOFTWARE. import base64 import binascii +import contextlib from datetime import datetime, timedelta, timezone import glob import gzip @@ -52,13 +53,9 @@ def _ntf_tidy(ntf): """Reusable NamedTemporaryFile cleanup.""" if ntf: # Cleanup - try: + with contextlib.suppress(OSError): ntf.close() - except OSError: - # Already closed - pass - try: os.unlink(ntf.name) logger.trace("Persistent temporary file removed: %s", ntf.name) diff --git a/apprise/plugins/aprs.py b/apprise/plugins/aprs.py index b4abe007..44d8b93b 100644 --- a/apprise/plugins/aprs.py +++ b/apprise/plugins/aprs.py @@ -66,6 +66,7 @@ # http://www.aprs.org/doc/APRS101.PDF # +import contextlib from itertools import chain import re import socket @@ -321,13 +322,8 @@ class NotifyAprs(NotifyBase): def socket_close(self): """Closes the socket connection whereas present.""" if self.sock: - try: + with contextlib.suppress(Exception): self.sock.close() - - except Exception: - # No worries if socket exception thrown on close() - pass - self.sock = None def socket_open(self): diff --git a/apprise/plugins/base.py b/apprise/plugins/base.py index 8cf5feb4..c60d515d 100644 --- a/apprise/plugins/base.py +++ b/apprise/plugins/base.py @@ -187,10 +187,11 @@ class NotifyBase(URLBase): "default": overflow_mode, # look up default using the following parent class value at # runtime. The variable name identified here (in this case - # overflow_mode) is checked and it's result is placed over-top of - # the 'default'. This is done because once a parent class inherits - # this one, the overflow_mode already set as a default 'could' be - # potentially over-ridden and changed to a different value. + # overflow_mode) is checked and it's result is placed over-top + # of the 'default'. This is done because once a parent class + # inherits this one, the overflow_mode already set as a default + # 'could' be potentially over-ridden and changed to a different + # value. "_lookup_default": "overflow_mode", }, "format": { diff --git a/apprise/plugins/d7networks.py b/apprise/plugins/d7networks.py index 528c46dd..89bf9ce2 100644 --- a/apprise/plugins/d7networks.py +++ b/apprise/plugins/d7networks.py @@ -133,10 +133,11 @@ class NotifyD7Networks(NotifyBase): "alias_of": "targets", }, "source": { - # Originating address,In cases where the rewriting of the sender's - # address is supported or permitted by the SMS-C. This is used to - # transmit the message, this number is transmitted as the - # originating address and is completely optional. + # Originating address,In cases where the rewriting of the + # sender's address is supported or permitted by the SMS-C. + # This is used to transmit the message, this number is + # transmitted as the originating address and is completely + # optional. "name": _("Originating Address"), "type": "string", "map_to": "source", diff --git a/apprise/plugins/gnome.py b/apprise/plugins/gnome.py index 0ae8befc..bcf8043c 100644 --- a/apprise/plugins/gnome.py +++ b/apprise/plugins/gnome.py @@ -144,9 +144,9 @@ class NotifyGnome(NotifyBase): "default": GnomeUrgency.NORMAL, }, "priority": { - # Apprise uses 'priority' everywhere; it's just a nice consistent - # feel to be able to use it here as well. Just map the - # value back to 'priority' + # Apprise uses 'priority' everywhere; it's just a nice + # consistent feel to be able to use it here as well. Just map + # the value back to 'priority' "alias_of": "urgency", }, "image": { diff --git a/apprise/plugins/gotify.py b/apprise/plugins/gotify.py index 702f26c0..9c53d43e 100644 --- a/apprise/plugins/gotify.py +++ b/apprise/plugins/gotify.py @@ -27,7 +27,7 @@ # Gotify Docker configuration: https://hub.docker.com/r/gotify/server # Example: https://github.com/gotify/server/blob/\ -# f2c2688f0b5e6a816bbcec768ca1c0de5af76b88/ADD_MESSAGE_EXAMPLES.md#python +# f2c2688f0b5e6a816bbcec768ca1c0de5af76b88/ADD_MESSAGE_EXAMPLES.md#python # API: https://gotify.net/docs/swagger-docs from json import dumps diff --git a/apprise/plugins/lametric.py b/apprise/plugins/lametric.py index ec46debf..34cc8e71 100644 --- a/apprise/plugins/lametric.py +++ b/apprise/plugins/lametric.py @@ -86,6 +86,7 @@ # - https://developer.lametric.com/icons +import contextlib from json import dumps import re @@ -1103,13 +1104,9 @@ class NotifyLametric(NotifyBase): ) # Set cycles - try: + with contextlib.suppress(TypeError, ValueError): results["cycles"] = abs(int(results["qsd"].get("cycles"))) - except (TypeError, ValueError): - # Not a valid integer; ignore entry - pass - return results @staticmethod diff --git a/apprise/plugins/lark.py b/apprise/plugins/lark.py index 9c025fbd..74131840 100644 --- a/apprise/plugins/lark.py +++ b/apprise/plugins/lark.py @@ -96,7 +96,9 @@ class NotifyLark(NotifyBase): """Returns the URL built dynamically based on specified arguments.""" params = self.url_parameters(privacy=privacy, *args, **kwargs) 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): diff --git a/apprise/plugins/mastodon.py b/apprise/plugins/mastodon.py index ba52e4a3..f825dd50 100644 --- a/apprise/plugins/mastodon.py +++ b/apprise/plugins/mastodon.py @@ -25,6 +25,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +import contextlib from copy import deepcopy from datetime import datetime, timezone from json import dumps, loads @@ -828,13 +829,10 @@ class NotifyMastodon(NotifyBase): # 'emojis': [], # 'fields': [] # } - try: + with contextlib.suppress(TypeError, KeyError): # Cache our response for future references self._whoami_cache = {response["username"]: response["id"]} - except (TypeError, KeyError): - pass - elif response and "authorized scopes" in response.get("error", ""): self.logger.warning( "Failed to lookup Mastodon Auth details; " diff --git a/apprise/plugins/nextcloud.py b/apprise/plugins/nextcloud.py index 7b82008f..4e4e5868 100644 --- a/apprise/plugins/nextcloud.py +++ b/apprise/plugins/nextcloud.py @@ -108,8 +108,8 @@ class NotifyNextcloud(NotifyBase): NotifyBase.template_args, **{ # Nextcloud uses different API end points depending on the version - # being used however the (API) payload remains the same. Allow users - # to specify the version they are using: + # being used however the (API) payload remains the same. Allow + # users to specify the version they are using: "version": { "name": _("Version"), "type": "int", diff --git a/apprise/plugins/one_signal.py b/apprise/plugins/one_signal.py index 587e44d7..dd72ced7 100644 --- a/apprise/plugins/one_signal.py +++ b/apprise/plugins/one_signal.py @@ -454,7 +454,8 @@ class NotifyOneSignal(NotifyBase): self.logger.debug( "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}") diff --git a/apprise/plugins/pagerduty.py b/apprise/plugins/pagerduty.py index f9beb3ff..04529252 100644 --- a/apprise/plugins/pagerduty.py +++ b/apprise/plugins/pagerduty.py @@ -179,8 +179,8 @@ class NotifyPagerDuty(NotifyBase): "default": PagerDutyRegion.US, "map_to": "region_name", }, - # The severity is automatically determined, however you can optionally - # over-ride its value and force it to be what you want + # The severity is automatically determined, however you can + # optionally over-ride its value and force it to be what you want "severity": { "name": _("Severity"), "type": "choice:string", @@ -276,8 +276,9 @@ class NotifyPagerDuty(NotifyBase): if self.region_name not in PAGERDUTY_REGIONS: # allow the outer except to handle this common response - raise - except: + raise IndexError() + + except (AttributeError, IndexError, TypeError): # Invalid region specified msg = f"The PagerDuty region specified ({region_name}) is invalid." self.logger.warning(msg) diff --git a/apprise/plugins/popcorn_notify.py b/apprise/plugins/popcorn_notify.py index 1a6e55fb..dd8a19db 100644 --- a/apprise/plugins/popcorn_notify.py +++ b/apprise/plugins/popcorn_notify.py @@ -240,8 +240,8 @@ class NotifyPopcornNotify(NotifyBase): except requests.RequestException as e: self.logger.warning( "A Connection error occured sending" - f" {len(self.targets[index:index + batch_size])} PopcornNotify" - " notification(s)." + f" {len(self.targets[index:index + batch_size])} " + "PopcornNotify notification(s)." ) self.logger.debug(f"Socket Exception: {e!s}") diff --git a/apprise/plugins/pushover.py b/apprise/plugins/pushover.py index 86659832..97b0a2e0 100644 --- a/apprise/plugins/pushover.py +++ b/apprise/plugins/pushover.py @@ -25,6 +25,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +import contextlib from itertools import chain import re @@ -339,19 +340,15 @@ class NotifyPushover(NotifyBase): # How often to resend notification, in seconds self.retry = self.template_args["retry"]["default"] - try: + with contextlib.suppress(ValueError, TypeError): + # Get our retry value self.retry = int(retry) - except (ValueError, TypeError): - # Do nothing - pass # How often to resend notification, in seconds self.expire = self.template_args["expire"]["default"] - try: + with contextlib.suppress(ValueError, TypeError): + # Acquire our expiry value self.expire = int(expire) - except (ValueError, TypeError): - # Do nothing - pass if self.retry < 30: msg = "Pushover retry must be at least 30 seconds." diff --git a/apprise/plugins/pushplus.py b/apprise/plugins/pushplus.py index 1e42e6e4..c1b7c8c8 100644 --- a/apprise/plugins/pushplus.py +++ b/apprise/plugins/pushplus.py @@ -90,7 +90,9 @@ class NotifyPushplus(NotifyBase): """Returns the URL built dynamically based on specified arguments.""" params = self.url_parameters(privacy=privacy, *args, **kwargs) 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 diff --git a/apprise/plugins/qq.py b/apprise/plugins/qq.py index 09da2846..c16baa83 100644 --- a/apprise/plugins/qq.py +++ b/apprise/plugins/qq.py @@ -94,7 +94,9 @@ class NotifyQQ(NotifyBase): """Returns the URL built dynamically based on specified arguments.""" params = self.url_parameters(privacy=privacy, *args, **kwargs) 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 diff --git a/apprise/plugins/ses.py b/apprise/plugins/ses.py index a375bdf8..01b53092 100644 --- a/apprise/plugins/ses.py +++ b/apprise/plugins/ses.py @@ -692,7 +692,8 @@ class NotifySES(NotifyBase): # Our Authorization header 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( signed_headers=";".join(signed_headers.keys()), diff --git a/apprise/plugins/seven.py b/apprise/plugins/seven.py index f90fa86e..dfd8679d 100644 --- a/apprise/plugins/seven.py +++ b/apprise/plugins/seven.py @@ -99,10 +99,11 @@ class NotifySeven(NotifyBase): "alias_of": "targets", }, "source": { - # Originating address,In cases where the rewriting of the sender's - # address is supported or permitted by the SMS-C. This is used to - # transmit the message, this number is transmitted as the - # originating address and is completely optional. + # Originating address,In cases where the rewriting of the + # sender's address is supported or permitted by the SMS-C. + # This is used to transmit the message, this number is + # transmitted as the originating address and is completely + # optional. "name": _("Originating Address"), "type": "string", "map_to": "source", diff --git a/apprise/plugins/slack.py b/apprise/plugins/slack.py index 347991b4..79c7ee4a 100644 --- a/apprise/plugins/slack.py +++ b/apprise/plugins/slack.py @@ -71,6 +71,7 @@ # - You will be able to select the Bot App you previously created # - Your bot will join your channel. +import contextlib from json import dumps, loads import re from time import time @@ -815,14 +816,13 @@ class NotifySlack(NotifyBase): ) # Attachment posts return a JSON string - try: - response = loads(r.content) + with contextlib.suppress(AttributeError, TypeError, ValueError): + # Load our JSON object if we can - except (AttributeError, TypeError, ValueError): # ValueError = r.content is Unparsable # TypeError = r.content is None # AttributeError = r is None - pass + response = loads(r.content) # We can get a 200 response, but still fail. A failure message # might look like this (missing bot permissions): @@ -980,14 +980,12 @@ class NotifySlack(NotifyBase): ) # Posts return a JSON string - try: - response = loads(r.content) - - except (AttributeError, TypeError, ValueError): + with contextlib.suppress(AttributeError, TypeError, ValueError): + # Load our JSON object if we can # ValueError = r.content is Unparsable # TypeError = r.content is None # AttributeError = r is None - pass + response = loads(r.content) # Another response type is: # { diff --git a/apprise/plugins/sns.py b/apprise/plugins/sns.py index 052def63..3d82e76a 100644 --- a/apprise/plugins/sns.py +++ b/apprise/plugins/sns.py @@ -419,7 +419,8 @@ class NotifySNS(NotifyBase): ("content-type", headers["Content-Type"]), ( "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"]), ]) @@ -455,7 +456,8 @@ class NotifySNS(NotifyBase): # Our Authorization header 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( signed_headers=";".join(signed_headers.keys()), diff --git a/apprise/plugins/sparkpost.py b/apprise/plugins/sparkpost.py index 13c2d7bd..bc1b7dcd 100644 --- a/apprise/plugins/sparkpost.py +++ b/apprise/plugins/sparkpost.py @@ -53,6 +53,7 @@ # # API Documentation: https://developers.sparkpost.com/api/ # Specifically: https://developers.sparkpost.com/api/transmissions/ +import contextlib from email.utils import formataddr from json import dumps, loads @@ -273,8 +274,9 @@ class NotifySparkPost(NotifyBase): if self.region_name not in SPARKPOST_REGIONS: # allow the outer except to handle this common response - raise - except: + raise IndexError() + + except (AttributeError, IndexError, TypeError): # Invalid region specified msg = f"The SparkPost region specified ({region_name}) is invalid." self.logger.warning(msg) @@ -448,18 +450,13 @@ class NotifySparkPost(NotifyBase): # ] # } # - try: - # Update our status response if we can - json_response = loads(r.content) - - except (AttributeError, TypeError, ValueError): + with contextlib.suppress( + AttributeError, TypeError, ValueError): + # Load our JSON Object if we can # ValueError = r.content is Unparsable # TypeError = r.content is None # AttributeError = r is None - - # We could not parse JSON response. - # We will just use the status we already have. - pass + json_response = loads(r.content) status_code = r.status_code diff --git a/apprise/plugins/spike.py b/apprise/plugins/spike.py index 7f5a851d..4dfedd58 100644 --- a/apprise/plugins/spike.py +++ b/apprise/plugins/spike.py @@ -101,7 +101,9 @@ class NotifySpike(NotifyBase): """Returns the URL built dynamically based on specified arguments.""" params = self.url_parameters(privacy=privacy, *args, **kwargs) 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): diff --git a/apprise/plugins/spugpush.py b/apprise/plugins/spugpush.py index 18d1e302..6641ee90 100644 --- a/apprise/plugins/spugpush.py +++ b/apprise/plugins/spugpush.py @@ -92,7 +92,9 @@ class NotifySpugpush(NotifyBase): """Returns the URL built dynamically based on specified arguments.""" params = self.url_parameters(privacy=privacy, *args, **kwargs) 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 diff --git a/apprise/plugins/vapid/__init__.py b/apprise/plugins/vapid/__init__.py index 2d1f5669..633aace3 100644 --- a/apprise/plugins/vapid/__init__.py +++ b/apprise/plugins/vapid/__init__.py @@ -25,6 +25,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +import contextlib from itertools import chain from json import dumps import os @@ -172,7 +173,8 @@ class NotifyVapid(NotifyBase): "map_to": "mode", }, # 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": { "name": _("ttl"), "type": "int", @@ -241,13 +243,10 @@ class NotifyVapid(NotifyBase): # Set our Time to Live Flag self.ttl = self.template_args["ttl"]["default"] 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) - except (ValueError, TypeError): - # Do nothing - pass - if ( self.ttl < self.template_args["ttl"]["min"] or self.ttl > self.template_args["ttl"]["max"] @@ -280,8 +279,9 @@ class NotifyVapid(NotifyBase): if self.mode not in VAPID_PUSH_MODES: # allow the outer except to handle this common response - raise - except: + raise IndexError() + + except (AttributeError, IndexError, TypeError): # Invalid region specified msg = f"The Vapid mode specified ({mode}) is invalid." self.logger.warning(msg) diff --git a/apprise/plugins/voipms.py b/apprise/plugins/voipms.py index 618ebf53..7f640ab7 100644 --- a/apprise/plugins/voipms.py +++ b/apprise/plugins/voipms.py @@ -33,6 +33,7 @@ # Read more about VoIP.ms API here: # - https://voip.ms/m/apidocs.php +import contextlib from json import loads import requests @@ -250,14 +251,13 @@ class NotifyVoipms(NotifyBase): timeout=self.request_timeout, ) - try: - response = loads(r.content) - - except (AttributeError, TypeError, ValueError): + with contextlib.suppress( + AttributeError, TypeError, ValueError): + # Load our JSON object if valid # ValueError = r.content is Unparsable # TypeError = r.content is None # AttributeError = r is None - pass + response = loads(r.content) if r.status_code != requests.codes.ok: # We had a problem diff --git a/apprise/plugins/vonage.py b/apprise/plugins/vonage.py index 726e564d..fded2f96 100644 --- a/apprise/plugins/vonage.py +++ b/apprise/plugins/vonage.py @@ -30,6 +30,8 @@ # Get your (api) key and secret here: # - https://dashboard.nexmo.com/getting-started-guide # +import contextlib + import requests from ..common import NotifyType @@ -126,10 +128,10 @@ class NotifyVonage(NotifyBase): "alias_of": "secret", }, # Default Time To Live - # By default Vonage attempt delivery for 72 hours, however the maximum - # effective value depends on the operator and is typically 24 - 48 - # hours. We recommend this value should be kept at its default or at - # least 30 minutes. + # By default Vonage attempt delivery for 72 hours, however the + # maximum effective value depends on the operator and is typically + # 24 - 48 hours. We recommend this value should be kept at its + # default or at least 30 minutes. "ttl": { "name": _("ttl"), "type": "int", @@ -166,13 +168,10 @@ class NotifyVonage(NotifyBase): # Set our Time to Live Flag 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) - except (ValueError, TypeError): - # Do nothing - pass - if ( self.ttl < self.template_args["ttl"]["min"] or self.ttl > self.template_args["ttl"]["max"] diff --git a/apprise/plugins/wecombot.py b/apprise/plugins/wecombot.py index 7ac45419..a23aebd7 100644 --- a/apprise/plugins/wecombot.py +++ b/apprise/plugins/wecombot.py @@ -93,7 +93,8 @@ class NotifyWeComBot(NotifyBase): template_tokens = dict( 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": { "name": _("Bot Webhook Key"), "type": "string", diff --git a/apprise/plugins/windows.py b/apprise/plugins/windows.py index 644e883c..474e79e5 100644 --- a/apprise/plugins/windows.py +++ b/apprise/plugins/windows.py @@ -25,6 +25,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +import contextlib from time import sleep from ..common import NotifyImageSize, NotifyType @@ -276,12 +277,9 @@ class NotifyWindows(NotifyBase): ) # 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")) - except (TypeError, ValueError): - # Not a valid integer; ignore entry - pass - # return results return results diff --git a/apprise/utils/parse.py b/apprise/utils/parse.py index 0a673490..c751be1f 100644 --- a/apprise/utils/parse.py +++ b/apprise/utils/parse.py @@ -467,13 +467,13 @@ def parse_qsd(qs, simple=False, plus_to_space=False, sanitize=True): # Our return result set: result = ( { - # The arguments passed in (the parsed query). This is in a dictionary - # of {'key': 'val', etc }. Keys are all made lowercase before storing - # to simplify access to them. + # The arguments passed in (the parsed query). This is in a + # dictionary of {'key': 'val', etc }. Keys are all made lowercase + # before storing to simplify access to them. "qsd": {}, - # Detected Entries that start with + or - are additionally stored in - # these values (un-touched). The :,+,- however are stripped from their - # name before they are stored here. + # Detected Entries that start with + or - are additionally stored + # in these values (un-touched). The :,+,- however are stripped + # from their name before they are stored here. "qsd+": {}, "qsd-": {}, "qsd:": {}, @@ -624,14 +624,14 @@ def parse_url( "schema": None, # The schema "url": None, - # The arguments passed in (the parsed query). This is in a dictionary - # of {'key': 'val', etc }. Keys are all made lowercase before storing - # to simplify access to them. + # The arguments passed in (the parsed query). This is in a + # dictionary of {'key': 'val', etc }. Keys are all made lowercase + # before storing to simplify access to them. # qsd = Query String Dictionary "qsd": {}, - # Detected Entries that start with +, - or : are additionally stored in - # these values (un-touched). The +, -, and : however are stripped - # from their name before they are stored here. + # Detected Entries that start with +, - or : are additionally + # stored in these values (un-touched). The +, -, and : however + # are stripped from their name before they are stored here. "qsd+": {}, "qsd-": {}, "qsd:": {}, diff --git a/apprise/utils/pem.py b/apprise/utils/pem.py index e1752867..ae03d638 100644 --- a/apprise/utils/pem.py +++ b/apprise/utils/pem.py @@ -518,8 +518,8 @@ class ApprisePEMController: if ( self.load_public_key(path) or - # Try to see if we can load a private key (which we can generate a - # public from) + # Try to see if we can load a private key (which we ca + # generate a public from) self.private_key(*names, autogen=autogen) ) else None diff --git a/pyproject.toml b/pyproject.toml index 0d402b51..0d72673a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -323,11 +323,6 @@ ignore = [ # The following needs to be supported at some point and is of great value "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 # of test cases; this will take a while to fix, so turning off # for now @@ -340,6 +335,8 @@ inline-quotes = "double" known-first-party = ["apprise"] force-sort-within-sections = 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] builtins-ignorelist = ["_"] diff --git a/tests/test_plugin_bulkvs.py b/tests/test_plugin_bulkvs.py index ad739bfd..516eb000 100644 --- a/tests/test_plugin_bulkvs.py +++ b/tests/test_plugin_bulkvs.py @@ -90,7 +90,8 @@ apprise_url_tests = ( "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, "privacy_url": "bulkvs://a...a:****@9876543210/33333333333", }, diff --git a/tests/test_plugin_d7networks.py b/tests/test_plugin_d7networks.py index f62041db..f9268ea3 100644 --- a/tests/test_plugin_d7networks.py +++ b/tests/test_plugin_d7networks.py @@ -136,7 +136,8 @@ apprise_url_tests = ( ( "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, }, ), diff --git a/tests/test_plugin_email.py b/tests/test_plugin_email.py index 2f2dcb8e..c44d00cd 100644 --- a/tests/test_plugin_email.py +++ b/tests/test_plugin_email.py @@ -900,7 +900,8 @@ def test_plugin_email_smtplib_internationalization(mock_smtp): # Further test encoding through the message content as well assert ( 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="دعونا نجعل العالم مكانا أفضل.", # Google Translated to Hungarian: "One line of code at a time.' body="Egy sor kódot egyszerre.", diff --git a/tests/test_plugin_enigma2.py b/tests/test_plugin_enigma2.py index 096a89d3..a46403c5 100644 --- a/tests/test_plugin_enigma2.py +++ b/tests/test_plugin_enigma2.py @@ -59,7 +59,8 @@ apprise_url_tests = ( "enigma2://localhost", { "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, }, ), diff --git a/tests/test_plugin_httpsms.py b/tests/test_plugin_httpsms.py index 834ac233..73b17266 100644 --- a/tests/test_plugin_httpsms.py +++ b/tests/test_plugin_httpsms.py @@ -81,7 +81,8 @@ apprise_url_tests = ( ( "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, "privacy_url": "httpsms://b...b@9876543210/33333333333", }, diff --git a/tests/test_plugin_mastodon.py b/tests/test_plugin_mastodon.py index 4f561f93..52407ecf 100644 --- a/tests/test_plugin_mastodon.py +++ b/tests/test_plugin_mastodon.py @@ -144,8 +144,8 @@ apprise_url_tests = ( "mastodon://access_token@hostname/?key=My%20Idempotency%20Key", { # Prevent duplicate submissions of the same status. Idempotency - # keys are stored for up to 1 hour, and can be any arbitrary string. - # Consider using a hash or UUID generated client-side. + # keys are stored for up to 1 hour, and can be any arbitrary + # string. Consider using a hash or UUID generated client-side. "instance": NotifyMastodon, }, ), diff --git a/tests/test_plugin_pushsafer.py b/tests/test_plugin_pushsafer.py index c42eb5d9..62436ded 100644 --- a/tests/test_plugin_pushsafer.py +++ b/tests/test_plugin_pushsafer.py @@ -68,7 +68,8 @@ apprise_url_tests = ( "psafer://{}".format("a" * 20), { "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, }, ), diff --git a/tests/test_plugin_pushy.py b/tests/test_plugin_pushy.py index d4846c4b..e60d1a4c 100644 --- a/tests/test_plugin_pushy.py +++ b/tests/test_plugin_pushy.py @@ -95,7 +95,8 @@ apprise_url_tests = ( { # Invalid topic specified "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, "requests_response_text": GOOD_RESPONSE, }, diff --git a/tests/test_plugin_seven.py b/tests/test_plugin_seven.py index d2f07960..9656fae2 100644 --- a/tests/test_plugin_seven.py +++ b/tests/test_plugin_seven.py @@ -108,7 +108,8 @@ apprise_url_tests = ( ( "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, }, ), @@ -122,14 +123,16 @@ apprise_url_tests = ( ( "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, }, ), ( "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, }, ), diff --git a/tests/test_plugin_signal.py b/tests/test_plugin_signal.py index bd83e9ff..27ffaa8d 100644 --- a/tests/test_plugin_signal.py +++ b/tests/test_plugin_signal.py @@ -157,21 +157,24 @@ apprise_url_tests = ( "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, }, ), ( "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, }, ), ( "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, }, ), diff --git a/tests/test_plugin_sinch.py b/tests/test_plugin_sinch.py index 98e70f66..04f93104 100644 --- a/tests/test_plugin_sinch.py +++ b/tests/test_plugin_sinch.py @@ -147,7 +147,8 @@ apprise_url_tests = ( "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, }, ), diff --git a/tests/test_plugin_slack.py b/tests/test_plugin_slack.py index c8f61b30..6c479f41 100644 --- a/tests/test_plugin_slack.py +++ b/tests/test_plugin_slack.py @@ -77,7 +77,8 @@ apprise_url_tests = ( "slack://T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#hmm/#-invalid-", { # 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, # There is an invalid channel that we will fail to deliver to # as a result the response type will be false @@ -92,7 +93,8 @@ apprise_url_tests = ( "slack://T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#channel", { # 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, # don't include an image by default "include_image": False, @@ -121,7 +123,8 @@ apprise_url_tests = ( }, ), ( - "slack://username@T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#nuxref", + ("slack://username@T1JJ3T3L2/A1BRTD4JD/" + "TIiajkdnlazkcOXrIdevi7FQ/#nuxref"), { "instance": NotifySlack, "requests_response_text": "ok", @@ -147,7 +150,8 @@ apprise_url_tests = ( ), # 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, "requests_response_text": "ok", @@ -155,7 +159,8 @@ apprise_url_tests = ( ), # Test webhook that doesn't have a proper response ( - "slack://username@T1JJ3T3L2/A1BRTD4JD/TIiajkdnlazkcOXrIdevi7FQ/#nuxref", + ("slack://username@T1JJ3T3L2/A1BRTD4JD/" + "TIiajkdnlazkcOXrIdevi7FQ/#nuxref"), { "instance": NotifySlack, "requests_response_text": "fail", @@ -244,8 +249,8 @@ apprise_url_tests = ( "ok": True, "message": "", }, - # we'll fail to send attachments because we had no 'file' response in - # our object + # we'll fail to send attachments because we had no 'file' response + # in our object "response": False, }, ), diff --git a/tests/test_plugin_smseagle.py b/tests/test_plugin_smseagle.py index 93114bc9..0cb9f6fd 100644 --- a/tests/test_plugin_smseagle.py +++ b/tests/test_plugin_smseagle.py @@ -270,7 +270,8 @@ apprise_url_tests = ( ( "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, # Our response expected server response "requests_response_text": SMSEAGLE_GOOD_RESPONSE, @@ -279,7 +280,8 @@ apprise_url_tests = ( ( "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, # Our response expected server response "requests_response_text": SMSEAGLE_GOOD_RESPONSE, diff --git a/tests/test_plugin_twilio.py b/tests/test_plugin_twilio.py index 79a9c2a9..a30d3fd3 100644 --- a/tests/test_plugin_twilio.py +++ b/tests/test_plugin_twilio.py @@ -165,7 +165,8 @@ apprise_url_tests = ( "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, }, ), @@ -258,7 +259,8 @@ def test_plugin_twilio_auth(mock_post): assert ( first_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 ( first_call[1]["data"]["Body"] diff --git a/tests/test_plugin_vapid.py b/tests/test_plugin_vapid.py index d7629be6..9b23c4b6 100644 --- a/tests/test_plugin_vapid.py +++ b/tests/test_plugin_vapid.py @@ -80,8 +80,8 @@ apprise_url_tests = ( ( "vapid://user@example.com", { - # bare bone requirements met, but we don't have our subscription file - # or our private key (pem) + # bare bone requirements met, but we don't have our subscription + # file or our private key (pem) "instance": NotifyVapid, # We'll fail to respond because we would not have found any # configuration to load diff --git a/tests/test_plugin_vonage.py b/tests/test_plugin_vonage.py index 4124b448..a5a5bf49 100644 --- a/tests/test_plugin_vonage.py +++ b/tests/test_plugin_vonage.py @@ -116,7 +116,8 @@ apprise_url_tests = ( "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, }, ), @@ -223,7 +224,8 @@ apprise_url_tests = ( "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, }, ), diff --git a/tests/test_plugin_whatsapp.py b/tests/test_plugin_whatsapp.py index b901ffcb..316ac3a7 100644 --- a/tests/test_plugin_whatsapp.py +++ b/tests/test_plugin_whatsapp.py @@ -157,7 +157,8 @@ apprise_url_tests = ( ), { # 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, }, ), @@ -200,7 +201,8 @@ apprise_url_tests = ( "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, }, ), diff --git a/tests/test_plugin_wxpusher.py b/tests/test_plugin_wxpusher.py index 241e37ef..adf4e7a1 100644 --- a/tests/test_plugin_wxpusher.py +++ b/tests/test_plugin_wxpusher.py @@ -218,7 +218,8 @@ apprise_url_tests = ( ( "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, # Our response expected server response "requests_response_text": WXPUSHER_GOOD_RESPONSE, @@ -227,7 +228,8 @@ apprise_url_tests = ( ( "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, # Our response expected server response "requests_response_text": WXPUSHER_GOOD_RESPONSE,