Update Apprise to 0.7.3

pull/489/head
Halali 6 years ago
parent 8dc026d19a
commit 1cdebd0617

@ -1,23 +1,27 @@
# -*- coding: utf-8 -*-
#
# Apprise Core
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
#
# You should have received a copy of the GNU Lesser General Public License
# along with apprise. If not, see <http://www.gnu.org/licenses/>.
# 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 logging
@ -27,6 +31,7 @@ from .common import NotifyType
from .common import NotifyFormat
from .utils import parse_list
from .utils import compat_is_basestring
from .utils import GET_SCHEMA_RE
from .AppriseAsset import AppriseAsset
@ -39,9 +44,6 @@ logger = logging.getLogger(__name__)
# Build a list of supported plugins
SCHEMA_MAP = {}
# Used for attempting to acquire the schema if the URL can't be parsed.
GET_SCHEMA_RE = re.compile(r'\s*(?P<schema>[a-z0-9]{3,9})://.*$', re.I)
# Load our Lookup Matrix
def __load_matrix():
@ -55,7 +57,7 @@ def __load_matrix():
# Get our plugin
plugin = getattr(plugins, entry)
if not hasattr(plugin, 'app_id'): # pragma: no branch
if not hasattr(plugin, 'app_id'): # pragma: no branch
# Filter out non-notification modules
continue
@ -119,7 +121,7 @@ class Apprise(object):
self.add(servers)
@staticmethod
def instantiate(url, asset=None, suppress_exceptions=True):
def instantiate(url, asset=None, tag=None, suppress_exceptions=True):
"""
Returns the instance of a instantiated plugin based on the provided
Server URL. If the url fails to be parsed, then None is returned.
@ -160,6 +162,9 @@ class Apprise(object):
logger.error('Could not parse URL: %s' % url)
return None
# Build a list of tags to associate with the newly added notifications
results['tag'] = set(parse_list(tag))
if suppress_exceptions:
try:
# Attempt to create an instance of our plugin using the parsed
@ -182,10 +187,16 @@ class Apprise(object):
return plugin
def add(self, servers, asset=None):
def add(self, servers, asset=None, tag=None):
"""
Adds one or more server URLs into our list.
You can override the global asset if you wish by including it with the
server(s) that you add.
The tag allows you to associate 1 or more tag values to the server(s)
being added. tagging a service allows you to exclusively access them
when calling the notify() function.
"""
# Initialize our return status
@ -200,12 +211,13 @@ class Apprise(object):
self.servers.append(servers)
return True
# build our server listings
servers = parse_list(servers)
for _server in servers:
# Instantiate ourselves an object, this function throws or
# returns None if it fails
instance = Apprise.instantiate(_server, asset=asset)
instance = Apprise.instantiate(_server, asset=asset, tag=tag)
if not instance:
return_status = False
logging.error(
@ -227,13 +239,18 @@ class Apprise(object):
self.servers[:] = []
def notify(self, title, body, notify_type=NotifyType.INFO,
body_format=None):
body_format=None, tag=None):
"""
Send a notification to all of the plugins previously loaded.
If the body_format specified is NotifyFormat.MARKDOWN, it will
be converted to HTML if the Notification type expects this.
if the tag is specified (either a string or a set/list/tuple
of strings), then only the notifications flagged with that
tagged value are notified. By default all added services
are notified (tag=None)
"""
# Initialize our return result
@ -245,8 +262,63 @@ class Apprise(object):
# Tracks conversions
conversion_map = dict()
# Build our tag setup
# - top level entries are treated as an 'or'
# - second level (or more) entries are treated as 'and'
#
# examples:
# tag="tagA, tagB" = tagA or tagB
# tag=['tagA', 'tagB'] = tagA or tagB
# tag=[('tagA', 'tagC'), 'tagB'] = (tagA and tagC) or tagB
# tag=[('tagB', 'tagC')] = tagB and tagC
# Iterate over our loaded plugins
for server in self.servers:
if tag is not None:
if isinstance(tag, (list, tuple, set)):
# using the tags detected; determine if we'll allow the
# notification to be sent or not
matched = False
# Every entry here will be or'ed with the next
for entry in tag:
if isinstance(entry, (list, tuple, set)):
# treat these entries as though all elements found
# must exist in the notification service
tags = set(parse_list(entry))
if len(tags.intersection(
server.tags)) == len(tags):
# our set contains all of the entries found
# in our notification server object
matched = True
break
elif entry in server:
# our entr(ies) match what was found in our server
# object.
matched = True
break
# else: keep looking
if not matched:
# We did not meet any of our and'ed criteria
continue
elif tag not in server:
# one or more tags were defined and they didn't match the
# entry in the current service; move along...
continue
# else: our content was found inside the server, so we're good
# If our code reaches here, we either did not define a tag (it was
# set to None), or we did define a tag and the logic above
# determined we need to notify the service it's associated with
if server.notify_format not in conversion_map:
if body_format == NotifyFormat.MARKDOWN and \
server.notify_format == NotifyFormat.HTML:
@ -254,6 +326,39 @@ class Apprise(object):
# Apply Markdown
conversion_map[server.notify_format] = markdown(body)
elif body_format == NotifyFormat.TEXT and \
server.notify_format == NotifyFormat.HTML:
# Basic TEXT to HTML format map; supports keys only
re_map = {
# Support Ampersand
r'&': '&amp;',
# Spaces to &nbsp; for formatting purposes since
# multiple spaces are treated as one an this may not
# be the callers intention
r' ': '&nbsp;',
# Tab support
r'\t': '&nbsp;&nbsp;&nbsp;',
# Greater than and Less than Characters
r'>': '&gt;',
r'<': '&lt;',
}
# Compile our map
re_table = re.compile(
r'(' + '|'.join(map(re.escape, re_map.keys())) + r')',
re.IGNORECASE,
)
# Execute our map against our body in addition to swapping
# out new lines and replacing them with <br/>
conversion_map[server.notify_format] = \
re.sub(r'\r*\n', '<br/>\r\n',
re_table.sub(lambda x: re_map[x.group()], body))
else:
# Store entry directly
conversion_map[server.notify_format] = body
@ -302,7 +407,7 @@ class Apprise(object):
# Get our plugin
plugin = getattr(plugins, entry)
if not hasattr(plugin, 'app_id'): # pragma: no branch
if not hasattr(plugin, 'app_id'): # pragma: no branch
# Filter out non-notification modules
continue

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# Apprise Asset
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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
@ -227,7 +234,7 @@ class AppriseAsset(object):
'app_desc': self.app_desc,
'default_extension': self.default_extension,
'theme': self.theme,
'image_path_mask': self.image_url_mask,
'image_path_mask': self.image_path_mask,
'image_url_mask': self.image_url_mask,
'image_url_logo': self.image_url_logo,
}

@ -1,26 +1,35 @@
# -*- coding: utf-8 -*-
#
# base class for easier library inclusion
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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.
__title__ = 'apprise'
__version__ = '0.5.0'
__author__ = 'Chris Caron <lead2gold@gmail.com>'
__license__ = 'GPLv3'
__copywrite__ = 'Copyright 2017-2018 Chris Caron <lead2gold@gmail.com>'
__version__ = '0.7.3'
__author__ = 'Chris Caron'
__license__ = 'MIT'
__copywrite__ = 'Copyright 2019 Chris Caron <lead2gold@gmail.com>'
__email__ = 'lead2gold@gmail.com'
__status__ = 'Production'
from .common import NotifyType
from .common import NOTIFY_TYPES

@ -1,24 +1,28 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Apprise CLI Tool
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
#
# You should have received a copy of the GNU Lesser General Public License
# along with apprise. If not, see <http://www.gnu.org/licenses/>.
# 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 click
import logging

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# Base Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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.
class NotifyType(object):

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# Base Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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 logging
@ -33,6 +40,7 @@ except ImportError:
from ..utils import parse_url
from ..utils import parse_bool
from ..utils import parse_list
from ..utils import is_hostname
from ..common import NOTIFY_TYPES
from ..common import NotifyFormat
@ -120,6 +128,9 @@ class NotifyBase(object):
# Default Notify Format
notify_format = NotifyFormat.TEXT
# Maintain a set of tags to associate with this specific notification
tags = set()
# Logging
logger = logging.getLogger(__name__)
@ -151,10 +162,11 @@ class NotifyBase(object):
self.user = kwargs.get('user')
self.password = kwargs.get('password')
self.headers = kwargs.get('headers')
if 'notify_format' in kwargs:
# Store the specified notify_format if specified
notify_format = kwargs.get('notify_format')
if 'format' in kwargs:
# Store the specified format if specified
notify_format = kwargs.get('format', '')
if notify_format.lower() not in NOTIFY_FORMATS:
self.logger.error(
'Invalid notification format %s' % notify_format,
@ -165,6 +177,12 @@ class NotifyBase(object):
# Provide override
self.notify_format = notify_format
if 'tag' in kwargs:
# We want to associate some tags with our notification service.
# the code below gets the 'tag' argument if defined, otherwise
# it just falls back to whatever was already defined globally
self.tags = set(parse_list(kwargs.get('tag', self.tags)))
def throttle(self, throttle_time=None):
"""
A common throttle control
@ -242,6 +260,19 @@ class NotifyBase(object):
color_type=color_type,
)
def __contains__(self, tags):
"""
Returns true if the tag specified is associated with this notification.
tag can also be a tuple, set, and/or list
"""
if isinstance(tags, (tuple, set, list)):
return bool(set(tags) & self.tags)
# return any match
return tags in self.tags
@property
def app_id(self):
return self.asset.app_id
@ -260,6 +291,10 @@ class NotifyBase(object):
Takes html text as input and escapes it so that it won't
conflict with any xml/html wrapping characters.
"""
if not html:
# nothing more to do; return object as is
return html
escaped = _escape(html)
if whitespace:
@ -390,4 +425,6 @@ class NotifyBase(object):
if 'user' in results['qsd']:
results['user'] = results['qsd']['user']
results['headers'] = {k[1:]: v for k, v in results['qsd'].items()
if re.match(r'^-.', k)}
return results

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# Boxcar Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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.
from json import dumps
import requests

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# Discord Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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.
# For this to work correctly you need to create a webhook. To do this just
# click on the little gear icon next to the channel you're part of. From
@ -59,7 +66,7 @@ class NotifyDiscord(NotifyBase):
secure_protocol = 'discord'
# A URL that takes you to the setup/help of the specific protocol
setup_url = 'https://github.com/caronc/apprise/wiki/Notify_discored'
setup_url = 'https://github.com/caronc/apprise/wiki/Notify_discord'
# Discord Webhook
notify_url = 'https://discordapp.com/api/webhooks'
@ -70,9 +77,6 @@ class NotifyDiscord(NotifyBase):
# The maximum allowable characters allowed in the body per message
body_maxlen = 2000
# Default Notify Format
notify_format = NotifyFormat.MARKDOWN
def __init__(self, webhook_id, webhook_token, tts=False, avatar=True,
footer=False, thumbnail=True, **kwargs):
"""
@ -129,9 +133,15 @@ class NotifyDiscord(NotifyBase):
'wait': self.tts is False,
# Our color associated with our notification
'color': self.color(notify_type, int),
'color': self.color(notify_type, int)
}
# Acquire image_url
image_url = self.image_url(notify_type)
'embeds': [{
if self.notify_format == NotifyFormat.MARKDOWN:
# Use embeds for payload
payload['embeds'] = [{
'provider': {
'name': self.app_id,
'url': self.app_url,
@ -140,9 +150,8 @@ class NotifyDiscord(NotifyBase):
'type': 'rich',
'description': body,
}]
}
if self.notify_format == NotifyFormat.MARKDOWN:
# Break titles out so that we can sort them in embeds
fields = self.extract_markdown_sections(body)
if len(fields) > 0:
@ -153,25 +162,29 @@ class NotifyDiscord(NotifyBase):
fields[0].get('name') + fields[0].get('value')
payload['embeds'][0]['fields'] = fields[1:]
if self.footer:
logo_url = self.image_url(notify_type, logo=True)
payload['embeds'][0]['footer'] = {
'text': self.app_desc,
}
if logo_url:
payload['embeds'][0]['footer']['icon_url'] = logo_url
if self.footer:
logo_url = self.image_url(notify_type, logo=True)
payload['embeds'][0]['footer'] = {
'text': self.app_desc,
}
image_url = self.image_url(notify_type)
if image_url:
if self.thumbnail:
if logo_url:
payload['embeds'][0]['footer']['icon_url'] = logo_url
if self.thumbnail and image_url:
payload['embeds'][0]['thumbnail'] = {
'url': image_url,
'height': 256,
'width': 256,
}
if self.avatar:
payload['avatar_url'] = image_url
else:
# not markdown
payload['content'] = body if not title \
else "{}\r\n{}".format(title, body)
if self.avatar and image_url:
payload['avatar_url'] = image_url
if self.user:
# Optionally override the default username of the webhook
@ -271,7 +284,7 @@ class NotifyDiscord(NotifyBase):
# Use Thumbnail
results['thumbnail'] = \
parse_bool(results['qsd'].get('thumbnail', True))
parse_bool(results['qsd'].get('thumbnail', False))
return results
@ -284,8 +297,8 @@ class NotifyDiscord(NotifyBase):
"""
regex = re.compile(
r'\s*#+\s*(?P<name>[^#\n]+)([ \r\t\v#]*)'
r'(?P<value>(.+?)(\n(?!\s#))|\s*$)', flags=re.S)
r'^\s*#+\s*(?P<name>[^#\n]+)([ \r\t\v#])?'
r'(?P<value>([^ \r\t\v#].+?)(\n(?!\s#))|\s*$)', flags=re.S | re.M)
common = regex.finditer(markdown)
fields = list()

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# Email Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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
@ -40,6 +47,18 @@ class WebBaseLogin(object):
USERID = 'UserID'
# Secure Email Modes
class SecureMailMode(object):
SSL = "ssl"
STARTTLS = "starttls"
# Define all of the secure modes (used during validation)
SECURE_MODES = (
SecureMailMode.SSL,
SecureMailMode.STARTTLS,
)
# To attempt to make this script stupid proof, if we detect an email address
# that is part of the this table, we can pre-use a lot more defaults if they
# aren't otherwise specified on the users input.
@ -47,11 +66,14 @@ WEBBASE_LOOKUP_TABLE = (
# Google GMail
(
'Google Mail',
re.compile(r'^((?P<label>[^+]+)\+)?(?P<id>[^@]+)@(?P<domain>gmail\.com)$', re.I),
re.compile(
r'^((?P<label>[^+]+)\+)?(?P<id>[^@]+)@'
r'(?P<domain>gmail\.com)$', re.I),
{
'port': 587,
'smtp_host': 'smtp.gmail.com',
'secure': True,
'secure_mode': SecureMailMode.STARTTLS,
'login_type': (WebBaseLogin.EMAIL, )
},
),
@ -59,11 +81,14 @@ WEBBASE_LOOKUP_TABLE = (
# Pronto Mail
(
'Pronto Mail',
re.compile(r'^((?P<label>[^+]+)\+)?(?P<id>[^@]+)@(?P<domain>prontomail\.com)$', re.I),
re.compile(
r'^((?P<label>[^+]+)\+)?(?P<id>[^@]+)@'
r'(?P<domain>prontomail\.com)$', re.I),
{
'port': 465,
'smtp_host': 'secure.emailsrvr.com',
'secure': True,
'secure_mode': SecureMailMode.STARTTLS,
'login_type': (WebBaseLogin.EMAIL, )
},
),
@ -71,11 +96,14 @@ WEBBASE_LOOKUP_TABLE = (
# Microsoft Hotmail
(
'Microsoft Hotmail',
re.compile(r'^((?P<label>[^+]+)\+)?(?P<id>[^@]+)@(?P<domain>(hotmail|live)\.com)$', re.I),
re.compile(
r'^((?P<label>[^+]+)\+)?(?P<id>[^@]+)@'
r'(?P<domain>(hotmail|live)\.com)$', re.I),
{
'port': 587,
'smtp_host': 'smtp.live.com',
'secure': True,
'secure_mode': SecureMailMode.STARTTLS,
'login_type': (WebBaseLogin.EMAIL, )
},
),
@ -83,11 +111,83 @@ WEBBASE_LOOKUP_TABLE = (
# Yahoo Mail
(
'Yahoo Mail',
re.compile(r'^((?P<label>[^+]+)\+)?(?P<id>[^@]+)@(?P<domain>yahoo\.(ca|com))$', re.I),
re.compile(
r'^((?P<label>[^+]+)\+)?(?P<id>[^@]+)@'
r'(?P<domain>yahoo\.(ca|com))$', re.I),
{
'port': 465,
'smtp_host': 'smtp.mail.yahoo.com',
'secure': True,
'secure_mode': SecureMailMode.STARTTLS,
'login_type': (WebBaseLogin.EMAIL, )
},
),
# Fast Mail (Series 1)
(
'Fast Mail',
re.compile(
r'^((?P<label>[^+]+)\+)?(?P<id>[^@]+)@'
r'(?P<domain>fastmail\.(com|cn|co\.uk|com\.au|de|es|fm|fr|im|'
r'in|jp|mx|net|nl|org|se|to|tw|uk|us))$', re.I),
{
'port': 465,
'smtp_host': 'smtp.fastmail.com',
'secure': True,
'secure_mode': SecureMailMode.SSL,
'login_type': (WebBaseLogin.EMAIL, )
},
),
# Fast Mail (Series 2)
(
'Fast Mail Extended Addresses',
re.compile(
r'^((?P<label>[^+]+)\+)?(?P<id>[^@]+)@'
r'(?P<domain>123mail\.org|airpost\.net|eml\.cc|fmail\.co\.uk|'
r'fmgirl\.com|fmguy\.com|mailbolt\.com|mailcan\.com|'
r'mailhaven\.com|mailmight\.com|ml1\.net|mm\.st|myfastmail\.com|'
r'proinbox\.com|promessage\.com|rushpost\.com|sent\.(as|at|com)|'
r'speedymail\.org|warpmail\.net|xsmail\.com|150mail\.com|'
r'150ml\.com|16mail\.com|2-mail\.com|4email\.net|50mail\.com|'
r'allmail\.net|bestmail\.us|cluemail\.com|elitemail\.org|'
r'emailcorner\.net|emailengine\.(net|org)|emailgroups\.net|'
r'emailplus\.org|emailuser\.net|f-m\.fm|fast-email\.com|'
r'fast-mail\.org|fastem\.com|fastemail\.us|fastemailer\.com|'
r'fastest\.cc|fastimap\.com|fastmailbox\.net|fastmessaging\.com|'
r'fea\.st|fmailbox\.com|ftml\.net|h-mail\.us|hailmail\.net|'
r'imap-mail\.com|imap\.cc|imapmail\.org|inoutbox\.com|'
r'internet-e-mail\.com|internet-mail\.org|internetemails\.net|'
r'internetmailing\.net|jetemail\.net|justemail\.net|'
r'letterboxes\.org|mail-central\.com|mail-page\.com|'
r'mailandftp\.com|mailas\.com|mailc\.net|mailforce\.net|'
r'mailftp\.com|mailingaddress\.org|mailite\.com|mailnew\.com|'
r'mailsent\.net|mailservice\.ms|mailup\.net|mailworks\.org|'
r'mymacmail\.com|nospammail\.net|ownmail\.net|petml\.com|'
r'postinbox\.com|postpro\.net|realemail\.net|reallyfast\.biz|'
r'reallyfast\.info|speedpost\.net|ssl-mail\.com|swift-mail\.com|'
r'the-fastest\.net|the-quickest\.com|theinternetemail\.com|'
r'veryfast\.biz|veryspeedy\.net|yepmail\.net)$', re.I),
{
'port': 465,
'smtp_host': 'smtp.fastmail.com',
'secure': True,
'secure_mode': SecureMailMode.SSL,
'login_type': (WebBaseLogin.EMAIL, )
},
),
# Zoho Mail
(
'Zoho Mail',
re.compile(
r'^((?P<label>[^+]+)\+)?(?P<id>[^@]+)@'
r'(?P<domain>zoho\.com)$', re.I),
{
'port': 465,
'smtp_host': 'smtp.zoho.com',
'secure': True,
'secure_mode': SecureMailMode.SSL,
'login_type': (WebBaseLogin.EMAIL, )
},
),
@ -95,7 +195,9 @@ WEBBASE_LOOKUP_TABLE = (
# Catch All
(
'Custom',
re.compile(r'^((?P<label>[^+]+)\+)?(?P<id>[^@]+)@(?P<domain>.+)$', re.I),
re.compile(
r'^((?P<label>[^+]+)\+)?(?P<id>[^@]+)@'
r'(?P<domain>.+)$', re.I),
{
# Setting smtp_host to None is a way of
# auto-detecting it based on other parameters
@ -125,12 +227,18 @@ class NotifyEmail(NotifyBase):
# A URL that takes you to the setup/help of the specific protocol
setup_url = 'https://github.com/caronc/apprise/wiki/Notify_email'
# Default Notify Format
notify_format = NotifyFormat.HTML
# Default Non-Encryption Port
default_port = 25
# Default Secure Port
default_secure_port = 587
# Default Secure Mode
default_secure_mode = SecureMailMode.STARTTLS
# Default SMTP Timeout (in seconds)
connect_timeout = 15
@ -171,6 +279,13 @@ class NotifyEmail(NotifyBase):
# Now detect the SMTP Server
self.smtp_host = kwargs.get('smtp_host', '')
# Now detect secure mode
self.secure_mode = kwargs.get('secure_mode', self.default_secure_mode)
if self.secure_mode not in SECURE_MODES:
raise TypeError(
'Invalid secure mode specified: %s.' % self.secure_mode)
# Apply any defaults based on certain known configurations
self.NotifyEmailDefaults()
@ -202,7 +317,8 @@ class NotifyEmail(NotifyBase):
.get('port', self.port)
self.secure = WEBBASE_LOOKUP_TABLE[i][2]\
.get('secure', self.secure)
self.secure_mode = WEBBASE_LOOKUP_TABLE[i][2]\
.get('secure_mode', self.secure_mode)
self.smtp_host = WEBBASE_LOOKUP_TABLE[i][2]\
.get('smtp_host', self.smtp_host)
@ -246,11 +362,9 @@ class NotifyEmail(NotifyBase):
# Prepare Email Message
if self.notify_format == NotifyFormat.HTML:
email = MIMEText(body, 'html')
email['Content-Type'] = 'text/html'
else:
email = MIMEText(body, 'text')
email['Content-Type'] = 'text/plain'
email = MIMEText(body, 'plain')
email['Subject'] = title
email['From'] = '%s <%s>' % (from_name, self.from_addr)
@ -263,16 +377,21 @@ class NotifyEmail(NotifyBase):
socket = None
try:
self.logger.debug('Connecting to remote SMTP server...')
socket = smtplib.SMTP(
socket_func = smtplib.SMTP
if self.secure and self.secure_mode == SecureMailMode.SSL:
self.logger.debug('Securing connection with SSL...')
socket_func = smtplib.SMTP_SSL
socket = socket_func(
self.smtp_host,
self.port,
None,
timeout=self.timeout,
)
if self.secure:
if self.secure and self.secure_mode == SecureMailMode.STARTTLS:
# Handle Secure Connections
self.logger.debug('Securing connection with TLS...')
self.logger.debug('Securing connection with STARTTLS...')
socket.starttls()
if self.user and self.password:
@ -317,19 +436,10 @@ class NotifyEmail(NotifyBase):
# Apply our settings now
# Default Format is HTML
results['notify_format'] = NotifyFormat.HTML
to_addr = ''
from_addr = ''
smtp_host = ''
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
# Attempt to detect 'from' email address
if 'from' in results['qsd'] and len(results['qsd']['from']):
from_addr = NotifyBase.unquote(results['qsd']['from'])
@ -369,6 +479,10 @@ class NotifyEmail(NotifyBase):
# Extract the smtp server
smtp_host = NotifyBase.unquote(results['qsd']['smtp'])
if 'mode' in results['qsd'] and len(results['qsd']['mode']):
# Extract the secure mode to over-ride the default
results['secure_mode'] = results['qsd']['mode'].lower()
results['to'] = to_addr
results['from'] = from_addr
results['smtp_host'] = smtp_host

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# Emby Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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.
# For this plugin to work correct, the Emby server must be set up to allow
# for remote connections.

@ -1,20 +1,26 @@
# -*- coding: utf-8 -*-
#
# Faast Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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 CON
import requests

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# Growl Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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

@ -1,18 +1,27 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017 Chris Caron <lead2gold@gmail.com>
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# This file is part of apprise.
# This code is licensed under the MIT License.
#
# 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.
# 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 :
#
# 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.
# 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.
from . import NotifyGrowl

@ -21,7 +21,7 @@ __all__ = [
logger = logging.getLogger(__name__)
class GrowlNotifier(gntp.notifier.GrowlNotifier):
class GrowlNotifier(notifier.GrowlNotifier):
"""
ConfigParser enhanced GrowlNotifier object
@ -36,7 +36,7 @@ class GrowlNotifier(gntp.notifier.GrowlNotifier):
port = ?
"""
def __init__(self, *args, **kwargs):
config = gntp.shim.RawConfigParser({
config = shim.RawConfigParser({
'hostname': kwargs.get('hostname', 'localhost'),
'password': kwargs.get('password'),
'port': kwargs.get('port', 23053),
@ -67,7 +67,7 @@ def mini(description, **kwargs):
:param string description: Notification message
"""
kwargs['notifierFactory'] = GrowlNotifier
gntp.notifier.mini(description, **kwargs)
notifier.mini(description, **kwargs)
if __name__ == '__main__':

@ -27,16 +27,16 @@ if PY3:
from configparser import RawConfigParser
else:
def b(s):
if isinstance(s, unicode):
if isinstance(s, unicode): # noqa
return s.encode('utf8', 'replace')
return s
def u(s):
if isinstance(s, unicode):
if isinstance(s, unicode): # noqa
return s
if isinstance(s, int):
s = str(s)
return unicode(s, "utf8", "replace")
return unicode(s, "utf8", "replace") # noqa
from StringIO import StringIO
from ConfigParser import RawConfigParser

@ -2,19 +2,28 @@
#
# IFTTT (If-This-Then-That)
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# This file is part of apprise.
# This code is licensed under the MIT License.
#
# 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.
# 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 :
#
# 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.
# 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.
#
# For this plugin to work, you need to add the Maker applet to your profile
# Simply visit https://ifttt.com/search and search for 'Webhooks'

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# JSON Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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 requests
from json import dumps
@ -84,6 +91,9 @@ class NotifyJSON(NotifyBase):
'Content-Type': 'application/json'
}
if self.headers:
headers.update(self.headers)
auth = None
if self.user:
auth = (self.user, self.password)

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# Join Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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.
# Join URL: http://joaoapps.com/join/
# To use this plugin, you need to first access (make sure your browser allows

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# MatterMost Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# Prowl Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# PushBullet Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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

@ -1,161 +0,0 @@
# -*- coding: utf-8 -*-
#
# Pushalot Notify Wrapper
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
#
# 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 json import dumps
from .NotifyBase import NotifyBase
from .NotifyBase import HTTP_ERROR_MAP
from ..common import NotifyImageSize
# Extend HTTP Error Messages
PUSHALOT_HTTP_ERROR_MAP = HTTP_ERROR_MAP.copy()
PUSHALOT_HTTP_ERROR_MAP.update({
406: 'Message throttle limit hit.',
410: 'AuthorizedToken is no longer valid.',
})
# Used to validate Authorization Token
VALIDATE_AUTHTOKEN = re.compile(r'[A-Za-z0-9]{32}')
class NotifyPushalot(NotifyBase):
"""
A wrapper for Pushalot Notifications
"""
# The default descriptive name associated with the Notification
service_name = 'Pushalot'
# The services URL
service_url = 'https://pushalot.com/'
# The default protocol is always secured
secure_protocol = 'palot'
# A URL that takes you to the setup/help of the specific protocol
setup_url = 'https://github.com/caronc/apprise/wiki/Notify_pushalot'
# Pushalot uses the http protocol with JSON requests
notify_url = 'https://pushalot.com/api/sendmessage'
# Allows the user to specify the NotifyImageSize object
image_size = NotifyImageSize.XY_72
def __init__(self, authtoken, is_important=False, **kwargs):
"""
Initialize Pushalot Object
"""
super(NotifyPushalot, self).__init__(**kwargs)
# Is Important Flag
self.is_important = is_important
self.authtoken = authtoken
# Validate authtoken
if not VALIDATE_AUTHTOKEN.match(authtoken):
self.logger.warning(
'Invalid Pushalot Authorization Token Specified.'
)
raise TypeError(
'Invalid Pushalot Authorization Token Specified.'
)
def notify(self, title, body, notify_type, **kwargs):
"""
Perform Pushalot Notification
"""
headers = {
'User-Agent': self.app_id,
'Content-Type': 'application/json'
}
# prepare JSON Object
payload = {
'AuthorizationToken': self.authtoken,
'IsImportant': self.is_important,
'Title': title,
'Body': body,
'Source': self.app_id,
}
image_url = self.image_url(notify_type)
if image_url:
payload['Image'] = image_url
self.logger.debug('Pushalot POST URL: %s (cert_verify=%r)' % (
self.notify_url, self.verify_certificate,
))
self.logger.debug('Pushalot Payload: %s' % str(payload))
try:
r = requests.post(
self.notify_url,
data=dumps(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 Pushalot notification: '
'%s (error=%s).' % (
PUSHALOT_HTTP_ERROR_MAP[r.status_code],
r.status_code))
except KeyError:
self.logger.warning(
'Failed to send Pushalot notification '
'(error=%s).' % r.status_code)
# Return; we're done
return False
else:
self.logger.info('Sent Pushalot notification.')
except requests.RequestException as e:
self.logger.warning(
'A Connection error occured sending Pushalot 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['authtoken'] = results['host']
return results

@ -1,20 +1,28 @@
# -*- coding: utf-8 -*-
#
# Pushjet Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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
from .pushjet import errors
from .pushjet import pushjet
@ -35,9 +43,6 @@ class NotifyPushjet(NotifyBase):
# The default descriptive name associated with the Notification
service_name = 'Pushjet'
# The services URL
service_url = 'https://pushjet.io/'
# The default protocol
protocol = 'pjet'
@ -58,21 +63,16 @@ class NotifyPushjet(NotifyBase):
Perform Pushjet Notification
"""
try:
if self.user and self.host:
server = "http://"
if self.secure:
server = "https://"
server += self.host
if self.port:
server += ":" + str(self.port)
server = "http://"
if self.secure:
server = "https://"
api = pushjet.Api(server)
service = api.Service(secret_key=self.user)
server += self.host
if self.port:
server += ":" + str(self.port)
else:
api = pushjet.Api(pushjet.DEFAULT_API_URL)
service = api.Service(secret_key=self.host)
api = pushjet.Api(server)
service = api.Service(secret_key=self.user)
service.send(body, title)
self.logger.info('Sent Pushjet notification.')
@ -83,3 +83,28 @@ class NotifyPushjet(NotifyBase):
return False
return True
@staticmethod
def parse_url(url):
"""
Parses the URL and returns enough arguments that can allow
us to substantiate this object.
Syntax:
pjet://secret@hostname
pjet://secret@hostname:port
pjets://secret@hostname
pjets://secret@hostname:port
"""
results = NotifyBase.parse_url(url)
if not results:
# We're done early as we couldn't load the results
return results
if not results.get('user'):
# a username is required
return None
return results

@ -1,18 +1,27 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017 Chris Caron <lead2gold@gmail.com>
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# This file is part of apprise.
# This code is licensed under the MIT License.
#
# 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.
# 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 :
#
# 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.
# 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.
from . import NotifyPushjet

@ -1,8 +1,12 @@
# -*- coding: utf-8 -*-
import sys
import requests
from functools import partial
from six import text_type
from six.moves.urllib.parse import urljoin
from .utilities import (
NoNoneDict,
requires_secret_key, with_api_bound,
@ -10,14 +14,6 @@ from .utilities import (
)
from .errors import NonexistentError, SubscriptionError, RequestError, ServerError
import sys
if sys.version_info[0] >= 3:
from urllib.parse import urljoin
unicode_type = str
else:
from urlparse import urljoin
unicode_type = unicode
DEFAULT_API_URL = 'https://api.pushjet.io/'
class PushjetModel(object):
@ -52,8 +48,8 @@ class Service(PushjetModel):
raise ValueError("Invalid secret key provided.")
elif public_key and not is_valid_public_key(public_key):
raise ValueError("Invalid public key provided.")
self.secret_key = unicode_type(secret_key) if secret_key else None
self.public_key = unicode_type(public_key) if public_key else None
self.secret_key = text_type(secret_key) if secret_key else None
self.public_key = text_type(public_key) if public_key else None
self.refresh()
def _request(self, endpoint, method, is_secret, params=None, data=None):
@ -97,8 +93,8 @@ class Service(PushjetModel):
if not data:
return
self._request('service', 'PATCH', is_secret=True, data=data)
self.name = unicode_type(name)
self.icon_url = unicode_type(icon_url)
self.name = text_type(name)
self.icon_url = text_type(icon_url)
@requires_secret_key
def delete(self):
@ -171,10 +167,10 @@ class Device(PushjetModel):
return "<Pushjet Device: {}>".format(self.uuid)
def __init__(self, uuid):
uuid = unicode_type(uuid)
uuid = text_type(uuid)
if not is_valid_uuid(uuid):
raise ValueError("Invalid UUID provided. Try uuid.uuid4().")
self.uuid = unicode_type(uuid)
self.uuid = text_type(uuid)
def _request(self, endpoint, method, params=None, data=None):
params = (params or {})
@ -292,7 +288,7 @@ class Api(object):
return "<Pushjet Api: {}>".format(self.url).encode(sys.stdout.encoding, errors='replace')
def __init__(self, url):
self.url = unicode_type(url)
self.url = text_type(url)
self.Service = with_api_bound(Service, self)
self.Device = with_api_bound(Device, self)

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# Pushover Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# Notify Rocket.Chat Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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
@ -114,7 +121,7 @@ class NotifyRocketChat(NotifyBase):
continue
self.logger.warning(
'Dropped invalid channel/room ' +
'Dropped invalid channel/room '
'(%s) specified.' % recipient,
)
@ -206,14 +213,14 @@ class NotifyRocketChat(NotifyBase):
# We had a problem
try:
self.logger.warning(
'Failed to send Rocket.Chat notification: ' +
'Failed to send Rocket.Chat notification: '
'%s (error=%s).' % (
RC_HTTP_ERROR_MAP[r.status_code],
r.status_code))
except KeyError:
self.logger.warning(
'Failed to send Rocket.Chat notification ' +
'Failed to send Rocket.Chat notification '
'(error=%s).' % (
r.status_code))
@ -226,7 +233,7 @@ class NotifyRocketChat(NotifyBase):
except requests.RequestException as e:
self.logger.warning(
'A Connection error occured sending Rocket.Chat ' +
'A Connection error occured sending Rocket.Chat '
'notification.')
self.logger.debug('Socket Exception: %s' % str(e))
@ -255,14 +262,14 @@ class NotifyRocketChat(NotifyBase):
# We had a problem
try:
self.logger.warning(
'Failed to authenticate with Rocket.Chat server: ' +
'Failed to authenticate with Rocket.Chat server: '
'%s (error=%s).' % (
RC_HTTP_ERROR_MAP[r.status_code],
r.status_code))
except KeyError:
self.logger.warning(
'Failed to authenticate with Rocket.Chat server ' +
'Failed to authenticate with Rocket.Chat server '
'(error=%s).' % (
r.status_code))
@ -285,7 +292,7 @@ class NotifyRocketChat(NotifyBase):
except requests.RequestException as e:
self.logger.warning(
'A Connection error occured authenticating to the ' +
'A Connection error occured authenticating to the '
'Rocket.Chat server.')
self.logger.debug('Socket Exception: %s' % str(e))
return False
@ -306,14 +313,14 @@ class NotifyRocketChat(NotifyBase):
# We had a problem
try:
self.logger.warning(
'Failed to log off Rocket.Chat server: ' +
'Failed to log off Rocket.Chat server: '
'%s (error=%s).' % (
RC_HTTP_ERROR_MAP[r.status_code],
r.status_code))
except KeyError:
self.logger.warning(
'Failed to log off Rocket.Chat server ' +
'Failed to log off Rocket.Chat server '
'(error=%s).' % (
r.status_code))
@ -327,7 +334,7 @@ class NotifyRocketChat(NotifyBase):
except requests.RequestException as e:
self.logger.warning(
'A Connection error occured logging off the ' +
'A Connection error occured logging off the '
'Rocket.Chat server')
self.logger.debug('Socket Exception: %s' % str(e))
return False

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# Slack Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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.
# To use this plugin, you need to first access https://api.slack.com
# Specifically https://my.slack.com/services/new/incoming-webhook/

@ -1,246 +0,0 @@
# -*- coding: utf-8 -*-
#
# Stride Notify Wrapper
#
# Copyright (C) 2018 Chris Caron <lead2gold@gmail.com>
#
# 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.
# When you sign-up with stride.com they'll ask if you want to join a channel
# or create your own.
#
# Once you get set up, you'll have the option of creating a channel.
#
# Now you'll want to connect apprise up. To do this, you need to go to
# the App Manager an choose to 'Connect your own app'. It will get you
# to provide a 'token name' which can be whatever you want. Call it
# 'Apprise' if you want (it really doesn't matter) and then click the
# 'Create' button.
#
# When it completes it will generate a token that looks something like:
# HQFtq4pF8rKFOlKTm9Th
#
# This will become your AUTH_TOKEN
#
# It will also provide you a conversation URL that might look like:
# https://api.atlassian.com/site/ce171c45-79ae-4fec-a73d-5a4b7a322872/\
# conversation/a54a80b3-eaad-4564-9a3a-f6653bcfb100/message
#
# Simplified, it looks like this:
# https://api.atlassian.com/site/CLOUD_ID/conversation/CONVO_ID/message
#
# This plugin will simply work using the url of:
# stride://AUTH_TOKEN/CLOUD_ID/CONVO_ID
#
import requests
import re
from json import dumps
from .NotifyBase import NotifyBase
from .NotifyBase import HTTP_ERROR_MAP
from ..common import NotifyImageSize
# A Simple UUID4 checker
IS_VALID_TOKEN = re.compile(
r'([0-9a-f]{8})-*([0-9a-f]{4})-*(4[0-9a-f]{3})-*'
r'([89ab][0-9a-f]{3})-*([0-9a-f]{12})', re.I)
class NotifyStride(NotifyBase):
"""
A wrapper to Stride Notifications
"""
# The default descriptive name associated with the Notification
service_name = 'Stride'
# The services URL
service_url = 'https://www.stride.com/'
# The default secure protocol
secure_protocol = 'stride'
# A URL that takes you to the setup/help of the specific protocol
setup_url = 'https://github.com/caronc/apprise/wiki/Notify_stride'
# Stride Webhook
notify_url = 'https://api.atlassian.com/site/{cloud_id}/' \
'conversation/{convo_id}/message'
# Allows the user to specify the NotifyImageSize object
image_size = NotifyImageSize.XY_256
# The maximum allowable characters allowed in the body per message
body_maxlen = 2000
def __init__(self, auth_token, cloud_id, convo_id, **kwargs):
"""
Initialize Stride Object
"""
super(NotifyStride, self).__init__(**kwargs)
if not auth_token:
raise TypeError(
'An invalid Authorization token was specified.'
)
if not cloud_id:
raise TypeError('No Cloud ID was specified.')
cloud_id_re = IS_VALID_TOKEN.match(cloud_id)
if cloud_id_re is None:
raise TypeError('The specified Cloud ID is not a valid UUID.')
if not convo_id:
raise TypeError('No Conversation ID was specified.')
convo_id_re = IS_VALID_TOKEN.match(convo_id)
if convo_id_re is None:
raise TypeError(
'The specified Conversation ID is not a valid UUID.')
# Store our validated token
self.cloud_id = '{0}-{1}-{2}-{3}-{4}'.format(
cloud_id_re.group(0),
cloud_id_re.group(1),
cloud_id_re.group(2),
cloud_id_re.group(3),
cloud_id_re.group(4),
)
# Store our validated token
self.convo_id = '{0}-{1}-{2}-{3}-{4}'.format(
convo_id_re.group(0),
convo_id_re.group(1),
convo_id_re.group(2),
convo_id_re.group(3),
convo_id_re.group(4),
)
self.auth_token = auth_token
return
def notify(self, title, body, notify_type, **kwargs):
"""
Perform Stride Notification
"""
headers = {
'User-Agent': self.app_id,
'Authorization': 'Bearer {auth_token}'.format(
auth_token=self.auth_token),
'Content-Type': 'application/json',
}
# Prepare JSON Object
payload = {
"body": {
"version": 1,
"type": "doc",
"content": [{
"type": "paragraph",
"content": [{
"type": "text",
"text": body,
}],
}],
}
}
# Construct Notify URL
notify_url = self.notify_url.format(
cloud_id=self.cloud_id,
convo_id=self.convo_id,
)
self.logger.debug('Stride POST URL: %s (cert_verify=%r)' % (
notify_url, self.verify_certificate,
))
self.logger.debug('Stride Payload: %s' % str(payload))
try:
r = requests.post(
notify_url,
data=dumps(payload),
headers=headers,
verify=self.verify_certificate,
)
if r.status_code not in (
requests.codes.ok, requests.codes.no_content):
# We had a problem
try:
self.logger.warning(
'Failed to send Stride notification: '
'%s (error=%s).' % (
HTTP_ERROR_MAP[r.status_code],
r.status_code))
except KeyError:
self.logger.warning(
'Failed to send Stride notification '
'(error=%s).' % r.status_code)
self.logger.debug('Response Details: %s' % r.raw.read())
# Return; we're done
return False
else:
self.logger.info('Sent Stride notification.')
except requests.RequestException as e:
self.logger.warning(
'A Connection error occured sending Stride '
'notification.'
)
self.logger.debug('Socket Exception: %s' % str(e))
return False
return True
@staticmethod
def parse_url(url):
"""
Parses the URL and returns enough arguments that can allow
us to substantiate this object.
Syntax:
stride://auth_token/cloud_id/convo_id
"""
results = NotifyBase.parse_url(url)
if not results:
# We're done early as we couldn't load the results
return results
# Store our Authentication Token
auth_token = results['host']
# Now fetch our tokens
try:
(ta, tb) = [x for x in filter(bool, NotifyBase.split_path(
results['fullpath']))][0:2]
except (ValueError, AttributeError, IndexError):
# Force some bad values that will get caught
# in parsing later
ta = None
tb = None
results['cloud_id'] = ta
results['convo_id'] = tb
results['auth_token'] = auth_token
return results

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# Telegram Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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.
# To use this plugin, you need to first access https://api.telegram.org
# You need to create a bot and acquire it's Token Identifier (bot_token)
@ -55,6 +62,7 @@ from .NotifyBase import HTTP_ERROR_MAP
from ..common import NotifyImageSize
from ..utils import compat_is_basestring
from ..utils import parse_bool
from ..common import NotifyFormat
TELEGRAM_IMAGE_XY = NotifyImageSize.XY_256
@ -255,7 +263,7 @@ class NotifyTelegram(NotifyBase):
# Try to get the error message if we can:
error_msg = loads(r.content)['description']
except:
except Exception:
error_msg = None
try:
@ -349,24 +357,50 @@ class NotifyTelegram(NotifyBase):
payload = {}
# HTML Spaces (&nbsp;) and tabs (&emsp;) aren't supported
# See https://core.telegram.org/bots/api#html-style
title = re.sub('&nbsp;?', ' ', title, re.I)
body = re.sub('&nbsp;?', ' ', body, re.I)
# Tabs become 3 spaces
title = re.sub('&emsp;?', ' ', title, re.I)
body = re.sub('&emsp;?', ' ', body, re.I)
# Prepare Email Message
if self.notify_format == NotifyFormat.MARKDOWN:
payload['parse_mode'] = 'MARKDOWN'
# HTML
title = NotifyBase.escape_html(title, whitespace=False)
body = NotifyBase.escape_html(body, whitespace=False)
else:
# Either TEXT or HTML; if TEXT we'll make it HTML
payload['parse_mode'] = 'HTML'
payload['parse_mode'] = 'HTML'
# HTML Spaces (&nbsp;) and tabs (&emsp;) aren't supported
# See https://core.telegram.org/bots/api#html-style
body = re.sub('&nbsp;?', ' ', body, re.I)
payload['text'] = '<b>%s</b>\r\n%s' % (
title,
body,
)
# Tabs become 3 spaces
body = re.sub('&emsp;?', ' ', body, re.I)
if title:
# HTML Spaces (&nbsp;) and tabs (&emsp;) aren't supported
# See https://core.telegram.org/bots/api#html-style
title = re.sub('&nbsp;?', ' ', title, re.I)
# Tabs become 3 spaces
title = re.sub('&emsp;?', ' ', title, re.I)
# HTML
title = NotifyBase.escape_html(title, whitespace=False)
body = NotifyBase.escape_html(body, whitespace=False)
# Assign the body
payload['text'] = body
if title and self.notify_format == NotifyFormat.TEXT:
# Text HTML Formatting
payload['text'] = '<b>%s</b>\r\n%s' % (
title,
body,
)
elif title:
# Already HTML; trust developer has wrapped
# the title appropriately
payload['text'] = '%s\r\n%s' % (
title,
body,
)
# Create a copy of the chat_ids list
chat_ids = list(self.chat_ids)
@ -419,7 +453,7 @@ class NotifyTelegram(NotifyBase):
# Try to get the error message if we can:
error_msg = loads(r.content)['description']
except:
except Exception:
error_msg = None
try:

@ -1,180 +0,0 @@
# -*- coding: utf-8 -*-
#
# (Super) Toasty Notify Wrapper
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
#
# 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 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

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# Twitter Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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.
from . import tweepy
from ..NotifyBase import NotifyBase

@ -1,18 +1,27 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017 Chris Caron <lead2gold@gmail.com>
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# This file is part of apprise.
# This code is licensed under the MIT License.
#
# 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.
# 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 :
#
# 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.
# 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.
from . import NotifyTwitter

@ -1,20 +1,28 @@
# -*- coding: utf-8 -*-
#
# Windows Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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.
from __future__ import absolute_import
from __future__ import print_function

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# XBMC/KODI Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# XML Notify Wrapper
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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
@ -89,6 +96,9 @@ class NotifyXML(NotifyBase):
'Content-Type': 'application/xml'
}
if self.headers:
headers.update(self.headers)
re_map = {
'{MESSAGE_TYPE}': NotifyBase.quote(notify_type),
'{SUBJECT}': NotifyBase.quote(title),

@ -1,45 +1,55 @@
# -*- coding: utf-8 -*-
#
# Our service wrappers
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017-2018 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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.
# Used for Testing; specifically test_email_plugin.py needs access
# to the modules WEBBASE_LOOKUP_TABLE and WebBaseLogin objects
from . import NotifyEmail as NotifyEmailBase
from .NotifyBoxcar import NotifyBoxcar
from .NotifyDBus import NotifyDBus
from .NotifyDiscord import NotifyDiscord
from .NotifyEmail import NotifyEmail
from .NotifyEmby import NotifyEmby
from .NotifyFaast import NotifyFaast
from .NotifyGrowl.NotifyGrowl import NotifyGrowl
from .NotifyGnome import NotifyGnome
from .NotifyIFTTT import NotifyIFTTT
from .NotifyJoin import NotifyJoin
from .NotifyJSON import NotifyJSON
from .NotifyMatrix import NotifyMatrix
from .NotifyMatterMost import NotifyMatterMost
from .NotifyProwl import NotifyProwl
from .NotifyPushalot import NotifyPushalot
from .NotifyPushed import NotifyPushed
from .NotifyPushBullet import NotifyPushBullet
from .NotifyPushjet.NotifyPushjet import NotifyPushjet
from .NotifyPushover import NotifyPushover
from .NotifyRocketChat import NotifyRocketChat
from .NotifyRyver import NotifyRyver
from .NotifySlack import NotifySlack
from .NotifyStride import NotifyStride
from .NotifySNS import NotifySNS
from .NotifyTelegram import NotifyTelegram
from .NotifyToasty import NotifyToasty
from .NotifyTwitter.NotifyTwitter import NotifyTwitter
from .NotifyXBMC import NotifyXBMC
from .NotifyXML import NotifyXML
@ -56,12 +66,13 @@ from ..common import NOTIFY_TYPES
__all__ = [
# Notification Services
'NotifyBoxcar', 'NotifyEmail', 'NotifyEmby', 'NotifyDiscord',
'NotifyFaast', 'NotifyGrowl', 'NotifyIFTTT', 'NotifyJoin', 'NotifyJSON',
'NotifyMatterMost', 'NotifyProwl', 'NotifyPushalot',
'NotifyPushBullet', 'NotifyPushjet', 'NotifyPushover', 'NotifyRocketChat',
'NotifySlack', 'NotifyStride', 'NotifyToasty', 'NotifyTwitter',
'NotifyTelegram', 'NotifyXBMC', 'NotifyXML', 'NotifyWindows',
'NotifyBoxcar', 'NotifyDBus', 'NotifyEmail', 'NotifyEmby', 'NotifyDiscord',
'NotifyFaast', 'NotifyGnome', 'NotifyGrowl', 'NotifyIFTTT', 'NotifyJoin',
'NotifyJSON', 'NotifyMatrix', 'NotifyMatterMost', 'NotifyProwl',
'NotifyPushed', 'NotifyPushBullet', 'NotifyPushjet',
'NotifyPushover', 'NotifyRocketChat', 'NotifyRyver', 'NotifySlack',
'NotifySNS', 'NotifyTwitter', 'NotifyTelegram', 'NotifyXBMC',
'NotifyXML', 'NotifyWindows',
# Reference
'NotifyImageSize', 'NOTIFY_IMAGE_SIZES', 'NotifyType', 'NOTIFY_TYPES',

@ -1,20 +1,27 @@
# -*- coding: utf-8 -*-
#
# A simple collection of general functions
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# Copyright (C) 2017 Chris Caron <lead2gold@gmail.com>
# This code is licensed under the MIT License.
#
# This file is part of apprise.
# 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 :
#
# 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.
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# 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.
# 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
@ -84,6 +91,9 @@ TIDY_NUX_TRIM_RE = re.compile(
),
)
# Used for attempting to acquire the schema if the URL can't be parsed.
GET_SCHEMA_RE = re.compile(r'\s*(?P<schema>[a-z0-9]{2,9})://.*$', re.I)
def is_hostname(hostname):
"""

Loading…
Cancel
Save