Rubka 7.1.7__tar.gz → 7.1.9__tar.gz

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.
Files changed (50) hide show
  1. {rubka-7.1.7 → rubka-7.1.9}/PKG-INFO +1 -2
  2. {rubka-7.1.7 → rubka-7.1.9}/Rubka.egg-info/PKG-INFO +1 -2
  3. {rubka-7.1.7 → rubka-7.1.9}/Rubka.egg-info/requires.txt +0 -1
  4. {rubka-7.1.7 → rubka-7.1.9}/rubka/asynco.py +45 -0
  5. {rubka-7.1.7 → rubka-7.1.9}/rubka/context.py +76 -4
  6. {rubka-7.1.7 → rubka-7.1.9}/setup.py +1 -2
  7. {rubka-7.1.7 → rubka-7.1.9}/README.md +0 -0
  8. {rubka-7.1.7 → rubka-7.1.9}/Rubka.egg-info/SOURCES.txt +0 -0
  9. {rubka-7.1.7 → rubka-7.1.9}/Rubka.egg-info/dependency_links.txt +0 -0
  10. {rubka-7.1.7 → rubka-7.1.9}/Rubka.egg-info/entry_points.txt +0 -0
  11. {rubka-7.1.7 → rubka-7.1.9}/Rubka.egg-info/not-zip-safe +0 -0
  12. {rubka-7.1.7 → rubka-7.1.9}/Rubka.egg-info/top_level.txt +0 -0
  13. {rubka-7.1.7 → rubka-7.1.9}/rubka/__init__.py +0 -0
  14. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/__init__.py +0 -0
  15. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/client/__init__.py +0 -0
  16. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/client/client.py +0 -0
  17. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/crypto/__init__.py +0 -0
  18. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/crypto/crypto.py +0 -0
  19. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/enums.py +0 -0
  20. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/exceptions.py +0 -0
  21. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/methods/__init__.py +0 -0
  22. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/methods/methods.py +0 -0
  23. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/network/__init__.py +0 -0
  24. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/network/helper.py +0 -0
  25. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/network/network.py +0 -0
  26. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/network/socket.py +0 -0
  27. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/sessions/__init__.py +0 -0
  28. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/sessions/sessions.py +0 -0
  29. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/types/__init__.py +0 -0
  30. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/types/socket/__init__.py +0 -0
  31. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/types/socket/message.py +0 -0
  32. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/utils/__init__.py +0 -0
  33. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/utils/configs.py +0 -0
  34. {rubka-7.1.7 → rubka-7.1.9}/rubka/adaptorrubka/utils/utils.py +0 -0
  35. {rubka-7.1.7 → rubka-7.1.9}/rubka/api.py +0 -0
  36. {rubka-7.1.7 → rubka-7.1.9}/rubka/button.py +0 -0
  37. {rubka-7.1.7 → rubka-7.1.9}/rubka/config.py +0 -0
  38. {rubka-7.1.7 → rubka-7.1.9}/rubka/decorators.py +0 -0
  39. {rubka-7.1.7 → rubka-7.1.9}/rubka/exceptions.py +0 -0
  40. {rubka-7.1.7 → rubka-7.1.9}/rubka/filters.py +0 -0
  41. {rubka-7.1.7 → rubka-7.1.9}/rubka/helpers.py +0 -0
  42. {rubka-7.1.7 → rubka-7.1.9}/rubka/jobs.py +0 -0
  43. {rubka-7.1.7 → rubka-7.1.9}/rubka/keyboards.py +0 -0
  44. {rubka-7.1.7 → rubka-7.1.9}/rubka/keypad.py +0 -0
  45. {rubka-7.1.7 → rubka-7.1.9}/rubka/logger.py +0 -0
  46. {rubka-7.1.7 → rubka-7.1.9}/rubka/rubino.py +0 -0
  47. {rubka-7.1.7 → rubka-7.1.9}/rubka/tv.py +0 -0
  48. {rubka-7.1.7 → rubka-7.1.9}/rubka/update.py +0 -0
  49. {rubka-7.1.7 → rubka-7.1.9}/rubka/utils.py +0 -0
  50. {rubka-7.1.7 → rubka-7.1.9}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Rubka
3
- Version: 7.1.7
3
+ Version: 7.1.9
4
4
  Summary: Rubika: A Python library for interacting with the Rubika Bot API. This library provides an easy-to-use interface to send messages, polls, stickers, media files, manage groups and channels, handle inline keyboards, and implement advanced bot features like subscription management, user authentication, and message handling. Ideal for developers looking to automate and extend their Rubika bots with Python.
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
@@ -27,7 +27,6 @@ Classifier: Natural Language :: Persian
27
27
  Requires-Python: >=3.6
28
28
  Description-Content-Type: text/markdown
29
29
  Requires-Dist: requests
30
- Requires-Dist: Pillow
31
30
  Requires-Dist: websocket-client
32
31
  Requires-Dist: pycryptodome
33
32
  Requires-Dist: aiohttp
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Rubka
3
- Version: 7.1.7
3
+ Version: 7.1.9
4
4
  Summary: Rubika: A Python library for interacting with the Rubika Bot API. This library provides an easy-to-use interface to send messages, polls, stickers, media files, manage groups and channels, handle inline keyboards, and implement advanced bot features like subscription management, user authentication, and message handling. Ideal for developers looking to automate and extend their Rubika bots with Python.
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
@@ -27,7 +27,6 @@ Classifier: Natural Language :: Persian
27
27
  Requires-Python: >=3.6
28
28
  Description-Content-Type: text/markdown
29
29
  Requires-Dist: requests
30
- Requires-Dist: Pillow
31
30
  Requires-Dist: websocket-client
32
31
  Requires-Dist: pycryptodome
33
32
  Requires-Dist: aiohttp
@@ -1,5 +1,4 @@
1
1
  requests
2
- Pillow
3
2
  websocket-client
4
3
  pycryptodome
5
4
  aiohttp
@@ -2171,6 +2171,51 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
2171
2171
  async def get_username(self, chat_id: str) -> str:
2172
2172
  chat_info = await self.get_chat(chat_id)
2173
2173
  return chat_info.get("data", {}).get("chat", {}).get("username", "None")
2174
+ async def send_bulk_message(
2175
+ self,
2176
+ chat_ids: List[str],
2177
+ text: str,
2178
+ concurrency: int = 5,
2179
+ delay_between: float = 0.0,
2180
+ log_errors: bool = True,
2181
+ **kwargs
2182
+ ) -> Dict[str, Optional[Dict]]:
2183
+ if not chat_ids:return {}
2184
+ semaphore = asyncio.Semaphore(concurrency)
2185
+ results: Dict[str, Optional[Dict]] = {}
2186
+ async def _send(chat_id: str):
2187
+ async with semaphore:
2188
+ try:
2189
+ res = await self.send_message(chat_id, text, **kwargs)
2190
+ results[chat_id] = res
2191
+ except Exception as e:
2192
+ results[chat_id] = None
2193
+ if log_errors:print(f"[send_bulk_message] Error {chat_id} : {e}")
2194
+ if delay_between > 0:await asyncio.sleep(delay_between)
2195
+ await asyncio.gather(*[_send(cid) for cid in chat_ids])
2196
+ return results
2197
+ async def delete_bulk_message(self, chat_id: str, message_ids: list[str]):
2198
+ tasks = [self.delete_message(chat_id, mid) for mid in message_ids]
2199
+ return await asyncio.gather(*tasks, return_exceptions=True)
2200
+ async def edit_bulk_message(self, chat_id: str, messages: dict[str, str]):
2201
+ tasks = [self.edit_message_text(chat_id, mid, new_text) for mid, new_text in messages.items()]
2202
+ return await asyncio.gather(*tasks, return_exceptions=True)
2203
+ async def send_scheduled_message(self, chat_id: str, text: str, delay: int, **kwargs):
2204
+ await asyncio.sleep(delay)
2205
+ return await self.send_message(chat_id, text, **kwargs)
2206
+ async def disable_inline_keyboard(
2207
+ self,
2208
+ chat_id: str,
2209
+ message_id: str,
2210
+ text: Optional[str] = "~",
2211
+ delay: float = 5.0,
2212
+ ) -> Dict[str, any]:
2213
+ if text is not None:await self.edit_inline_keypad(chat_id, message_id, inline_keypad={}, text=text)
2214
+ if delay > 0:
2215
+ await asyncio.sleep(delay)
2216
+ response = await self.edit_inline_keypad(chat_id, message_id, inline_keypad={})
2217
+ return response
2218
+ else:return await self.edit_inline_keypad(chat_id, message_id, inline_keypad={})
2174
2219
  async def get_chat_admins(self, chat_id: str) -> Dict[str, Any]:
2175
2220
  return await self._post("getChatAdmins", {"chat_id": chat_id})
2176
2221
  async def get_chat_members(self, chat_id: str, start_id: str = "") -> Dict[str, Any]:
@@ -3,6 +3,66 @@ from pathlib import Path
3
3
  from typing import List, Optional, Dict, Any, Literal, Callable, Union,Set
4
4
  import re,inspect
5
5
  import asyncio
6
+ _EMOJI_PATTERN = re.compile(
7
+ "["
8
+ "\U0001F300-\U0001F5FF"
9
+ "\U0001F600-\U0001F64F"
10
+ "\U0001F680-\U0001F6FF"
11
+ "\U0001F700-\U0001F77F"
12
+ "\U0001F780-\U0001F7FF"
13
+ "\U0001F800-\U0001F8FF"
14
+ "\U0001F900-\U0001F9FF"
15
+ "\U0001FA00-\U0001FA6F"
16
+ "\U0001FA70-\U0001FAFF"
17
+ "\U00002700-\U000027BF"
18
+ "\U00002600-\U000026FF"
19
+ "\U00002000-\U000023FF"
20
+ "]+",
21
+ flags=re.UNICODE
22
+ )
23
+
24
+ def contains_emoji(text: str) -> bool:
25
+ if not text:return False
26
+ return bool(_EMOJI_PATTERN.search(text))
27
+
28
+ def count_emojis(text: str) -> int:
29
+ if not text:return 0
30
+ return len(_EMOJI_PATTERN.findall(text))
31
+ def contains_link_or_mention(text: str) -> bool:
32
+ if not text:return False
33
+ pattern = re.compile(
34
+ r"(?i)\b("
35
+ r"https?://[^\s]+"
36
+ r"|www\.[^\s]+"
37
+ r"|[a-zA-Z0-9.-]+\.(com|net|org|ir|edu|gov|info|biz|io|me|co|xyz|in|us|uk|ru|tv|cc|app|dev|site|store|cloud|shop)"
38
+ r"|t\.me/[^\s]+"
39
+ r"|telegram\.me/[^\s]+"
40
+ r"|rubika\.(ir|app)/[^\s]+"
41
+ r"|whatsapp\.com/[^\s]+"
42
+ r"|wa\.me/[^\s]+"
43
+ r"|instagram\.com/[^\s]+"
44
+ r"|instagr\.am/[^\s]+"
45
+ r"|youtube\.com/[^\s]+"
46
+ r"|youtu\.be/[^\s]+"
47
+ r"|aparat\.com/[^\s]+"
48
+ r"|discord\.gg/[^\s]+"
49
+ r"|discord\.com/[^\s]+"
50
+ r"|splus\.ir/[^\s]+"
51
+ r"|eitaa\.com/[^\s]+"
52
+ r"|ble\.ir/[^\s]+"
53
+ r"|gap\.im/[^\s]+"
54
+ r"|rubino\.ir/[^\s]+"
55
+ r"|pin\.it/[^\s]+"
56
+ r"|twitter\.com/[^\s]+"
57
+ r"|x\.com/[^\s]+"
58
+ r"|facebook\.com/[^\s]+"
59
+ r"|threads\.net/[^\s]+"
60
+ r"|@\w+"
61
+ r"|\b\d{1,3}(?:\.\d{1,3}){3}\b"
62
+ r"|\[?[A-F0-9:]{2,39}\]?"
63
+ r")\b"
64
+ )
65
+ return bool(pattern.search(text))
6
66
  class File:
7
67
  def __init__(self, data: dict):
8
68
  self.file_id: str = data.get("file_id")
@@ -215,10 +275,22 @@ class Message:
215
275
  self.author_guid = self.raw_data.get("sender_id", sender_id)
216
276
  self.message_id: str = self.raw_data.get("message_id", message_id)
217
277
  self.text: str = self.raw_data.get("text", text)
218
- self.has_link = bool(re.search(
219
- 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)",
220
- self.raw_data.get("text", text) or ""
221
- ))
278
+ self.has_link = contains_link_or_mention(self.raw_data.get("text", text))
279
+ self.is_link = self.has_link
280
+ self.is_mention = bool(re.search(r"@\w+", self.raw_data.get("text", text) or ""))
281
+ self.is_hashtag = bool(re.search(r"#\w+", text or ""))
282
+ self.is_number = bool(re.search(r"\d+", text or ""))
283
+ self.is_emoji = contains_emoji(self.raw_data.get("text", text))
284
+ self.emoji_count = count_emojis(self.raw_data.get("text", text))
285
+ self.is_pure_emoji = bool(self.is_emoji and self.emoji_count == len(self.text))
286
+ self.is_photo = None
287
+ self.is_video = None
288
+ self.is_audio = None
289
+ self.is_voice = None
290
+ self.is_document = None
291
+ self.is_archive = None
292
+ self.is_executable = None
293
+ self.is_font = None
222
294
  self.sender_id: str = self.raw_data.get("sender_id", sender_id)
223
295
  self.time: str = self.raw_data.get("time")
224
296
  self.is_edited: bool = self.raw_data.get("is_edited", False)
@@ -13,7 +13,7 @@ with open("README.md", "r", encoding="utf-8") as f:
13
13
 
14
14
  setup(
15
15
  name='Rubka',
16
- version='7.1.7',
16
+ version='7.1.9',
17
17
  description=(
18
18
  "Rubika: A Python library for interacting with the Rubika Bot API. "
19
19
  "This library provides an easy-to-use interface to send messages, polls, "
@@ -49,7 +49,6 @@ setup(
49
49
  python_requires='>=3.6',
50
50
  install_requires=[
51
51
  "requests",
52
- "Pillow",
53
52
  "websocket-client",
54
53
  'pycryptodome',
55
54
  'aiohttp',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes