diff --git a/README.md b/README.md
index c0df29a5..c74feb84 100644
--- a/README.md
+++ b/README.md
@@ -51,7 +51,6 @@ The table below identifies the services this tool supports and some example serv
| [Rocket.Chat](https://github.com/caronc/apprise/wiki/Notify_rocketchat) | rocket:// or rockets:// | (TCP) 80 or 443 | rocket://user:password@hostname/RoomID/Channel
rockets://user:password@hostname:443/Channel1/Channel1/RoomID
rocket://user:password@hostname/Channel
| [Slack](https://github.com/caronc/apprise/wiki/Notify_slack) | slack:// | (TCP) 443 | slack://TokenA/TokenB/TokenC/Channel
slack://botname@TokenA/TokenB/TokenC/Channel
slack://user@TokenA/TokenB/TokenC/Channel1/Channel2/ChannelN
| [Stride](https://github.com/caronc/apprise/wiki/Notify_stride) | stride:// | (TCP) 443 | stride://auth_token/cloud_id/convo_id
-| [Super Toasty](https://github.com/caronc/apprise/wiki/Notify_toasty) | toasty:// | (TCP) 80 | toasty://user@DEVICE
toasty://user@DEVICE1/DEVICE2/DEVICEN
_Note: you must specify both your user_id and at least 1 device!_
| [Telegram](https://github.com/caronc/apprise/wiki/Notify_telegram) | tgram:// | (TCP) 443 | tgram://bottoken/ChatID
tgram://bottoken/ChatID1/ChatID2/ChatIDN
| [Twitter](https://github.com/caronc/apprise/wiki/Notify_twitter) | tweet:// | (TCP) 443 | tweet://user@CKey/CSecret/AKey/ASecret
| [XBMC](https://github.com/caronc/apprise/wiki/Notify_xbmc) | xbmc:// or xbmcs:// | (TCP) 8080 or 443 | xbmc://hostname
xbmc://user@hostname
xbmc://user:password@hostname:port
diff --git a/apprise/plugins/NotifyToasty.py b/apprise/plugins/NotifyToasty.py
deleted file mode 100644
index 0f16881a..00000000
--- a/apprise/plugins/NotifyToasty.py
+++ /dev/null
@@ -1,187 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2019 Chris Caron
-# All rights reserved.
-#
-# This code is licensed under the MIT License.
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files(the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions :
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-import re
-import requests
-
-from .NotifyBase import NotifyBase
-from .NotifyBase import HTTP_ERROR_MAP
-from ..common import NotifyImageSize
-from ..utils import compat_is_basestring
-
-# Used to break apart list of potential devices by their delimiter
-# into a usable list.
-DEVICES_LIST_DELIM = re.compile(r'[ \t\r\n,\\/]+')
-
-
-class NotifyToasty(NotifyBase):
- """
- A wrapper for Toasty Notifications
- """
-
- # The default descriptive name associated with the Notification
- service_name = 'Toasty'
-
- # The services URL
- service_url = 'http://supertoasty.com/'
-
- # The default protocol
- protocol = 'toasty'
-
- # A URL that takes you to the setup/help of the specific protocol
- setup_url = 'https://github.com/caronc/apprise/wiki/Notify_toasty'
-
- # Toasty uses the http protocol with JSON requests
- notify_url = 'http://api.supertoasty.com/notify/'
-
- # Allows the user to specify the NotifyImageSize object
- image_size = NotifyImageSize.XY_128
-
- def __init__(self, devices, **kwargs):
- """
- Initialize Toasty Object
- """
- super(NotifyToasty, self).__init__(**kwargs)
-
- if compat_is_basestring(devices):
- self.devices = [x for x in filter(bool, DEVICES_LIST_DELIM.split(
- devices,
- ))]
-
- elif isinstance(devices, (set, tuple, list)):
- self.devices = devices
-
- else:
- self.devices = list()
-
- if len(devices) == 0:
- raise TypeError('You must specify at least 1 device.')
-
- if not self.user:
- raise TypeError('You must specify a username.')
-
- def notify(self, title, body, notify_type, **kwargs):
- """
- Perform Toasty Notification
- """
-
- headers = {
- 'User-Agent': self.app_id,
- 'Content-Type': 'multipart/form-data',
- }
-
- # error tracking (used for function return)
- has_error = False
-
- # Create a copy of the devices list
- devices = list(self.devices)
- while len(devices):
- device = devices.pop(0)
-
- # prepare JSON Object
- payload = {
- 'sender': NotifyBase.quote(self.user),
- 'title': NotifyBase.quote(title),
- 'text': NotifyBase.quote(body),
- }
-
- image_url = self.image_url(notify_type)
- if image_url:
- payload['image'] = image_url
-
- # URL to transmit content via
- url = '%s%s' % (self.notify_url, device)
-
- self.logger.debug('Toasty POST URL: %s (cert_verify=%r)' % (
- url, self.verify_certificate,
- ))
- self.logger.debug('Toasty Payload: %s' % str(payload))
- try:
- r = requests.get(
- 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 Toasty:%s '
- 'notification: %s (error=%s).' % (
- device,
- HTTP_ERROR_MAP[r.status_code],
- r.status_code))
-
- except KeyError:
- self.logger.warning(
- 'Failed to send Toasty:%s '
- 'notification (error=%s).' % (
- device,
- r.status_code))
-
- # self.logger.debug('Response Details: %s' % r.raw.read())
-
- # Return; we're done
- has_error = True
-
- else:
- self.logger.info(
- 'Sent Toasty notification to %s.' % device)
-
- except requests.RequestException as e:
- self.logger.warning(
- 'A Connection error occured sending Toasty:%s ' % (
- device) + 'notification.'
- )
- self.logger.debug('Socket Exception: %s' % str(e))
- has_error = True
-
- if len(devices):
- # Prevent thrashing requests
- self.throttle()
-
- return not has_error
-
- @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
- devices = NotifyBase.unquote(results['fullpath'])
-
- # Store our devices
- results['devices'] = '%s/%s' % (results['host'], devices)
-
- return results
diff --git a/apprise/plugins/__init__.py b/apprise/plugins/__init__.py
index fdc8e2f9..74880fed 100644
--- a/apprise/plugins/__init__.py
+++ b/apprise/plugins/__init__.py
@@ -49,7 +49,6 @@ from .NotifyRocketChat import NotifyRocketChat
from .NotifySlack import NotifySlack
from .NotifyStride import NotifyStride
from .NotifyTelegram import NotifyTelegram
-from .NotifyToasty import NotifyToasty
from .NotifyTwitter.NotifyTwitter import NotifyTwitter
from .NotifyXBMC import NotifyXBMC
from .NotifyXML import NotifyXML
@@ -71,7 +70,7 @@ __all__ = [
'NotifyJSON', 'NotifyMatrix', 'NotifyMatterMost', 'NotifyProwl',
'NotifyPushalot', 'NotifyPushed', 'NotifyPushBullet', 'NotifyPushjet',
'NotifyPushover', 'NotifyRocketChat', 'NotifySlack', 'NotifyStride',
- 'NotifyToasty', 'NotifyTwitter', 'NotifyTelegram', 'NotifyXBMC',
+ 'NotifyTwitter', 'NotifyTelegram', 'NotifyXBMC',
'NotifyXML', 'NotifyWindows',
# Reference
diff --git a/test/test_rest_plugins.py b/test/test_rest_plugins.py
index 266dc19b..56c100d6 100644
--- a/test/test_rest_plugins.py
+++ b/test/test_rest_plugins.py
@@ -1361,49 +1361,6 @@ TEST_URLS = (
'test_requests_exceptions': True,
}),
- ##################################
- # NotifyToasty (SuperToasty)
- ##################################
- ('toasty://', {
- 'instance': None,
- }),
- # No username specified but contains a device
- ('toasty://%s' % ('d' * 32), {
- 'instance': TypeError,
- }),
- # User + 1 device
- ('toasty://user@device', {
- 'instance': plugins.NotifyToasty,
- }),
- # User + 3 devices
- ('toasty://user@device0/device1/device2/', {
- 'instance': plugins.NotifyToasty,
- # don't include an image by default
- 'include_image': False,
- }),
- # bad url
- ('toasty://:@/', {
- 'instance': None,
- }),
- ('toasty://user@device', {
- 'instance': plugins.NotifyToasty,
- # force a failure
- 'response': False,
- 'requests_response_code': requests.codes.internal_server_error,
- }),
- ('toasty://user@device', {
- 'instance': plugins.NotifyToasty,
- # throw a bizzare code forcing us to fail to look it up
- 'response': False,
- 'requests_response_code': 999,
- }),
- ('toasty://user@device', {
- 'instance': plugins.NotifyToasty,
- # Throws a series of connection and transfer exceptions when this flag
- # is set and tests that we gracfully handle them
- 'test_requests_exceptions': True,
- }),
-
##################################
# NotifyKODI
##################################
@@ -2710,54 +2667,6 @@ def test_notify_rocketchat_plugin(mock_post, mock_get):
assert obj.logout() is False
-@mock.patch('requests.get')
-@mock.patch('requests.post')
-def test_notify_toasty_plugin(mock_post, mock_get):
- """
- API: NotifyToasty() Extra Checks
-
- """
-
- # Support strings
- devices = 'device1,device2,,,,'
-
- # User
- user = 'l2g'
-
- # Prepare Mock
- mock_get.return_value = requests.Request()
- mock_post.return_value = requests.Request()
- mock_post.return_value.status_code = requests.codes.ok
- mock_get.return_value.status_code = requests.codes.ok
-
- try:
- obj = plugins.NotifyToasty(user=user, devices=None)
- # No devices specified
- assert(False)
-
- except TypeError:
- # Exception should be thrown about the fact no token was specified
- assert(True)
-
- try:
- obj = plugins.NotifyToasty(user=user, devices=set())
- # No devices specified
- assert(False)
-
- except TypeError:
- # Exception should be thrown about the fact no token was specified
- assert(True)
-
- obj = plugins.NotifyToasty(user=user, devices=devices)
- assert(isinstance(obj, plugins.NotifyToasty))
- assert(len(obj.devices) == 2)
-
- # Support the handling of an empty and invalid URL strings
- assert(plugins.NotifyToasty.parse_url(None) is None)
- assert(plugins.NotifyToasty.parse_url('') is None)
- assert(plugins.NotifyToasty.parse_url(42) is None)
-
-
@mock.patch('requests.get')
@mock.patch('requests.post')
def test_notify_telegram_plugin(mock_post, mock_get):