Added send_image_bytes(...) to avoid temp files
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
from io import BytesIO
|
||||||
import logging
|
import logging
|
||||||
from html.parser import HTMLParser
|
from html.parser import HTMLParser
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -214,6 +215,69 @@ class ClientSender:
|
|||||||
}
|
}
|
||||||
return (await self.send_content(room, content)).event_id
|
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,
|
async def send_video(self,
|
||||||
room: MatrixRoom | str,
|
room: MatrixRoom | str,
|
||||||
path: Path | str,
|
path: Path | str,
|
||||||
|
|||||||
@@ -177,6 +177,39 @@ class MatrixBot:
|
|||||||
timeout=timeout
|
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,
|
async def send_video(self,
|
||||||
room: MatrixRoom | str,
|
room: MatrixRoom | str,
|
||||||
path: Path | str,
|
path: Path | str,
|
||||||
|
|||||||
Reference in New Issue
Block a user