Notica Support Added; fixes #165 (#166)

This commit is contained in:
Chris Caron 2019-10-19 09:28:31 -04:00 committed by GitHub
parent 2a31d393b7
commit acc461d598
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 271 additions and 6 deletions

View File

@ -50,6 +50,7 @@ The table below identifies the services this tool supports and some example serv
| [Matrix](https://github.com/caronc/apprise/wiki/Notify_matrix) | matrix:// or matrixs:// | (TCP) 80 or 443 | matrix://hostname<br />matrix://user@hostname<br />matrixs://user:pass@hostname:port/#room_alias<br />matrixs://user:pass@hostname:port/!room_id<br />matrixs://user:pass@hostname:port/#room_alias/!room_id/#room2<br />matrixs://token@hostname:port/?webhook=matrix<br />matrix://user:token@hostname/?webhook=slack&format=markdown
| [Mattermost](https://github.com/caronc/apprise/wiki/Notify_mattermost) | mmost:// | (TCP) 8065 | mmost://hostname/authkey<br />mmost://hostname:80/authkey<br />mmost://user@hostname:80/authkey<br />mmost://hostname/authkey?channel=channel<br />mmosts://hostname/authkey<br />mmosts://user@hostname/authkey<br />
| [Microsoft Teams](https://github.com/caronc/apprise/wiki/Notify_msteams) | msteams:// | (TCP) 443 | msteams://TokenA/TokenB/TokenC/
| [Notica](https://github.com/caronc/apprise/wiki/Notify_notica) | notica:// | (TCP) 443 | notica://Token/
| [Notifico](https://github.com/caronc/apprise/wiki/Notify_notifico) | notifico:// | (TCP) 443 | notifico://ProjectID/MessageHook/
| [Prowl](https://github.com/caronc/apprise/wiki/Notify_prowl) | prowl:// | (TCP) 443 | prowl://apikey<br />prowl://apikey/providerkey
| [PushBullet](https://github.com/caronc/apprise/wiki/Notify_pushbullet) | pbul:// | (TCP) 443 | pbul://accesstoken<br />pbul://accesstoken/#channel<br/>pbul://accesstoken/A_DEVICE_ID<br />pbul://accesstoken/email@address.com<br />pbul://accesstoken/#channel/#channel2/email@address.net/DEVICE

View File

@ -0,0 +1,216 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019 Chris Caron <lead2gold@gmail.com>
# All rights reserved.
#
# This code is licensed under the MIT License.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files(the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions :
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CON
# 1. Simply visit https://notica.us
# 2. You'll be provided a new variation of the website which will look
# something like: https://notica.us/?abc123.
# ^
# |
# token
#
# Your token is actually abc123 (do not include/grab the question mark)
# You can use that URL as is directly in Apprise, or you can follow
# the next step which shows you how to assemble the Apprise URL:
#
# 3. With respect to the above, your apprise URL would be:
# notica://abc123
#
import re
import requests
from .NotifyBase import NotifyBase
from ..common import NotifyType
from ..utils import validate_regex
from ..AppriseLocale import gettext_lazy as _
class NotifyNotica(NotifyBase):
"""
A wrapper for Notica Notifications
"""
# The default descriptive name associated with the Notification
service_name = 'Notica'
# The services URL
service_url = 'https://notica.us/'
# The default protocol (this is secure for notica)
secure_protocol = 'notica'
# A URL that takes you to the setup/help of the specific protocol
setup_url = 'https://github.com/caronc/apprise/wiki/Notify_notica'
# Notica URL
notify_url = 'https://notica.us/?{token}'
# Notica does not support a title
title_maxlen = 0
# Define object templates
templates = (
'{schema}://{token}',
)
# Define our template tokens
template_tokens = dict(NotifyBase.template_tokens, **{
'token': {
'name': _('Token'),
'type': 'string',
'private': True,
'required': True,
'regex': r'^\?*(?P<token>[^/]+)\s*$'
},
})
def __init__(self, token, **kwargs):
"""
Initialize Notica Object
"""
super(NotifyNotica, self).__init__(**kwargs)
# Token (associated with project)
self.token = validate_regex(token)
if not self.token:
msg = 'An invalid Notica Token ' \
'({}) was specified.'.format(token)
self.logger.warning(msg)
raise TypeError(msg)
return
def send(self, body, title='', notify_type=NotifyType.INFO, **kwargs):
"""
Perform Notica Notification
"""
headers = {
'User-Agent': self.app_id,
'Content-Type': 'application/x-www-form-urlencoded'
}
# Prepare our payload
payload = 'd:{}'.format(body)
# prepare our notify url
notify_url = self.notify_url.format(token=self.token)
self.logger.debug('Notica POST URL: %s (cert_verify=%r)' % (
notify_url, self.verify_certificate,
))
self.logger.debug('Notica Payload: %s' % str(payload))
# Always call throttle before any remote server i/o is made
self.throttle()
try:
r = requests.post(
notify_url.format(token=self.token),
data=payload,
headers=headers,
verify=self.verify_certificate,
)
if r.status_code != requests.codes.ok:
# We had a problem
status_str = \
NotifyNotica.http_response_code_lookup(r.status_code)
self.logger.warning(
'Failed to send Notica notification:'
'{}{}error={}.'.format(
status_str,
', ' if status_str else '',
r.status_code))
self.logger.debug('Response Details:\r\n{}'.format(r.content))
# Return; we're done
return False
else:
self.logger.info('Sent Notica notification.')
except requests.RequestException as e:
self.logger.warning(
'A Connection error occured sending Notica notification.',
)
self.logger.debug('Socket Exception: %s' % str(e))
# Return; we're done
return False
return True
def url(self, privacy=False, *args, **kwargs):
"""
Returns the URL built dynamically based on specified arguments.
"""
# Define any arguments set
args = {
'format': self.notify_format,
'overflow': self.overflow_mode,
'verify': 'yes' if self.verify_certificate else 'no',
}
return '{schema}://{token}/?{args}'.format(
schema=self.secure_protocol,
token=self.pprint(self.token, privacy, safe=''),
args=NotifyNotica.urlencode(args),
)
@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, verify_host=False)
if not results:
# We're done early as we couldn't load the results
return results
# Store our token using the host
results['token'] = NotifyNotica.unquote(results['host'])
return results
@staticmethod
def parse_native_url(url):
"""
Support https://notica.us/?abc123
"""
result = re.match(
r'^https?://notica\.us/?'
r'\??(?P<token>[^/&=]+)$', url, re.I)
if result:
return NotifyNotica.parse_url(
'{schema}://{token}'.format(
schema=NotifyNotica.secure_protocol,
token=result.group('token')))
return None

View File

@ -49,10 +49,10 @@ it easy to access:
Boxcar, ClickSend, Discord, E-Mail, Emby, Faast, Flock, Gitter, Gotify, Growl,
IFTTT, Join, KODI, Kumulos, Mailgun, MatterMost, Matrix, Microsoft Windows
Notifications, Microsoft Teams, MessageBird, MSG91, Nexmo, Notifico,
Notifications, Microsoft Teams, MessageBird, MSG91, Nexmo, Notica, Notifico,
Notify MyAndroid, Prowl, Pushalot, PushBullet, Pushjet, Pushover, Rocket.Chat,
SendGrid, SimplePush, Slack, Super Toasty, Stride, Syslog, Techulus Push, Telegram,
Twilio, Twitter, Twist, XBMC, XMPP, Webex Teams}
SendGrid, SimplePush, Slack, Super Toasty, Stride, Syslog, Techulus Push,
Telegram, Twilio, Twitter, Twist, XBMC, XMPP, Webex Teams}
Name: python-%{pypi_name}
Version: 0.8.1

View File

@ -72,9 +72,10 @@ setup(
keywords='Push Notifications Alerts Email AWS SNS Boxcar ClickSend '
'Discord Dbus Emby Faast Flock Gitter Gnome Gotify Growl IFTTT Join '
'KODI Kumulos Mailgun Matrix Mattermost MessageBird MSG91 Nexmo '
'Notifico Prowl PushBullet Pushjet Pushed Pushover Rocket.Chat Ryver '
'SendGrid SimplePush Slack Stride Syslog Techulus Push Telegram '
'Twilio Twist Twitter XBMC Microsoft MSTeams Windows Webex CLI API',
'Notica, Notifico Prowl PushBullet Pushjet Pushed Pushover '
'Rocket.Chat Ryver SendGrid SimplePush Slack Stride Syslog Techulus '
'Push Telegram Twilio Twist Twitter XBMC Microsoft MSTeams Windows '
'Webex CLI API',
author='Chris Caron',
author_email='lead2gold@gmail.com',
packages=find_packages(),

View File

@ -1401,6 +1401,53 @@ TEST_URLS = (
'test_requests_exceptions': True,
}),
##################################
# NotifyNotica
##################################
('notica://', {
'instance': TypeError,
}),
('notica://:@/', {
'instance': TypeError,
}),
# Native URL
('https://notica.us/?%s' % ('z' * 6), {
'instance': plugins.NotifyNotica,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'notica://z...z',
}),
# Token specified
('notica://%s' % ('a' * 6), {
'instance': plugins.NotifyNotica,
# Our expected url(privacy=True) startswith() response:
'privacy_url': 'notica://a...a',
}),
('notica://%s' % ('b' * 6), {
'instance': plugins.NotifyNotica,
# don't include an image by default
'include_image': False,
}),
('notica://%s' % ('c' * 6), {
'instance': plugins.NotifyNotica,
# force a failure
'response': False,
'requests_response_code': requests.codes.internal_server_error,
}),
('notica://%s' % ('d' * 7), {
'instance': plugins.NotifyNotica,
# throw a bizzare code forcing us to fail to look it up
'response': False,
'requests_response_code': 999,
}),
('notica://%s' % ('e' * 8), {
'instance': plugins.NotifyNotica,
# Throws a series of connection and transfer exceptions when this flag
# is set and tests that we gracfully handle them
'test_requests_exceptions': True,
}),
##################################
# NotifyNotifico
##################################