feat: parse matrix staged attachment commands
This commit is contained in:
parent
0eaf124e21
commit
83c9a1513b
2 changed files with 100 additions and 17 deletions
|
|
@ -14,42 +14,52 @@ PLATFORM = "matrix"
|
|||
|
||||
|
||||
def extract_attachments(event: Any) -> list[Attachment]:
|
||||
content = getattr(event, "content", {}) or {}
|
||||
msgtype = getattr(event, "msgtype", None)
|
||||
if msgtype is None:
|
||||
content = getattr(event, "content", {}) or {}
|
||||
msgtype = content.get("msgtype")
|
||||
url = content.get("url") or getattr(event, "url", None)
|
||||
filename = content.get("body") or getattr(event, "body", None)
|
||||
mime_type = content.get("mimetype") or getattr(event, "mimetype", None)
|
||||
if mime_type is None:
|
||||
info = content.get("info") or {}
|
||||
if isinstance(info, dict):
|
||||
mime_type = info.get("mimetype")
|
||||
|
||||
if msgtype == "m.image":
|
||||
return [
|
||||
Attachment(
|
||||
type="image",
|
||||
url=getattr(event, "url", None),
|
||||
mime_type=getattr(event, "mimetype", None),
|
||||
url=url,
|
||||
filename=filename,
|
||||
mime_type=mime_type,
|
||||
)
|
||||
]
|
||||
if msgtype == "m.file":
|
||||
return [
|
||||
Attachment(
|
||||
type="document",
|
||||
url=getattr(event, "url", None),
|
||||
filename=getattr(event, "body", None),
|
||||
mime_type=getattr(event, "mimetype", None),
|
||||
url=url,
|
||||
filename=filename,
|
||||
mime_type=mime_type,
|
||||
)
|
||||
]
|
||||
if msgtype == "m.audio":
|
||||
return [
|
||||
Attachment(
|
||||
type="audio",
|
||||
url=getattr(event, "url", None),
|
||||
mime_type=getattr(event, "mimetype", None),
|
||||
url=url,
|
||||
filename=filename,
|
||||
mime_type=mime_type,
|
||||
)
|
||||
]
|
||||
if msgtype == "m.video":
|
||||
return [
|
||||
Attachment(
|
||||
type="video",
|
||||
url=getattr(event, "url", None),
|
||||
mime_type=getattr(event, "mimetype", None),
|
||||
url=url,
|
||||
filename=filename,
|
||||
mime_type=mime_type,
|
||||
)
|
||||
]
|
||||
return []
|
||||
|
|
@ -75,6 +85,24 @@ def from_command(body: str, sender: str, chat_id: str, room_id: str | None = Non
|
|||
},
|
||||
)
|
||||
|
||||
if command == "list" and not args:
|
||||
return IncomingCommand(
|
||||
user_id=sender,
|
||||
platform=PLATFORM,
|
||||
chat_id=chat_id,
|
||||
command="matrix_list_attachments",
|
||||
args=[],
|
||||
)
|
||||
|
||||
if command == "remove" and len(args) == 1:
|
||||
return IncomingCommand(
|
||||
user_id=sender,
|
||||
platform=PLATFORM,
|
||||
chat_id=chat_id,
|
||||
command="matrix_remove_attachment",
|
||||
args=[args[0]],
|
||||
)
|
||||
|
||||
aliases = {
|
||||
"skills": "settings_skills",
|
||||
"connectors": "settings_connectors",
|
||||
|
|
|
|||
|
|
@ -37,7 +37,23 @@ def image_event(url: str = "mxc://x/img", mime: str = "image/jpeg"):
|
|||
)
|
||||
|
||||
|
||||
async def test_plain_text_to_incoming_message():
|
||||
def content_file_event():
|
||||
return SimpleNamespace(
|
||||
sender="@a:m.org",
|
||||
body="doc.pdf",
|
||||
event_id="$e4",
|
||||
msgtype=None,
|
||||
replyto_event_id=None,
|
||||
content={
|
||||
"msgtype": "m.file",
|
||||
"body": "nested.pdf",
|
||||
"url": "mxc://x/nested",
|
||||
"info": {"mimetype": "application/pdf"},
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def test_plain_text_to_incoming_message():
|
||||
result = from_room_event(text_event("Hello"), room_id="!r:m.org", chat_id="C1")
|
||||
assert isinstance(result, IncomingMessage)
|
||||
assert result.text == "Hello"
|
||||
|
|
@ -46,20 +62,48 @@ async def test_plain_text_to_incoming_message():
|
|||
assert result.attachments == []
|
||||
|
||||
|
||||
async def test_bang_command_to_incoming_command():
|
||||
def test_bang_command_to_incoming_command():
|
||||
result = from_room_event(text_event("!new Analysis"), room_id="!r:m.org", chat_id="C1")
|
||||
assert isinstance(result, IncomingCommand)
|
||||
assert result.command == "new"
|
||||
assert result.args == ["Analysis"]
|
||||
|
||||
|
||||
async def test_skills_alias_to_settings_command():
|
||||
def test_list_command_maps_to_matrix_list_attachments():
|
||||
result = from_room_event(text_event("!list"), room_id="!r:m.org", chat_id="C1")
|
||||
assert isinstance(result, IncomingCommand)
|
||||
assert result.command == "matrix_list_attachments"
|
||||
assert result.args == []
|
||||
|
||||
|
||||
def test_remove_all_maps_to_matrix_remove_attachment():
|
||||
result = from_room_event(text_event("!remove all"), room_id="!r:m.org", chat_id="C1")
|
||||
assert isinstance(result, IncomingCommand)
|
||||
assert result.command == "matrix_remove_attachment"
|
||||
assert result.args == ["all"]
|
||||
|
||||
|
||||
def test_remove_index_maps_to_matrix_remove_attachment():
|
||||
result = from_room_event(text_event("!remove 2"), room_id="!r:m.org", chat_id="C1")
|
||||
assert isinstance(result, IncomingCommand)
|
||||
assert result.command == "matrix_remove_attachment"
|
||||
assert result.args == ["2"]
|
||||
|
||||
|
||||
def test_remove_arbitrary_index_maps_to_matrix_remove_attachment():
|
||||
result = from_room_event(text_event("!remove 99"), room_id="!r:m.org", chat_id="C1")
|
||||
assert isinstance(result, IncomingCommand)
|
||||
assert result.command == "matrix_remove_attachment"
|
||||
assert result.args == ["99"]
|
||||
|
||||
|
||||
def test_skills_alias_to_settings_command():
|
||||
result = from_command("!skills", sender="@a:m.org", chat_id="C1")
|
||||
assert isinstance(result, IncomingCommand)
|
||||
assert result.command == "settings_skills"
|
||||
|
||||
|
||||
async def test_yes_to_callback():
|
||||
def test_yes_to_callback():
|
||||
result = from_room_event(text_event("!yes"), room_id="!room:example.org", chat_id="C7")
|
||||
assert isinstance(result, IncomingCallback)
|
||||
assert result.action == "confirm"
|
||||
|
|
@ -67,7 +111,7 @@ async def test_yes_to_callback():
|
|||
assert result.payload["room_id"] == "!room:example.org"
|
||||
|
||||
|
||||
async def test_no_to_callback():
|
||||
def test_no_to_callback():
|
||||
result = from_room_event(text_event("!no"), room_id="!room:example.org", chat_id="C7")
|
||||
assert isinstance(result, IncomingCallback)
|
||||
assert result.action == "cancel"
|
||||
|
|
@ -75,7 +119,7 @@ async def test_no_to_callback():
|
|||
assert result.payload["room_id"] == "!room:example.org"
|
||||
|
||||
|
||||
async def test_file_attachment():
|
||||
def test_file_attachment():
|
||||
result = from_room_event(file_event(), room_id="!r:m.org", chat_id="C1")
|
||||
assert isinstance(result, IncomingMessage)
|
||||
assert len(result.attachments) == 1
|
||||
|
|
@ -86,11 +130,22 @@ async def test_file_attachment():
|
|||
assert a.mime_type == "application/pdf"
|
||||
|
||||
|
||||
async def test_image_attachment():
|
||||
def test_image_attachment():
|
||||
result = from_room_event(image_event(), room_id="!r:m.org", chat_id="C1")
|
||||
assert result.attachments[0].type == "image"
|
||||
assert result.attachments[0].filename == "img.jpg"
|
||||
assert result.attachments[0].mime_type == "image/jpeg"
|
||||
|
||||
|
||||
def test_attachment_falls_back_to_content_payload():
|
||||
result = from_room_event(content_file_event(), room_id="!r:m.org", chat_id="C1")
|
||||
assert isinstance(result, IncomingMessage)
|
||||
a = result.attachments[0]
|
||||
assert a.type == "document"
|
||||
assert a.url == "mxc://x/nested"
|
||||
assert a.filename == "nested.pdf"
|
||||
assert a.mime_type == "application/pdf"
|
||||
|
||||
|
||||
def test_converter_module_does_not_expose_reaction_callbacks():
|
||||
assert not hasattr(converter, "from_reaction")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue