mirror of
https://github.com/luk3yx/miniirc_matrix.git
synced 2026-05-17 05:25:44 +03:00
Send mentions in new format
This commit is contained in:
@@ -45,11 +45,22 @@ def _register_event(event_name: str):
|
|||||||
return _register
|
return _register
|
||||||
|
|
||||||
|
|
||||||
_formatting_re = re.compile(
|
_invisible_formatting_re = re.compile(
|
||||||
r'\x02|\x1d|\x1f|\x1e|\x11|\x16|\x0f'
|
r'\x02|\x1d|\x1f|\x1e|\x11|\x16|\x0f'
|
||||||
r'|\x03([0-9]{1,2})?(?:,([0-9]{1,2}))?'
|
r'|\x03([0-9]{1,2})?(?:,([0-9]{1,2}))?'
|
||||||
|
|
||||||
|
# Hex colours
|
||||||
r'|\x04([0-9a-fA-F]{6})?(?:,([0-9a-fA-F]{6}))?'
|
r'|\x04([0-9a-fA-F]{6})?(?:,([0-9a-fA-F]{6}))?'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_full_formatting_re = re.compile(
|
||||||
|
_invisible_formatting_re.pattern +
|
||||||
|
|
||||||
|
# Matrix mentions
|
||||||
|
# These currently get inserted without any escaping, if HTML characters get
|
||||||
|
# added to the regex then make sure escaping gets added
|
||||||
|
r'|\B@[a-z0-9\._=\-/+]+:[a-zA-Z0-9_\-\.]+\.[a-zA-Z]{2,}(?!\.\w)\b'
|
||||||
|
)
|
||||||
_html_tags = {'\x02': 'strong', '\x1d': 'em', '\x1f': 'u', '\x1e': 'del',
|
_html_tags = {'\x02': 'strong', '\x1d': 'em', '\x1f': 'u', '\x1e': 'del',
|
||||||
'\x11': 'code'}
|
'\x11': 'code'}
|
||||||
|
|
||||||
@@ -86,9 +97,15 @@ class _TagManager:
|
|||||||
self.write_tags()
|
self.write_tags()
|
||||||
self.text.append(s)
|
self.text.append(s)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _encode_attribute(param: str) -> str:
|
||||||
|
if param == 'href':
|
||||||
|
return param
|
||||||
|
return 'data-mx-' + param.replace('_', '-')
|
||||||
|
|
||||||
def open(self, tag: str, **kwargs: Optional[str]) -> None:
|
def open(self, tag: str, **kwargs: Optional[str]) -> None:
|
||||||
self.tags[tag] = ''.join(
|
self.tags[tag] = ''.join(
|
||||||
f' data-mx-{param.replace("_", "-")}="{value}"'
|
f' {self._encode_attribute(param)}="{value}"'
|
||||||
for param, value in kwargs.items() if value is not None
|
for param, value in kwargs.items() if value is not None
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -167,20 +184,21 @@ def _irc_colour_to_hex(code: Optional[str]) -> Optional[str]:
|
|||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
def _irc_to_html(irc_msg: str) -> Optional[str]:
|
def _irc_to_html(irc_msg: str) -> tuple[Optional[str], set[str]]:
|
||||||
"""
|
"""
|
||||||
Converts IRC formatting to Matrix HTML. Returns None if the message
|
Converts IRC formatting to Matrix HTML. Returns None if the message
|
||||||
contains no formatting.
|
contains no formatting.
|
||||||
"""
|
"""
|
||||||
|
mentions: set[str] = set()
|
||||||
|
|
||||||
# Escaping quotes seems to make matrix-appservice-discord do strange things
|
# Escaping quotes seems to make matrix-appservice-discord do strange things
|
||||||
irc_msg = html.escape(irc_msg, quote=False)
|
irc_msg = html.escape(irc_msg, quote=False)
|
||||||
|
|
||||||
# If there is no formatting return immediately
|
# If there is no formatting return immediately
|
||||||
it = _formatting_re.finditer(irc_msg)
|
it = _full_formatting_re.finditer(irc_msg)
|
||||||
first_match = next(it, None)
|
first_match = next(it, None)
|
||||||
if first_match is None:
|
if first_match is None:
|
||||||
return None
|
return None, mentions
|
||||||
|
|
||||||
tags = _TagManager()
|
tags = _TagManager()
|
||||||
prev_end = start = 0
|
prev_end = start = 0
|
||||||
@@ -212,12 +230,20 @@ def _irc_to_html(irc_msg: str) -> Optional[str]:
|
|||||||
elif char == '\x0f':
|
elif char == '\x0f':
|
||||||
tags.fg = tags.bg = None
|
tags.fg = tags.bg = None
|
||||||
tags.tags.clear()
|
tags.tags.clear()
|
||||||
|
elif char == '@':
|
||||||
|
# Matrix mention
|
||||||
|
mention = match.group(0)
|
||||||
|
tags.open('a', href=f'https://matrix.to/#/{mention}')
|
||||||
|
tags.write(mention)
|
||||||
|
tags.close('a')
|
||||||
|
mentions.add(mention)
|
||||||
|
|
||||||
prev_end = match.end()
|
prev_end = match.end()
|
||||||
|
|
||||||
tags.write(irc_msg[prev_end:])
|
tags.write(irc_msg[prev_end:])
|
||||||
tags.tags.clear()
|
tags.tags.clear()
|
||||||
tags.write_tags()
|
tags.write_tags()
|
||||||
return ''.join(tags.text).replace('\n', '<br>')
|
return ''.join(tags.text).replace('\n', '<br>'), mentions
|
||||||
|
|
||||||
|
|
||||||
# This simple space collapsing regex "collapses" newlines as well
|
# This simple space collapsing regex "collapses" newlines as well
|
||||||
@@ -570,13 +596,16 @@ class Matrix(miniirc.IRC):
|
|||||||
msgtype = 'm.text'
|
msgtype = 'm.text'
|
||||||
|
|
||||||
params: dict[str, Any]
|
params: dict[str, Any]
|
||||||
if html_msg := _irc_to_html(msg):
|
html_msg, mentions = _irc_to_html(msg)
|
||||||
|
if html_msg:
|
||||||
params = {
|
params = {
|
||||||
'msgtype': msgtype,
|
'msgtype': msgtype,
|
||||||
'body': _formatting_re.sub('', msg),
|
'body': _invisible_formatting_re.sub('', msg),
|
||||||
'format': 'org.matrix.custom.html',
|
'format': 'org.matrix.custom.html',
|
||||||
'formatted_body': html_msg,
|
'formatted_body': html_msg,
|
||||||
}
|
}
|
||||||
|
if mentions:
|
||||||
|
params['m.mentions'] = {'user_ids': list(mentions)}
|
||||||
else:
|
else:
|
||||||
# No formatting
|
# No formatting
|
||||||
params = {'msgtype': msgtype, 'body': msg}
|
params = {'msgtype': msgtype, 'body': msg}
|
||||||
|
|||||||
@@ -2,10 +2,14 @@ from miniirc_matrix import _Event, _irc_to_html, _matrix_html_to_irc
|
|||||||
|
|
||||||
|
|
||||||
def test_irc_to_html():
|
def test_irc_to_html():
|
||||||
assert _irc_to_html('Hello world!') is None
|
assert _irc_to_html('Hello world!') == (None, set())
|
||||||
assert _irc_to_html('\x02Bold text') == '<strong>Bold text</strong>'
|
assert _irc_to_html('\x02Bold') == ('<strong>Bold</strong>', set())
|
||||||
assert (_irc_to_html('\x021 \x1d2\x02 3') ==
|
assert (_irc_to_html('\x021 \x1d2\x02 3') ==
|
||||||
'<strong>1 <em>2</em></strong><em> 3</em>')
|
('<strong>1 <em>2</em></strong><em> 3</em>', set()))
|
||||||
|
|
||||||
|
assert (_irc_to_html('@test:example.com: \x1dHello') ==
|
||||||
|
('<a href="https://matrix.to/#/@test:example.com">'
|
||||||
|
'@test:example.com</a>: <em>Hello</em>', {'@test:example.com'}))
|
||||||
|
|
||||||
|
|
||||||
def html_to_irc(html):
|
def html_to_irc(html):
|
||||||
|
|||||||
Reference in New Issue
Block a user