Matrix HTML and Markdown Support (#431)

This commit is contained in:
Chris Caron 2021-08-29 11:29:30 -04:00 committed by GitHub
parent bb7c77105e
commit a888b85f8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 108 additions and 18 deletions

View File

@ -30,6 +30,7 @@
import re
import six
import requests
from markdown import markdown
from json import dumps
from json import loads
from time import time
@ -41,6 +42,7 @@ from ..common import NotifyImageSize
from ..common import NotifyFormat
from ..utils import parse_bool
from ..utils import parse_list
from ..utils import apply_template
from ..utils import validate_regex
from ..AppriseLocale import gettext_lazy as _
@ -415,20 +417,31 @@ class NotifyMatrix(NotifyBase):
payload = {
'displayName':
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:
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
title = NotifyMatrix.escape_html(title)
body = NotifyMatrix.escape_html(body)
payload['text'] = '{}{}'.format(
'' if not title else '<h4>{}</h4>'.format(title), body)
else: # NotifyFormat.TEXT
payload['text'] = \
body if not title else '{}\r\n{}'.format(title, body)
return payload
@ -497,11 +510,6 @@ class NotifyMatrix(NotifyBase):
has_error = True
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
image_url = None if not self.include_image else \
self.image_url(notify_type)
@ -527,9 +535,35 @@ class NotifyMatrix(NotifyBase):
# Define our payload
payload = {
'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
path = '/rooms/{}/send/m.room.message'.format(
NotifyMatrix.quote(room_id))
@ -697,7 +731,7 @@ class NotifyMatrix(NotifyBase):
# Prepare our Join 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)
if result:
# We detected ourselves the home_server
@ -710,11 +744,23 @@ class NotifyMatrix(NotifyBase):
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
path = '/join/{}'.format(NotifyMatrix.quote(room_id))
# Make our query
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
# Try to see if it's an alias then...

View File

@ -28,7 +28,6 @@ import mock
import requests
from apprise import plugins
from apprise import AppriseAsset
# from apprise import Apprise
from json import dumps
# Disable logging for a cleaner testing output
@ -86,6 +85,31 @@ def test_notify_matrix_plugin_general(mock_post, mock_get):
# Registration Successful
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
ro = response_obj.copy()
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.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']
obj._room_cache = {}
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 = {}
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 = {}
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 = {}
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 = {}
assert obj._room_join('%') is None
assert obj._room_join(None) is None

View File

@ -1948,7 +1948,7 @@ TEST_URLS = (
.format('a' * 64), {
# user and token specified; image set to True
'instance': plugins.NotifyMatrix}),
('matrix://user@{}?mode=t2bot&format=markdown&image=False'
('matrix://user@{}?mode=t2bot&format=html&image=False'
.format('z' * 64), {
# user and token specified; image set to True
'instance': plugins.NotifyMatrix}),