Got rid of proxy methods in MatrixBot, v0.6.0
- Updated README.md - Updated examples - `MatrixBot` does not redefine methods from classes it is composed of anymore
This commit is contained in:
@@ -10,6 +10,7 @@ The library supports the following features:
|
||||
- **Completely `asyncio` based**
|
||||
- **Filter-based callback system**
|
||||
- **Downloading and transparently decrypting files**
|
||||
- **Sending files**
|
||||
- **Sending images**
|
||||
- **Sending videos with automatic thumbnail generation (requires `ffmpeg`)**
|
||||
|
||||
@@ -22,7 +23,7 @@ install the latest version of the library:
|
||||
|
||||
```bash
|
||||
apt install libmagic1-dev libolm-dev
|
||||
python -m pip install git+https://git.tyukalov.su/nikita/mab@v0.5.1
|
||||
python -m pip install git+https://git.tyukalov.su/nikita/mab@v0.6.0
|
||||
```
|
||||
|
||||
`libmagic1-dev` is needed for automatic file MIME type detection, `libolm-dev`
|
||||
|
||||
@@ -29,18 +29,18 @@ async def on_help_command(ctx: EventContext) -> None:
|
||||
"<li><code>!args arg1 [arg2] ... [arg5]</code> - command that takes 1..5 arguments</li>"
|
||||
"</ul>"
|
||||
)
|
||||
await ctx.bot.send_text(ctx.room, HELP_MESSAGE)
|
||||
await ctx.bot.send.text(ctx.room, HELP_MESSAGE)
|
||||
|
||||
async def on_time_command(ctx: EventContext) -> None:
|
||||
"""!time"""
|
||||
await ctx.bot.send_text(
|
||||
await ctx.bot.send.text(
|
||||
ctx.room,
|
||||
f"Current UNIX timestamp is <strong>{int(time.time())}</strong>"
|
||||
)
|
||||
|
||||
async def on_raise_command(ctx: EventContext) -> None:
|
||||
"""!raise"""
|
||||
await ctx.bot.send_text(
|
||||
await ctx.bot.send.text(
|
||||
ctx.room,
|
||||
"<strong>Executing <code>raise RuntimeError()</code>...</strong>"
|
||||
)
|
||||
@@ -48,7 +48,7 @@ async def on_raise_command(ctx: EventContext) -> None:
|
||||
|
||||
async def on_assert_command(ctx: EventContext) -> None:
|
||||
"""!assert"""
|
||||
await ctx.bot.send_text(
|
||||
await ctx.bot.send.text(
|
||||
ctx.room,
|
||||
"<strong>Executing <code>assert False</code>...</strong>"
|
||||
)
|
||||
@@ -63,9 +63,9 @@ async def on_mul_command(ctx: EventContext) -> None:
|
||||
v *= n
|
||||
response = " * ".join(html.escape("%.2f" % n) for n in numbers)
|
||||
response += f" = <strong>{html.escape(str(v))}<strong>"
|
||||
await ctx.bot.send_text(ctx.room, response)
|
||||
await ctx.bot.send.text(ctx.room, response)
|
||||
except Exception as e:
|
||||
await ctx.bot.send_text(ctx.room, f"Could not process the command: {e}")
|
||||
await ctx.bot.send.text(ctx.room, f"Could not process the command: {e}")
|
||||
|
||||
async def on_args_command(ctx: EventContext) -> None:
|
||||
"""!args"""
|
||||
@@ -79,19 +79,19 @@ async def on_args_command(ctx: EventContext) -> None:
|
||||
for arg in ctx[CTX_CMD_ARGS]:
|
||||
response += f"<li><code>{html.escape(arg)}</code></li>"
|
||||
response += "</ol>"
|
||||
await ctx.bot.send_text(
|
||||
await ctx.bot.send.text(
|
||||
ctx.room,
|
||||
response
|
||||
)
|
||||
except:
|
||||
await ctx.bot.send_text(
|
||||
await ctx.bot.send.text(
|
||||
ctx.room,
|
||||
f"Could not process the command: {traceback.format_exc()}"
|
||||
)
|
||||
|
||||
async def invalid_usage(ctx: EventContext) -> None:
|
||||
"""This callback is called when the bot used incorrectly."""
|
||||
await ctx.bot.send_text(ctx.room, "Use <code>!help</code>")
|
||||
await ctx.bot.send.text(ctx.room, "Use <code>!help</code>")
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
|
||||
@@ -15,7 +15,7 @@ from _environment import check_environment
|
||||
|
||||
async def on_text_message(ctx: EventContext) -> None:
|
||||
"""This callback is called when a text message arrives."""
|
||||
await ctx.bot.send_text(ctx.room, ctx[CTX_BODY])
|
||||
await ctx.bot.send.text(ctx.room, ctx[CTX_BODY])
|
||||
|
||||
async def main() -> None:
|
||||
"""Application entry point"""
|
||||
|
||||
@@ -18,18 +18,18 @@ from _environment import check_environment
|
||||
|
||||
async def on_text_message(ctx: EventContext) -> None:
|
||||
"""This callback is called when a text message arrives."""
|
||||
await ctx.bot.send_text(ctx.room, "Please send a file/image/video")
|
||||
await ctx.bot.send.text(ctx.room, "Please send a file/image/video")
|
||||
|
||||
async def on_file_message(ctx: EventContext) -> None:
|
||||
"""This callback is called when a file arrives."""
|
||||
sha = hashlib.sha256()
|
||||
does_temp_exist = False
|
||||
if ctx[CTX_FILE_SIZE] > 1_000_000:
|
||||
await ctx.bot.send_text(
|
||||
await ctx.bot.send.text(
|
||||
ctx.room,
|
||||
"The file is larger than 1 MB, downloading to filesystem"
|
||||
)
|
||||
await ctx.bot.download_file(ctx, path="temp.tmp")
|
||||
await ctx.bot.download.file(ctx, path="temp.tmp")
|
||||
async with aiofiles.open("temp.tmp", "rb") as f:
|
||||
while True:
|
||||
data = await f.read(64 * 1024)
|
||||
@@ -38,16 +38,16 @@ async def on_file_message(ctx: EventContext) -> None:
|
||||
sha.update(data)
|
||||
does_temp_exist = True
|
||||
else:
|
||||
await ctx.bot.send_text(
|
||||
await ctx.bot.send.text(
|
||||
ctx.room,
|
||||
"The file is smaller than 1 MB, downloading to RAM"
|
||||
)
|
||||
content = await ctx.bot.download_file(ctx, path=None)
|
||||
content = await ctx.bot.download.file(ctx, path=None)
|
||||
sha.update(content)
|
||||
# result
|
||||
response = f"SHA256 for file `{ctx[CTX_FILE_NAME]}`"
|
||||
response += f" ({ctx[CTX_FILE_SIZE]} bytes, {ctx[CTX_FILE_MIME]})"
|
||||
await ctx.bot.send_file_bytes(
|
||||
await ctx.bot.send.file_bytes(
|
||||
room=ctx.room,
|
||||
data=sha.hexdigest().encode("utf-8"),
|
||||
filename="hash of the file.txt",
|
||||
@@ -56,7 +56,7 @@ async def on_file_message(ctx: EventContext) -> None:
|
||||
)
|
||||
# resend the file to test uploading
|
||||
if does_temp_exist:
|
||||
await ctx.bot.send_file(
|
||||
await ctx.bot.send.file(
|
||||
room=ctx.room,
|
||||
path="temp.tmp",
|
||||
filename=ctx[CTX_FILE_NAME],
|
||||
|
||||
@@ -24,9 +24,9 @@ async def on_gen_command(data: EventContext) -> None:
|
||||
try:
|
||||
r, g, b = [float(v) for v in data[CTX_CMD_ARGS]]
|
||||
except:
|
||||
await data.bot.send_text(data.room, "Invalid arguments")
|
||||
await data.bot.send.text(data.room, "Invalid arguments")
|
||||
return
|
||||
await data.bot.send_text(data.room, "Generating the noise...")
|
||||
await data.bot.send.text(data.room, "Generating the noise...")
|
||||
# create the basic noise
|
||||
img = Image.new("RGB", (16, 16))
|
||||
for x in range(img.width):
|
||||
@@ -44,13 +44,13 @@ async def on_gen_command(data: EventContext) -> None:
|
||||
buf.seek(0)
|
||||
buf = buf.read()
|
||||
# send
|
||||
await data.bot.send_image_bytes(data.room, buf, "noise.png")
|
||||
await data.bot.send.image_bytes(data.room, buf, "noise.png")
|
||||
|
||||
async def on_image(ctx: EventContext) -> None:
|
||||
"""This callback is called when an image is received."""
|
||||
# download
|
||||
s = time.time()
|
||||
data = await ctx.bot.download_file(ctx)
|
||||
data = await ctx.bot.download.file(ctx)
|
||||
took_time = time.time() - s
|
||||
# convert to Image
|
||||
with BytesIO(data) as buf:
|
||||
@@ -66,7 +66,7 @@ async def on_image(ctx: EventContext) -> None:
|
||||
buf.seek(0)
|
||||
buf = buf.read()
|
||||
# send
|
||||
await ctx.bot.send_image_bytes(
|
||||
await ctx.bot.send.image_bytes(
|
||||
ctx.room,
|
||||
buf,
|
||||
"blurred.png",
|
||||
@@ -75,7 +75,7 @@ async def on_image(ctx: EventContext) -> None:
|
||||
|
||||
async def on_wrong_message(data: EventContext) -> None:
|
||||
"""This callback is called when a wrong message is received."""
|
||||
await data.bot.send_text(
|
||||
await data.bot.send.text(
|
||||
data.room,
|
||||
"Text me something like <code>!gen 0.1 0.7 1.0</code> or send an image to blur"
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "mab"
|
||||
version = "0.5.2"
|
||||
version = "0.6.0"
|
||||
authors = [
|
||||
{ name = "Tyukalov Nikita", email = "nikita@tyukalov.su" }
|
||||
]
|
||||
|
||||
@@ -2,6 +2,7 @@ import asyncio
|
||||
import aiofiles
|
||||
import logging
|
||||
import os
|
||||
from typing import overload
|
||||
import threading
|
||||
from uuid import uuid4
|
||||
from pathlib import Path
|
||||
@@ -149,7 +150,19 @@ class ClientDownloader:
|
||||
cancel.set()
|
||||
raise
|
||||
|
||||
async def download_file(self,
|
||||
@overload
|
||||
async def file(self,
|
||||
source: EventContext | Event,
|
||||
*,
|
||||
path: str | Path) -> Path: ...
|
||||
|
||||
@overload
|
||||
async def file(self,
|
||||
source: EventContext | Event,
|
||||
*,
|
||||
path: None = None) -> bytes: ...
|
||||
|
||||
async def file(self,
|
||||
source: EventContext | Event,
|
||||
*,
|
||||
path: str | Path | None = None) -> Path | bytes:
|
||||
|
||||
@@ -98,9 +98,9 @@ class ClientSender:
|
||||
self._client = client
|
||||
self._uploader = uploader
|
||||
|
||||
async def send_content(self,
|
||||
room: MatrixRoom | str,
|
||||
content: dict) -> RoomSendResponse:
|
||||
async def content(self,
|
||||
room: MatrixRoom | str,
|
||||
content: dict) -> RoomSendResponse:
|
||||
"""
|
||||
Send raw `content` JSON to `room`.
|
||||
|
||||
@@ -124,7 +124,7 @@ class ClientSender:
|
||||
if self._config.auto_verify_all_known_devices:
|
||||
if not Utils.verify_all_known_devices(self._client):
|
||||
raise
|
||||
return await self.send_content(room, content)
|
||||
return await self.content(room, content)
|
||||
else:
|
||||
raise
|
||||
if type(result) is RoomSendResponse:
|
||||
@@ -134,11 +134,11 @@ class ClientSender:
|
||||
else:
|
||||
raise RuntimeError("Unknown error has occured", result)
|
||||
|
||||
async def send_text(self,
|
||||
room: MatrixRoom | str,
|
||||
text: str,
|
||||
*,
|
||||
is_html: bool | None = None) -> str:
|
||||
async def text(self,
|
||||
room: MatrixRoom | str,
|
||||
text: str,
|
||||
*,
|
||||
is_html: bool | None = None) -> str:
|
||||
"""
|
||||
Send text message to `room`.
|
||||
|
||||
@@ -156,15 +156,15 @@ class ClientSender:
|
||||
"msgtype": "m.text",
|
||||
**text_data
|
||||
}
|
||||
return (await self.send_content(room, content)).event_id
|
||||
return (await self.content(room, content)).event_id
|
||||
|
||||
async def send_image(self,
|
||||
room: MatrixRoom | str,
|
||||
path: Path | str, *,
|
||||
text: str | None = None,
|
||||
is_html: bool | None = None,
|
||||
filename: str | None = None,
|
||||
timeout: float | None = 60 * 60) -> str:
|
||||
async def image(self,
|
||||
room: MatrixRoom | str,
|
||||
path: Path | str, *,
|
||||
text: str | None = None,
|
||||
is_html: bool | None = None,
|
||||
filename: str | 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
|
||||
@@ -213,16 +213,16 @@ class ClientSender:
|
||||
"h": height
|
||||
}
|
||||
}
|
||||
return (await self.send_content(room, content)).event_id
|
||||
return (await self.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:
|
||||
async def 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
|
||||
@@ -276,16 +276,16 @@ class ClientSender:
|
||||
"h": height
|
||||
}
|
||||
}
|
||||
return (await self.send_content(room, content)).event_id
|
||||
return (await self.content(room, content)).event_id
|
||||
|
||||
async def send_video(self,
|
||||
room: MatrixRoom | str,
|
||||
path: Path | str,
|
||||
*,
|
||||
props: VideoFileProperties | None = None,
|
||||
text: str | None = None,
|
||||
is_html: bool | None = None,
|
||||
timeout: float | None = 60 * 60) -> str:
|
||||
async def video(self,
|
||||
room: MatrixRoom | str,
|
||||
path: Path | str,
|
||||
*,
|
||||
props: VideoFileProperties | None = None,
|
||||
text: str | None = None,
|
||||
is_html: bool | None = None,
|
||||
timeout: float | None = 60 * 60) -> str:
|
||||
"""
|
||||
Send the video to `room`. Please note that formatted text is displayed
|
||||
incorrectly in some clients as of September 8th, 2026. Unknown video
|
||||
@@ -361,17 +361,17 @@ class ClientSender:
|
||||
}
|
||||
}
|
||||
# send
|
||||
return (await self.send_content(room, content)).event_id
|
||||
return (await self.content(room, content)).event_id
|
||||
|
||||
async def send_file(self,
|
||||
room: MatrixRoom | str,
|
||||
path: Path | str,
|
||||
*,
|
||||
filename: str | None = None,
|
||||
mime_type: str | None = None,
|
||||
text: str | None = None,
|
||||
is_html: bool | None = None,
|
||||
timeout: float | None = 60 * 60):
|
||||
async def file(self,
|
||||
room: MatrixRoom | str,
|
||||
path: Path | str,
|
||||
*,
|
||||
filename: str | None = None,
|
||||
mime_type: str | None = None,
|
||||
text: str | None = None,
|
||||
is_html: bool | None = None,
|
||||
timeout: float | None = 60 * 60):
|
||||
"""
|
||||
Send the file to `room`. Please note that formatted text is displayed
|
||||
incorrectly in some clients as of September 8th, 2026.
|
||||
@@ -422,17 +422,17 @@ class ClientSender:
|
||||
"size": upload_result.filesize
|
||||
}
|
||||
}
|
||||
return (await self.send_content(room, content)).event_id
|
||||
return (await self.content(room, content)).event_id
|
||||
|
||||
async def send_file_bytes(self,
|
||||
room: MatrixRoom | str,
|
||||
data: bytes,
|
||||
filename: str,
|
||||
*,
|
||||
mime_type: str | None = None,
|
||||
text: str | None = None,
|
||||
is_html: bool | None = None,
|
||||
timeout: float | None = 60 * 60) -> str:
|
||||
async def file_bytes(self,
|
||||
room: MatrixRoom | str,
|
||||
data: bytes,
|
||||
filename: str,
|
||||
*,
|
||||
mime_type: str | None = None,
|
||||
text: str | None = None,
|
||||
is_html: bool | None = None,
|
||||
timeout: float | None = 60 * 60) -> str:
|
||||
"""
|
||||
Send the file to `room`.
|
||||
|
||||
@@ -480,4 +480,4 @@ class ClientSender:
|
||||
"size": upload_result.filesize
|
||||
}
|
||||
}
|
||||
return (await self.send_content(room, content)).event_id
|
||||
return (await self.content(room, content)).event_id
|
||||
@@ -119,7 +119,8 @@ class MatrixBot:
|
||||
finally:
|
||||
await self.stop()
|
||||
|
||||
def get_client(self) -> AsyncClient:
|
||||
@property
|
||||
def client(self) -> AsyncClient:
|
||||
"""
|
||||
Get AsyncClient.
|
||||
|
||||
@@ -129,231 +130,12 @@ class MatrixBot:
|
||||
"""
|
||||
return self._client_manager.get_client()
|
||||
|
||||
async def send_text(self,
|
||||
room: MatrixRoom | str,
|
||||
text: str,
|
||||
*,
|
||||
is_html: bool | None = None) -> str:
|
||||
"""
|
||||
Send text message to `room`.
|
||||
@property
|
||||
def send(self) -> ClientSender:
|
||||
"""Get ClientSender that you should use to send messages."""
|
||||
return self._client_sender
|
||||
|
||||
Args:
|
||||
- room - the room to send the text to
|
||||
- text - the text to send to the room
|
||||
- is_html - whether the text is HTML-formatted. Use `None` for auto
|
||||
|
||||
Returns:
|
||||
- `event_id` of sent message on success
|
||||
- Raises an exception on error
|
||||
"""
|
||||
return await self._client_sender.send_text(
|
||||
room=room,
|
||||
text=text,
|
||||
is_html=is_html
|
||||
)
|
||||
|
||||
async def send_image(self,
|
||||
room: MatrixRoom | str,
|
||||
path: Path | str, *,
|
||||
text: str | None = None,
|
||||
is_html: bool | None = None,
|
||||
filename: str | 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
|
||||
- path - path to the image file
|
||||
- text - image caption to use (`None` to disable)
|
||||
- is_html - whether the text is HTML-formatted (`None` for auto)
|
||||
- filename - filename to use for the file (`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(
|
||||
room=room,
|
||||
path=path,
|
||||
text=text,
|
||||
is_html=is_html,
|
||||
filename=filename,
|
||||
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,
|
||||
*,
|
||||
props: VideoFileProperties | None = None,
|
||||
text: str | None = None,
|
||||
is_html: bool | None = None,
|
||||
timeout: float | None = 60 * 60) -> str:
|
||||
"""
|
||||
Send the video to `room`. Please note that formatted text is displayed
|
||||
incorrectly in some clients as of September 8th, 2026. Unknown video
|
||||
properties will be automatically deduced as configured in
|
||||
`MatrixBotConfig`.
|
||||
|
||||
Args:
|
||||
- room - the room to send the text to
|
||||
- path - path to the video file
|
||||
- props - video properties (`None` for auto, if the feature is ON)
|
||||
- text - video 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_video(
|
||||
room=room,
|
||||
path=path,
|
||||
props=props,
|
||||
text=text,
|
||||
is_html=is_html,
|
||||
timeout=timeout
|
||||
)
|
||||
|
||||
async def send_file(self,
|
||||
room: MatrixRoom | str,
|
||||
path: Path | str,
|
||||
*,
|
||||
filename: str | None = None,
|
||||
mime_type: str | None = None,
|
||||
text: str | None = None,
|
||||
is_html: bool | None = None,
|
||||
timeout: float | None = 60 * 60):
|
||||
"""
|
||||
Send the file 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 file to
|
||||
- path - path to the file
|
||||
- filename - filename to use for upload (`None` to use basename from
|
||||
`path`)
|
||||
- mime_type - mime type to use (`None` for auto)
|
||||
- text - 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_file(
|
||||
room=room,
|
||||
path=path,
|
||||
filename=filename,
|
||||
mime_type=mime_type,
|
||||
text=text,
|
||||
is_html=is_html,
|
||||
timeout=timeout
|
||||
)
|
||||
|
||||
async def send_file_bytes(self,
|
||||
room: MatrixRoom | str,
|
||||
data: bytes,
|
||||
filename: str,
|
||||
*,
|
||||
mime_type: str | None = None,
|
||||
text: str | None = None,
|
||||
is_html: bool | None = None,
|
||||
timeout: float | None = 60 * 60) -> str:
|
||||
"""
|
||||
Send the file to `room`.
|
||||
|
||||
Args:
|
||||
- room - the room to send the file to
|
||||
- data - the content of the file to send
|
||||
- filename - filename to use for the file
|
||||
- text - 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_file_bytes(
|
||||
room=room,
|
||||
data=data,
|
||||
filename=filename,
|
||||
mime_type=mime_type,
|
||||
text=text,
|
||||
is_html=is_html,
|
||||
timeout=timeout
|
||||
)
|
||||
|
||||
@overload
|
||||
async def download_file(self,
|
||||
source: EventContext | Event,
|
||||
*,
|
||||
path: str | Path) -> Path: ...
|
||||
|
||||
@overload
|
||||
async def download_file(self,
|
||||
source: EventContext | Event,
|
||||
*,
|
||||
path: None = None) -> bytes: ...
|
||||
|
||||
async def download_file(self,
|
||||
source: EventContext | Event,
|
||||
*,
|
||||
path: str | Path | None = None) -> Path | bytes:
|
||||
"""
|
||||
Download the file from the event. Automatically dechiphers encrypted
|
||||
media.
|
||||
|
||||
Args:
|
||||
- source - event that has a file in its `content`
|
||||
- path - where to save the file to. Use `None` to store the file in
|
||||
memory. Use path to specify file download path.
|
||||
|
||||
Returns:
|
||||
- Returns `Path` to the file on success (if `path` isn't `None`)
|
||||
- Returns `bytes` of the file on success (if `path` is `None`)
|
||||
- Raises an exception on error
|
||||
"""
|
||||
return await self._client_downloader.download_file(
|
||||
source=source,
|
||||
path=path
|
||||
)
|
||||
@property
|
||||
def download(self) -> ClientDownloader:
|
||||
"""Get ClientDownloader that you should use to download files."""
|
||||
return self._client_downloader
|
||||
@@ -123,7 +123,7 @@ class SenderIsBotFilter(BaseEventFilter):
|
||||
async def __call__(self, context: EventContext) -> bool:
|
||||
if not await super().__call__(context):
|
||||
return False
|
||||
return context.bot.get_client().user_id == context.event.sender
|
||||
return context.bot.client.user_id == context.event.sender
|
||||
|
||||
class MessageHasFile(BaseEventFilter):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user