Added send_image_bytes(...) to avoid temp files

This commit is contained in:
2026-09-12 20:04:55 +03:00
parent 3e15ae426c
commit 31fbcb4697
2 changed files with 97 additions and 0 deletions

View File

@@ -1,4 +1,5 @@
import asyncio
from io import BytesIO
import logging
from html.parser import HTMLParser
from pathlib import Path
@@ -214,6 +215,69 @@ class ClientSender:
}
return (await self.send_content(room, content)).event_id
async def send_image_bytes(self,
room: MatrixRoom | str,
data: bytes,
filename: str,
*,
text: str | None = None,
is_html: bool | None = None,
timeout: float | None = 60 * 60) -> str:
"""
Send the image to `room`. Please note that formatted text is displayed
incorrectly in some clients as of September 8th, 2026
Args:
- room - the room to send the text to
- bytes - the image to send
- filename - filename to use for the file
- text - image caption to use (`None` to disable)
- is_html - whether the text is HTML-formatted (`None` for auto)
- timeout - upload timeout in seconds (`None` to disable)
Returns:
- `event_id` of sent message on success
- Raises an exception on error
"""
# caption must not actually be empty
if text is None or not text.strip():
text = filename
is_html = False
# check if the file is image
mime_type: str = magic.from_buffer(data, mime=True)
if not mime_type.startswith("image/"):
raise RuntimeError(f"Data has non-image mime-type")
# get image size
buffer = BytesIO(data)
with Image.open(buffer) as image:
width, height = image.size
buffer.seek(0)
# upload
async with asyncio.timeout(timeout):
upload_result = await self._uploader.upload_using_provider(
provider=buffer,
mime_type=mime_type,
filename=filename,
filesize=len(data))
# prepare the content and send
content = {
"msgtype": "m.image",
"filename": filename,
**self._process_html_text(text, is_html),
"file": {
"url": upload_result.response.content_uri,
"mimetype": mime_type,
**upload_result.keys
},
"info": {
"mimetype": mime_type,
"size": upload_result.filesize,
"w": width,
"h": height
}
}
return (await self.send_content(room, content)).event_id
async def send_video(self,
room: MatrixRoom | str,
path: Path | str,

View File

@@ -177,6 +177,39 @@ class MatrixBot:
timeout=timeout
)
async def send_image_bytes(self,
room: MatrixRoom | str,
data: bytes,
filename: str,
*,
text: str | None = None,
is_html: bool | None = None,
timeout: float | None = 60 * 60) -> str:
"""
Send the image to `room`. Please note that formatted text is displayed
incorrectly in some clients as of September 8th, 2026
Args:
- room - the room to send the text to
- bytes - the image to send
- filename - filename to use for the file
- text - image caption to use (`None` to disable)
- is_html - whether the text is HTML-formatted (`None` for auto)
- timeout - upload timeout in seconds (`None` to disable)
Returns:
- `event_id` of sent message on success
- Raises an exception on error
"""
return await self._client_sender.send_image_bytes(
room=room,
data=data,
filename=filename,
text=text,
is_html=is_html,
timeout=timeout
)
async def send_video(self,
room: MatrixRoom | str,
path: Path | str,