Inbound replies (and some kwarg cleanup)

This commit is contained in:
Andrew Ferrazzutti 2022-04-05 02:44:03 -04:00
parent ce5006269f
commit 3ced968494
1 changed files with 78 additions and 49 deletions

View File

@ -31,7 +31,7 @@ import time
from mautrix.appservice import IntentAPI
from mautrix.bridge import BasePortal, NotificationDisabler, async_getter_lock
from mautrix.errors import MatrixError
from mautrix.errors import MatrixError, MForbidden, MNotFound, SessionNotFound
from mautrix.types import (
AudioInfo,
ContentURI,
@ -73,6 +73,7 @@ from .kt.types.chat.attachment import (
MediaAttachment,
MultiPhotoAttachment,
PhotoAttachment,
ReplyAttachment,
VideoAttachment,
)
@ -190,6 +191,7 @@ class Portal(DBPortal, BasePortal):
# TODO More
cls._message_type_handler_map = {
KnownChatType.TEXT: cls._handle_remote_text,
KnownChatType.REPLY: cls._handle_remote_reply,
KnownChatType.PHOTO: cls._handle_remote_photo,
KnownChatType.MULTIPHOTO: cls._handle_remote_multiphoto,
KnownChatType.VIDEO: cls._handle_remote_video,
@ -953,6 +955,38 @@ class Portal(DBPortal, BasePortal):
return False
return True
async def _add_remote_reply(
self, content: MessageEventContent, reply_to: ReplyAttachment
) -> None:
message = await DBMessage.get_by_ktid(reply_to.src_logId, self.kt_receiver)
if not message:
self.log.warning(
f"Couldn't find reply target {reply_to.src_logId} to bridge reply metadata to Matrix"
)
return
content.set_reply(message.mxid)
if not isinstance(content, TextMessageEventContent):
return
try:
evt = await self.main_intent.get_event(message.mx_room, message.mxid)
except (MNotFound, MForbidden):
evt = None
if not evt:
return
if evt.type == EventType.ROOM_ENCRYPTED:
try:
evt = await self.matrix.e2ee.decrypt(evt, wait_session_timeout=0)
except SessionNotFound:
return
if isinstance(evt.content, TextMessageEventContent):
evt.content.trim_reply_fallback()
content.set_reply(evt)
async def handle_remote_message(
self,
source: u.User,
@ -1039,52 +1073,58 @@ class Portal(DBPortal, BasePortal):
type_str,
f"text = {message_text}" if message_text is not None else "no text",
)
if message_text:
events = await self._handle_remote_text(
intent=intent,
timestamp=timestamp,
message_text=message_text,
)
else:
events = []
content = TextMessageEventContent(
msgtype=MessageType.NOTICE,
body=f"\u26a0 Unbridgeable message ({type_str})",
)
# TODO Replies
return [await self._send_message(intent, content, timestamp=timestamp)]
if events:
content.set_reply(events[-1])
events.append(await self._send_message(intent, content, timestamp=timestamp))
return events
async def _handle_remote_text(
self,
intent: IntentAPI,
timestamp: int,
message_text: str,
message_text: str | None,
**_
) -> list[EventID]:
# TODO Handle mentions properly
content = await kakaotalk_to_matrix(message_text)
# TODO Replies
return [await self._send_message(intent, content, timestamp=timestamp)]
def _handle_remote_photo(
async def _handle_remote_reply(
self,
source: u.User,
intent: IntentAPI,
attachment: PhotoAttachment,
attachment: ReplyAttachment,
timestamp: int,
message_text: str | None,
message_text: str,
**_
) -> Awaitable[list[EventID]]:
return asyncio.gather(self._handle_remote_uniphoto(
source, intent, attachment, timestamp, message_text
))
) -> list[EventID]:
content = await kakaotalk_to_matrix(message_text)
await self._add_remote_reply(content, attachment)
return [await self._send_message(intent, content, timestamp=timestamp)]
def _handle_remote_photo(self, **kwargs) -> Awaitable[list[EventID]]:
return asyncio.gather(self._handle_remote_uniphoto(**kwargs))
async def _handle_remote_multiphoto(
self,
source: u.User,
intent: IntentAPI,
attachment: MultiPhotoAttachment,
timestamp: int,
message_text: str | None,
**_
**kwargs
) -> Awaitable[list[EventID]]:
# TODO Upload media concurrently, but post messages sequentially
return [
await self._handle_remote_uniphoto(
source, intent,
PhotoAttachment(
attachment=PhotoAttachment(
shout=attachment.shout,
mentions=attachment.mentions,
urls=attachment.urls,
@ -1099,22 +1139,18 @@ class Portal(DBPortal, BasePortal):
cs=attachment.csl[i],
mt=attachment.mtl[i],
),
timestamp, message_text,
**kwargs
)
for i in range(len(attachment.imageUrls))
]
def _handle_remote_uniphoto(
self,
source: u.User,
intent: IntentAPI,
attachment: PhotoAttachment,
timestamp: int,
message_text: str | None,
**_
**kwargs
) -> Awaitable[EventID]:
return self._handle_remote_media(
source, intent, attachment, timestamp, message_text,
attachment,
ImageInfo(
mimetype=attachment.mt,
size=attachment.s,
@ -1122,72 +1158,66 @@ class Portal(DBPortal, BasePortal):
height=attachment.h,
),
MessageType.IMAGE,
**kwargs
)
def _handle_remote_video(
self,
source: u.User,
intent: IntentAPI,
attachment: VideoAttachment,
timestamp: int,
message_text: str | None,
**_
**kwargs
) -> Awaitable[list[EventID]]:
return asyncio.gather(self._handle_remote_media(
source, intent, attachment, timestamp, message_text,
attachment,
VideoInfo(
duration=attachment.d,
width=attachment.w,
height=attachment.h,
),
MessageType.VIDEO,
**kwargs
))
def _handle_remote_audio(
self,
source: u.User,
intent: IntentAPI,
attachment: AudioAttachment,
timestamp: int,
message_text: str | None,
**_
**kwargs
) -> Awaitable[list[EventID]]:
return asyncio.gather(self._handle_remote_media(
source, intent, attachment, timestamp, message_text,
attachment,
AudioInfo(
size=attachment.s,
duration=attachment.d,
),
MessageType.AUDIO,
**kwargs
))
""" TODO Find what auth is required for reading file contents
def _handle_remote_file(
self,
source: u.User,
intent: IntentAPI,
attachment: FileAttachment,
timestamp: int,
message_text: str | None,
**kwargs
) -> Awaitable[list[EventID]]:
return asyncio.gather(self._handle_remote_media(
source, intent, attachment, timestamp, message_text,
attachment,
FileInfo(
size=attachment.size,
),
MessageType.FILE,
**kwargs
))
"""
async def _handle_remote_media(
self,
source: u.User,
intent: IntentAPI,
attachment: MediaAttachment,
timestamp: int,
message_text: str | None,
info: MediaInfo,
msgtype: MessageType,
*,
source: u.User,
intent: IntentAPI,
timestamp: int,
message_text: str | None,
**_
) -> EventID:
mxc, additional_info, decryption_info = await self._reupload_remote_file(
@ -1203,7 +1233,6 @@ class Portal(DBPortal, BasePortal):
content = MediaMessageEventContent(
url=mxc, file=decryption_info, msgtype=msgtype, body=message_text, info=info
)
# TODO Replies
return await self._send_message(intent, content, timestamp=timestamp)
# TODO Many more remote handlers