Rubka 7.1.17__py3-none-any.whl → 7.2.2__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.
rubka/__init__.py CHANGED
@@ -66,8 +66,7 @@ Sync = simple, step-by-step, blocking.
66
66
  Async = scalable, concurrent, non-blocking.
67
67
  """
68
68
 
69
- from .api import Robot
70
- from .rubino import Bot
69
+ from .api import Robot,Bot,robot,bot
71
70
  from .exceptions import APIRequestError
72
71
  from .rubino import Bot as rubino
73
72
  from .tv import TV as TvRubika
rubka/asynco.py CHANGED
@@ -280,6 +280,7 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
280
280
  self.proxy = proxy
281
281
  self.max_msg_age = max_msg_age
282
282
  self.retries = retries
283
+ self.middleware_data = []
283
284
 
284
285
  self.retry_delay = retry_delay
285
286
  self.raise_errors = raise_errors
@@ -346,7 +347,6 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
346
347
  async def _post(self, method: str, data: Dict[str, Any]) -> Dict[str, Any]:
347
348
  base_url = BASE_URLS[self.api_endpoint]
348
349
  url = f"{base_url}/{self.token}/{method}"
349
- print(url)
350
350
  session = await self._get_session()
351
351
  for attempt in range(1, self.retries + 1):
352
352
  try:
@@ -542,6 +542,11 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
542
542
 
543
543
  #decorator#
544
544
 
545
+ def middleware(self):
546
+ def decorator(func: Callable[[Any, Union[Message, InlineMessage]], None]):
547
+ self.middleware_data.append(func)
548
+ return func
549
+ return decorator
545
550
  def on_message_private(
546
551
  self,
547
552
  chat_id: Optional[Union[str, List[str]]] = None,
@@ -1843,20 +1848,23 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
1843
1848
  reply_to_message_id: Optional[str] = None,
1844
1849
  chat_keypad_type: Optional[Literal["New", "Remove"]] = None,
1845
1850
  delete_after: Optional[int] = None,
1846
- parse_mode: Optional[Literal["HTML", "Markdown"]] = None
1851
+ parse_mode: Optional[Literal["HTML", "Markdown"]] = None,
1852
+ meta_data:Optional[dict] = None
1847
1853
  ) -> Dict[str, Any]:
1848
-
1849
1854
  payload = {
1850
1855
  "chat_id": chat_id,
1851
1856
  "text": text,
1852
1857
  "disable_notification": disable_notification,
1853
1858
  }
1854
- parse_mode_to_use = parse_mode or self.parse_mode
1855
- if text:
1856
- text, metadata = self._parse_text_metadata(text, parse_mode_to_use)
1857
- payload["text"] = text
1858
- if metadata:
1859
- payload["metadata"] = metadata
1859
+ if not meta_data:
1860
+ parse_mode_to_use = parse_mode or self.parse_mode
1861
+ if text:
1862
+ text, metadata = self._parse_text_metadata(text, parse_mode_to_use)
1863
+ payload["text"] = text
1864
+ if metadata:
1865
+ payload["metadata"] = metadata
1866
+ else :
1867
+ payload["metadata"] = meta_data
1860
1868
  if chat_keypad:
1861
1869
  payload["chat_keypad"] = chat_keypad
1862
1870
  payload["chat_keypad_type"] = chat_keypad_type or "New"
@@ -2018,7 +2026,7 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
2018
2026
  if reply_to_message_id: payload["reply_to_message_id"] = reply_to_message_id
2019
2027
  if chat_keypad_type: payload["chat_keypad_type"] = chat_keypad_type
2020
2028
  return await self._post("sendLocation", {k: v for k, v in payload.items() if v is not None})
2021
- async def upload_media_file(self, upload_url: str, name: str, path: Union[str, Path]) -> str:
2029
+ async def upload_media_file(self, upload_url: str, name: str, path: Union[str, Path, bytes]) -> str:
2022
2030
  session = await self._get_session()
2023
2031
  is_temp_file = False
2024
2032
  if isinstance(path, str) and path.startswith("http"):
@@ -2030,12 +2038,17 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
2030
2038
  tmp.write(content)
2031
2039
  path = tmp.name
2032
2040
  is_temp_file = True
2041
+ elif isinstance(path, bytes):
2042
+ with tempfile.NamedTemporaryFile(delete=False) as tmp:
2043
+ tmp.write(path)
2044
+ path = tmp.name
2045
+ is_temp_file = True
2033
2046
 
2034
2047
  file_size = os.path.getsize(path)
2035
2048
  chunk_size = self.chunk_size
2036
2049
 
2037
2050
  progress_bar = tqdm(total=file_size, unit='B', unit_scale=True, unit_divisor=1024,
2038
- desc=f'Uploading: {name}', colour='cyan', disable=not getattr(self, 'show_progress', True))
2051
+ desc=f'Upload : {name}', colour='blue', disable=not getattr(self, 'show_progress', True))
2039
2052
 
2040
2053
  async def file_generator(file_path):
2041
2054
  async with aiofiles.open(file_path, 'rb') as f:
@@ -2045,7 +2058,6 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
2045
2058
 
2046
2059
  form = aiohttp.FormData()
2047
2060
  form.add_field('file', file_generator(path), filename=name, content_type='application/octet-stream')
2048
-
2049
2061
  try:
2050
2062
  async with session.post(upload_url, data=form, timeout=aiohttp.ClientTimeout(total=None)) as response:
2051
2063
  progress_bar.close()
@@ -2054,7 +2066,7 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
2054
2066
  raise Exception(f"Upload failed ({response.status}): {text}")
2055
2067
  return (await response.json()).get('data', {}).get('file_id')
2056
2068
  except Exception as e:
2057
- raise FeatureNotAvailableError(f"File upload not supported: {e}")
2069
+ raise FeatureNotAvailableError(f"File upload not supported : {e}")
2058
2070
  finally:
2059
2071
  if is_temp_file:
2060
2072
  os.remove(path)
@@ -2143,16 +2155,20 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
2143
2155
  raise ValueError(f"Invalid media type. Must be one of {allowed}")
2144
2156
  result = await self._post("requestSendFile", {"type": media_type})
2145
2157
  return result.get("data", {}).get("upload_url")
2146
- async def _send_uploaded_file(self, chat_id: str, file_id: str,type_file : str = "file",text: Optional[str] = None, chat_keypad: Optional[Dict[str, Any]] = None, inline_keypad: Optional[Dict[str, Any]] = None, disable_notification: bool = False, reply_to_message_id: Optional[str] = None, chat_keypad_type: Optional[Literal["New", "Remove", "None"]] = "None",parse_mode: Optional[Literal["HTML", "Markdown"]] = None) -> Dict[str, Any]:
2158
+ async def _send_uploaded_file(self, chat_id: str, file_id: str,type_file : str = "file",text: Optional[str] = None, chat_keypad: Optional[Dict[str, Any]] = None, inline_keypad: Optional[Dict[str, Any]] = None, disable_notification: bool = False, reply_to_message_id: Optional[str] = None, chat_keypad_type: Optional[Literal["New", "Remove", "None"]] = "None",parse_mode: Optional[Literal["HTML", "Markdown"]] = None,meta_data:Optional[dict] = None) -> Dict[str, Any]:
2147
2159
  payload = {"chat_id": chat_id, "file_id": file_id, "text": text, "disable_notification": disable_notification, "chat_keypad_type": chat_keypad_type}
2148
2160
  if chat_keypad: payload["chat_keypad"] = chat_keypad
2149
2161
  if inline_keypad: payload["inline_keypad"] = inline_keypad
2150
2162
  if reply_to_message_id: payload["reply_to_message_id"] = str(reply_to_message_id)
2151
- parse_mode_to_use = parse_mode or self.parse_mode
2152
- if text:
2153
- text, metadata = self._parse_text_metadata(text, parse_mode_to_use)
2154
- payload["text"] = text
2155
- if metadata:payload["metadata"] = metadata
2163
+ if not meta_data:
2164
+ parse_mode_to_use = parse_mode or self.parse_mode
2165
+ if text:
2166
+ text, metadata = self._parse_text_metadata(text, parse_mode_to_use)
2167
+ payload["text"] = text
2168
+ if metadata:
2169
+ payload["metadata"] = metadata
2170
+ else :
2171
+ payload["metadata"] = meta_data
2156
2172
  payload["time"] = "10"
2157
2173
  resp = await self._post("sendFile", payload)
2158
2174
  message_id_put = resp["data"]["message_id"]
@@ -2172,26 +2188,26 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
2172
2188
  "chat_keypad_type":chat_keypad_type
2173
2189
  }
2174
2190
  return AttrDict(result)
2175
- async def _send_file_generic(self, media_type, chat_id, path, file_id, text, file_name, inline_keypad, chat_keypad, reply_to_message_id, disable_notification, chat_keypad_type,parse_mode: Optional[Literal["HTML", "Markdown"]] = None):
2191
+ async def _send_file_generic(self, media_type, chat_id, path, file_id, text, file_name, inline_keypad, chat_keypad, reply_to_message_id, disable_notification, chat_keypad_type,parse_mode: Optional[Literal["HTML", "Markdown"]] = None,meta_data:Optional[dict] = None):
2176
2192
  if path:
2177
2193
  file_name = file_name or Path(path).name
2178
2194
  upload_url = await self.get_upload_url(media_type)
2179
2195
  file_id = await self.upload_media_file(upload_url, file_name, path)
2180
2196
  if not file_id:
2181
2197
  raise ValueError("Either path or file_id must be provided.")
2182
- return await self._send_uploaded_file(chat_id=chat_id, file_id=file_id, text=text, inline_keypad=inline_keypad, chat_keypad=chat_keypad, reply_to_message_id=reply_to_message_id, disable_notification=disable_notification, chat_keypad_type=chat_keypad_type,type_file=media_type,parse_mode=parse_mode)
2183
- async def send_document(self, chat_id: str, path: Optional[Union[str, Path]] = None, file_id: Optional[str] = None, text: Optional[str] = None, file_name: Optional[str] = None, inline_keypad: Optional[Dict[str, Any]] = None, chat_keypad: Optional[Dict[str, Any]] = None, reply_to_message_id: Optional[str] = None, disable_notification: bool = False, chat_keypad_type: Optional[Literal["New", "Remove", "None"]] = "None",parse_mode: Optional[Literal["HTML", "Markdown"]] = None) -> Dict[str, Any]:
2184
- return await self._send_file_generic("File", chat_id, path, file_id, text, file_name, inline_keypad, chat_keypad, reply_to_message_id, disable_notification, chat_keypad_type,parse_mode=parse_mode)
2185
- async def send_file(self, chat_id: str, path: Optional[Union[str, Path]] = None, file_id: Optional[str] = None, caption: Optional[str] = None, file_name: Optional[str] = None, inline_keypad: Optional[Dict[str, Any]] = None, chat_keypad: Optional[Dict[str, Any]] = None, reply_to_message_id: Optional[str] = None, disable_notification: bool = False, chat_keypad_type: Optional[Literal["New", "Remove", "None"]] = "None",parse_mode: Optional[Literal["HTML", "Markdown"]] = None) -> Dict[str, Any]:
2186
- return await self._send_file_generic("File", chat_id, path, file_id, caption, file_name, inline_keypad, chat_keypad, reply_to_message_id, disable_notification, chat_keypad_type,parse_mode=parse_mode)
2187
- async def re_send(self, chat_id: str, path: Optional[Union[str, Path]] = None, file_id: Optional[str] = None, caption: Optional[str] = None, file_name: Optional[str] = None, inline_keypad: Optional[Dict[str, Any]] = None, chat_keypad: Optional[Dict[str, Any]] = None, reply_to_message_id: Optional[str] = None, disable_notification: bool = False, chat_keypad_type: Optional[Literal["New", "Remove", "None"]] = "None",parse_mode: Optional[Literal["HTML", "Markdown"]] = None) -> Dict[str, Any]:
2188
- return await self._send_file_generic("File", chat_id, path, file_id, caption, file_name, inline_keypad, chat_keypad, reply_to_message_id, disable_notification, chat_keypad_type,parse_mode=parse_mode)
2189
- async def send_video(self, chat_id: str, path: Optional[Union[str, Path]] = None, file_id: Optional[str] = None, text: Optional[str] = None, file_name: Optional[str] = None, inline_keypad: Optional[Dict[str, Any]] = None, chat_keypad: Optional[Dict[str, Any]] = None, reply_to_message_id: Optional[str] = None, disable_notification: bool = False, chat_keypad_type: Optional[Literal["New", "Remove", "None"]] = "None",parse_mode: Optional[Literal["HTML", "Markdown"]] = None) -> Dict[str, Any]:
2190
- return await self._send_file_generic("Video", chat_id, path, file_id, text, file_name, inline_keypad, chat_keypad, reply_to_message_id, disable_notification, chat_keypad_type,parse_mode=parse_mode)
2191
- async def send_voice(self, chat_id: str, path: Optional[Union[str, Path]] = None, file_id: Optional[str] = None, text: Optional[str] = None, file_name: Optional[str] = None, inline_keypad: Optional[Dict[str, Any]] = None, chat_keypad: Optional[Dict[str, Any]] = None, reply_to_message_id: Optional[str] = None, disable_notification: bool = False, chat_keypad_type: Optional[Literal["New", "Remove", "None"]] = "None",parse_mode: Optional[Literal["HTML", "Markdown"]] = None) -> Dict[str, Any]:
2192
- return await self._send_file_generic("voice", chat_id, path, file_id, text, file_name, inline_keypad, chat_keypad, reply_to_message_id, disable_notification, chat_keypad_type,parse_mode=parse_mode)
2193
- async def send_image(self, chat_id: str, path: Optional[Union[str, Path]] = None, file_id: Optional[str] = None, text: Optional[str] = None, file_name: Optional[str] = None, inline_keypad: Optional[Dict[str, Any]] = None, chat_keypad: Optional[Dict[str, Any]] = None, reply_to_message_id: Optional[str] = None, disable_notification: bool = False, chat_keypad_type: Optional[Literal["New", "Remove", "None"]] = "None",parse_mode: Optional[Literal["HTML", "Markdown"]] = None) -> Dict[str, Any]:
2194
- return await self._send_file_generic("Image", chat_id, path, file_id, text, file_name, inline_keypad, chat_keypad, reply_to_message_id, disable_notification, chat_keypad_type,parse_mode=parse_mode)
2198
+ return await self._send_uploaded_file(chat_id=chat_id, file_id=file_id, text=text, inline_keypad=inline_keypad, chat_keypad=chat_keypad, reply_to_message_id=reply_to_message_id, disable_notification=disable_notification, chat_keypad_type=chat_keypad_type,type_file=media_type,parse_mode=parse_mode,meta_data=meta_data)
2199
+ async def send_document(self, chat_id: str, path: Optional[Union[str, Path]] = None, file_id: Optional[str] = None, text: Optional[str] = None, file_name: Optional[str] = None, inline_keypad: Optional[Dict[str, Any]] = None, chat_keypad: Optional[Dict[str, Any]] = None, reply_to_message_id: Optional[str] = None, disable_notification: bool = False, chat_keypad_type: Optional[Literal["New", "Remove", "None"]] = "None",parse_mode: Optional[Literal["HTML", "Markdown"]] = None,meta_data:Optional[dict] = None) -> Dict[str, Any]:
2200
+ return await self._send_file_generic("File", chat_id, path, file_id, text, file_name, inline_keypad, chat_keypad, reply_to_message_id, disable_notification, chat_keypad_type,parse_mode=parse_mode,meta_data=meta_data)
2201
+ async def send_file(self, chat_id: str, path: Optional[Union[str, Path]] = None, file_id: Optional[str] = None, caption: Optional[str] = None, file_name: Optional[str] = None, inline_keypad: Optional[Dict[str, Any]] = None, chat_keypad: Optional[Dict[str, Any]] = None, reply_to_message_id: Optional[str] = None, disable_notification: bool = False, chat_keypad_type: Optional[Literal["New", "Remove", "None"]] = "None",parse_mode: Optional[Literal["HTML", "Markdown"]] = None,meta_data:Optional[dict] = None) -> Dict[str, Any]:
2202
+ return await self._send_file_generic("File", chat_id, path, file_id, caption, file_name, inline_keypad, chat_keypad, reply_to_message_id, disable_notification, chat_keypad_type,parse_mode=parse_mode,meta_data=meta_data)
2203
+ async def re_send(self, chat_id: str, path: Optional[Union[str, Path]] = None, file_id: Optional[str] = None, caption: Optional[str] = None, file_name: Optional[str] = None, inline_keypad: Optional[Dict[str, Any]] = None, chat_keypad: Optional[Dict[str, Any]] = None, reply_to_message_id: Optional[str] = None, disable_notification: bool = False, chat_keypad_type: Optional[Literal["New", "Remove", "None"]] = "None",parse_mode: Optional[Literal["HTML", "Markdown"]] = None,meta_data:Optional[dict] = None) -> Dict[str, Any]:
2204
+ return await self._send_file_generic("File", chat_id, path, file_id, caption, file_name, inline_keypad, chat_keypad, reply_to_message_id, disable_notification, chat_keypad_type,parse_mode=parse_mode,meta_data=meta_data)
2205
+ async def send_video(self, chat_id: str, path: Optional[Union[str, Path]] = None, file_id: Optional[str] = None, text: Optional[str] = None, file_name: Optional[str] = None, inline_keypad: Optional[Dict[str, Any]] = None, chat_keypad: Optional[Dict[str, Any]] = None, reply_to_message_id: Optional[str] = None, disable_notification: bool = False, chat_keypad_type: Optional[Literal["New", "Remove", "None"]] = "None",parse_mode: Optional[Literal["HTML", "Markdown"]] = None,meta_data:Optional[dict] = None) -> Dict[str, Any]:
2206
+ return await self._send_file_generic("Video", chat_id, path, file_id, text, file_name, inline_keypad, chat_keypad, reply_to_message_id, disable_notification, chat_keypad_type,parse_mode=parse_mode,meta_data=meta_data)
2207
+ async def send_voice(self, chat_id: str, path: Optional[Union[str, Path]] = None, file_id: Optional[str] = None, text: Optional[str] = None, file_name: Optional[str] = None, inline_keypad: Optional[Dict[str, Any]] = None, chat_keypad: Optional[Dict[str, Any]] = None, reply_to_message_id: Optional[str] = None, disable_notification: bool = False, chat_keypad_type: Optional[Literal["New", "Remove", "None"]] = "None",parse_mode: Optional[Literal["HTML", "Markdown"]] = None,meta_data:Optional[dict] = None) -> Dict[str, Any]:
2208
+ return await self._send_file_generic("voice", chat_id, path, file_id, text, file_name, inline_keypad, chat_keypad, reply_to_message_id, disable_notification, chat_keypad_type,parse_mode=parse_mode,meta_data=meta_data)
2209
+ async def send_image(self, chat_id: str, path: Optional[Union[str, Path]] = None, file_id: Optional[str] = None, text: Optional[str] = None, file_name: Optional[str] = None, inline_keypad: Optional[Dict[str, Any]] = None, chat_keypad: Optional[Dict[str, Any]] = None, reply_to_message_id: Optional[str] = None, disable_notification: bool = False, chat_keypad_type: Optional[Literal["New", "Remove", "None"]] = "None",parse_mode: Optional[Literal["HTML", "Markdown"]] = None,meta_data:Optional[dict] = None) -> Dict[str, Any]:
2210
+ return await self._send_file_generic("Image", chat_id, path, file_id, text, file_name, inline_keypad, chat_keypad, reply_to_message_id, disable_notification, chat_keypad_type,parse_mode=parse_mode,meta_data=meta_data)
2195
2211
  async def send_music(
2196
2212
  self,
2197
2213
  chat_id: str,
@@ -2204,7 +2220,8 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
2204
2220
  reply_to_message_id: Optional[str] = None,
2205
2221
  disable_notification: bool = False,
2206
2222
  chat_keypad_type: Optional[Literal["New", "Remove", "None"]] = "None",
2207
- parse_mode: Optional[Literal["HTML", "Markdown"]] = None
2223
+ parse_mode: Optional[Literal["HTML", "Markdown"]] = None,
2224
+ meta_data:Optional[dict] = None
2208
2225
  ) -> Dict[str, Any]:
2209
2226
  valid_extensions = {"ogg", "oga", "opus", "flac"}
2210
2227
  extension = "flac"
@@ -2237,7 +2254,8 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
2237
2254
  reply_to_message_id,
2238
2255
  disable_notification,
2239
2256
  chat_keypad_type,
2240
- parse_mode=parse_mode
2257
+ parse_mode=parse_mode,
2258
+ meta_data=meta_data
2241
2259
  )
2242
2260
  async def send_gif(
2243
2261
  self,
@@ -2251,7 +2269,8 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
2251
2269
  reply_to_message_id: Optional[str] = None,
2252
2270
  disable_notification: bool = False,
2253
2271
  chat_keypad_type: Optional[Literal["New", "Remove", "None"]] = "None",
2254
- parse_mode: Optional[Literal["HTML", "Markdown"]] = None
2272
+ parse_mode: Optional[Literal["HTML", "Markdown"]] = None,
2273
+ meta_data:Optional[dict] = None
2255
2274
  ) -> Dict[str, Any]:
2256
2275
  valid_extensions = {"gif"}
2257
2276
  extension = "gif"
@@ -2284,7 +2303,7 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
2284
2303
  reply_to_message_id,
2285
2304
  disable_notification,
2286
2305
  chat_keypad_type,
2287
- parse_mode=parse_mode
2306
+ parse_mode=parse_mode,meta_data=meta_data
2288
2307
  )
2289
2308
 
2290
2309
  async def get_avatar_me(self, save_as: str = None) -> str:
@@ -2428,18 +2447,21 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
2428
2447
  return await self._post("leaveChat", {"chat_id": chat_id})
2429
2448
  async def forward_message(self, from_chat_id: str, message_id: str, to_chat_id: str, disable_notification: bool = False) -> Dict[str, Any]:
2430
2449
  return await self._post("forwardMessage", {"from_chat_id": from_chat_id, "message_id": message_id, "to_chat_id": to_chat_id, "disable_notification": disable_notification})
2431
- async def edit_message_text(self, chat_id: str, message_id: str, text: str, parse_mode: Optional[Literal["HTML", "Markdown"]] = None) -> Dict[str, Any]:
2450
+ async def edit_message_text(self, chat_id: str, message_id: str, text: str, parse_mode: Optional[Literal["HTML", "Markdown"]] = None,meta_data:Optional[dict] = None) -> Dict[str, Any]:
2432
2451
  payload = {
2433
2452
  "chat_id": chat_id,
2434
2453
  "message_id": message_id,
2435
2454
  "text": text,
2436
2455
  }
2437
- parse_mode_to_use = parse_mode or self.parse_mode
2438
- if text:
2439
- text, metadata = self._parse_text_metadata(text, parse_mode_to_use)
2440
- payload["text"] = text
2441
- if metadata:
2442
- payload["metadata"] = metadata
2456
+ if not meta_data:
2457
+ parse_mode_to_use = parse_mode or self.parse_mode
2458
+ if text:
2459
+ text, metadata = self._parse_text_metadata(text, parse_mode_to_use)
2460
+ payload["text"] = text
2461
+ if metadata:
2462
+ payload["metadata"] = metadata
2463
+ else :
2464
+ payload["metadata"] = meta_data
2443
2465
  return await self._post("editMessageText", payload)
2444
2466
  async def edit_inline_keypad(self,chat_id: str,message_id: str,inline_keypad: Dict[str, Any],text: str = None) -> Dict[str, Any]:
2445
2467
  if text is not None:await self._post("editMessageText", {"chat_id": chat_id,"message_id": message_id,"text": text})
@@ -2512,4 +2534,11 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
2512
2534
  result = await asyncio.to_thread(self.get_all_member, channel_guid, search_text=first_name)
2513
2535
  members = result.get('in_chat_members', [])
2514
2536
  return any(m.get('first_name') == first_name for m in members)
2515
- return False
2537
+ return False
2538
+
2539
+ class Bot(Robot):
2540
+ pass
2541
+ class bot(Robot):
2542
+ pass
2543
+ class robot(Robot):
2544
+ pass
rubka/context.py CHANGED
@@ -288,6 +288,7 @@ class Message:
288
288
  self.is_audio = None
289
289
  self.is_voice = None
290
290
  self.is_document = None
291
+ self.is_music = None
291
292
  self.is_archive = None
292
293
  self.is_executable = None
293
294
  self.is_font = None
@@ -356,6 +357,7 @@ class Message:
356
357
  self.is_photo = name.endswith((".jpg", ".jpeg", ".png", ".gif", ".webp"))
357
358
  self.is_video = name.endswith((".mp4", ".mov", ".avi", ".mkv", ".webm"))
358
359
  self.is_audio = name.endswith((".mp3", ".wav", ".ogg", ".m4a", ".flac"))
360
+ self.is_music = name.endswith((".mp3", ".wav", ".ogg", ".m4a", ".flac"))
359
361
  self.is_voice = name.endswith((".ogg", ".m4a"))
360
362
  self.is_document = name.endswith((".pdf", ".doc", ".docx", ".txt", ".xls", ".xlsx", ".ppt", ".pptx"))
361
363
  self.is_archive = name.endswith((".zip", ".rar", ".7z", ".tar", ".gz"))
@@ -437,8 +439,32 @@ class Message:
437
439
  reply_to_message_id=self.message_id,
438
440
  **kwargs
439
441
  )
440
-
441
-
442
+ async def copy(self, to_chat_id: Optional[str], message_id: Optional[str] = None):await self.copy_message(to_chat_id, message_id)
443
+ async def copy_message(self, to_chat_id: Optional[str], message_id: Optional[str] = None):
444
+ try:
445
+ send_func = None
446
+ kwargs = {
447
+ "chat_id": to_chat_id,
448
+ "reply_to_message_id": message_id,
449
+ "meta_data": self.metadata
450
+ }
451
+ if getattr(self, "is_photo", False):
452
+ send_func = self.bot.send_image
453
+ elif getattr(self, "is_video", False):
454
+ send_func = self.bot.send_video
455
+ elif getattr(self, "is_document", False):
456
+ send_func = self.bot.send_document
457
+ elif getattr(self, "is_text", False):
458
+ send_func = self.bot.send_message
459
+ kwargs["text"] = self.text
460
+ if send_func:
461
+ if hasattr(self, "file") and self.file:
462
+ kwargs["path"] = await self.bot.get_url_file(self.file.file_id)
463
+ return await send_func(**kwargs)
464
+ else:
465
+ raise Exception("Unsupported message type.")
466
+ except Exception as e:
467
+ raise Exception(f"Error: {e}")
442
468
  def reply_poll(
443
469
  self,
444
470
  question: str,
rubka/filters.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import Callable
1
+ from typing import Callable,Union
2
2
  import re
3
3
  class TextFilter:
4
4
  def __call__(self, keyword=None):
@@ -244,9 +244,18 @@ def chat_title_equals(value: str):
244
244
 
245
245
  return Filter(lambda m: getattr(m, "chat", None) and getattr(m.chat, "title", "") == value)
246
246
 
247
- def chat_id_is(cid: str):
248
- return Filter(lambda m: getattr(m, "chat", None) and getattr(m.chat, "id", None) == cid)
249
-
247
+ def chat_id_is(sender_id: str):
248
+ return Filter(lambda m: getattr(m, "chat_id", None) == sender_id)
249
+ def sender_id_is(sender_id: str):
250
+ return Filter(lambda m: getattr(m, "sender_id", None) == sender_id)
251
+ def senders_id(sender_ids: Union[str, list]):
252
+ if isinstance(sender_ids, list):
253
+ return Filter(lambda m: getattr(m, "sender_id", None) in sender_ids)
254
+ return Filter(lambda m: getattr(m, "sender_id", None) == sender_ids)
255
+ def chat_ids(sender_ids: Union[str, list]):
256
+ if isinstance(sender_ids, list):
257
+ return Filter(lambda m: getattr(m, "chat_id", None) in sender_ids)
258
+ return Filter(lambda m: getattr(m, "chat_id", None) == sender_ids)
250
259
  def chat_member_count(min_count: int = 0, max_count: int = None):
251
260
 
252
261
  def _filter(m):
rubka/rubino.py CHANGED
@@ -1228,4 +1228,44 @@ class Bot():
1228
1228
  "limit": limit,
1229
1229
  "sort": sort
1230
1230
  }
1231
- return self._reuests_post("getNewFollowRequests", data=payload)
1231
+ return self._reuests_post("getNewFollowRequests", data=payload)
1232
+ def get_myprofile_posts(
1233
+ self,
1234
+ profile_id: Optional[str] = None ,
1235
+ limit: int = 20,
1236
+ sort: str = "FromMax"
1237
+ ) -> Dict[str, Any]:
1238
+ payload = {
1239
+ "profile_id": profile_id,
1240
+ "limit": limit,
1241
+ "sort": sort
1242
+ }
1243
+ return self._reuests_post("getMyProfilePosts", data=payload)
1244
+ def get_recent_following_posts(
1245
+ self,
1246
+ profile_id: Optional[str] = None ,
1247
+ limit: int = 20,
1248
+ sort: str = "FromMax"
1249
+ ) -> Dict[str, Any]:
1250
+ payload = {
1251
+ "profile_id": profile_id,
1252
+ "limit": limit,
1253
+ "sort": sort
1254
+ }
1255
+ return self._reuests_post("getRecentFollowingPosts", data=payload)
1256
+ def get_explore_post_topics(
1257
+ self,
1258
+ profile_id: Optional[str] = None ,
1259
+ ) -> Dict[str, Any]:
1260
+ payload = {
1261
+ "profile_id": profile_id,
1262
+ }
1263
+ return self._reuests_post("getExplorePostTopics", data=payload)
1264
+ def get_profiles_stories(
1265
+ self,
1266
+ profile_id: Optional[str] = None ,
1267
+ ) -> Dict[str, Any]:
1268
+ payload = {
1269
+ "profile_id": profile_id,
1270
+ }
1271
+ return self._reuests_post("getProfilesStories", data=payload)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Rubka
3
- Version: 7.1.17
3
+ Version: 7.2.2
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
@@ -1,19 +1,19 @@
1
- rubka/__init__.py,sha256=P6IBiORfp-GqKHe5LZ-5lldWyG7tnrUYUcAQDUgwXmY,1973
1
+ rubka/__init__.py,sha256=wNKEZ2JKPY9lPb5qGJs_JPxDimzQ_V-jJR3HUCdKekk,1962
2
2
  rubka/api.py,sha256=71B10uy2iU3gP6yHQltjyTkq2mgkzWuV1TsE2kgHOZg,68092
3
- rubka/asynco.py,sha256=KRYnEyB6y49VwwC6Xp-42dPVukacCwnQs9tlSRlJU9w,120288
3
+ rubka/asynco.py,sha256=-27KRNkshnj6DmDCxWIu3tJ78M0s68qN9ZECrf8noxM,121769
4
4
  rubka/button.py,sha256=woSzZVd5MtTqOrP-YgkH5b0GS9y4DuKBsFSc9-KuLnk,13320
5
5
  rubka/config.py,sha256=Bck59xkOiqioLv0GkQ1qPGnBXVctz1hKk6LT4h2EPx0,78
6
- rubka/context.py,sha256=brl7WXe4nzpLpcaMiOLVMfOs8BFTU5z5Sw6AIecCtOA,42492
6
+ rubka/context.py,sha256=rvdnZYDcOIEvQhl3fAt2HfTw2IGozCtHffhCk_56FEQ,43879
7
7
  rubka/decorators.py,sha256=hGwUoE4q2ImrunJIGJ_kzGYYxQf1ueE0isadqraKEts,1157
8
8
  rubka/exceptions.py,sha256=DDOGIHEMoliHNW5E7C_s38WZgqqMBv9812fcJGvj7TY,1173
9
- rubka/filters.py,sha256=fQYgFKhXfq18pOzjkKc3BmOgoZqQKriid_SAQR5uVT4,13254
9
+ rubka/filters.py,sha256=fMoQbEL-XujnjAuheGni_zaElkXUh6zsjgayX7CIolg,13817
10
10
  rubka/helpers.py,sha256=QvK5lg4QDmycImxJia4m8HDpfacYzbKKZiOk536mafc,65161
11
11
  rubka/jobs.py,sha256=GvLMLsVhcSEzRTgkvnPISPEBN71suW2xXI0hUaUZPTo,378
12
12
  rubka/keyboards.py,sha256=7nr-dT2bQJVQnQ6RMWPTSjML6EEk6dsBx-4d8pab8xk,488
13
13
  rubka/keypad.py,sha256=yGsNt8W5HtUFBzVF1m_p7GySlu1hwIcSvXZ4BTdrlvg,9558
14
14
  rubka/logger.py,sha256=J2I6NiK1z32lrAzC4H1Et6WPMBXxXGCVUsW4jgcAofs,289
15
15
  rubka/metadata.py,sha256=RWle8mwWAcIFVAETHzRPD3vCwqPidB0ERsMatQY8h_w,4329
16
- rubka/rubino.py,sha256=HOILsm2zOIRe9EW1hxhLinhjwE_TvFrOAxBsg9T_L5E,61701
16
+ rubka/rubino.py,sha256=3JoQueC260UG_RCabjX8KGRykhqHV8TONN1O-twAXZw,62971
17
17
  rubka/tv.py,sha256=rBoyCadCH3I3YqQGrQYv_dLtTg1I63AzVf1orn-hbko,5724
18
18
  rubka/update.py,sha256=brl7WXe4nzpLpcaMiOLVMfOs8BFTU5z5Sw6AIecCtOA,42492
19
19
  rubka/utils.py,sha256=XUQUZxQt9J2f0X5hmAH_MH1kibTAfdT1T4AaBkBhBBs,148
@@ -38,8 +38,8 @@ rubka/adaptorrubka/types/socket/message.py,sha256=0WgLMZh4eow8Zn7AiSX4C3GZjQTkIg
38
38
  rubka/adaptorrubka/utils/__init__.py,sha256=OgCFkXdNFh379quNwIVOAWY2NP5cIOxU5gDRRALTk4o,54
39
39
  rubka/adaptorrubka/utils/configs.py,sha256=nMUEOJh1NqDJsf9W9PurkN_DLYjO6kKPMm923i4Jj_A,492
40
40
  rubka/adaptorrubka/utils/utils.py,sha256=5-LioLNYX_TIbQGDeT50j7Sg9nAWH2LJUUs-iEXpsUY,8816
41
- rubka-7.1.17.dist-info/METADATA,sha256=AGwgmYuMwUYRTEVhvDfDKXk3qeA4Q3BYJbEEAoWMsg8,34673
42
- rubka-7.1.17.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
43
- rubka-7.1.17.dist-info/entry_points.txt,sha256=4aESuUmuUOALMUy7Kucv_Gb5YlqhsJmTmdXLlZU9sJ0,46
44
- rubka-7.1.17.dist-info/top_level.txt,sha256=vy2A4lot11cRMdQS-F4HDCIXL3JK8RKfu7HMDkezJW4,6
45
- rubka-7.1.17.dist-info/RECORD,,
41
+ rubka-7.2.2.dist-info/METADATA,sha256=8VS4kIm9YGoa_0PSGg5zSwCzGU1jrEhCwaX6I58L8Jg,34672
42
+ rubka-7.2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
43
+ rubka-7.2.2.dist-info/entry_points.txt,sha256=4aESuUmuUOALMUy7Kucv_Gb5YlqhsJmTmdXLlZU9sJ0,46
44
+ rubka-7.2.2.dist-info/top_level.txt,sha256=vy2A4lot11cRMdQS-F4HDCIXL3JK8RKfu7HMDkezJW4,6
45
+ rubka-7.2.2.dist-info/RECORD,,
File without changes