diff --git a/apprise/plugins/NotifyNextcloud.py b/apprise/plugins/NotifyNextcloud.py index 455f2343..30000f0d 100644 --- a/apprise/plugins/NotifyNextcloud.py +++ b/apprise/plugins/NotifyNextcloud.py @@ -51,11 +51,7 @@ class NotifyNextcloud(NotifyBase): # A URL that takes you to the setup/help of the specific protocol setup_url = 'https://github.com/caronc/apprise/wiki/Notify_nextcloud' - # Nextcloud URL - notify_url = '{schema}://{host}/ocs/v2.php/apps/admin_notifications/' \ - 'api/v1/notifications/{target}' - - # Nextcloud does not support a title + # Nextcloud title length title_maxlen = 255 # Defines the maximum allowable characters per message. @@ -101,6 +97,22 @@ class NotifyNextcloud(NotifyBase): }, }) + # Define our template arguments + template_args = dict(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: + 'version': { + 'name': _('Version'), + 'type': 'int', + 'min': 1, + 'default': 21, + }, + 'to': { + 'alias_of': 'targets', + }, + }) + # Define any kwargs we're using template_kwargs = { 'headers': { @@ -109,7 +121,7 @@ class NotifyNextcloud(NotifyBase): }, } - def __init__(self, targets=None, headers=None, **kwargs): + def __init__(self, targets=None, version=None, headers=None, **kwargs): """ Initialize Nextcloud Object """ @@ -121,6 +133,20 @@ class NotifyNextcloud(NotifyBase): self.logger.warning(msg) raise TypeError(msg) + self.version = self.template_args['version']['default'] + if version is not None: + try: + self.version = int(version) + if self.version < self.template_args['version']['min']: + # Let upper exception handle this + raise ValueError() + + except (ValueError, TypeError): + msg = 'At invalid Nextcloud version ({}) was specified.'\ + .format(version) + self.logger.warning(msg) + raise TypeError(msg) + self.headers = {} if headers: # Store our extra headers @@ -163,17 +189,28 @@ class NotifyNextcloud(NotifyBase): if self.user: auth = (self.user, self.password) - notify_url = self.notify_url.format( + # Nextcloud URL based on version used + notify_url = '{schema}://{host}/ocs/v2.php/'\ + 'apps/admin_notifications/' \ + 'api/v1/notifications/{target}' \ + if self.version < 21 else \ + '{schema}://{host}/ocs/v2.php/'\ + 'apps/notifications/'\ + 'api/v2/admin_notifications/{target}' + + notify_url = notify_url.format( schema='https' if self.secure else 'http', host=self.host if not isinstance(self.port, int) else '{}:{}'.format(self.host, self.port), target=target, ) - self.logger.debug('Nextcloud POST URL: %s (cert_verify=%r)' % ( - notify_url, self.verify_certificate, - )) - self.logger.debug('Nextcloud Payload: %s' % str(payload)) + self.logger.debug( + 'Nextcloud v%d POST URL: %s (cert_verify=%r)', + self.version, notify_url, self.verify_certificate) + self.logger.debug( + 'Nextcloud v%d Payload: %s', + self.version, str(payload)) # Always call throttle before any remote server i/o is made self.throttle() @@ -194,8 +231,9 @@ class NotifyNextcloud(NotifyBase): r.status_code) self.logger.warning( - 'Failed to send Nextcloud notification:' + 'Failed to send Nextcloud v{} notification:' '{}{}error={}.'.format( + self.version, status_str, ', ' if status_str else '', r.status_code)) @@ -207,13 +245,13 @@ class NotifyNextcloud(NotifyBase): continue else: - self.logger.info('Sent Nextcloud notification.') + self.logger.info( + 'Sent Nextcloud %d notification.', self.version) except requests.RequestException as e: self.logger.warning( - 'A Connection error occurred sending Nextcloud ' - 'notification.', - ) + 'A Connection error occurred sending Nextcloud v%d' + 'notification.', self.version) self.logger.debug('Socket Exception: %s' % str(e)) # track our failure @@ -230,8 +268,11 @@ class NotifyNextcloud(NotifyBase): # Create URL parameters from our headers params = {'+{}'.format(k): v for k, v in self.headers.items()} - # Our URL parameters - params = self.url_parameters(privacy=privacy, *args, **kwargs) + # Set our version + params['version'] = str(self.version) + + # Extend our parameters + params.update(self.url_parameters(privacy=privacy, *args, **kwargs)) # Determine Authentication auth = '' @@ -285,6 +326,11 @@ class NotifyNextcloud(NotifyBase): results['targets'] += \ NotifyNextcloud.parse_list(results['qsd']['to']) + # Allow users to over-ride the Nextcloud version being used + if 'version' in results['qsd'] and len(results['qsd']['version']): + results['version'] = \ + NotifyNextcloud.unquote(results['qsd']['version']) + # Add our headers that the user can potentially over-ride if they # wish to to our returned result set results['headers'] = results['qsd+'] diff --git a/test/test_rest_plugins.py b/test/test_rest_plugins.py index 684d4ae0..0c78ca77 100644 --- a/test/test_rest_plugins.py +++ b/test/test_rest_plugins.py @@ -2461,6 +2461,18 @@ TEST_URLS = ( # No user specified 'instance': TypeError, }), + ('ncloud://user@localhost?to=user1,user2&version=invalid', { + # An invalid version was specified + 'instance': TypeError, + }), + ('ncloud://user@localhost?to=user1,user2&version=0', { + # An invalid version was specified + 'instance': TypeError, + }), + ('ncloud://user@localhost?to=user1,user2&version=-23', { + # An invalid version was specified + 'instance': TypeError, + }), ('ncloud://localhost/admin', { 'instance': plugins.NotifyNextcloud, }), @@ -2470,6 +2482,12 @@ TEST_URLS = ( ('ncloud://user@localhost?to=user1,user2', { 'instance': plugins.NotifyNextcloud, }), + ('ncloud://user@localhost?to=user1,user2&version=20', { + 'instance': plugins.NotifyNextcloud, + }), + ('ncloud://user@localhost?to=user1,user2&version=21', { + 'instance': plugins.NotifyNextcloud, + }), ('ncloud://user:pass@localhost/user1/user2', { 'instance': plugins.NotifyNextcloud,