Incoming mentions
This commit is contained in:
parent
2b9c59a2af
commit
6867e6b349
@ -16,11 +16,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Match
|
||||
from html import escape
|
||||
import re
|
||||
|
||||
from mautrix.types import Format, MessageType, TextMessageEventContent
|
||||
|
||||
from ..kt.types.chat.attachment.mention import MentionStruct
|
||||
|
||||
from .. import puppet as pu, user as u
|
||||
|
||||
_START = r"^|\s"
|
||||
@ -79,92 +80,38 @@ def _handle_blockquote(output: list[str], blockquote: bool, line: str) -> tuple[
|
||||
return blockquote, line
|
||||
|
||||
|
||||
def _handle_codeblock_pre(
|
||||
output: list[str], codeblock: bool, line: str
|
||||
) -> tuple[bool, str, tuple[str | None, str | None, str | None]]:
|
||||
cb = line.find("```")
|
||||
cb_lang = None
|
||||
cb_content = None
|
||||
post_cb_content = None
|
||||
if cb != -1:
|
||||
if not codeblock:
|
||||
cb_lang = line[cb + 3 :]
|
||||
if "```" in cb_lang:
|
||||
end = cb_lang.index("```")
|
||||
cb_content = cb_lang[:end]
|
||||
post_cb_content = cb_lang[end + 3 :]
|
||||
cb_lang = ""
|
||||
else:
|
||||
codeblock = True
|
||||
line = line[:cb]
|
||||
else:
|
||||
output.append("</code></pre>")
|
||||
codeblock = False
|
||||
line = line[cb + 3 :]
|
||||
return codeblock, line, (cb_lang, cb_content, post_cb_content)
|
||||
|
||||
|
||||
def _handle_codeblock_post(
|
||||
output: list[str], cb_lang: str | None, cb_content: str | None, post_cb_content: str | None
|
||||
) -> None:
|
||||
if cb_lang is not None:
|
||||
if cb_lang:
|
||||
output.append(f'<pre><code class="language-{cb_lang}">')
|
||||
else:
|
||||
output.append("<pre><code>")
|
||||
if cb_content:
|
||||
output.append(cb_content)
|
||||
output.append("</code></pre>")
|
||||
output.append(_convert_formatting(post_cb_content))
|
||||
|
||||
|
||||
async def kakaotalk_to_matrix(msg: str) -> TextMessageEventContent:
|
||||
async def kakaotalk_to_matrix(msg: str | None, mentions: list[MentionStruct] | None) -> TextMessageEventContent:
|
||||
# TODO Shouts
|
||||
text = msg or ""
|
||||
mentions = []
|
||||
content = TextMessageEventContent(msgtype=MessageType.TEXT, body=text)
|
||||
mention_user_ids = []
|
||||
for m in reversed(mentions):
|
||||
original = text[m.offset : m.offset + m.length]
|
||||
if len(original) > 0 and original[0] == "@":
|
||||
original = original[1:]
|
||||
mention_user_ids.append(int(m.user_id))
|
||||
text = f"{text[:m.offset]}@{m.user_id}\u2063{original}\u2063{text[m.offset + m.length:]}"
|
||||
html = escape(text)
|
||||
output = []
|
||||
if html:
|
||||
codeblock = False
|
||||
blockquote = False
|
||||
line: str
|
||||
lines = html.split("\n")
|
||||
for i, line in enumerate(lines):
|
||||
blockquote, line = _handle_blockquote(output, blockquote, line)
|
||||
codeblock, line, post_args = _handle_codeblock_pre(output, codeblock, line)
|
||||
output.append(_convert_formatting(line))
|
||||
if i != len(lines) - 1:
|
||||
if codeblock:
|
||||
output.append("\n")
|
||||
else:
|
||||
output.append("<br/>")
|
||||
_handle_codeblock_post(output, *post_args)
|
||||
html = "".join(output)
|
||||
|
||||
mention_user_map = {}
|
||||
for ktid in mention_user_ids:
|
||||
user = await u.User.get_by_ktid(ktid)
|
||||
if user:
|
||||
mention_user_map[ktid] = user.mxid
|
||||
else:
|
||||
puppet = await pu.Puppet.get_by_ktid(ktid, create=False)
|
||||
mention_user_map[ktid] = puppet.mxid if puppet else None
|
||||
if mentions:
|
||||
mention_user_ids = []
|
||||
at_chunks = text.split("@")
|
||||
for m in mentions:
|
||||
for idx in m.at:
|
||||
chunk = at_chunks[idx]
|
||||
original = chunk[:m.len]
|
||||
mention_user_ids.append(int(m.user_id))
|
||||
at_chunks[idx] = f"{m.user_id}\u2063{original}\u2063{chunk[m.len:]}"
|
||||
text = "@".join(at_chunks)
|
||||
|
||||
def _mention_replacer(match: Match) -> str:
|
||||
mxid = mention_user_map[int(match.group(1))]
|
||||
if not mxid:
|
||||
return match.group(2)
|
||||
return f'<a href="https://matrix.to/#/{mxid}">{match.group(2)}</a>'
|
||||
mention_user_map = {}
|
||||
for ktid in mention_user_ids:
|
||||
user = await u.User.get_by_ktid(ktid)
|
||||
if user:
|
||||
mention_user_map[ktid] = user.mxid
|
||||
else:
|
||||
puppet = await pu.Puppet.get_by_ktid(ktid, create=False)
|
||||
mention_user_map[ktid] = puppet.mxid if puppet else None
|
||||
|
||||
html = MENTION_REGEX.sub(_mention_replacer, html)
|
||||
if html != escape(content.body).replace("\n", "<br/>\n"):
|
||||
content.format = Format.HTML
|
||||
content.formatted_body = html
|
||||
if mention_user_map:
|
||||
def _mention_replacer(match: Match) -> str:
|
||||
mxid = mention_user_map[int(match.group(1))]
|
||||
if not mxid:
|
||||
return match.group(2)
|
||||
return f'<a href="https://matrix.to/#/{mxid}">{match.group(2)}</a>'
|
||||
|
||||
content.format = Format.HTML
|
||||
content.formatted_body = MENTION_REGEX.sub(_mention_replacer, text).replace("\n", "<br/>\n")
|
||||
return content
|
||||
|
@ -69,6 +69,7 @@ from .kt.types.channel.channel_info import ChannelInfo
|
||||
from .kt.types.channel.channel_type import KnownChannelType, ChannelType
|
||||
from .kt.types.chat import Chatlog, ChatType, KnownChatType
|
||||
from .kt.types.chat.attachment import (
|
||||
Attachment,
|
||||
AudioAttachment,
|
||||
#FileAttachment,
|
||||
MediaAttachment,
|
||||
@ -1082,12 +1083,12 @@ class Portal(DBPortal, BasePortal):
|
||||
async def _handle_remote_text(
|
||||
self,
|
||||
intent: IntentAPI,
|
||||
attachment: Attachment | None,
|
||||
timestamp: int,
|
||||
message_text: str | None,
|
||||
**_
|
||||
) -> list[EventID]:
|
||||
# TODO Handle mentions properly
|
||||
content = await kakaotalk_to_matrix(message_text)
|
||||
content = await kakaotalk_to_matrix(message_text, attachment.mentions if attachment else None)
|
||||
return [await self._send_message(intent, content, timestamp=timestamp)]
|
||||
|
||||
async def _handle_remote_reply(
|
||||
|
Loading…
Reference in New Issue
Block a user