diff --git a/apprise/plugins/NotifyEmby.py b/apprise/plugins/NotifyEmby.py index bf9066cc..45b5bcb3 100644 --- a/apprise/plugins/NotifyEmby.py +++ b/apprise/plugins/NotifyEmby.py @@ -697,3 +697,28 @@ class NotifyEmby(NotifyBase): # ticket system as unresolved and has provided work-arounds # - https://github.com/kennethreitz/requests/issues/3578 pass + + except ImportError: # pragma: no cover + # The actual exception is `ModuleNotFoundError` however ImportError + # grants us backwards compatiblity with versions of Python older + # than v3.6 + + # Python code that makes early calls to sys.exit() can cause + # the __del__() code to run. However in some newer versions of + # Python, this causes the `sys` library to no longer be + # available. The stack overflow also goes on to suggest that + # it's not wise to use the __del__() as a deconstructor + # which is the case here. + + # https://stackoverflow.com/questions/67218341/\ + # modulenotfounderror-import-of-time-halted-none-in-sys-\ + # modules-occured-when-obj?noredirect=1&lq=1 + # + # + # Also see: https://stackoverflow.com/questions\ + # /1481488/what-is-the-del-method-and-how-do-i-call-it + + # At this time it seems clean to try to log out (if we can) + # but not throw any unessisary exceptions (like this one) to + # the end user if we don't have to. + pass diff --git a/apprise/plugins/NotifyMatrix.py b/apprise/plugins/NotifyMatrix.py index 35a3e1e8..fb93bd9c 100644 --- a/apprise/plugins/NotifyMatrix.py +++ b/apprise/plugins/NotifyMatrix.py @@ -131,13 +131,13 @@ class NotifyMatrix(NotifyBase): '{schema}://{token}', '{schema}://{user}@{token}', - # All other non-t2bot setups require targets + # Disabled webhook '{schema}://{user}:{password}@{host}/{targets}', '{schema}://{user}:{password}@{host}:{port}/{targets}', - '{schema}://{token}:{password}@{host}/{targets}', - '{schema}://{token}:{password}@{host}:{port}/{targets}', - '{schema}://{user}:{token}:{password}@{host}/{targets}', - '{schema}://{user}:{token}:{password}@{host}:{port}/{targets}', + + # Webhook mode + '{schema}://{user}:{token}@{host}/{targets}', + '{schema}://{user}:{token}@{host}:{port}/{targets}', ) # Define our template tokens @@ -207,6 +207,9 @@ class NotifyMatrix(NotifyBase): 'to': { 'alias_of': 'targets', }, + 'token': { + 'alias_of': 'token', + }, }) def __init__(self, targets=None, mode=None, include_image=False, **kwargs): @@ -245,10 +248,10 @@ class NotifyMatrix(NotifyBase): if self.mode == MatrixWebhookMode.T2BOT: # t2bot configuration requires that a webhook id is specified self.access_token = validate_regex( - self.host, r'^[a-z0-9]{64}$', 'i') + self.password, r'^[a-z0-9]{64}$', 'i') if not self.access_token: msg = 'An invalid T2Bot/Matrix Webhook ID ' \ - '({}) was specified.'.format(self.host) + '({}) was specified.'.format(self.password) self.logger.warning(msg) raise TypeError(msg) @@ -1003,9 +1006,54 @@ class NotifyMatrix(NotifyBase): """ Ensure we relinquish our token """ - if self.mode != MatrixWebhookMode.T2BOT: + if self.mode == MatrixWebhookMode.T2BOT: + # nothing to do + return + + try: self._logout() + except LookupError: # pragma: no cover + # Python v3.5 call to requests can sometimes throw the exception + # "/usr/lib64/python3.7/socket.py", line 748, in getaddrinfo + # LookupError: unknown encoding: idna + # + # This occurs every time when running unit-tests against Apprise: + # LANG=C.UTF-8 PYTHONPATH=$(pwd) py.test-3.7 + # + # There has been an open issue on this since Jan 2017. + # - https://bugs.python.org/issue29288 + # + # A ~similar~ issue can be identified here in the requests + # ticket system as unresolved and has provided work-arounds + # - https://github.com/kennethreitz/requests/issues/3578 + pass + + except ImportError: # pragma: no cover + # The actual exception is `ModuleNotFoundError` however ImportError + # grants us backwards compatiblity with versions of Python older + # than v3.6 + + # Python code that makes early calls to sys.exit() can cause + # the __del__() code to run. However in some newer versions of + # Python, this causes the `sys` library to no longer be + # available. The stack overflow also goes on to suggest that + # it's not wise to use the __del__() as a deconstructor + # which is the case here. + + # https://stackoverflow.com/questions/67218341/\ + # modulenotfounderror-import-of-time-halted-none-in-sys-\ + # modules-occured-when-obj?noredirect=1&lq=1 + # + # + # Also see: https://stackoverflow.com/questions\ + # /1481488/what-is-the-del-method-and-how-do-i-call-it + + # At this time it seems clean to try to log out (if we can) + # but not throw any unessisary exceptions (like this one) to + # the end user if we don't have to. + pass + def url(self, privacy=False, *args, **kwargs): """ Returns the URL built dynamically based on specified arguments. @@ -1020,26 +1068,30 @@ class NotifyMatrix(NotifyBase): # Extend our parameters params.update(self.url_parameters(privacy=privacy, *args, **kwargs)) - # Determine Authentication auth = '' - if self.user and self.password: - auth = '{user}:{password}@'.format( - user=NotifyMatrix.quote(self.user, safe=''), - password=self.pprint( - self.password, privacy, mode=PrivacyMode.Secret, safe=''), - ) + if self.mode != MatrixWebhookMode.T2BOT: + # Determine Authentication + if self.user and self.password: + auth = '{user}:{password}@'.format( + user=NotifyMatrix.quote(self.user, safe=''), + password=self.pprint( + self.password, privacy, mode=PrivacyMode.Secret, + safe=''), + ) - elif self.user: - auth = '{user}@'.format( - user=NotifyMatrix.quote(self.user, safe=''), - ) + elif self.user: + auth = '{user}@'.format( + user=NotifyMatrix.quote(self.user, safe=''), + ) default_port = 443 if self.secure else 80 return '{schema}://{auth}{hostname}{port}/{rooms}?{params}'.format( schema=self.secure_protocol if self.secure else self.protocol, auth=auth, - hostname=NotifyMatrix.quote(self.host, safe=''), + hostname=NotifyMatrix.quote(self.host, safe='') + if self.mode != MatrixWebhookMode.T2BOT + else self.pprint(self.access_token, privacy, safe=''), port='' if self.port is None or self.port == default_port else ':{}'.format(self.port), rooms=NotifyMatrix.quote('/'.join(self.rooms)), @@ -1086,6 +1138,15 @@ class NotifyMatrix(NotifyBase): # Default mode to t2bot results['mode'] = MatrixWebhookMode.T2BOT + if results['mode'] and \ + results['mode'].lower() == MatrixWebhookMode.T2BOT: + # unquote our hostname and pass it in as the password/token + results['password'] = NotifyMatrix.unquote(results['host']) + + # Support the use of the token= keyword + if 'token' in results['qsd'] and len(results['qsd']['token']): + results['password'] = NotifyMatrix.unquote(results['qsd']['token']) + return results @staticmethod diff --git a/apprise/plugins/NotifyTwist.py b/apprise/plugins/NotifyTwist.py index d6354de4..7f9c7c88 100644 --- a/apprise/plugins/NotifyTwist.py +++ b/apprise/plugins/NotifyTwist.py @@ -790,7 +790,7 @@ class NotifyTwist(NotifyBase): try: self.logout() - except LookupError: + except LookupError: # pragma: no cover # Python v3.5 call to requests can sometimes throw the exception # "/usr/lib64/python3.7/socket.py", line 748, in getaddrinfo # LookupError: unknown encoding: idna @@ -805,3 +805,28 @@ class NotifyTwist(NotifyBase): # ticket system as unresolved and has provided work-arounds # - https://github.com/kennethreitz/requests/issues/3578 pass + + except ImportError: # pragma: no cover + # The actual exception is `ModuleNotFoundError` however ImportError + # grants us backwards compatiblity with versions of Python older + # than v3.6 + + # Python code that makes early calls to sys.exit() can cause + # the __del__() code to run. However in some newer versions of + # Python, this causes the `sys` library to no longer be + # available. The stack overflow also goes on to suggest that + # it's not wise to use the __del__() as a deconstructor + # which is the case here. + + # https://stackoverflow.com/questions/67218341/\ + # modulenotfounderror-import-of-time-halted-none-in-sys-\ + # modules-occured-when-obj?noredirect=1&lq=1 + # + # + # Also see: https://stackoverflow.com/questions\ + # /1481488/what-is-the-del-method-and-how-do-i-call-it + + # At this time it seems clean to try to log out (if we can) + # but not throw any unessisary exceptions (like this one) to + # the end user if we don't have to. + pass diff --git a/test/test_rest_plugins.py b/test/test_rest_plugins.py index d96d181b..d5680588 100644 --- a/test/test_rest_plugins.py +++ b/test/test_rest_plugins.py @@ -1858,6 +1858,18 @@ TEST_URLS = ( # despite uppercase characters 'instance': plugins.NotifyMatrix, }), + ('matrix://user@localhost?mode=SLACK&format=markdown&token=mytoken', { + # user and token specified; slack webhook still detected + # despite uppercase characters; token also set on URL as arg + 'instance': plugins.NotifyMatrix, + }), + ('matrix://_?mode=t2bot&token={}'.format('b' * 64), { + # Testing t2bot initialization and setting the password using the + # token directive + 'instance': plugins.NotifyMatrix, + # Our expected url(privacy=True) startswith() response: + 'privacy_url': 'matrix://b...b/', + }), # Image Reference ('matrixs://user:token@localhost?mode=slack&format=markdown&image=True', { # user and token specified; image set to True