diff --git a/README b/README
index 52ca208f..d90c6ec1 100644
--- a/README
+++ b/README
@@ -62,9 +62,6 @@ The table below identifies the services this tool supports and some example serv
mmosts://hostname/authkey
mmosts://user@hostname/authkey
-* Notify My Android
- nma://apikey
-
* Prowl
prowl://apikey
prowl://apikey/providerkey
diff --git a/README.md b/README.md
index 9b5ef2cd..7384d35e 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,6 @@ The table below identifies the services this tool supports and some example serv
| [Join](https://github.com/caronc/apprise/wiki/Notify_join) | join:// | (TCP) 443 | join://apikey/device
join://apikey/device1/device2/deviceN/
join://apikey/group
join://apikey/groupA/groupB/groupN
join://apikey/DeviceA/groupA/groupN/DeviceN/
| [KODI](https://github.com/caronc/apprise/wiki/Notify_kodi) | kodi:// or kodis:// | (TCP) 8080 or 443 | kodi://hostname
kodi://user@hostname
kodi://user:password@hostname:port
| [Mattermost](https://github.com/caronc/apprise/wiki/Notify_mattermost) | mmost:// | (TCP) 8065 | mmost://hostname/authkey
mmost://hostname:80/authkey
mmost://user@hostname:80/authkey
mmost://hostname/authkey?channel=channel
mmosts://hostname/authkey
mmosts://user@hostname/authkey
-| [Notify My Android](https://github.com/caronc/apprise/wiki/Notify_my_android) | nma:// | (TCP) 443 | nma://apikey
| [Prowl](https://github.com/caronc/apprise/wiki/Notify_prowl) | prowl:// | (TCP) 443 | prowl://apikey
prowl://apikey/providerkey
| [Pushalot](https://github.com/caronc/apprise/wiki/Notify_pushalot) | palot:// | (TCP) 443 | palot://authorizationtoken
| [PushBullet](https://github.com/caronc/apprise/wiki/Notify_pushbullet) | pbul:// | (TCP) 443 | pbul://accesstoken
pbul://accesstoken/#channel
pbul://accesstoken/A_DEVICE_ID
pbul://accesstoken/email@address.com
pbul://accesstoken/#channel/#channel2/email@address.net/DEVICE
diff --git a/apprise/plugins/NotifyMyAndroid.py b/apprise/plugins/NotifyMyAndroid.py
deleted file mode 100644
index 2312fd95..00000000
--- a/apprise/plugins/NotifyMyAndroid.py
+++ /dev/null
@@ -1,223 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Notify My Android (NMA) Notify Wrapper
-#
-# Copyright (C) 2017-2018 Chris Caron
-#
-# This file is part of apprise.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-
-import re
-import requests
-
-from .NotifyBase import NotifyBase
-from .NotifyBase import HTTP_ERROR_MAP
-from ..common import NotifyFormat
-
-# Extend HTTP Error Messages
-NMA_HTTP_ERROR_MAP = HTTP_ERROR_MAP.copy()
-NMA_HTTP_ERROR_MAP.update({
- 400: 'Data is wrong format, invalid length or null.',
- 401: 'API Key provided is invalid',
- 402: 'Maximum number of API calls per hour reached.',
-})
-
-# Used to validate Authorization Token
-VALIDATE_APIKEY = re.compile(r'[A-Za-z0-9]{48}')
-
-
-# Priorities
-class NotifyMyAndroidPriority(object):
- LOW = -2
- MODERATE = -1
- NORMAL = 0
- HIGH = 1
- EMERGENCY = 2
-
-
-NMA_PRIORITIES = (
- NotifyMyAndroidPriority.LOW,
- NotifyMyAndroidPriority.MODERATE,
- NotifyMyAndroidPriority.NORMAL,
- NotifyMyAndroidPriority.HIGH,
- NotifyMyAndroidPriority.EMERGENCY,
-)
-
-
-class NotifyMyAndroid(NotifyBase):
- """
- A wrapper for Notify My Android (NMA) Notifications
- """
-
- # The default protocol
- protocol = 'nma'
-
- # Notify My Android uses the http protocol with JSON requests
- notify_url = 'https://www.notifymyandroid.com/publicapi/notify'
-
- # The maximum allowable characters allowed in the body per message
- body_maxlen = 10000
-
- # Defines the maximum allowable characters in the title
- title_maxlen = 1000
-
- def __init__(self, apikey, priority=None, devapikey=None, **kwargs):
- """
- Initialize Notify My Android Object
- """
- super(NotifyMyAndroid, self).__init__(**kwargs)
-
- # The Priority of the message
- if priority not in NMA_PRIORITIES:
- self.priority = NotifyMyAndroidPriority.NORMAL
-
- else:
- self.priority = priority
-
- # Validate apikey
- if not VALIDATE_APIKEY.match(apikey):
- self.logger.warning(
- 'Invalid NMA API Key specified.'
- )
- raise TypeError(
- 'Invalid NMA API Key specified.'
- )
- self.apikey = apikey
-
- if devapikey:
- # Validate apikey
- if not VALIDATE_APIKEY.match(devapikey):
- self.logger.warning(
- 'Invalid NMA DEV API Key specified.'
- )
- raise TypeError(
- 'Invalid NMA DEV API Key specified.'
- )
- self.devapikey = devapikey
-
- def notify(self, title, body, notify_type, **kwargs):
- """
- Perform Notify My Android Notification
- """
-
- headers = {
- 'User-Agent': self.app_id,
- }
-
- # prepare JSON Object
- payload = {
- 'apikey': self.apikey,
- 'application': self.app_id,
- 'event': title,
- 'description': body,
- 'priority': self.priority,
- }
-
- if self.notify_format == NotifyFormat.HTML:
- payload['content-type'] = 'text/html'
-
- if self.devapikey:
- payload['developerkey'] = self.devapikey
-
- self.logger.debug('NMA POST URL: %s (cert_verify=%r)' % (
- self.notify_url, self.verify_certificate,
- ))
- self.logger.debug('NMA Payload: %s' % str(payload))
- try:
- r = requests.post(
- self.notify_url,
- data=payload,
- headers=headers,
- verify=self.verify_certificate,
- )
- if r.status_code != requests.codes.ok:
- # We had a problem
- try:
- self.logger.warning(
- 'Failed to send NMA notification: %s (error=%s).' % (
- NMA_HTTP_ERROR_MAP[r.status_code],
- r.status_code))
-
- except KeyError:
- self.logger.warning(
- 'Failed to send NMA notification (error=%s).' % (
- r.status_code))
-
- # Return; we're done
- return False
-
- else:
- self.logger.debug('NMA Server Response: %s.' % r.raw.read())
- self.logger.info('Sent NMA notification.')
-
- except requests.RequestException as e:
- self.logger.warning(
- 'A Connection error occured sending NMA notification.'
- )
- self.logger.debug('Socket Exception: %s' % str(e))
-
- # Return; we're done
- return False
-
- return True
-
- @staticmethod
- def parse_url(url):
- """
- Parses the URL and returns enough arguments that can allow
- us to substantiate this object.
-
- """
- results = NotifyBase.parse_url(url)
-
- if not results:
- # We're done early as we couldn't load the results
- return results
-
- # Apply our settings now
- results['notify_format'] = NotifyFormat.HTML
-
- if 'format' in results['qsd'] and len(results['qsd']['format']):
- # Extract email format (Text/Html)
- format = NotifyBase.unquote(results['qsd']['format']).lower()
- if len(format) > 0 and format[0] == 't':
- results['notify_format'] = NotifyFormat.TEXT
-
- if 'priority' in results['qsd'] and len(results['qsd']['priority']):
- _map = {
- 'l': NotifyMyAndroidPriority.LOW,
- '-2': NotifyMyAndroidPriority.LOW,
- 'm': NotifyMyAndroidPriority.MODERATE,
- '-1': NotifyMyAndroidPriority.MODERATE,
- 'n': NotifyMyAndroidPriority.NORMAL,
- '0': NotifyMyAndroidPriority.NORMAL,
- 'h': NotifyMyAndroidPriority.HIGH,
- '1': NotifyMyAndroidPriority.HIGH,
- 'e': NotifyMyAndroidPriority.EMERGENCY,
- '2': NotifyMyAndroidPriority.EMERGENCY,
- }
- try:
- results['priority'] = \
- _map[results['qsd']['priority'][0].lower()]
-
- except KeyError:
- # No priority was set
- pass
-
- # Now fetch devapi if specified
- devapi = NotifyBase.split_path(results['fullpath'])[0]
- if devapi:
- results['devapikey'] = devapi
-
- results['apikey'] = results['host']
-
- return results
diff --git a/test/test_rest_plugins.py b/test/test_rest_plugins.py
index fb067f38..69a6dbe2 100644
--- a/test/test_rest_plugins.py
+++ b/test/test_rest_plugins.py
@@ -599,88 +599,6 @@ TEST_URLS = (
'test_requests_exceptions': True,
}),
- ##################################
- # NotifyMyAndroid
- ##################################
- ('nma://', {
- 'instance': None,
- }),
- # APIkey; no device
- ('nma://%s' % ('a' * 48), {
- 'instance': plugins.NotifyMyAndroid,
- }),
- # Invalid APIKey
- ('nma://%s' % ('a' * 24), {
- 'instance': TypeError,
- }),
- # APIKey
- ('nma://%s' % ('a' * 48), {
- 'instance': plugins.NotifyMyAndroid,
- # don't include an image by default
- 'include_image': False,
- }),
- # APIKey + priority setting
- ('nma://%s?priority=high' % ('a' * 48), {
- 'instance': plugins.NotifyMyAndroid,
- }),
- # APIKey + invalid priority setting
- ('nma://%s?priority=invalid' % ('a' * 48), {
- 'instance': plugins.NotifyMyAndroid,
- }),
- # APIKey + priority setting (empty)
- ('nma://%s?priority=' % ('a' * 48), {
- 'instance': plugins.NotifyMyAndroid,
- }),
- # APIKey + Invalid DevAPI Key
- ('nma://%s/%s' % ('a' * 48, 'b' * 24), {
- 'instance': TypeError,
- }),
- # APIKey + DevAPI Key
- ('nma://%s/%s' % ('a' * 48, 'b' * 48), {
- 'instance': plugins.NotifyMyAndroid,
- }),
- # Testing valid format
- ('nma://%s?format=text' % ('a' * 48), {
- 'instance': plugins.NotifyMyAndroid,
- }),
- # Testing valid format
- ('nma://%s?format=html' % ('a' * 48), {
- 'instance': plugins.NotifyMyAndroid,
- }),
- # Testing invalid format (fall's back to html)
- ('nma://%s?format=invalid' % ('a' * 48), {
- 'instance': plugins.NotifyMyAndroid,
- }),
- # Testing empty format (falls back to html)
- ('nma://%s?format=' % ('a' * 48), {
- 'instance': plugins.NotifyMyAndroid,
- }),
- # APIKey + with image
- ('nma://%s' % ('a' * 48), {
- 'instance': plugins.NotifyMyAndroid,
- }),
- # bad url
- ('nma://:@/', {
- 'instance': None,
- }),
- ('nma://%s' % ('a' * 48), {
- 'instance': plugins.NotifyMyAndroid,
- # force a failure
- 'response': False,
- 'requests_response_code': requests.codes.internal_server_error,
- }),
- ('nma://%s' % ('a' * 48), {
- 'instance': plugins.NotifyMyAndroid,
- # throw a bizzare code forcing us to fail to look it up
- 'response': False,
- 'requests_response_code': 999,
- }),
- ('nma://%s' % ('a' * 48), {
- 'instance': plugins.NotifyMyAndroid,
- # Throws a series of connection and transfer exceptions when this flag
- # is set and tests that we gracfully handle them
- 'test_requests_exceptions': True,
- }),
##################################
# NotifyProwl