Merge pull request #57 from caronc/52-telegram-code-block-support

telegram markdown support added; refs #52
pull/58/head
Chris Caron 2019-02-06 00:03:20 -05:00 committed by GitHub
commit 042c5ed2da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 139 additions and 46 deletions

View File

@ -159,9 +159,9 @@ class NotifyBase(object):
self.user = kwargs.get('user')
self.password = kwargs.get('password')
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,

View File

@ -227,6 +227,9 @@ 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
@ -433,20 +436,10 @@ class NotifyEmail(NotifyBase):
# Apply our settings now
# Default Format is HTML
results['notify_format'] = NotifyFormat.HTML
results['secure_mode'] = NotifyEmail.default_secure_mode
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'])

View File

@ -62,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
@ -262,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:
@ -356,25 +357,51 @@ class NotifyTelegram(NotifyBase):
payload = {}
# Prepare Email Message
if self.notify_format == NotifyFormat.MARKDOWN:
payload['parse_mode'] = 'MARKDOWN'
else:
# Either TEXT or HTML; if TEXT we'll make it HTML
payload['parse_mode'] = 'HTML'
# HTML Spaces ( ) and tabs ( ) aren't supported
# See https://core.telegram.org/bots/api#html-style
body = re.sub(' ?', ' ', body, re.I)
# Tabs become 3 spaces
body = re.sub(' ?', ' ', body, re.I)
if title:
# HTML Spaces ( ) and tabs ( ) aren't supported
# See https://core.telegram.org/bots/api#html-style
title = re.sub(' ?', ' ', title, re.I)
body = re.sub(' ?', ' ', body, re.I)
# Tabs become 3 spaces
title = re.sub(' ?', ' ', title, re.I)
body = re.sub(' ?', ' ', body, re.I)
# HTML
title = NotifyBase.escape_html(title, whitespace=False)
body = NotifyBase.escape_html(body, whitespace=False)
payload['parse_mode'] = 'HTML'
# 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)
while len(chat_ids):
@ -426,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:

View File

@ -35,7 +35,6 @@ from apprise import NotifyBase
from apprise import NotifyType
from apprise import NotifyFormat
from apprise import NotifyImageSize
from apprise import plugins
from apprise import __version__
from apprise.Apprise import __load_matrix
import pytest
@ -243,27 +242,35 @@ def test_apprise_notify_formats(tmpdir):
assert(len(a) == 0)
class TextNotification(NotifyBase):
# set our default notification format
notify_format = NotifyFormat.TEXT
def __init__(self, **kwargs):
super(TextNotification, self).__init__(
notify_format=NotifyFormat.TEXT)
super(TextNotification, self).__init__()
def notify(self, **kwargs):
# Pretend everything is okay
return True
class HtmlNotification(NotifyBase):
# set our default notification format
notify_format = NotifyFormat.HTML
def __init__(self, **kwargs):
super(HtmlNotification, self).__init__(
notify_format=NotifyFormat.HTML)
super(HtmlNotification, self).__init__()
def notify(self, **kwargs):
# Pretend everything is okay
return True
class MarkDownNotification(NotifyBase):
# set our default notification format
notify_format = NotifyFormat.MARKDOWN
def __init__(self, **kwargs):
super(MarkDownNotification, self).__init__(
notify_format=NotifyFormat.MARKDOWN)
super(MarkDownNotification, self).__init__()
def notify(self, **kwargs):
# Pretend everything is okay
@ -339,7 +346,7 @@ def test_apprise_asset(tmpdir):
# The exception we expect since dict is not supported
assert(True)
except:
except Exception:
# Any other exception is not good
assert(False)

View File

@ -26,6 +26,8 @@
from apprise import plugins
from apprise import NotifyType
from apprise import Apprise
from apprise.plugins import NotifyEmailBase
import smtplib
import mock
import re
@ -287,8 +289,6 @@ def test_webbase_lookup(mock_smtp, mock_smtpssl):
"""
from apprise.plugins import NotifyEmailBase
# Insert a test email at the head of our table
NotifyEmailBase.WEBBASE_LOOKUP_TABLE = (
(
@ -324,8 +324,6 @@ def test_smtplib_init_fail(mock_smtplib):
"""
from apprise.plugins import NotifyEmailBase
obj = Apprise.instantiate(
'mailto://user:pass@gmail.com', suppress_exceptions=False)
assert(isinstance(obj, plugins.NotifyEmail))
@ -362,8 +360,7 @@ def test_smtplib_send_okay(mock_smtplib):
"""
from apprise.plugins import NotifyEmailBase
# Defaults to HTML
obj = Apprise.instantiate(
'mailto://user:pass@gmail.com', suppress_exceptions=False)
assert(isinstance(obj, plugins.NotifyEmail))
@ -374,4 +371,13 @@ def test_smtplib_send_okay(mock_smtplib):
mock_smtplib.sendmail.return_value = True
mock_smtplib.quit.return_value = True
obj.notify(title='test', body='body', notify_type=NotifyType.INFO)
assert(obj.notify(
title='test', body='body', notify_type=NotifyType.INFO) is True)
# Set Text
obj = Apprise.instantiate(
'mailto://user:pass@gmail.com?format=text', suppress_exceptions=False)
assert(isinstance(obj, plugins.NotifyEmail))
assert(obj.notify(
title='test', body='body', notify_type=NotifyType.INFO) is True)

View File

@ -38,7 +38,7 @@ def test_notify_base():
# invalid types throw exceptions
try:
nb = NotifyBase(notify_format='invalid')
nb = NotifyBase(**{'format': 'invalid'})
# We should never reach here as an exception should be thrown
assert(False)

View File

@ -140,6 +140,15 @@ TEST_URLS = (
'instance': plugins.NotifyDiscord,
'requests_response_code': requests.codes.no_content,
}),
# different format support
('discord://%s/%s?format=markdown' % ('i' * 24, 't' * 64), {
'instance': plugins.NotifyDiscord,
'requests_response_code': requests.codes.no_content,
}),
('discord://%s/%s?format=text' % ('i' * 24, 't' * 64), {
'instance': plugins.NotifyDiscord,
'requests_response_code': requests.codes.no_content,
}),
# Test without image set
('discord://%s/%s' % ('i' * 24, 't' * 64), {
'instance': plugins.NotifyDiscord,
@ -1155,6 +1164,16 @@ TEST_URLS = (
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?format=', {
'instance': plugins.NotifyTelegram,
}),
# Testing valid formats
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?format=markdown', {
'instance': plugins.NotifyTelegram,
}),
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?format=html', {
'instance': plugins.NotifyTelegram,
}),
('tgram://123456789:abcdefg_hijklmnop/lead2gold/?format=text', {
'instance': plugins.NotifyTelegram,
}),
# Simple Message without image
('tgram://123456789:abcdefg_hijklmnop/lead2gold/', {
'instance': plugins.NotifyTelegram,
@ -1486,6 +1505,9 @@ def test_rest_plugins(mock_post, mock_get):
assert(hasattr(key, obj))
assert(getattr(key, obj) == val)
#
# Stage 1: with title defined
#
try:
if test_requests_exceptions is False:
# check that we're as expected
@ -1521,6 +1543,44 @@ def test_rest_plugins(mock_post, mock_get):
# Check that we were expecting this exception to happen
assert isinstance(e, response)
#
# Stage 1: without title defined
#
try:
if test_requests_exceptions is False:
# check that we're as expected
assert obj.notify(
title='', body='body',
notify_type=notify_type) == response
else:
for _exception in REQUEST_EXCEPTIONS:
mock_post.side_effect = _exception
mock_get.side_effect = _exception
try:
assert obj.notify(
title='', body='body',
notify_type=NotifyType.INFO) is False
except AssertionError:
# Don't mess with these entries
raise
except Exception as e:
# We can't handle this exception type
print('%s / %s' % (url, str(e)))
assert False
except AssertionError:
# Don't mess with these entries
print('%s AssertionError' % url)
raise
except Exception as e:
# Check that we were expecting this exception to happen
assert isinstance(e, response)
except AssertionError:
# Don't mess with these entries
print('%s AssertionError' % url)