Rubka 6.6.11__py3-none-any.whl → 6.6.13__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.
Potentially problematic release.
This version of Rubka might be problematic. Click here for more details.
- rubka/asynco.py +112 -5
- rubka/context.py +63 -2
- rubka/update.py +63 -2
- {rubka-6.6.11.dist-info → rubka-6.6.13.dist-info}/METADATA +1 -1
- {rubka-6.6.11.dist-info → rubka-6.6.13.dist-info}/RECORD +8 -8
- {rubka-6.6.11.dist-info → rubka-6.6.13.dist-info}/WHEEL +0 -0
- {rubka-6.6.11.dist-info → rubka-6.6.13.dist-info}/entry_points.txt +0 -0
- {rubka-6.6.11.dist-info → rubka-6.6.13.dist-info}/top_level.txt +0 -0
rubka/asynco.py
CHANGED
|
@@ -143,6 +143,7 @@ class Robot:
|
|
|
143
143
|
self._inline_query_handler = None
|
|
144
144
|
|
|
145
145
|
self._callback_handlers: List[dict] = []
|
|
146
|
+
self._edited_message_handlers = []
|
|
146
147
|
self._processed_message_ids: Dict[str, float] = {}
|
|
147
148
|
self._message_handlers: List[dict] = []
|
|
148
149
|
|
|
@@ -223,7 +224,7 @@ class Robot:
|
|
|
223
224
|
allow_polls: bool = True,
|
|
224
225
|
allow_contacts: bool = True,
|
|
225
226
|
allow_locations: bool = True,
|
|
226
|
-
min_text_length: Optional[int] = None,
|
|
227
|
+
min_text_length: Optional[int] = None,
|
|
227
228
|
max_text_length: Optional[int] = None,
|
|
228
229
|
contains: Optional[str] = None,
|
|
229
230
|
startswith: Optional[str] = None,
|
|
@@ -410,6 +411,7 @@ class Robot:
|
|
|
410
411
|
|
|
411
412
|
def decorator(func: Callable[[Any, Message], None]):
|
|
412
413
|
async def wrapper(bot, message: Message):
|
|
414
|
+
|
|
413
415
|
if not message.is_group:
|
|
414
416
|
return
|
|
415
417
|
if chat_id:
|
|
@@ -470,7 +472,37 @@ class Robot:
|
|
|
470
472
|
})
|
|
471
473
|
return wrapper
|
|
472
474
|
return decorator
|
|
475
|
+
def remove_handler(self, func: Callable):
|
|
476
|
+
"""
|
|
477
|
+
Remove a message handler by its original function reference.
|
|
478
|
+
"""
|
|
479
|
+
self._message_handlers = [
|
|
480
|
+
h for h in self._message_handlers if h["func"].__wrapped__ != func
|
|
481
|
+
]
|
|
482
|
+
def on_edited_message(
|
|
483
|
+
self,
|
|
484
|
+
filters: Optional[Callable[[Message], bool]] = None,
|
|
485
|
+
commands: Optional[List[str]] = None
|
|
486
|
+
):
|
|
487
|
+
def decorator(func: Callable[[Any, Message], None]):
|
|
488
|
+
async def wrapper(bot, message: Message):
|
|
489
|
+
if filters and not filters(message):
|
|
490
|
+
return
|
|
491
|
+
if commands:
|
|
492
|
+
if not message.is_command:
|
|
493
|
+
return
|
|
494
|
+
cmd = message.text.split()[0].lstrip("/")
|
|
495
|
+
if cmd not in commands:
|
|
496
|
+
return
|
|
497
|
+
return await func(bot, message)
|
|
473
498
|
|
|
499
|
+
self._edited_message_handlers.append({
|
|
500
|
+
"func": wrapper,
|
|
501
|
+
"filters": filters,
|
|
502
|
+
"commands": commands
|
|
503
|
+
})
|
|
504
|
+
return wrapper
|
|
505
|
+
return decorator
|
|
474
506
|
def on_message(
|
|
475
507
|
self,
|
|
476
508
|
filters: Optional[Callable[[Message], bool]] = None,
|
|
@@ -762,7 +794,34 @@ class Robot:
|
|
|
762
794
|
if handler_info["commands"] or handler_info["filters"]:
|
|
763
795
|
asyncio.create_task(handler_info["func"](self, context))#jaq
|
|
764
796
|
continue
|
|
797
|
+
elif update.get("type") == "UpdatedMessage":
|
|
798
|
+
msg = update.get("updated_message", {})
|
|
799
|
+
if not msg:
|
|
800
|
+
return
|
|
765
801
|
|
|
802
|
+
context = Message(
|
|
803
|
+
bot=self,
|
|
804
|
+
chat_id=update.get("chat_id"),
|
|
805
|
+
message_id=msg.get("message_id"),
|
|
806
|
+
text=msg.get("text"),
|
|
807
|
+
sender_id=msg.get("sender_id"),
|
|
808
|
+
raw_data=msg
|
|
809
|
+
)
|
|
810
|
+
if self._edited_message_handlers:
|
|
811
|
+
for handler_info in self._edited_message_handlers:
|
|
812
|
+
if handler_info["commands"]:
|
|
813
|
+
if not context.text or not context.text.startswith("/"):
|
|
814
|
+
continue
|
|
815
|
+
parts = context.text.split()
|
|
816
|
+
cmd = parts[0][1:]
|
|
817
|
+
if cmd not in handler_info["commands"]:
|
|
818
|
+
continue
|
|
819
|
+
context.args = parts[1:]
|
|
820
|
+
if handler_info["filters"]:
|
|
821
|
+
if not handler_info["filters"](context):
|
|
822
|
+
continue
|
|
823
|
+
asyncio.create_task(handler_info["func"](self, context))
|
|
824
|
+
|
|
766
825
|
async def get_updates(self, offset_id: Optional[str] = None, limit: Optional[int] = None) -> Dict[str, Any]:
|
|
767
826
|
data = {}
|
|
768
827
|
if offset_id: data["offset_id"] = offset_id
|
|
@@ -834,7 +893,7 @@ class Robot:
|
|
|
834
893
|
notify_on_error: bool = False,
|
|
835
894
|
notification_handler: Optional[Callable[[str], Any]] = None,
|
|
836
895
|
watchdog_timeout: Optional[float] = None,
|
|
837
|
-
|
|
896
|
+
):
|
|
838
897
|
"""
|
|
839
898
|
Starts the bot's main execution loop with extensive configuration options.
|
|
840
899
|
|
|
@@ -977,12 +1036,16 @@ class Robot:
|
|
|
977
1036
|
im = update.get("inline_message", {})
|
|
978
1037
|
sender = im.get("author_object_guid") or im.get("author_guid")
|
|
979
1038
|
chat = im.get("object_guid") or im.get("chat_id")
|
|
1039
|
+
elif t == "UpdatedMessage":
|
|
1040
|
+
im = update.get("updated_message", {})
|
|
1041
|
+
sender = im.get("author_object_guid") or im.get("author_guid")
|
|
1042
|
+
chat = im.get("object_guid") or im.get("chat_id")
|
|
980
1043
|
else:
|
|
981
1044
|
sender = update.get("author_guid") or update.get("from_id")
|
|
982
1045
|
chat = update.get("object_guid") or update.get("chat_id")
|
|
983
1046
|
return str(sender) if sender is not None else None, str(chat) if chat is not None else None
|
|
984
1047
|
|
|
985
|
-
def _is_group_chat(chat_guid: str
|
|
1048
|
+
def _is_group_chat(chat_guid: Optional[str]) -> Optional[bool]:
|
|
986
1049
|
|
|
987
1050
|
if chat_guid is None:
|
|
988
1051
|
return None
|
|
@@ -1050,8 +1113,6 @@ class Robot:
|
|
|
1050
1113
|
return False
|
|
1051
1114
|
if skip_service_messages and t == "ServiceMessage":
|
|
1052
1115
|
return False
|
|
1053
|
-
if skip_edited_messages and t == "EditMessage":
|
|
1054
|
-
return False
|
|
1055
1116
|
if skip_channel_posts and t == "ChannelPost":
|
|
1056
1117
|
return False
|
|
1057
1118
|
|
|
@@ -1081,6 +1142,8 @@ class Robot:
|
|
|
1081
1142
|
content = (update.get("new_message") or {}).get("text")
|
|
1082
1143
|
elif t == "ReceiveQuery":
|
|
1083
1144
|
content = (update.get("inline_message") or {}).get("text")
|
|
1145
|
+
elif t == "UpdatedMessage":
|
|
1146
|
+
content = (update.get("updated_message") or {}).get("text")
|
|
1084
1147
|
elif "text" in update:
|
|
1085
1148
|
content = update.get("text")
|
|
1086
1149
|
if content and isinstance(content, str) and len(content) > max_message_size:
|
|
@@ -1197,6 +1260,8 @@ class Robot:
|
|
|
1197
1260
|
message_id = update.get("new_message", {}).get("message_id")
|
|
1198
1261
|
elif update.get("type") == "ReceiveQuery":
|
|
1199
1262
|
message_id = update.get("inline_message", {}).get("message_id")
|
|
1263
|
+
elif update.get("type") == "UpdatedMessage":
|
|
1264
|
+
message_id = update.get("updated_message", {}).get("message_id")
|
|
1200
1265
|
elif "message_id" in update:
|
|
1201
1266
|
message_id = update.get("message_id")
|
|
1202
1267
|
|
|
@@ -1220,6 +1285,8 @@ class Robot:
|
|
|
1220
1285
|
message_id = update.get("new_message", {}).get("message_id")
|
|
1221
1286
|
elif update.get("type") == "ReceiveQuery":
|
|
1222
1287
|
message_id = update.get("inline_message", {}).get("message_id")
|
|
1288
|
+
elif update.get("type") == "UpdatedMessage":
|
|
1289
|
+
message_id = update.get("updated_message", {}).get("message_id")
|
|
1223
1290
|
elif "message_id" in update:
|
|
1224
1291
|
message_id = update.get("message_id")
|
|
1225
1292
|
|
|
@@ -1377,6 +1444,46 @@ class Robot:
|
|
|
1377
1444
|
if reply_to_message_id:
|
|
1378
1445
|
payload["reply_to_message_id"] = reply_to_message_id
|
|
1379
1446
|
return await self._post("sendMessage", payload)
|
|
1447
|
+
|
|
1448
|
+
from typing import Optional, Dict, Any, Literal
|
|
1449
|
+
|
|
1450
|
+
async def send_sticker(
|
|
1451
|
+
self,
|
|
1452
|
+
chat_id: str,
|
|
1453
|
+
sticker_id: str,
|
|
1454
|
+
chat_keypad: Optional[Dict[str, Any]] = None,
|
|
1455
|
+
disable_notification: bool = False,
|
|
1456
|
+
inline_keypad: Optional[Dict[str, Any]] = None,
|
|
1457
|
+
reply_to_message_id: Optional[str] = None,
|
|
1458
|
+
chat_keypad_type: Optional[Literal['New', 'Remove']] = None,
|
|
1459
|
+
) -> str:
|
|
1460
|
+
"""
|
|
1461
|
+
Send a sticker to a chat.
|
|
1462
|
+
|
|
1463
|
+
Args:
|
|
1464
|
+
token: Bot token.
|
|
1465
|
+
chat_id: Target chat ID.
|
|
1466
|
+
sticker_id: ID of the sticker to send.
|
|
1467
|
+
chat_keypad: Optional chat keypad data.
|
|
1468
|
+
disable_notification: If True, disables notification.
|
|
1469
|
+
inline_keypad: Optional inline keyboard data.
|
|
1470
|
+
reply_to_message_id: Optional message ID to reply to.
|
|
1471
|
+
chat_keypad_type: Type of chat keypad change ('New' or 'Remove').
|
|
1472
|
+
|
|
1473
|
+
Returns:
|
|
1474
|
+
API response as a string.
|
|
1475
|
+
"""
|
|
1476
|
+
data = {
|
|
1477
|
+
'chat_id': chat_id,
|
|
1478
|
+
'sticker_id': sticker_id,
|
|
1479
|
+
'chat_keypad': chat_keypad,
|
|
1480
|
+
'disable_notification': disable_notification,
|
|
1481
|
+
'inline_keypad': inline_keypad,
|
|
1482
|
+
'reply_to_message_id': reply_to_message_id,
|
|
1483
|
+
'chat_keypad_type': chat_keypad_type,
|
|
1484
|
+
}
|
|
1485
|
+
return await self._post("sendSticker", data)
|
|
1486
|
+
|
|
1380
1487
|
|
|
1381
1488
|
async def get_url_file(self,file_id):
|
|
1382
1489
|
data = await self._post("getFile", {'file_id': file_id})
|
rubka/context.py
CHANGED
|
@@ -186,7 +186,7 @@ class Bot:
|
|
|
186
186
|
self.share_url: str = data.get("share_url")
|
|
187
187
|
from typing import Union
|
|
188
188
|
from pathlib import Path
|
|
189
|
-
|
|
189
|
+
import re
|
|
190
190
|
class Message:
|
|
191
191
|
def __init__(self, bot, chat_id, message_id, sender_id, text=None, raw_data=None):
|
|
192
192
|
self.bot = bot
|
|
@@ -196,6 +196,10 @@ class Message:
|
|
|
196
196
|
self.author_guid = self.raw_data.get("sender_id", sender_id)
|
|
197
197
|
self.message_id: str = self.raw_data.get("message_id", message_id)
|
|
198
198
|
self.text: str = self.raw_data.get("text", text)
|
|
199
|
+
self.has_link = bool(re.search(
|
|
200
|
+
r"(https?://[^\s]+|www\.[^\s]+|[a-zA-Z0-9.-]+\.(com|net|org|ir|edu|gov|info|biz|io|me|co)|t\.me/[^\s]+|telegram\.me/[^\s]+|@\w+|\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)",
|
|
201
|
+
self.raw_data.get("text", text) or ""
|
|
202
|
+
))
|
|
199
203
|
self.sender_id: str = self.raw_data.get("sender_id", sender_id)
|
|
200
204
|
self.time: str = self.raw_data.get("time")
|
|
201
205
|
self.is_edited: bool = self.raw_data.get("is_edited", False)
|
|
@@ -226,6 +230,16 @@ class Message:
|
|
|
226
230
|
self.is_contact = self.contact_message is not None
|
|
227
231
|
self.has_any_media = any([self.file, self.sticker, self.poll, self.location, self.live_location])
|
|
228
232
|
self.edited_text = self.raw_data.get("edited_text") if self.is_edited else None
|
|
233
|
+
if self.file and self.file.file_name:
|
|
234
|
+
name = self.file.file_name.lower()
|
|
235
|
+
self.is_photo = name.endswith((".jpg", ".jpeg", ".png", ".gif", ".webp"))
|
|
236
|
+
self.is_video = name.endswith((".mp4", ".mov", ".avi", ".mkv", ".webm"))
|
|
237
|
+
self.is_audio = name.endswith((".mp3", ".wav", ".ogg", ".m4a", ".flac"))
|
|
238
|
+
self.is_voice = name.endswith((".ogg", ".m4a"))
|
|
239
|
+
self.is_document = name.endswith((".pdf", ".doc", ".docx", ".txt", ".xls", ".xlsx", ".ppt", ".pptx"))
|
|
240
|
+
self.is_archive = name.endswith((".zip", ".rar", ".7z", ".tar", ".gz"))
|
|
241
|
+
self.is_executable = name.endswith((".exe", ".msi", ".bat", ".sh"))
|
|
242
|
+
self.is_font = name.endswith((".ttf", ".otf", ".woff", ".woff2"))
|
|
229
243
|
self.info = {attr: value for attr, value in vars(self).items()}
|
|
230
244
|
@property
|
|
231
245
|
def session(self):
|
|
@@ -467,12 +481,59 @@ class InlineMessage:
|
|
|
467
481
|
def __init__(self, bot, raw_data: dict):
|
|
468
482
|
self.bot = bot
|
|
469
483
|
self.raw_data = raw_data
|
|
470
|
-
|
|
484
|
+
chat_id : str = raw_data.get("chat_id")
|
|
485
|
+
sender_id : str = raw_data.get("sender_id")
|
|
471
486
|
self.chat_id: str = raw_data.get("chat_id")
|
|
472
487
|
self.message_id: str = raw_data.get("message_id")
|
|
473
488
|
self.sender_id: str = raw_data.get("sender_id")
|
|
474
489
|
self.text: str = raw_data.get("text")
|
|
475
490
|
self.aux_data = AuxData(raw_data.get("aux_data", {})) if "aux_data" in raw_data else None
|
|
491
|
+
self.bot = bot
|
|
492
|
+
self.raw_data = raw_data or {}
|
|
493
|
+
self.object_guid = chat_id
|
|
494
|
+
self.author_guid = self.raw_data.get("sender_id", sender_id)
|
|
495
|
+
self.has_link = bool(re.search(r"(https?://[^\s]+ | www\.[^\s]+ | [a-zA-Z0-9.-]+\.(com|net|org|ir|edu|gov|info|biz|io|me|co) | t\.me/[^\s]+ | telegram\.me/[^\s]+ | @\w+ | \b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)", self.text))
|
|
496
|
+
self.sender_id: str = self.raw_data.get("sender_id", sender_id)
|
|
497
|
+
self.time: str = self.raw_data.get("time")
|
|
498
|
+
self.is_edited: bool = self.raw_data.get("is_edited", False)
|
|
499
|
+
self.sender_type: str = self.raw_data.get("sender_type")
|
|
500
|
+
self.args = []
|
|
501
|
+
self.is_command = bool(self.text and self.text.startswith("/"))
|
|
502
|
+
self.is_user = self.chat_id.startswith("b")
|
|
503
|
+
self.is_private = self.chat_id.startswith("b")
|
|
504
|
+
self.is_group = self.chat_id.startswith("g")
|
|
505
|
+
self.is_channel = self.chat_id.startswith("c")
|
|
506
|
+
self.reply_to_message_id: Optional[str] = self.raw_data.get("reply_to_message_id")
|
|
507
|
+
self.forwarded_from = ForwardedFrom(self.raw_data["forwarded_from"]) if "forwarded_from" in self.raw_data else None
|
|
508
|
+
self.file = File(self.raw_data["file"]) if "file" in self.raw_data else None
|
|
509
|
+
self.sticker = Sticker(self.raw_data["sticker"]) if "sticker" in self.raw_data else None
|
|
510
|
+
self.contact_message = ContactMessage(self.raw_data["contact_message"]) if "contact_message" in self.raw_data else None
|
|
511
|
+
self.poll = Poll(self.raw_data["poll"]) if "poll" in self.raw_data else None
|
|
512
|
+
self.location = Location(self.raw_data["location"]) if "location" in self.raw_data else None
|
|
513
|
+
self.live_location = LiveLocation(self.raw_data["live_location"]) if "live_location" in self.raw_data else None
|
|
514
|
+
self.aux_data = AuxData(self.raw_data["aux_data"]) if "aux_data" in self.raw_data else None
|
|
515
|
+
self.is_reply = self.reply_to_message_id is not None
|
|
516
|
+
self.has_media = any([self.file, self.sticker, self.poll, self.location, self.live_location])
|
|
517
|
+
self.is_forwarded = self.forwarded_from is not None
|
|
518
|
+
self.is_text = bool(self.text and not self.has_media)
|
|
519
|
+
self.is_media = self.has_media
|
|
520
|
+
self.is_poll = self.poll is not None
|
|
521
|
+
self.is_location = self.location is not None
|
|
522
|
+
self.is_live_location = self.live_location is not None
|
|
523
|
+
self.is_contact = self.contact_message is not None
|
|
524
|
+
self.has_any_media = any([self.file, self.sticker, self.poll, self.location, self.live_location])
|
|
525
|
+
self.edited_text = self.raw_data.get("edited_text") if self.is_edited else None
|
|
526
|
+
if self.file and self.file.file_name:
|
|
527
|
+
name = self.file.file_name.lower()
|
|
528
|
+
self.is_photo = name.endswith((".jpg", ".jpeg", ".png", ".gif", ".webp"))
|
|
529
|
+
self.is_video = name.endswith((".mp4", ".mov", ".avi", ".mkv", ".webm"))
|
|
530
|
+
self.is_audio = name.endswith((".mp3", ".wav", ".ogg", ".m4a", ".flac"))
|
|
531
|
+
self.is_voice = name.endswith((".ogg", ".m4a"))
|
|
532
|
+
self.is_document = name.endswith((".pdf", ".doc", ".docx", ".txt", ".xls", ".xlsx", ".ppt", ".pptx"))
|
|
533
|
+
self.is_archive = name.endswith((".zip", ".rar", ".7z", ".tar", ".gz"))
|
|
534
|
+
self.is_executable = name.endswith((".exe", ".msi", ".bat", ".sh"))
|
|
535
|
+
self.is_font = name.endswith((".ttf", ".otf", ".woff", ".woff2"))
|
|
536
|
+
|
|
476
537
|
|
|
477
538
|
def reply(self, text: str, **kwargs):
|
|
478
539
|
return self.bot.send_message(
|
rubka/update.py
CHANGED
|
@@ -186,7 +186,7 @@ class Bot:
|
|
|
186
186
|
self.share_url: str = data.get("share_url")
|
|
187
187
|
from typing import Union
|
|
188
188
|
from pathlib import Path
|
|
189
|
-
|
|
189
|
+
import re
|
|
190
190
|
class Message:
|
|
191
191
|
def __init__(self, bot, chat_id, message_id, sender_id, text=None, raw_data=None):
|
|
192
192
|
self.bot = bot
|
|
@@ -196,6 +196,10 @@ class Message:
|
|
|
196
196
|
self.author_guid = self.raw_data.get("sender_id", sender_id)
|
|
197
197
|
self.message_id: str = self.raw_data.get("message_id", message_id)
|
|
198
198
|
self.text: str = self.raw_data.get("text", text)
|
|
199
|
+
self.has_link = bool(re.search(
|
|
200
|
+
r"(https?://[^\s]+|www\.[^\s]+|[a-zA-Z0-9.-]+\.(com|net|org|ir|edu|gov|info|biz|io|me|co)|t\.me/[^\s]+|telegram\.me/[^\s]+|@\w+|\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)",
|
|
201
|
+
self.raw_data.get("text", text) or ""
|
|
202
|
+
))
|
|
199
203
|
self.sender_id: str = self.raw_data.get("sender_id", sender_id)
|
|
200
204
|
self.time: str = self.raw_data.get("time")
|
|
201
205
|
self.is_edited: bool = self.raw_data.get("is_edited", False)
|
|
@@ -226,6 +230,16 @@ class Message:
|
|
|
226
230
|
self.is_contact = self.contact_message is not None
|
|
227
231
|
self.has_any_media = any([self.file, self.sticker, self.poll, self.location, self.live_location])
|
|
228
232
|
self.edited_text = self.raw_data.get("edited_text") if self.is_edited else None
|
|
233
|
+
if self.file and self.file.file_name:
|
|
234
|
+
name = self.file.file_name.lower()
|
|
235
|
+
self.is_photo = name.endswith((".jpg", ".jpeg", ".png", ".gif", ".webp"))
|
|
236
|
+
self.is_video = name.endswith((".mp4", ".mov", ".avi", ".mkv", ".webm"))
|
|
237
|
+
self.is_audio = name.endswith((".mp3", ".wav", ".ogg", ".m4a", ".flac"))
|
|
238
|
+
self.is_voice = name.endswith((".ogg", ".m4a"))
|
|
239
|
+
self.is_document = name.endswith((".pdf", ".doc", ".docx", ".txt", ".xls", ".xlsx", ".ppt", ".pptx"))
|
|
240
|
+
self.is_archive = name.endswith((".zip", ".rar", ".7z", ".tar", ".gz"))
|
|
241
|
+
self.is_executable = name.endswith((".exe", ".msi", ".bat", ".sh"))
|
|
242
|
+
self.is_font = name.endswith((".ttf", ".otf", ".woff", ".woff2"))
|
|
229
243
|
self.info = {attr: value for attr, value in vars(self).items()}
|
|
230
244
|
@property
|
|
231
245
|
def session(self):
|
|
@@ -467,12 +481,59 @@ class InlineMessage:
|
|
|
467
481
|
def __init__(self, bot, raw_data: dict):
|
|
468
482
|
self.bot = bot
|
|
469
483
|
self.raw_data = raw_data
|
|
470
|
-
|
|
484
|
+
chat_id : str = raw_data.get("chat_id")
|
|
485
|
+
sender_id : str = raw_data.get("sender_id")
|
|
471
486
|
self.chat_id: str = raw_data.get("chat_id")
|
|
472
487
|
self.message_id: str = raw_data.get("message_id")
|
|
473
488
|
self.sender_id: str = raw_data.get("sender_id")
|
|
474
489
|
self.text: str = raw_data.get("text")
|
|
475
490
|
self.aux_data = AuxData(raw_data.get("aux_data", {})) if "aux_data" in raw_data else None
|
|
491
|
+
self.bot = bot
|
|
492
|
+
self.raw_data = raw_data or {}
|
|
493
|
+
self.object_guid = chat_id
|
|
494
|
+
self.author_guid = self.raw_data.get("sender_id", sender_id)
|
|
495
|
+
self.has_link = bool(re.search(r"(https?://[^\s]+ | www\.[^\s]+ | [a-zA-Z0-9.-]+\.(com|net|org|ir|edu|gov|info|biz|io|me|co) | t\.me/[^\s]+ | telegram\.me/[^\s]+ | @\w+ | \b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)", self.text))
|
|
496
|
+
self.sender_id: str = self.raw_data.get("sender_id", sender_id)
|
|
497
|
+
self.time: str = self.raw_data.get("time")
|
|
498
|
+
self.is_edited: bool = self.raw_data.get("is_edited", False)
|
|
499
|
+
self.sender_type: str = self.raw_data.get("sender_type")
|
|
500
|
+
self.args = []
|
|
501
|
+
self.is_command = bool(self.text and self.text.startswith("/"))
|
|
502
|
+
self.is_user = self.chat_id.startswith("b")
|
|
503
|
+
self.is_private = self.chat_id.startswith("b")
|
|
504
|
+
self.is_group = self.chat_id.startswith("g")
|
|
505
|
+
self.is_channel = self.chat_id.startswith("c")
|
|
506
|
+
self.reply_to_message_id: Optional[str] = self.raw_data.get("reply_to_message_id")
|
|
507
|
+
self.forwarded_from = ForwardedFrom(self.raw_data["forwarded_from"]) if "forwarded_from" in self.raw_data else None
|
|
508
|
+
self.file = File(self.raw_data["file"]) if "file" in self.raw_data else None
|
|
509
|
+
self.sticker = Sticker(self.raw_data["sticker"]) if "sticker" in self.raw_data else None
|
|
510
|
+
self.contact_message = ContactMessage(self.raw_data["contact_message"]) if "contact_message" in self.raw_data else None
|
|
511
|
+
self.poll = Poll(self.raw_data["poll"]) if "poll" in self.raw_data else None
|
|
512
|
+
self.location = Location(self.raw_data["location"]) if "location" in self.raw_data else None
|
|
513
|
+
self.live_location = LiveLocation(self.raw_data["live_location"]) if "live_location" in self.raw_data else None
|
|
514
|
+
self.aux_data = AuxData(self.raw_data["aux_data"]) if "aux_data" in self.raw_data else None
|
|
515
|
+
self.is_reply = self.reply_to_message_id is not None
|
|
516
|
+
self.has_media = any([self.file, self.sticker, self.poll, self.location, self.live_location])
|
|
517
|
+
self.is_forwarded = self.forwarded_from is not None
|
|
518
|
+
self.is_text = bool(self.text and not self.has_media)
|
|
519
|
+
self.is_media = self.has_media
|
|
520
|
+
self.is_poll = self.poll is not None
|
|
521
|
+
self.is_location = self.location is not None
|
|
522
|
+
self.is_live_location = self.live_location is not None
|
|
523
|
+
self.is_contact = self.contact_message is not None
|
|
524
|
+
self.has_any_media = any([self.file, self.sticker, self.poll, self.location, self.live_location])
|
|
525
|
+
self.edited_text = self.raw_data.get("edited_text") if self.is_edited else None
|
|
526
|
+
if self.file and self.file.file_name:
|
|
527
|
+
name = self.file.file_name.lower()
|
|
528
|
+
self.is_photo = name.endswith((".jpg", ".jpeg", ".png", ".gif", ".webp"))
|
|
529
|
+
self.is_video = name.endswith((".mp4", ".mov", ".avi", ".mkv", ".webm"))
|
|
530
|
+
self.is_audio = name.endswith((".mp3", ".wav", ".ogg", ".m4a", ".flac"))
|
|
531
|
+
self.is_voice = name.endswith((".ogg", ".m4a"))
|
|
532
|
+
self.is_document = name.endswith((".pdf", ".doc", ".docx", ".txt", ".xls", ".xlsx", ".ppt", ".pptx"))
|
|
533
|
+
self.is_archive = name.endswith((".zip", ".rar", ".7z", ".tar", ".gz"))
|
|
534
|
+
self.is_executable = name.endswith((".exe", ".msi", ".bat", ".sh"))
|
|
535
|
+
self.is_font = name.endswith((".ttf", ".otf", ".woff", ".woff2"))
|
|
536
|
+
|
|
476
537
|
|
|
477
538
|
def reply(self, text: str, **kwargs):
|
|
478
539
|
return self.bot.send_message(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Rubka
|
|
3
|
-
Version: 6.6.
|
|
3
|
+
Version: 6.6.13
|
|
4
4
|
Summary: rubika A Python library for interacting with Rubika Bot API.
|
|
5
5
|
Home-page: https://github.com/Mahdy-Ahmadi/Rubka
|
|
6
6
|
Download-URL: https://github.com/Mahdy-Ahmadi/rubka/archive/refs/tags/v6.6.4.zip
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
rubka/__init__.py,sha256=P6IBiORfp-GqKHe5LZ-5lldWyG7tnrUYUcAQDUgwXmY,1973
|
|
2
2
|
rubka/api.py,sha256=1S8JIcYN_Zxb7JT73eQl9me-qDDDTDzcSk6_qawAfkA,68861
|
|
3
|
-
rubka/asynco.py,sha256=
|
|
3
|
+
rubka/asynco.py,sha256=9GdEzmOk9_n5MV7FxEJ4fWdZtuedPAsqJUj2Upnm9Gc,90044
|
|
4
4
|
rubka/button.py,sha256=vU9OvWXCD4MRrTJ8Xmivd4L471-06zrD2qpZBTw5vjY,13305
|
|
5
5
|
rubka/config.py,sha256=Bck59xkOiqioLv0GkQ1qPGnBXVctz1hKk6LT4h2EPx0,78
|
|
6
|
-
rubka/context.py,sha256=
|
|
6
|
+
rubka/context.py,sha256=OcYY0G0IFQa29zpw6YRm873RwJOf568qxJplm1UdeAM,23936
|
|
7
7
|
rubka/decorators.py,sha256=hGwUoE4q2ImrunJIGJ_kzGYYxQf1ueE0isadqraKEts,1157
|
|
8
8
|
rubka/exceptions.py,sha256=tujZt1XrhWaw-lmdeVadVceUptpw4XzNgE44sAAY0gs,90
|
|
9
9
|
rubka/filters.py,sha256=DY1bdkpRKIiLtVcy6X3hOnlGPcVOK4HFb3QgmaPx6Oo,12116
|
|
@@ -14,7 +14,7 @@ rubka/keypad.py,sha256=yGsNt8W5HtUFBzVF1m_p7GySlu1hwIcSvXZ4BTdrlvg,9558
|
|
|
14
14
|
rubka/logger.py,sha256=J2I6NiK1z32lrAzC4H1Et6WPMBXxXGCVUsW4jgcAofs,289
|
|
15
15
|
rubka/rubino.py,sha256=GuXnEUTTSZUw68FMTQBYsB2zG_3rzdDa-krsrl4ib8w,58755
|
|
16
16
|
rubka/tv.py,sha256=o7CW-6EKLhmM--rzcHcKPcXfzOixcL_B4j037R3mHts,5399
|
|
17
|
-
rubka/update.py,sha256=
|
|
17
|
+
rubka/update.py,sha256=OcYY0G0IFQa29zpw6YRm873RwJOf568qxJplm1UdeAM,23936
|
|
18
18
|
rubka/utils.py,sha256=XUQUZxQt9J2f0X5hmAH_MH1kibTAfdT1T4AaBkBhBBs,148
|
|
19
19
|
rubka/adaptorrubka/__init__.py,sha256=6o2tCXnVeES7nx-LjnzsuMqjKcWIm9qwKficLE54s-U,83
|
|
20
20
|
rubka/adaptorrubka/enums.py,sha256=cyiakExmZi-QQpYuf_A93HQvfZVmyG_0uVuvTTNT5To,1053
|
|
@@ -37,8 +37,8 @@ rubka/adaptorrubka/types/socket/message.py,sha256=0WgLMZh4eow8Zn7AiSX4C3GZjQTkIg
|
|
|
37
37
|
rubka/adaptorrubka/utils/__init__.py,sha256=OgCFkXdNFh379quNwIVOAWY2NP5cIOxU5gDRRALTk4o,54
|
|
38
38
|
rubka/adaptorrubka/utils/configs.py,sha256=nMUEOJh1NqDJsf9W9PurkN_DLYjO6kKPMm923i4Jj_A,492
|
|
39
39
|
rubka/adaptorrubka/utils/utils.py,sha256=5-LioLNYX_TIbQGDeT50j7Sg9nAWH2LJUUs-iEXpsUY,8816
|
|
40
|
-
rubka-6.6.
|
|
41
|
-
rubka-6.6.
|
|
42
|
-
rubka-6.6.
|
|
43
|
-
rubka-6.6.
|
|
44
|
-
rubka-6.6.
|
|
40
|
+
rubka-6.6.13.dist-info/METADATA,sha256=-UinFermTRpXMLTPl4D6Whjgun6xhXdsrfqqoobw-gY,34270
|
|
41
|
+
rubka-6.6.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
42
|
+
rubka-6.6.13.dist-info/entry_points.txt,sha256=4aESuUmuUOALMUy7Kucv_Gb5YlqhsJmTmdXLlZU9sJ0,46
|
|
43
|
+
rubka-6.6.13.dist-info/top_level.txt,sha256=vy2A4lot11cRMdQS-F4HDCIXL3JK8RKfu7HMDkezJW4,6
|
|
44
|
+
rubka-6.6.13.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|