mirror of https://github.com/caronc/apprise
Matrix HTML and Markdown Support (#431)
parent
bb7c77105e
commit
a888b85f8e
|
@ -30,6 +30,7 @@
|
||||||
import re
|
import re
|
||||||
import six
|
import six
|
||||||
import requests
|
import requests
|
||||||
|
from markdown import markdown
|
||||||
from json import dumps
|
from json import dumps
|
||||||
from json import loads
|
from json import loads
|
||||||
from time import time
|
from time import time
|
||||||
|
@ -41,6 +42,7 @@ from ..common import NotifyImageSize
|
||||||
from ..common import NotifyFormat
|
from ..common import NotifyFormat
|
||||||
from ..utils import parse_bool
|
from ..utils import parse_bool
|
||||||
from ..utils import parse_list
|
from ..utils import parse_list
|
||||||
|
from ..utils import apply_template
|
||||||
from ..utils import validate_regex
|
from ..utils import validate_regex
|
||||||
from ..AppriseLocale import gettext_lazy as _
|
from ..AppriseLocale import gettext_lazy as _
|
||||||
|
|
||||||
|
@ -415,20 +417,31 @@ class NotifyMatrix(NotifyBase):
|
||||||
payload = {
|
payload = {
|
||||||
'displayName':
|
'displayName':
|
||||||
self.user if self.user else self.app_id,
|
self.user if self.user else self.app_id,
|
||||||
'format': 'html',
|
'format': 'plain' if self.notify_format == NotifyFormat.TEXT
|
||||||
|
else 'html',
|
||||||
|
'text': '',
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.notify_format == NotifyFormat.HTML:
|
if self.notify_format == NotifyFormat.HTML:
|
||||||
payload['text'] = '{}{}'.format('' if not title else title, body)
|
# Add additional information to our content; use {{app_title}}
|
||||||
|
# to apply the title to the html body
|
||||||
|
tokens = {
|
||||||
|
'app_title': NotifyMatrix.escape_html(
|
||||||
|
title, whitespace=False),
|
||||||
|
}
|
||||||
|
payload['text'] = apply_template(body, **tokens)
|
||||||
|
|
||||||
else: # TEXT or MARKDOWN
|
elif self.notify_format == NotifyFormat.MARKDOWN:
|
||||||
|
# Add additional information to our content; use {{app_title}}
|
||||||
|
# to apply the title to the html body
|
||||||
|
tokens = {
|
||||||
|
'app_title': title,
|
||||||
|
}
|
||||||
|
payload['text'] = markdown(apply_template(body, **tokens))
|
||||||
|
|
||||||
# Ensure our content is escaped
|
else: # NotifyFormat.TEXT
|
||||||
title = NotifyMatrix.escape_html(title)
|
payload['text'] = \
|
||||||
body = NotifyMatrix.escape_html(body)
|
body if not title else '{}\r\n{}'.format(title, body)
|
||||||
|
|
||||||
payload['text'] = '{}{}'.format(
|
|
||||||
'' if not title else '<h4>{}</h4>'.format(title), body)
|
|
||||||
|
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
|
@ -497,11 +510,6 @@ class NotifyMatrix(NotifyBase):
|
||||||
has_error = True
|
has_error = True
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# We have our data cached at this point we can freely use it
|
|
||||||
msg = '{title}{body}'.format(
|
|
||||||
title='' if not title else '{}\r\n'.format(title),
|
|
||||||
body=body)
|
|
||||||
|
|
||||||
# Acquire our image url if we're configured to do so
|
# Acquire our image url if we're configured to do so
|
||||||
image_url = None if not self.include_image else \
|
image_url = None if not self.include_image else \
|
||||||
self.image_url(notify_type)
|
self.image_url(notify_type)
|
||||||
|
@ -527,9 +535,35 @@ class NotifyMatrix(NotifyBase):
|
||||||
# Define our payload
|
# Define our payload
|
||||||
payload = {
|
payload = {
|
||||||
'msgtype': 'm.text',
|
'msgtype': 'm.text',
|
||||||
'body': msg,
|
'body': '{title}{body}'.format(
|
||||||
|
title='' if not title else '{}\r\n'.format(title),
|
||||||
|
body=body),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Update our payload advance formatting for the services that
|
||||||
|
# support them.
|
||||||
|
if self.notify_format == NotifyFormat.HTML:
|
||||||
|
# Add additional information to our content; use {{app_title}}
|
||||||
|
# to apply the title to the html body
|
||||||
|
tokens = {
|
||||||
|
'app_title': NotifyMatrix.escape_html(
|
||||||
|
title, whitespace=False),
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.update({
|
||||||
|
'format': 'org.matrix.custom.html',
|
||||||
|
'formatted_body': apply_template(body, **tokens),
|
||||||
|
})
|
||||||
|
|
||||||
|
elif self.notify_format == NotifyFormat.MARKDOWN:
|
||||||
|
tokens = {
|
||||||
|
'app_title': title,
|
||||||
|
}
|
||||||
|
payload.update({
|
||||||
|
'format': 'org.matrix.custom.html',
|
||||||
|
'formatted_body': markdown(apply_template(body, **tokens))
|
||||||
|
})
|
||||||
|
|
||||||
# Build our path
|
# Build our path
|
||||||
path = '/rooms/{}/send/m.room.message'.format(
|
path = '/rooms/{}/send/m.room.message'.format(
|
||||||
NotifyMatrix.quote(room_id))
|
NotifyMatrix.quote(room_id))
|
||||||
|
@ -697,7 +731,7 @@ class NotifyMatrix(NotifyBase):
|
||||||
# Prepare our Join Payload
|
# Prepare our Join Payload
|
||||||
payload = {}
|
payload = {}
|
||||||
|
|
||||||
# Not in cache, next step is to check if it's a room id...
|
# Check if it's a room id...
|
||||||
result = IS_ROOM_ID.match(room)
|
result = IS_ROOM_ID.match(room)
|
||||||
if result:
|
if result:
|
||||||
# We detected ourselves the home_server
|
# We detected ourselves the home_server
|
||||||
|
@ -710,11 +744,23 @@ class NotifyMatrix(NotifyBase):
|
||||||
home_server,
|
home_server,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Check our cache for speed:
|
||||||
|
if room_id in self._room_cache:
|
||||||
|
# We're done as we've already joined the channel
|
||||||
|
return self._room_cache[room_id]['id']
|
||||||
|
|
||||||
# Build our URL
|
# Build our URL
|
||||||
path = '/join/{}'.format(NotifyMatrix.quote(room_id))
|
path = '/join/{}'.format(NotifyMatrix.quote(room_id))
|
||||||
|
|
||||||
# Make our query
|
# Make our query
|
||||||
postokay, _ = self._fetch(path, payload=payload)
|
postokay, _ = self._fetch(path, payload=payload)
|
||||||
|
if postokay:
|
||||||
|
# Cache our entry for fast access later
|
||||||
|
self._room_cache[room_id] = {
|
||||||
|
'id': room_id,
|
||||||
|
'home_server': home_server,
|
||||||
|
}
|
||||||
|
|
||||||
return room_id if postokay else None
|
return room_id if postokay else None
|
||||||
|
|
||||||
# Try to see if it's an alias then...
|
# Try to see if it's an alias then...
|
||||||
|
|
|
@ -28,7 +28,6 @@ import mock
|
||||||
import requests
|
import requests
|
||||||
from apprise import plugins
|
from apprise import plugins
|
||||||
from apprise import AppriseAsset
|
from apprise import AppriseAsset
|
||||||
# from apprise import Apprise
|
|
||||||
from json import dumps
|
from json import dumps
|
||||||
|
|
||||||
# Disable logging for a cleaner testing output
|
# Disable logging for a cleaner testing output
|
||||||
|
@ -86,6 +85,31 @@ def test_notify_matrix_plugin_general(mock_post, mock_get):
|
||||||
# Registration Successful
|
# Registration Successful
|
||||||
assert obj.send(body="test") is True
|
assert obj.send(body="test") is True
|
||||||
|
|
||||||
|
# Test sending other format types
|
||||||
|
kwargs = plugins.NotifyMatrix.parse_url(
|
||||||
|
'matrix://user:passwd@hostname/#abcd?format=html')
|
||||||
|
obj = plugins.NotifyMatrix(**kwargs)
|
||||||
|
assert isinstance(obj.url(), six.string_types) is True
|
||||||
|
assert isinstance(obj, plugins.NotifyMatrix) is True
|
||||||
|
obj.send(body="test") is True
|
||||||
|
obj.send(title="title", body="test") is True
|
||||||
|
|
||||||
|
kwargs = plugins.NotifyMatrix.parse_url(
|
||||||
|
'matrix://user:passwd@hostname/#abcd/#abcd:localhost?format=markdown')
|
||||||
|
obj = plugins.NotifyMatrix(**kwargs)
|
||||||
|
assert isinstance(obj.url(), six.string_types) is True
|
||||||
|
assert isinstance(obj, plugins.NotifyMatrix) is True
|
||||||
|
obj.send(body="test") is True
|
||||||
|
obj.send(title="title", body="test") is True
|
||||||
|
|
||||||
|
kwargs = plugins.NotifyMatrix.parse_url(
|
||||||
|
'matrix://user:passwd@hostname/#abcd/!abcd:localhost?format=text')
|
||||||
|
obj = plugins.NotifyMatrix(**kwargs)
|
||||||
|
assert isinstance(obj.url(), six.string_types) is True
|
||||||
|
assert isinstance(obj, plugins.NotifyMatrix) is True
|
||||||
|
obj.send(body="test") is True
|
||||||
|
obj.send(title="title", body="test") is True
|
||||||
|
|
||||||
# Force a failed login
|
# Force a failed login
|
||||||
ro = response_obj.copy()
|
ro = response_obj.copy()
|
||||||
del ro['access_token']
|
del ro['access_token']
|
||||||
|
@ -392,16 +416,36 @@ def test_notify_matrix_plugin_rooms(mock_post, mock_get):
|
||||||
|
|
||||||
assert obj._register() is True
|
assert obj._register() is True
|
||||||
assert obj.access_token is not None
|
assert obj.access_token is not None
|
||||||
|
|
||||||
|
assert obj._room_join('!abc123') == response_obj['room_id']
|
||||||
|
# Use cache to get same results
|
||||||
|
assert len(obj._room_cache) == 1
|
||||||
assert obj._room_join('!abc123') == response_obj['room_id']
|
assert obj._room_join('!abc123') == response_obj['room_id']
|
||||||
|
|
||||||
obj._room_cache = {}
|
obj._room_cache = {}
|
||||||
assert obj._room_join('!abc123:localhost') == response_obj['room_id']
|
assert obj._room_join('!abc123:localhost') == response_obj['room_id']
|
||||||
|
# Use cache to get same results
|
||||||
|
assert len(obj._room_cache) == 1
|
||||||
|
assert obj._room_join('!abc123:localhost') == response_obj['room_id']
|
||||||
|
|
||||||
obj._room_cache = {}
|
obj._room_cache = {}
|
||||||
assert obj._room_join('abc123') == response_obj['room_id']
|
assert obj._room_join('abc123') == response_obj['room_id']
|
||||||
|
# Use cache to get same results
|
||||||
|
assert len(obj._room_cache) == 1
|
||||||
|
assert obj._room_join('abc123') == response_obj['room_id']
|
||||||
|
|
||||||
obj._room_cache = {}
|
obj._room_cache = {}
|
||||||
assert obj._room_join('abc123:localhost') == response_obj['room_id']
|
assert obj._room_join('abc123:localhost') == response_obj['room_id']
|
||||||
|
# Use cache to get same results
|
||||||
|
assert len(obj._room_cache) == 1
|
||||||
|
assert obj._room_join('abc123:localhost') == response_obj['room_id']
|
||||||
|
|
||||||
obj._room_cache = {}
|
obj._room_cache = {}
|
||||||
assert obj._room_join('#abc123:localhost') == response_obj['room_id']
|
assert obj._room_join('#abc123:localhost') == response_obj['room_id']
|
||||||
|
# Use cache to get same results
|
||||||
|
assert len(obj._room_cache) == 1
|
||||||
|
assert obj._room_join('#abc123:localhost') == response_obj['room_id']
|
||||||
|
|
||||||
obj._room_cache = {}
|
obj._room_cache = {}
|
||||||
assert obj._room_join('%') is None
|
assert obj._room_join('%') is None
|
||||||
assert obj._room_join(None) is None
|
assert obj._room_join(None) is None
|
||||||
|
|
|
@ -1948,7 +1948,7 @@ TEST_URLS = (
|
||||||
.format('a' * 64), {
|
.format('a' * 64), {
|
||||||
# user and token specified; image set to True
|
# user and token specified; image set to True
|
||||||
'instance': plugins.NotifyMatrix}),
|
'instance': plugins.NotifyMatrix}),
|
||||||
('matrix://user@{}?mode=t2bot&format=markdown&image=False'
|
('matrix://user@{}?mode=t2bot&format=html&image=False'
|
||||||
.format('z' * 64), {
|
.format('z' * 64), {
|
||||||
# user and token specified; image set to True
|
# user and token specified; image set to True
|
||||||
'instance': plugins.NotifyMatrix}),
|
'instance': plugins.NotifyMatrix}),
|
||||||
|
|
Loading…
Reference in New Issue