RubigramClient 1.7.17__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rubigram/__init__.py +15 -0
- rubigram/client.py +294 -0
- rubigram/enums/__init__.py +52 -0
- rubigram/enums/buttons/__init__.py +13 -0
- rubigram/enums/buttons/button_calendar_type.py +20 -0
- rubigram/enums/buttons/button_location_type.py +20 -0
- rubigram/enums/buttons/button_selection_get_type.py +20 -0
- rubigram/enums/buttons/button_selection_search_type.py +20 -0
- rubigram/enums/buttons/button_selection_type.py +22 -0
- rubigram/enums/buttons/button_textbox_type_keypad.py +20 -0
- rubigram/enums/buttons/button_textbox_type_line.py +20 -0
- rubigram/enums/buttons/button_type.py +58 -0
- rubigram/enums/chat_action_type.py +22 -0
- rubigram/enums/chat_keypad_type.py +20 -0
- rubigram/enums/chat_type.py +24 -0
- rubigram/enums/enum.py +6 -0
- rubigram/enums/file_type.py +28 -0
- rubigram/enums/forwarded_from_type.py +22 -0
- rubigram/enums/live_location_status.py +20 -0
- rubigram/enums/message_sender_type.py +20 -0
- rubigram/enums/metadata_type.py +18 -0
- rubigram/enums/parse_mode.py +20 -0
- rubigram/enums/payment_status_type.py +20 -0
- rubigram/enums/poll_status_type.py +20 -0
- rubigram/enums/update_endpoint_type.py +26 -0
- rubigram/enums/update_type.py +28 -0
- rubigram/errors.py +16 -0
- rubigram/filters.py +865 -0
- rubigram/http_session.py +96 -0
- rubigram/methods/__init__.py +26 -0
- rubigram/methods/chats/__init__.py +10 -0
- rubigram/methods/chats/get_chat.py +53 -0
- rubigram/methods/decorators/__init__.py +25 -0
- rubigram/methods/decorators/on_inline_message.py +70 -0
- rubigram/methods/decorators/on_message.py +62 -0
- rubigram/methods/decorators/on_remove_message.py +65 -0
- rubigram/methods/decorators/on_start.py +65 -0
- rubigram/methods/decorators/on_started_bot.py +70 -0
- rubigram/methods/decorators/on_stop.py +65 -0
- rubigram/methods/decorators/on_stopped_bot.py +70 -0
- rubigram/methods/decorators/on_update_message.py +70 -0
- rubigram/methods/files/__init__.py +32 -0
- rubigram/methods/files/download_file.py +118 -0
- rubigram/methods/files/get_file.py +41 -0
- rubigram/methods/files/get_file_name.py +41 -0
- rubigram/methods/files/request_send_file.py +49 -0
- rubigram/methods/files/send_file.py +133 -0
- rubigram/methods/files/send_gif.py +51 -0
- rubigram/methods/files/send_music.py +97 -0
- rubigram/methods/files/send_photo.py +95 -0
- rubigram/methods/files/send_video.py +96 -0
- rubigram/methods/files/send_voice.py +96 -0
- rubigram/methods/files/upload_file.py +114 -0
- rubigram/methods/messages/__init__.py +34 -0
- rubigram/methods/messages/delete_messages.py +84 -0
- rubigram/methods/messages/edit_chat_keypad.py +68 -0
- rubigram/methods/messages/edit_message.py +82 -0
- rubigram/methods/messages/edit_message_keypad.py +72 -0
- rubigram/methods/messages/edit_message_text.py +68 -0
- rubigram/methods/messages/forward_message.py +78 -0
- rubigram/methods/messages/remove_chat_keypad.py +46 -0
- rubigram/methods/messages/send_contact.py +114 -0
- rubigram/methods/messages/send_location.py +108 -0
- rubigram/methods/messages/send_message.py +115 -0
- rubigram/methods/messages/send_poll.py +104 -0
- rubigram/methods/messages/send_sticker.py +98 -0
- rubigram/methods/network/__init__.py +12 -0
- rubigram/methods/network/request.py +129 -0
- rubigram/methods/settings/__init__.py +16 -0
- rubigram/methods/settings/set_command.py +50 -0
- rubigram/methods/settings/setup_endpoints.py +48 -0
- rubigram/methods/settings/update_bot_endpoint.py +62 -0
- rubigram/methods/updates/__init__.py +14 -0
- rubigram/methods/updates/get_me.py +35 -0
- rubigram/methods/updates/get_update.py +62 -0
- rubigram/methods/utilities/__init__.py +14 -0
- rubigram/methods/utilities/dispatcher.py +66 -0
- rubigram/methods/utilities/run.py +118 -0
- rubigram/rubino/__init__.py +6 -0
- rubigram/rubino/client.py +374 -0
- rubigram/rubino/network.py +129 -0
- rubigram/server/__init__.py +6 -0
- rubigram/server/server.py +245 -0
- rubigram/state/__init__.py +7 -0
- rubigram/state/state.py +121 -0
- rubigram/state/storage.py +131 -0
- rubigram/types/__init__.py +66 -0
- rubigram/types/aux_data.py +28 -0
- rubigram/types/bot.py +51 -0
- rubigram/types/bot_command.py +26 -0
- rubigram/types/buttons/__init__.py +13 -0
- rubigram/types/buttons/button.py +59 -0
- rubigram/types/buttons/button_calendar.py +40 -0
- rubigram/types/buttons/button_location.py +40 -0
- rubigram/types/buttons/button_number_picker.py +34 -0
- rubigram/types/buttons/button_selection.py +48 -0
- rubigram/types/buttons/button_selection_item.py +32 -0
- rubigram/types/buttons/button_string_picker.py +29 -0
- rubigram/types/buttons/button_text_box.py +40 -0
- rubigram/types/chat.py +86 -0
- rubigram/types/config/__init__.py +6 -0
- rubigram/types/config/object.py +442 -0
- rubigram/types/contact_message.py +29 -0
- rubigram/types/file.py +78 -0
- rubigram/types/forwarded_from.py +39 -0
- rubigram/types/keypads/__init__.py +7 -0
- rubigram/types/keypads/keypad.py +31 -0
- rubigram/types/keypads/keypad_row.py +23 -0
- rubigram/types/live_location.py +44 -0
- rubigram/types/location.py +24 -0
- rubigram/types/messages/__init__.py +8 -0
- rubigram/types/messages/inline_message.py +78 -0
- rubigram/types/messages/message.py +117 -0
- rubigram/types/messages/update_message.py +341 -0
- rubigram/types/metadata/__init__.py +7 -0
- rubigram/types/metadata/metadata.py +43 -0
- rubigram/types/metadata/metadata_parts.py +42 -0
- rubigram/types/payment_status.py +30 -0
- rubigram/types/poll.py +32 -0
- rubigram/types/poll_status.py +40 -0
- rubigram/types/sticker.py +33 -0
- rubigram/types/updates/__init__.py +7 -0
- rubigram/types/updates/update.py +917 -0
- rubigram/types/updates/updates.py +56 -0
- rubigram/utils/__init__.py +14 -0
- rubigram/utils/auto_delete.py +93 -0
- rubigram/utils/parser.py +99 -0
- rubigramclient-1.7.17.dist-info/METADATA +215 -0
- rubigramclient-1.7.17.dist-info/RECORD +132 -0
- rubigramclient-1.7.17.dist-info/WHEEL +5 -0
- rubigramclient-1.7.17.dist-info/licenses/LICENSE +21 -0
- rubigramclient-1.7.17.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# RubigramClient - Rubika API library for python
|
|
2
|
+
# Copyright (C) 2025-present Javad <https://github.com/DevJavad>
|
|
3
|
+
# Github - https://github.com/DevJavad/rubigram
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from typing import Optional, Callable
|
|
7
|
+
from rubigram.filters import Filter
|
|
8
|
+
import rubigram
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class OnUpdateMessage:
|
|
12
|
+
def on_update_message(
|
|
13
|
+
self: "rubigram.Client",
|
|
14
|
+
filters: Optional["Filter"] = None
|
|
15
|
+
):
|
|
16
|
+
"""
|
|
17
|
+
**Decorator for handling edited messages.**
|
|
18
|
+
`@client.on_edit_message(filters.text)`
|
|
19
|
+
|
|
20
|
+
This decorator registers a function to handle message edit events
|
|
21
|
+
that match the specified filters. If no filters are provided,
|
|
22
|
+
all message edits will be handled.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
filters (`Optional[Filter]`):
|
|
26
|
+
Filter to determine which message edits should be handled.
|
|
27
|
+
If None, all message edits will be processed.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
Callable: The decorator function.
|
|
31
|
+
|
|
32
|
+
Example:
|
|
33
|
+
.. code-block:: python
|
|
34
|
+
|
|
35
|
+
# Handle text message edits
|
|
36
|
+
@client.on_edit_message(filters.text)
|
|
37
|
+
async def handle_text_edit(client, update):
|
|
38
|
+
old_text = update.updated_message.text
|
|
39
|
+
await client.send_message(
|
|
40
|
+
update.chat_id,
|
|
41
|
+
f"Message was edited to: {old_text}"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# Handle edits in specific chats only
|
|
45
|
+
@client.on_edit_message(filters.chat("g0123456789"))
|
|
46
|
+
async def handle_group_edits(client, update):
|
|
47
|
+
print(f"Message edited in group: {update.updated_message.text}")
|
|
48
|
+
|
|
49
|
+
# Handle all message edits (no filter)
|
|
50
|
+
@client.on_edit_message()
|
|
51
|
+
async def handle_all_edits(client, update):
|
|
52
|
+
print(f"Message {update.updated_message.message_id} was edited")
|
|
53
|
+
|
|
54
|
+
Note:
|
|
55
|
+
This handler only triggers for messages that have been edited,
|
|
56
|
+
not for new messages. The edited message is available in `update.updated_message`.
|
|
57
|
+
"""
|
|
58
|
+
def decorator(func: Callable) -> Callable:
|
|
59
|
+
async def wrapper(
|
|
60
|
+
client: "rubigram.Client",
|
|
61
|
+
update: "rubigram.types.Update"
|
|
62
|
+
):
|
|
63
|
+
if filters is None or await filters(client, update):
|
|
64
|
+
await func(client, update)
|
|
65
|
+
return True
|
|
66
|
+
return False
|
|
67
|
+
|
|
68
|
+
self.update_message_handlers.append(wrapper)
|
|
69
|
+
return func
|
|
70
|
+
return decorator
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# RubigramClient - Rubika API library for python
|
|
2
|
+
# Copyright (C) 2025-present Javad <https://github.com/DevJavad>
|
|
3
|
+
# Github - https://github.com/DevJavad/rubigram
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from .get_file import GetFile
|
|
7
|
+
from .upload_file import UploadFile
|
|
8
|
+
from .get_file_name import GetFileName
|
|
9
|
+
from .send_file import SendFile
|
|
10
|
+
from .send_gif import SendGif
|
|
11
|
+
from .send_music import SendMusic
|
|
12
|
+
from .send_photo import SendPhoto
|
|
13
|
+
from .send_video import SendVideo
|
|
14
|
+
from .send_voice import SendVoice
|
|
15
|
+
from .download_file import DownloadFile
|
|
16
|
+
from .request_send_file import RequestSendFile
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Files(
|
|
20
|
+
GetFile,
|
|
21
|
+
UploadFile,
|
|
22
|
+
GetFileName,
|
|
23
|
+
RequestSendFile,
|
|
24
|
+
SendFile,
|
|
25
|
+
SendGif,
|
|
26
|
+
SendMusic,
|
|
27
|
+
SendPhoto,
|
|
28
|
+
SendVideo,
|
|
29
|
+
SendVoice,
|
|
30
|
+
DownloadFile
|
|
31
|
+
):
|
|
32
|
+
pass
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# RubigramClient - Rubika API library for python
|
|
2
|
+
# Copyright (C) 2025-present Javad <https://github.com/DevJavad>
|
|
3
|
+
# Github - https://github.com/DevJavad/rubigram
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
import os
|
|
8
|
+
import asyncio
|
|
9
|
+
import rubigram
|
|
10
|
+
from io import BytesIO
|
|
11
|
+
from aiohttp import ClientError
|
|
12
|
+
from typing import Optional, Union
|
|
13
|
+
import aiofiles
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class DownloadFile:
|
|
17
|
+
"""
|
|
18
|
+
File download manager for Rubika API.
|
|
19
|
+
|
|
20
|
+
This class provides an asynchronous method to download files from
|
|
21
|
+
the Rubika server by file ID, supporting saving to disk or loading
|
|
22
|
+
directly into memory. It handles HTTP errors, timeouts, and
|
|
23
|
+
filesystem exceptions.
|
|
24
|
+
"""
|
|
25
|
+
__slots__ = ()
|
|
26
|
+
|
|
27
|
+
async def download_file(
|
|
28
|
+
self: "rubigram.Client",
|
|
29
|
+
file_id: str,
|
|
30
|
+
file_name: Optional[str] = None,
|
|
31
|
+
directory: Optional[str] = None,
|
|
32
|
+
chunk_size: int = 64 * 1024,
|
|
33
|
+
in_memory: bool = False,
|
|
34
|
+
) -> Union[str, BytesIO]:
|
|
35
|
+
"""
|
|
36
|
+
Download a file from Rubika by file ID.
|
|
37
|
+
|
|
38
|
+
Parameters:
|
|
39
|
+
file_id (str):
|
|
40
|
+
Unique identifier of the file to download.
|
|
41
|
+
file_name (Optional[str], default=None):
|
|
42
|
+
Custom name for the downloaded file. If not provided,
|
|
43
|
+
the name is inferred from the file URL.
|
|
44
|
+
directory (Optional[str], default=None):
|
|
45
|
+
Directory path to save the file. If None, saves to
|
|
46
|
+
the current working directory.
|
|
47
|
+
chunk_size (int, default=64*1024):
|
|
48
|
+
Size (in bytes) of each chunk to read during download.
|
|
49
|
+
in_memory (bool, default=False):
|
|
50
|
+
If True, the file will be loaded into a BytesIO buffer
|
|
51
|
+
instead of being written to disk.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
Union[str, BytesIO]:
|
|
55
|
+
Path to the saved file on disk, or a BytesIO buffer
|
|
56
|
+
if in_memory is True.
|
|
57
|
+
|
|
58
|
+
Raises:
|
|
59
|
+
ValueError:
|
|
60
|
+
If the file_id is invalid or the URL cannot be obtained.
|
|
61
|
+
RuntimeError:
|
|
62
|
+
If file name cannot be determined or a filesystem error occurs.
|
|
63
|
+
TimeoutError:
|
|
64
|
+
If the download times out.
|
|
65
|
+
ConnectionError:
|
|
66
|
+
If a network error occurs during download.
|
|
67
|
+
|
|
68
|
+
Example:
|
|
69
|
+
.. code-block:: python
|
|
70
|
+
# Save file to disk
|
|
71
|
+
path = await client.download_file(file_id="file_id", directory="downloads")
|
|
72
|
+
|
|
73
|
+
# Load file into memory
|
|
74
|
+
buffer = await client.download_file(file_id="file_id", in_memory=True)
|
|
75
|
+
"""
|
|
76
|
+
print(file_name)
|
|
77
|
+
url = await self.get_file(file_id)
|
|
78
|
+
if url is None:
|
|
79
|
+
raise ValueError(f"Invalid file_id: {file_id}")
|
|
80
|
+
|
|
81
|
+
name = file_name or await self.get_file_name(url)
|
|
82
|
+
if name is None:
|
|
83
|
+
raise RuntimeError("Could not determine file name")
|
|
84
|
+
|
|
85
|
+
if directory:
|
|
86
|
+
os.makedirs(directory, exist_ok=True)
|
|
87
|
+
path = os.path.join(directory, name)
|
|
88
|
+
else:
|
|
89
|
+
path = name
|
|
90
|
+
|
|
91
|
+
try:
|
|
92
|
+
async with self.http.session.get(url, allow_redirects=True) as response:
|
|
93
|
+
response.raise_for_status()
|
|
94
|
+
|
|
95
|
+
if in_memory:
|
|
96
|
+
buf = BytesIO()
|
|
97
|
+
buf.name = name
|
|
98
|
+
|
|
99
|
+
async for chunk in response.content.iter_chunked(chunk_size):
|
|
100
|
+
buf.write(chunk)
|
|
101
|
+
|
|
102
|
+
buf.seek(0)
|
|
103
|
+
return buf
|
|
104
|
+
|
|
105
|
+
async with aiofiles.open(path, "wb") as f:
|
|
106
|
+
async for chunk in response.content.iter_chunked(chunk_size):
|
|
107
|
+
await f.write(chunk)
|
|
108
|
+
|
|
109
|
+
return path
|
|
110
|
+
|
|
111
|
+
except asyncio.TimeoutError as error:
|
|
112
|
+
raise TimeoutError(str(error))
|
|
113
|
+
|
|
114
|
+
except ClientError as error:
|
|
115
|
+
raise ConnectionError(str(error))
|
|
116
|
+
|
|
117
|
+
except OSError as error:
|
|
118
|
+
raise RuntimeError(str(error))
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# RubigramClient - Rubika API library for python
|
|
2
|
+
# Copyright (C) 2025-present Javad <https://github.com/DevJavad>
|
|
3
|
+
# Github - https://github.com/DevJavad/rubigram
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from typing import Union
|
|
7
|
+
import rubigram
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class GetFile:
|
|
11
|
+
"""
|
|
12
|
+
File retrieval utility for Rubika API.
|
|
13
|
+
|
|
14
|
+
This class provides an asynchronous method to obtain the download
|
|
15
|
+
URL of a file stored on the Rubika server using its file ID. It
|
|
16
|
+
interacts with the Rubika API and returns a URL that can be used
|
|
17
|
+
to download the file.
|
|
18
|
+
"""
|
|
19
|
+
__slots__ = ()
|
|
20
|
+
|
|
21
|
+
async def get_file(
|
|
22
|
+
self: "rubigram.Client",
|
|
23
|
+
file_id: str
|
|
24
|
+
) -> Union[str, None]:
|
|
25
|
+
"""
|
|
26
|
+
Retrieve the download URL of a file by its ID.
|
|
27
|
+
|
|
28
|
+
Parameters:
|
|
29
|
+
file_id (str):
|
|
30
|
+
Unique identifier of the file on the Rubika server.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Union[str, None]:
|
|
34
|
+
The download URL of the file if found, otherwise None.
|
|
35
|
+
|
|
36
|
+
Example:
|
|
37
|
+
.. code-block:: python
|
|
38
|
+
url = await client.get_file(file_id="file_id")
|
|
39
|
+
"""
|
|
40
|
+
response = await self.request("getFile", {"file_id": file_id})
|
|
41
|
+
return response.get("download_url")
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# RubigramClient - Rubika API library for python
|
|
2
|
+
# Copyright (C) 2025-present Javad <https://github.com/DevJavad>
|
|
3
|
+
# Github - https://github.com/DevJavad/rubigram
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from urllib.parse import urlparse
|
|
7
|
+
import os
|
|
8
|
+
import rubigram
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class GetFileName:
|
|
12
|
+
"""
|
|
13
|
+
Utility to extract the file name from a URL.
|
|
14
|
+
|
|
15
|
+
This class provides a simple asynchronous method to parse a
|
|
16
|
+
given file URL and return its base name. It is intended to be
|
|
17
|
+
used internally by Rubigram for file management operations.
|
|
18
|
+
"""
|
|
19
|
+
__slots__ = ()
|
|
20
|
+
|
|
21
|
+
async def get_file_name(
|
|
22
|
+
self: "rubigram.Client",
|
|
23
|
+
url: str
|
|
24
|
+
) -> str:
|
|
25
|
+
"""
|
|
26
|
+
Extract the base name of a file from its URL.
|
|
27
|
+
|
|
28
|
+
Parameters:
|
|
29
|
+
url (str):
|
|
30
|
+
The full URL of the file.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
str: The base name of the file (e.g., "file.jpg").
|
|
34
|
+
|
|
35
|
+
Example:
|
|
36
|
+
.. code-block:: python
|
|
37
|
+
name = await client.get_file_name("https://example.com/path/to/file.png")
|
|
38
|
+
print(name) # Output: "file.png"
|
|
39
|
+
"""
|
|
40
|
+
parser = urlparse(url)
|
|
41
|
+
return os.path.basename(parser.path)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# RubigramClient - Rubika API library for python
|
|
2
|
+
# Copyright (C) 2025-present Javad <https://github.com/DevJavad>
|
|
3
|
+
# Github - https://github.com/DevJavad/rubigram
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from typing import Union
|
|
7
|
+
import rubigram
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class RequestSendFile:
|
|
11
|
+
"""
|
|
12
|
+
File upload URL request utility for Rubika API.
|
|
13
|
+
|
|
14
|
+
This class provides an asynchronous method to request a temporary
|
|
15
|
+
upload URL from the Rubika server. The URL can then be used to
|
|
16
|
+
upload files of a specified type.
|
|
17
|
+
"""
|
|
18
|
+
__slots__ = ()
|
|
19
|
+
|
|
20
|
+
async def request_send_file(
|
|
21
|
+
self: "rubigram.Client",
|
|
22
|
+
type: Union[str, "rubigram.enums.FileType"] = "File"
|
|
23
|
+
) -> str:
|
|
24
|
+
"""
|
|
25
|
+
Request a temporary file upload URL from the Rubika server.
|
|
26
|
+
|
|
27
|
+
Parameters:
|
|
28
|
+
type (Union[str, rubigram.enums.FileType], default="File"):
|
|
29
|
+
Type of the file to upload. Can be a string or a
|
|
30
|
+
FileType enum member.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
str: Temporary URL for uploading the file.
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
Example:
|
|
37
|
+
.. code-block:: python
|
|
38
|
+
# Using enum
|
|
39
|
+
from rubigram.enums import FileType
|
|
40
|
+
upload_url = await client.request_send_file(type=FileType.Image)
|
|
41
|
+
|
|
42
|
+
# Using string
|
|
43
|
+
upload_url = await client.request_send_file(type="File")
|
|
44
|
+
"""
|
|
45
|
+
type = type.value if isinstance(
|
|
46
|
+
type, rubigram.enums.FileType
|
|
47
|
+
) else type
|
|
48
|
+
response = await self.request("requestSendFile", {"type": type})
|
|
49
|
+
return response["upload_url"]
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# RubigramClient - Rubika API library for python
|
|
2
|
+
# Copyright (C) 2025-present Javad <https://github.com/DevJavad>
|
|
3
|
+
# Github - https://github.com/DevJavad/rubigram
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from typing import Optional, Union, BinaryIO
|
|
9
|
+
from rubigram.utils import AutoDelete, Parser
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
import rubigram
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SendFile:
|
|
15
|
+
"""
|
|
16
|
+
File sender for Rubika API.
|
|
17
|
+
|
|
18
|
+
This class provides an asynchronous method to send files to a
|
|
19
|
+
chat. Supports sending local files, remote URLs, bytes, file-like
|
|
20
|
+
objects, or existing File IDs. Handles uploading, metadata parsing,
|
|
21
|
+
keypads, notifications, replies, and optional auto-deletion.
|
|
22
|
+
"""
|
|
23
|
+
__slots__ = ()
|
|
24
|
+
|
|
25
|
+
async def send_file(
|
|
26
|
+
self: rubigram.Client,
|
|
27
|
+
chat_id: str,
|
|
28
|
+
file: Union[str, bytes, BinaryIO],
|
|
29
|
+
caption: Optional[str] = None,
|
|
30
|
+
filename: Optional[str] = None,
|
|
31
|
+
type: Union[str, rubigram.enums.FileType] = rubigram.enums.FileType.FILE,
|
|
32
|
+
chat_keypad: Optional[rubigram.types.Keypad] = None,
|
|
33
|
+
inline_keypad: Optional[rubigram.types.Keypad] = None,
|
|
34
|
+
chat_keypad_type: Optional[rubigram.enums.ChatKeypadType] = None,
|
|
35
|
+
disable_notification: bool = False,
|
|
36
|
+
reply_to_message_id: Optional[str] = None,
|
|
37
|
+
parse_mode: Optional[Union[str, rubigram.enums.ParseMode]] = None,
|
|
38
|
+
auto_delete: Optional[int] = None
|
|
39
|
+
) -> rubigram.types.UMessage:
|
|
40
|
+
"""
|
|
41
|
+
Send a file to a chat on Rubika.
|
|
42
|
+
|
|
43
|
+
Parameters:
|
|
44
|
+
chat_id (str):
|
|
45
|
+
Unique identifier of the chat to send the file to.
|
|
46
|
+
file (Union[str, bytes, BinaryIO]):
|
|
47
|
+
File path, URL, bytes, file-like object, or existing File ID.
|
|
48
|
+
caption (Optional[str], default=None):
|
|
49
|
+
Caption or text to send with the file.
|
|
50
|
+
filename (Optional[str], default=None):
|
|
51
|
+
Custom file name for uploads. Inferred if not provided.
|
|
52
|
+
type (Union[str, rubigram.enums.FileType], default="File"):
|
|
53
|
+
Type of the file to send (e.g., File, Image, Video).
|
|
54
|
+
chat_keypad (Optional[rubigram.types.Keypad], default=None):
|
|
55
|
+
Custom chat keypad to attach to the message.
|
|
56
|
+
inline_keypad (Optional[rubigram.types.Keypad], default=None):
|
|
57
|
+
Inline keypad to attach to the message.
|
|
58
|
+
chat_keypad_type (Optional[rubigram.enums.ChatKeypadType], default=None):
|
|
59
|
+
Type of chat keypad (e.g., persistent, one-time).
|
|
60
|
+
disable_notification (bool, default=False):
|
|
61
|
+
If True, sends the message silently.
|
|
62
|
+
reply_to_message_id (Optional[str], default=None):
|
|
63
|
+
Message ID to reply to.
|
|
64
|
+
auto_delete (Optional[int], default=None):
|
|
65
|
+
Time in seconds after which the message will be deleted automatically.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
rubigram.types.UMessage:
|
|
69
|
+
The sent message object.
|
|
70
|
+
|
|
71
|
+
Example:
|
|
72
|
+
.. code-block:: python
|
|
73
|
+
# Send a local file
|
|
74
|
+
message = await client.send_file(chat_id="chat_id", file="example.jpg")
|
|
75
|
+
|
|
76
|
+
# Send a file from URL
|
|
77
|
+
message = await client.send_file(chat_id="chat_id", file="https://example.com/file.png")
|
|
78
|
+
|
|
79
|
+
# Send an existing file by File ID
|
|
80
|
+
message = await client.send_file(chat_id="chat_id", file="file_id")
|
|
81
|
+
|
|
82
|
+
# Send bytes
|
|
83
|
+
message = await client.send_file(chat_id="chat_id", file=b"binary data")
|
|
84
|
+
"""
|
|
85
|
+
type = type if isinstance(type, str) else type.value
|
|
86
|
+
upload_url = await self.request_send_file(type)
|
|
87
|
+
|
|
88
|
+
if isinstance(file, str):
|
|
89
|
+
if file.startswith(("http://", "https://")) or Path(file).exists():
|
|
90
|
+
file_id = await self.upload_file(upload_url, file, filename)
|
|
91
|
+
else:
|
|
92
|
+
download_url = await self.get_file(file)
|
|
93
|
+
if not download_url:
|
|
94
|
+
raise ValueError(f"Invalid file_id: {file}")
|
|
95
|
+
file_id = await self.upload_file(upload_url, download_url, filename)
|
|
96
|
+
else:
|
|
97
|
+
file_id = await self.upload_file(upload_url, file, filename)
|
|
98
|
+
|
|
99
|
+
if not file_id:
|
|
100
|
+
raise RuntimeError("Upload succeeded but file_id is missing")
|
|
101
|
+
|
|
102
|
+
data = {"chat_id": chat_id, "file_id": file_id, "text": caption}
|
|
103
|
+
if caption:
|
|
104
|
+
parse = Parser.parser(caption, parse_mode or self.parse_mode)
|
|
105
|
+
|
|
106
|
+
if "metadata" in parse:
|
|
107
|
+
data["text"] = parse["text"]
|
|
108
|
+
data["metadata"] = parse["metadata"]
|
|
109
|
+
|
|
110
|
+
if chat_keypad:
|
|
111
|
+
data["chat_keypad"] = chat_keypad.as_dict()
|
|
112
|
+
|
|
113
|
+
if inline_keypad:
|
|
114
|
+
data["inline_keypad"] = inline_keypad.as_dict()
|
|
115
|
+
|
|
116
|
+
if chat_keypad_type:
|
|
117
|
+
data["chat_keypad_type"] = chat_keypad_type
|
|
118
|
+
|
|
119
|
+
if disable_notification:
|
|
120
|
+
data["disable_notification"] = disable_notification
|
|
121
|
+
|
|
122
|
+
if reply_to_message_id:
|
|
123
|
+
data["reply_to_message_id"] = reply_to_message_id
|
|
124
|
+
|
|
125
|
+
response = await self.request("sendFile", data)
|
|
126
|
+
message = rubigram.types.UMessage.parse(response, self)
|
|
127
|
+
message.chat_id = chat_id
|
|
128
|
+
message.file_id = file_id
|
|
129
|
+
|
|
130
|
+
if auto_delete and auto_delete > 0:
|
|
131
|
+
AutoDelete.run(self, message, auto_delete)
|
|
132
|
+
|
|
133
|
+
return message
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# RubigramClient - Rubika API library for python
|
|
2
|
+
# Copyright (C) 2025-present Javad <https://github.com/DevJavad>
|
|
3
|
+
# Github - https://github.com/DevJavad/rubigram
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from typing import Optional, Union, BinaryIO
|
|
9
|
+
import rubigram
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SendGif:
|
|
13
|
+
"""
|
|
14
|
+
Gif sender for Rubika API.
|
|
15
|
+
|
|
16
|
+
This class provides an asynchronous method to send Gif
|
|
17
|
+
files to a chat. It is a specialized wrapper around `send_gif`
|
|
18
|
+
that automatically sets the file type to Gif and supports
|
|
19
|
+
captions, keypads, notifications, replies, and auto-deletion.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
__slots__ = ()
|
|
23
|
+
|
|
24
|
+
async def send_gif(
|
|
25
|
+
self: rubigram.Client,
|
|
26
|
+
chat_id: str,
|
|
27
|
+
gif: Union[str, bytes, BinaryIO],
|
|
28
|
+
caption: Optional[str] = None,
|
|
29
|
+
filename: Optional[str] = None,
|
|
30
|
+
chat_keypad: Optional[rubigram.types.Keypad] = None,
|
|
31
|
+
inline_keypad: Optional[rubigram.types.Keypad] = None,
|
|
32
|
+
chat_keypad_type: Optional[rubigram.enums.ChatKeypadType] = None,
|
|
33
|
+
disable_notification: bool = False,
|
|
34
|
+
reply_to_message_id: Optional[str] = None,
|
|
35
|
+
parse_mode: Optional[Union[str, rubigram.enums.ParseMode]] = None,
|
|
36
|
+
auto_delete: Optional[int] = None
|
|
37
|
+
) -> rubigram.types.UMessage:
|
|
38
|
+
return await self.send_file(
|
|
39
|
+
chat_id,
|
|
40
|
+
gif,
|
|
41
|
+
caption,
|
|
42
|
+
filename,
|
|
43
|
+
rubigram.enums.FileType.GIF,
|
|
44
|
+
chat_keypad,
|
|
45
|
+
inline_keypad,
|
|
46
|
+
chat_keypad_type,
|
|
47
|
+
disable_notification,
|
|
48
|
+
reply_to_message_id,
|
|
49
|
+
parse_mode,
|
|
50
|
+
auto_delete
|
|
51
|
+
)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# RubigramClient - Rubika API library for python
|
|
2
|
+
# Copyright (C) 2025-present Javad <https://github.com/DevJavad>
|
|
3
|
+
# Github - https://github.com/DevJavad/rubigram
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from typing import Optional, Union, BinaryIO
|
|
9
|
+
import rubigram
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SendMusic:
|
|
13
|
+
"""
|
|
14
|
+
Music sender for Rubika API.
|
|
15
|
+
|
|
16
|
+
This class provides an asynchronous method to send music/audio
|
|
17
|
+
files to a chat. It is a specialized wrapper around `send_file`
|
|
18
|
+
that automatically sets the file type to Music and supports
|
|
19
|
+
captions, keypads, notifications, replies, and auto-deletion.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
__slots__ = ()
|
|
23
|
+
|
|
24
|
+
async def send_music(
|
|
25
|
+
self: rubigram.Client,
|
|
26
|
+
chat_id: str,
|
|
27
|
+
music: Union[str, bytes, BinaryIO],
|
|
28
|
+
caption: Optional[str] = None,
|
|
29
|
+
filename: Optional[str] = None,
|
|
30
|
+
chat_keypad: Optional[rubigram.types.Keypad] = None,
|
|
31
|
+
inline_keypad: Optional[rubigram.types.Keypad] = None,
|
|
32
|
+
chat_keypad_type: Optional[rubigram.enums.ChatKeypadType] = None,
|
|
33
|
+
disable_notification: bool = False,
|
|
34
|
+
reply_to_message_id: Optional[str] = None,
|
|
35
|
+
parse_mode: Optional[Union[str, rubigram.enums.ParseMode]] = None,
|
|
36
|
+
auto_delete: Optional[int] = None
|
|
37
|
+
) -> rubigram.types.UMessage:
|
|
38
|
+
"""
|
|
39
|
+
Send a music/audio file to a chat on Rubika.
|
|
40
|
+
|
|
41
|
+
Parameters:
|
|
42
|
+
chat_id (str):
|
|
43
|
+
Unique identifier of the target chat.
|
|
44
|
+
music (Union[str, bytes, BinaryIO]):
|
|
45
|
+
Music source. Can be a local file path, URL, bytes,
|
|
46
|
+
file-like object, or an existing File ID.
|
|
47
|
+
caption (Optional[str], default=None):
|
|
48
|
+
Caption or description for the music.
|
|
49
|
+
filename (Optional[str], default=None):
|
|
50
|
+
Custom filename for the uploaded music.
|
|
51
|
+
chat_keypad (Optional[rubigram.types.Keypad], default=None):
|
|
52
|
+
Custom chat keypad to attach to the message.
|
|
53
|
+
inline_keypad (Optional[rubigram.types.Keypad], default=None):
|
|
54
|
+
Inline keypad to attach to the message.
|
|
55
|
+
chat_keypad_type (Optional[rubigram.enums.ChatKeypadType], default=None):
|
|
56
|
+
Type of chat keypad.
|
|
57
|
+
disable_notification (bool, default=False):
|
|
58
|
+
If True, sends the message silently.
|
|
59
|
+
reply_to_message_id (Optional[str], default=None):
|
|
60
|
+
Message ID to reply to.
|
|
61
|
+
auto_delete (Optional[int], default=None):
|
|
62
|
+
Time in seconds after which the message will be
|
|
63
|
+
automatically deleted.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
rubigram.types.UMessage:
|
|
67
|
+
The sent music message object.
|
|
68
|
+
|
|
69
|
+
Example:
|
|
70
|
+
.. code-block:: python
|
|
71
|
+
# Send a local file
|
|
72
|
+
message = await client.send_music(chat_id="chat_id", music="example.mp3")
|
|
73
|
+
|
|
74
|
+
# Send a file from URL
|
|
75
|
+
message = await client.send_music(chat_id="chat_id", music="https://example.com/file.mp3")
|
|
76
|
+
|
|
77
|
+
# Send an existing file by File ID
|
|
78
|
+
message = await client.send_music(chat_id="chat_id", music="file_id")
|
|
79
|
+
|
|
80
|
+
# Send bytes
|
|
81
|
+
message = await client.send_music(chat_id="chat_id", music=b"binary data")
|
|
82
|
+
)
|
|
83
|
+
"""
|
|
84
|
+
return await self.send_file(
|
|
85
|
+
chat_id,
|
|
86
|
+
music,
|
|
87
|
+
caption,
|
|
88
|
+
filename,
|
|
89
|
+
rubigram.enums.FileType.MUSIC,
|
|
90
|
+
chat_keypad,
|
|
91
|
+
inline_keypad,
|
|
92
|
+
chat_keypad_type,
|
|
93
|
+
disable_notification,
|
|
94
|
+
reply_to_message_id,
|
|
95
|
+
parse_mode,
|
|
96
|
+
auto_delete
|
|
97
|
+
)
|