mirror of https://github.com/caronc/apprise
markdown support
parent
e6106de81b
commit
602b9bab6f
|
@ -21,8 +21,10 @@
|
|||
|
||||
import re
|
||||
import logging
|
||||
from markdown import markdown
|
||||
|
||||
from .common import NotifyType
|
||||
from .common import NotifyFormat
|
||||
from .utils import parse_list
|
||||
from .utils import compat_is_basestring
|
||||
|
||||
|
@ -217,9 +219,14 @@ class Apprise(object):
|
|||
"""
|
||||
self.servers[:] = []
|
||||
|
||||
def notify(self, title, body, notify_type=NotifyType.INFO):
|
||||
def notify(self, title, body, notify_type=NotifyType.INFO,
|
||||
body_format=None):
|
||||
"""
|
||||
Send a notification to all of the plugins previously loaded
|
||||
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.
|
||||
|
||||
"""
|
||||
|
||||
# Initialize our return result
|
||||
|
@ -228,12 +235,28 @@ class Apprise(object):
|
|||
if not (title or body):
|
||||
return False
|
||||
|
||||
# Tracks conversions
|
||||
conversion_map = dict()
|
||||
|
||||
# Iterate over our loaded plugins
|
||||
for server in self.servers:
|
||||
if server.notify_format not in conversion_map:
|
||||
if body_format == NotifyFormat.MARKDOWN and \
|
||||
server.notify_format == NotifyFormat.HTML:
|
||||
|
||||
# Apply Markdown
|
||||
conversion_map[server.notify_format] = markdown(body)
|
||||
|
||||
else:
|
||||
# Store entry directly
|
||||
conversion_map[server.notify_format] = body
|
||||
|
||||
try:
|
||||
# Send notification
|
||||
if not server.notify(
|
||||
title=title, body=body, notify_type=notify_type):
|
||||
title=title,
|
||||
body=conversion_map[server.notify_format],
|
||||
notify_type=notify_type):
|
||||
|
||||
# Toggle our return status flag
|
||||
status = False
|
||||
|
|
|
@ -24,9 +24,10 @@ __copywrite__ = 'Copyright 2017 Chris Caron <lead2gold@gmail.com>'
|
|||
|
||||
from .common import NotifyType
|
||||
from .common import NOTIFY_TYPES
|
||||
from .common import NOTIFY_IMAGE_SIZES
|
||||
from .common import NotifyImageSize
|
||||
from .plugins.NotifyBase import NotifyFormat
|
||||
from .common import NOTIFY_IMAGE_SIZES
|
||||
from .common import NotifyFormat
|
||||
from .common import NOTIFY_FORMATS
|
||||
from .plugins.NotifyBase import NotifyBase
|
||||
|
||||
from .Apprise import Apprise
|
||||
|
@ -43,5 +44,5 @@ __all__ = [
|
|||
|
||||
# Reference
|
||||
'NotifyType', 'NotifyImageSize', 'NotifyFormat', 'NOTIFY_TYPES',
|
||||
'NOTIFY_IMAGE_SIZES',
|
||||
'NOTIFY_IMAGE_SIZES', 'NOTIFY_FORMATS',
|
||||
]
|
||||
|
|
|
@ -53,3 +53,20 @@ NOTIFY_IMAGE_SIZES = (
|
|||
NotifyImageSize.XY_128,
|
||||
NotifyImageSize.XY_256,
|
||||
)
|
||||
|
||||
|
||||
class NotifyFormat(object):
|
||||
"""
|
||||
A list of pre-defined text message formats that can be passed via the
|
||||
apprise library.
|
||||
"""
|
||||
TEXT = 'text'
|
||||
HTML = 'html'
|
||||
MARKDOWN = 'markdown'
|
||||
|
||||
|
||||
NOTIFY_FORMATS = (
|
||||
NotifyFormat.TEXT,
|
||||
NotifyFormat.HTML,
|
||||
NotifyFormat.MARKDOWN,
|
||||
)
|
||||
|
|
|
@ -36,6 +36,8 @@ from ..utils import parse_bool
|
|||
from ..utils import is_hostname
|
||||
from ..common import NOTIFY_IMAGE_SIZES
|
||||
from ..common import NOTIFY_TYPES
|
||||
from ..common import NotifyFormat
|
||||
from ..common import NOTIFY_FORMATS
|
||||
|
||||
from ..AppriseAsset import AppriseAsset
|
||||
|
||||
|
@ -60,24 +62,11 @@ HTTP_ERROR_MAP = {
|
|||
}
|
||||
|
||||
# HTML New Line Delimiter
|
||||
NOTIFY_NEWLINE = '\n'
|
||||
NOTIFY_NEWLINE = '\r\n'
|
||||
|
||||
# Used to break a path list into parts
|
||||
PATHSPLIT_LIST_DELIM = re.compile(r'[ \t\r\n,\\/]+')
|
||||
|
||||
|
||||
class NotifyFormat(object):
|
||||
TEXT = 'text'
|
||||
HTML = 'html'
|
||||
MARKDOWN = 'markdown'
|
||||
|
||||
|
||||
NOTIFY_FORMATS = (
|
||||
NotifyFormat.TEXT,
|
||||
NotifyFormat.HTML,
|
||||
NotifyFormat.MARKDOWN,
|
||||
)
|
||||
|
||||
# Regular expression retrieved from:
|
||||
# http://www.regular-expressions.info/email.html
|
||||
IS_EMAIL_RE = re.compile(
|
||||
|
@ -327,7 +316,7 @@ class NotifyBase(object):
|
|||
return is_hostname(hostname)
|
||||
|
||||
@staticmethod
|
||||
def parse_url(url, verify_host=True):
|
||||
def parse_url(url, verify_host=True, default_format=NotifyFormat.TEXT):
|
||||
"""
|
||||
Parses the URL and returns it broken apart into a dictionary.
|
||||
|
||||
|
@ -343,10 +332,10 @@ class NotifyBase(object):
|
|||
results['secure'] = (results['schema'][-1] == 's')
|
||||
|
||||
# Our default notification format
|
||||
results['notify_format'] = NotifyFormat.TEXT
|
||||
results['notify_format'] = default_format
|
||||
|
||||
# Support SSL Certificate 'verify' keyword. Default to being enabled
|
||||
results['verify'] = True
|
||||
results['verify'] = verify_host
|
||||
|
||||
if 'verify' in results['qsd']:
|
||||
results['verify'] = parse_bool(
|
||||
|
|
|
@ -25,7 +25,7 @@ from socket import error as SocketError
|
|||
from email.mime.text import MIMEText
|
||||
|
||||
from .NotifyBase import NotifyBase
|
||||
from .NotifyBase import NotifyFormat
|
||||
from ..common import NotifyFormat
|
||||
|
||||
|
||||
class WebBaseLogin(object):
|
||||
|
|
|
@ -20,8 +20,8 @@ import re
|
|||
import requests
|
||||
|
||||
from .NotifyBase import NotifyBase
|
||||
from .NotifyBase import NotifyFormat
|
||||
from .NotifyBase import HTTP_ERROR_MAP
|
||||
from ..common import NotifyFormat
|
||||
|
||||
# Extend HTTP Error Messages
|
||||
NMA_HTTP_ERROR_MAP = HTTP_ERROR_MAP.copy()
|
||||
|
|
|
@ -47,8 +47,8 @@ from json import loads
|
|||
from json import dumps
|
||||
|
||||
from .NotifyBase import NotifyBase
|
||||
from .NotifyBase import NotifyFormat
|
||||
from .NotifyBase import HTTP_ERROR_MAP
|
||||
from ..common import NotifyFormat
|
||||
from ..common import NotifyImageSize
|
||||
from ..utils import compat_is_basestring
|
||||
|
||||
|
|
|
@ -5,3 +5,4 @@ oauthlib
|
|||
urllib3
|
||||
six
|
||||
click >= 5.0
|
||||
markdown
|
||||
|
|
|
@ -25,6 +25,7 @@ from apprise import AppriseAsset
|
|||
from apprise.Apprise import SCHEMA_MAP
|
||||
from apprise import NotifyBase
|
||||
from apprise import NotifyType
|
||||
from apprise import NotifyFormat
|
||||
from apprise import NotifyImageSize
|
||||
from apprise.Apprise import __load_matrix
|
||||
|
||||
|
@ -107,7 +108,8 @@ def test_apprise():
|
|||
|
||||
class GoodNotification(NotifyBase):
|
||||
def __init__(self, **kwargs):
|
||||
super(GoodNotification, self).__init__()
|
||||
super(GoodNotification, self).__init__(
|
||||
notify_format=NotifyFormat.HTML)
|
||||
|
||||
def notify(self, **kwargs):
|
||||
# Pretend everything is okay
|
||||
|
@ -205,6 +207,79 @@ def test_apprise():
|
|||
assert(len(a) == 0)
|
||||
|
||||
|
||||
def test_apprise_notify_formats(tmpdir):
|
||||
"""
|
||||
API: Apprise() TextFormat tests
|
||||
|
||||
"""
|
||||
# Caling load matix a second time which is an internal function causes it
|
||||
# to skip over content already loaded into our matrix and thefore accesses
|
||||
# other if/else parts of the code that aren't otherwise called
|
||||
__load_matrix()
|
||||
|
||||
a = Apprise()
|
||||
|
||||
# no items
|
||||
assert(len(a) == 0)
|
||||
|
||||
class TextNotification(NotifyBase):
|
||||
def __init__(self, **kwargs):
|
||||
super(TextNotification, self).__init__(
|
||||
notify_format=NotifyFormat.TEXT)
|
||||
|
||||
def notify(self, **kwargs):
|
||||
# Pretend everything is okay
|
||||
return True
|
||||
|
||||
class HtmlNotification(NotifyBase):
|
||||
def __init__(self, **kwargs):
|
||||
super(HtmlNotification, self).__init__(
|
||||
notify_format=NotifyFormat.HTML)
|
||||
|
||||
def notify(self, **kwargs):
|
||||
# Pretend everything is okay
|
||||
return True
|
||||
|
||||
class MarkDownNotification(NotifyBase):
|
||||
def __init__(self, **kwargs):
|
||||
super(MarkDownNotification, self).__init__(
|
||||
notify_format=NotifyFormat.MARKDOWN)
|
||||
|
||||
def notify(self, **kwargs):
|
||||
# Pretend everything is okay
|
||||
return True
|
||||
|
||||
# Store our notifications into our schema map
|
||||
SCHEMA_MAP['text'] = TextNotification
|
||||
SCHEMA_MAP['html'] = HtmlNotification
|
||||
SCHEMA_MAP['markdown'] = MarkDownNotification
|
||||
|
||||
# Test Markdown; the above calls the markdown because our good://
|
||||
# defined plugin above was defined to default to HTML which triggers
|
||||
# a markdown to take place if the body_format specified on the notify
|
||||
# call
|
||||
assert(a.add('html://localhost') is True)
|
||||
assert(a.add('html://another.server') is True)
|
||||
assert(a.add('html://and.another') is True)
|
||||
assert(a.add('text://localhost') is True)
|
||||
assert(a.add('text://another.server') is True)
|
||||
assert(a.add('text://and.another') is True)
|
||||
assert(a.add('markdown://localhost') is True)
|
||||
assert(a.add('markdown://another.server') is True)
|
||||
assert(a.add('markdown://and.another') is True)
|
||||
|
||||
assert(len(a) == 9)
|
||||
|
||||
assert(a.notify(title="markdown", body="## Testing Markdown",
|
||||
body_format=NotifyFormat.MARKDOWN) is True)
|
||||
|
||||
assert(a.notify(title="text", body="Testing Text",
|
||||
body_format=NotifyFormat.TEXT) is True)
|
||||
|
||||
assert(a.notify(title="html", body="<b>HTML</b>",
|
||||
body_format=NotifyFormat.HTML) is True)
|
||||
|
||||
|
||||
def test_apprise_asset(tmpdir):
|
||||
"""
|
||||
API: AppriseAsset() object
|
||||
|
|
Loading…
Reference in New Issue