Rubka 6.8.5__py3-none-any.whl → 7.1.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.
Potentially problematic release.
This version of Rubka might be problematic. Click here for more details.
- rubka/api.py +2 -1
- rubka/asynco.py +154 -12
- rubka/button.py +1 -1
- rubka/context.py +63 -19
- rubka/rubino.py +4 -1
- rubka/tv.py +2 -0
- rubka/update.py +64 -10
- {rubka-6.8.5.dist-info → rubka-7.1.2.dist-info}/METADATA +2 -1
- {rubka-6.8.5.dist-info → rubka-7.1.2.dist-info}/RECORD +12 -12
- {rubka-6.8.5.dist-info → rubka-7.1.2.dist-info}/WHEEL +0 -0
- {rubka-6.8.5.dist-info → rubka-7.1.2.dist-info}/entry_points.txt +0 -0
- {rubka-6.8.5.dist-info → rubka-7.1.2.dist-info}/top_level.txt +0 -0
rubka/api.py
CHANGED
|
@@ -1016,7 +1016,8 @@ class Robot:
|
|
|
1016
1016
|
inline_keypad: Optional[Dict[str, Any]] = None,
|
|
1017
1017
|
disable_notification: bool = False,
|
|
1018
1018
|
reply_to_message_id: Optional[str] = None,
|
|
1019
|
-
chat_keypad_type: Optional[Literal["New", "Removed"]] = None
|
|
1019
|
+
chat_keypad_type: Optional[Literal["New", "Removed"]] = None,
|
|
1020
|
+
delete_after = None
|
|
1020
1021
|
) -> Dict[str, Any]:
|
|
1021
1022
|
"""
|
|
1022
1023
|
Send a text message to a chat.
|
rubka/asynco.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import asyncio,aiohttp,aiofiles,time,datetime,json,tempfile,os,sys,subprocess,mimetypes,time, hashlib
|
|
1
|
+
import asyncio,aiohttp,aiofiles,time,datetime,json,tempfile,os,sys,subprocess,mimetypes,time, hashlib,sqlite3
|
|
2
2
|
from typing import List, Optional, Dict, Any, Literal, Callable, Union,Set
|
|
3
3
|
from collections import OrderedDict
|
|
4
4
|
from .exceptions import APIRequestError,raise_for_status,InvalidAccessError,InvalidInputError,TooRequestError,InvalidTokenError
|
|
@@ -8,6 +8,8 @@ from .rubino import Bot as Rubino
|
|
|
8
8
|
from . import filters
|
|
9
9
|
try:from .context import Message, InlineMessage
|
|
10
10
|
except (ImportError, ModuleNotFoundError):from context import Message, InlineMessage
|
|
11
|
+
try:from .button import ChatKeypadBuilder, InlineBuilder
|
|
12
|
+
except (ImportError, ModuleNotFoundError):from button import ChatKeypadBuilder, InlineBuilder
|
|
11
13
|
class FeatureNotAvailableError(Exception):
|
|
12
14
|
pass
|
|
13
15
|
|
|
@@ -19,7 +21,6 @@ from tqdm import tqdm
|
|
|
19
21
|
API_URL = "https://botapi.rubika.ir/v3"
|
|
20
22
|
|
|
21
23
|
def install_package(package_name: str) -> bool:
|
|
22
|
-
"""Installs a package using pip."""
|
|
23
24
|
try:
|
|
24
25
|
subprocess.check_call([sys.executable, "-m", "pip", "install", package_name], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
25
26
|
return True
|
|
@@ -27,7 +28,6 @@ def install_package(package_name: str) -> bool:
|
|
|
27
28
|
return False
|
|
28
29
|
|
|
29
30
|
def get_importlib_metadata():
|
|
30
|
-
"""Dynamically imports and returns metadata functions from importlib."""
|
|
31
31
|
try:
|
|
32
32
|
from importlib.metadata import version, PackageNotFoundError
|
|
33
33
|
return version, PackageNotFoundError
|
|
@@ -43,7 +43,6 @@ def get_importlib_metadata():
|
|
|
43
43
|
version, PackageNotFoundError = get_importlib_metadata()
|
|
44
44
|
|
|
45
45
|
def get_installed_version(package_name: str) -> Optional[str]:
|
|
46
|
-
"""Gets the installed version of a package."""
|
|
47
46
|
if version is None:
|
|
48
47
|
return "unknown"
|
|
49
48
|
try:
|
|
@@ -52,7 +51,6 @@ def get_installed_version(package_name: str) -> Optional[str]:
|
|
|
52
51
|
return None
|
|
53
52
|
|
|
54
53
|
async def get_latest_version(package_name: str) -> Optional[str]:
|
|
55
|
-
"""Fetches the latest version of a package from PyPI asynchronously."""
|
|
56
54
|
url = f"https://pypi.org/pypi/{package_name}/json"
|
|
57
55
|
try:
|
|
58
56
|
async with aiohttp.ClientSession() as session:
|
|
@@ -64,7 +62,6 @@ async def get_latest_version(package_name: str) -> Optional[str]:
|
|
|
64
62
|
return None
|
|
65
63
|
|
|
66
64
|
async def check_rubka_version():
|
|
67
|
-
"""Checks for outdated 'rubka' package and warns the user."""
|
|
68
65
|
package_name = "rubka"
|
|
69
66
|
installed_version = get_installed_version(package_name)
|
|
70
67
|
if installed_version is None:
|
|
@@ -87,7 +84,6 @@ async def check_rubka_version():
|
|
|
87
84
|
|
|
88
85
|
|
|
89
86
|
def show_last_six_words(text: str) -> str:
|
|
90
|
-
"""Returns the last 6 characters of a stripped string."""
|
|
91
87
|
text = text.strip()
|
|
92
88
|
return text[-6:]
|
|
93
89
|
class AttrDict(dict):
|
|
@@ -170,12 +166,16 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
|
|
|
170
166
|
self._max_cache_size = max_cache_size
|
|
171
167
|
self._callback_handlers: List[dict] = []
|
|
172
168
|
self._edited_message_handlers = []
|
|
169
|
+
self._message_saver_enabled = False
|
|
170
|
+
self._max_messages = None
|
|
171
|
+
self._db_path = os.path.join(os.getcwd(), "RubkaSaveMessage.db")
|
|
172
|
+
self._ensure_db()
|
|
173
173
|
self._message_handlers: List[dict] = []
|
|
174
174
|
|
|
175
175
|
logger.info(f"Initialized RubikaBot with token: {token[:8]}***")
|
|
176
176
|
async def _get_session(self) -> aiohttp.ClientSession:
|
|
177
177
|
if self._aiohttp_session is None or self._aiohttp_session.closed:
|
|
178
|
-
connector = aiohttp.TCPConnector(limit=100, ssl=False)
|
|
178
|
+
connector = aiohttp.TCPConnector(limit=100, ssl=False)
|
|
179
179
|
timeout = aiohttp.ClientTimeout(total=self.timeout)
|
|
180
180
|
self._aiohttp_session = aiohttp.ClientSession(connector=connector, timeout=timeout)
|
|
181
181
|
return self._aiohttp_session
|
|
@@ -251,15 +251,157 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
|
|
|
251
251
|
raw = f"{message_id}:{update_type}:{msg_data.get('text','')}:{msg_data.get('author_guid','')}"
|
|
252
252
|
return hashlib.sha1(raw.encode()).hexdigest()
|
|
253
253
|
async def get_me(self) -> Dict[str, Any]:
|
|
254
|
-
"""Get info about the bot itself."""
|
|
255
254
|
return await self._post("getMe", {})
|
|
256
255
|
async def geteToken(self):
|
|
257
|
-
"""Check if the bot token is valid."""
|
|
258
256
|
if (await self.get_me())['status'] != "OK":
|
|
259
257
|
raise InvalidTokenError("The provided bot token is invalid or expired.")
|
|
260
258
|
from typing import Callable, Any, Optional, List
|
|
261
259
|
|
|
262
260
|
|
|
261
|
+
#save message database __________________________
|
|
262
|
+
|
|
263
|
+
def _ensure_db(self):
|
|
264
|
+
conn = sqlite3.connect(self._db_path)
|
|
265
|
+
cur = conn.cursor()
|
|
266
|
+
cur.execute("""
|
|
267
|
+
CREATE TABLE IF NOT EXISTS messages (
|
|
268
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
269
|
+
chat_id TEXT NOT NULL,
|
|
270
|
+
message_id TEXT NOT NULL,
|
|
271
|
+
sender_id TEXT,
|
|
272
|
+
text TEXT,
|
|
273
|
+
raw_data TEXT,
|
|
274
|
+
time TEXT,
|
|
275
|
+
saved_at INTEGER
|
|
276
|
+
);
|
|
277
|
+
""")
|
|
278
|
+
cur.execute("CREATE UNIQUE INDEX IF NOT EXISTS idx_chat_message ON messages(chat_id, message_id);")
|
|
279
|
+
conn.commit()
|
|
280
|
+
conn.close()
|
|
281
|
+
|
|
282
|
+
def _insert_message(self, record: dict):
|
|
283
|
+
conn = sqlite3.connect(self._db_path)
|
|
284
|
+
cur = conn.cursor()
|
|
285
|
+
cur.execute("""
|
|
286
|
+
INSERT OR IGNORE INTO messages
|
|
287
|
+
(chat_id, message_id, sender_id, text, raw_data, time, saved_at)
|
|
288
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
289
|
+
""", (
|
|
290
|
+
record.get("chat_id"),
|
|
291
|
+
record.get("message_id"),
|
|
292
|
+
record.get("sender_id"),
|
|
293
|
+
record.get("text"),
|
|
294
|
+
json.dumps(record.get("raw_data") or {}, ensure_ascii=False),
|
|
295
|
+
record.get("time"),
|
|
296
|
+
int(time.time())
|
|
297
|
+
))
|
|
298
|
+
conn.commit()
|
|
299
|
+
if getattr(self, "_max_messages", None) is not None:
|
|
300
|
+
cur.execute("SELECT COUNT(*) FROM messages")
|
|
301
|
+
total = cur.fetchone()[0]
|
|
302
|
+
if total > self._max_messages:
|
|
303
|
+
remove_count = total - self._max_messages
|
|
304
|
+
cur.execute(
|
|
305
|
+
"DELETE FROM messages WHERE id IN (SELECT id FROM messages ORDER BY saved_at ASC LIMIT ?)",
|
|
306
|
+
(remove_count,)
|
|
307
|
+
)
|
|
308
|
+
conn.commit()
|
|
309
|
+
|
|
310
|
+
conn.close()
|
|
311
|
+
|
|
312
|
+
def _fetch_message(self, chat_id: str, message_id: str):
|
|
313
|
+
conn = sqlite3.connect(self._db_path)
|
|
314
|
+
cur = conn.cursor()
|
|
315
|
+
cur.execute(
|
|
316
|
+
"SELECT chat_id, message_id, sender_id, text, raw_data, time, saved_at FROM messages WHERE chat_id=? AND message_id=?",
|
|
317
|
+
(chat_id, message_id)
|
|
318
|
+
)
|
|
319
|
+
row = cur.fetchone()
|
|
320
|
+
conn.close()
|
|
321
|
+
if not row:
|
|
322
|
+
return None
|
|
323
|
+
chat_id, message_id, sender_id, text, raw_data_json, time_val, saved_at = row
|
|
324
|
+
try:
|
|
325
|
+
raw = json.loads(raw_data_json)
|
|
326
|
+
except:
|
|
327
|
+
raw = {}
|
|
328
|
+
return {
|
|
329
|
+
"chat_id": chat_id,
|
|
330
|
+
"message_id": message_id,
|
|
331
|
+
"sender_id": sender_id,
|
|
332
|
+
"text": text,
|
|
333
|
+
"raw_data": raw,
|
|
334
|
+
"time": time_val,
|
|
335
|
+
"saved_at": saved_at
|
|
336
|
+
}
|
|
337
|
+
async def save_message(self, message: Message):
|
|
338
|
+
try:
|
|
339
|
+
record = {
|
|
340
|
+
"chat_id": getattr(message, "chat_id", None),
|
|
341
|
+
"message_id": getattr(message, "message_id", None),
|
|
342
|
+
"sender_id": getattr(message, "author_guid", None),
|
|
343
|
+
"text": getattr(message, "text", None),
|
|
344
|
+
"raw_data": getattr(message, "raw_data", {}),
|
|
345
|
+
"time": getattr(message, "time", None),
|
|
346
|
+
}
|
|
347
|
+
await asyncio.to_thread(self._insert_message, record)
|
|
348
|
+
except Exception as e:
|
|
349
|
+
print(f"[DB] Error saving message: {e}")
|
|
350
|
+
|
|
351
|
+
async def get_message(self, chat_id: str, message_id: str):
|
|
352
|
+
return await asyncio.to_thread(self._fetch_message, chat_id, message_id)
|
|
353
|
+
|
|
354
|
+
def start_save_message(self, max_messages: int = 1000):
|
|
355
|
+
if self._message_saver_enabled:
|
|
356
|
+
return
|
|
357
|
+
self._message_saver_enabled = True
|
|
358
|
+
self._max_messages = max_messages
|
|
359
|
+
decorators = [
|
|
360
|
+
"on_message", "on_edited_message", "on_message_file", "on_message_forwarded",
|
|
361
|
+
"on_message_reply", "on_message_text", "on_update", "on_callback",
|
|
362
|
+
"on_callback_query", "callback_query_handler", "callback_query",
|
|
363
|
+
"on_inline_query", "on_inline_query_prefix", "on_message_private", "on_message_group"
|
|
364
|
+
]
|
|
365
|
+
|
|
366
|
+
for decorator_name in decorators:
|
|
367
|
+
if hasattr(self, decorator_name):
|
|
368
|
+
original_decorator = getattr(self, decorator_name)
|
|
369
|
+
|
|
370
|
+
def make_wrapper(orig_decorator):
|
|
371
|
+
def wrapper(*args, **kwargs):
|
|
372
|
+
decorator = orig_decorator(*args, **kwargs)
|
|
373
|
+
def inner_wrapper(func):
|
|
374
|
+
async def inner(bot, message, *a, **kw):
|
|
375
|
+
try:
|
|
376
|
+
await bot.save_message(message)
|
|
377
|
+
if getattr(self, "_max_messages", None) is not None:
|
|
378
|
+
await asyncio.to_thread(self._prune_old_messages)
|
|
379
|
+
except Exception as e:
|
|
380
|
+
print(f"[DB] Save error: {e}")
|
|
381
|
+
return await func(bot, message, *a, **kw)
|
|
382
|
+
return decorator(inner)
|
|
383
|
+
return inner_wrapper
|
|
384
|
+
return wrapper
|
|
385
|
+
|
|
386
|
+
setattr(self, decorator_name, make_wrapper(original_decorator))
|
|
387
|
+
def _prune_old_messages(self):
|
|
388
|
+
if not hasattr(self, "_max_messages") or self._max_messages is None:
|
|
389
|
+
return
|
|
390
|
+
conn = sqlite3.connect(self._db_path)
|
|
391
|
+
cur = conn.cursor()
|
|
392
|
+
cur.execute("SELECT COUNT(*) FROM messages")
|
|
393
|
+
total = cur.fetchone()[0]
|
|
394
|
+
if total > self._max_messages:
|
|
395
|
+
remove_count = total - self._max_messages
|
|
396
|
+
cur.execute(
|
|
397
|
+
"DELETE FROM messages WHERE id IN (SELECT id FROM messages ORDER BY saved_at ASC LIMIT ?)",
|
|
398
|
+
(remove_count,)
|
|
399
|
+
)
|
|
400
|
+
conn.commit()
|
|
401
|
+
conn.close()
|
|
402
|
+
|
|
403
|
+
#save message database __________________________ end
|
|
404
|
+
|
|
263
405
|
#decorator#
|
|
264
406
|
|
|
265
407
|
def on_message_private(
|
|
@@ -852,7 +994,7 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
|
|
|
852
994
|
asyncio.create_task(handler_info["func"](self, context))
|
|
853
995
|
continue
|
|
854
996
|
if handler_info["commands"] or handler_info["filters"]:
|
|
855
|
-
asyncio.create_task(handler_info["func"](self, context))#
|
|
997
|
+
asyncio.create_task(handler_info["func"](self, context))#kir baba kir
|
|
856
998
|
continue
|
|
857
999
|
elif update.get("type") == "UpdatedMessage":
|
|
858
1000
|
msg = update.get("updated_message", {})
|
|
@@ -912,7 +1054,7 @@ max_cache_size and max_msg_age help manage duplicate message processing efficien
|
|
|
912
1054
|
async def run(
|
|
913
1055
|
self,
|
|
914
1056
|
debug: bool = False,
|
|
915
|
-
sleep_time: float = 0.
|
|
1057
|
+
sleep_time: float = 0.1,
|
|
916
1058
|
webhook_timeout: int = 20,
|
|
917
1059
|
update_limit: int = 100,
|
|
918
1060
|
retry_delay: float = 5.0,
|
rubka/button.py
CHANGED
rubka/context.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Any, Dict, List,Optional
|
|
2
2
|
from typing import Union
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
import re
|
|
4
|
+
import re,inspect
|
|
5
5
|
import asyncio
|
|
6
6
|
class File:
|
|
7
7
|
def __init__(self, data: dict):
|
|
@@ -265,24 +265,68 @@ class Message:
|
|
|
265
265
|
self.bot.sessions[self.chat_id] = {}
|
|
266
266
|
return self.bot.sessions[self.chat_id]
|
|
267
267
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
self.
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
268
|
+
def reply(self, text: str, delete_after: int = None, **kwargs):
|
|
269
|
+
async def _reply_async():
|
|
270
|
+
send_func = self.bot.send_message
|
|
271
|
+
if inspect.iscoroutinefunction(send_func):
|
|
272
|
+
msg = await send_func(
|
|
273
|
+
self.chat_id,
|
|
274
|
+
text,
|
|
275
|
+
reply_to_message_id=self.message_id,
|
|
276
|
+
delete_after=delete_after,
|
|
277
|
+
**kwargs
|
|
278
|
+
)
|
|
279
|
+
else:
|
|
280
|
+
msg = send_func(
|
|
281
|
+
self.chat_id,
|
|
282
|
+
text,
|
|
283
|
+
reply_to_message_id=self.message_id,
|
|
284
|
+
delete_after=delete_after,
|
|
285
|
+
**kwargs
|
|
286
|
+
)
|
|
287
|
+
class Pick:
|
|
288
|
+
def __init__(self, bot, chat_id, message_id):
|
|
289
|
+
self.bot = bot
|
|
290
|
+
self.chat_id = chat_id
|
|
291
|
+
self.message_id = message_id
|
|
292
|
+
|
|
293
|
+
def edit(self, new_text):
|
|
294
|
+
async def _edit():
|
|
295
|
+
func = self.bot.edit_message_text
|
|
296
|
+
if inspect.iscoroutinefunction(func):
|
|
297
|
+
await func(self.chat_id, self.message_id, new_text)
|
|
298
|
+
else:
|
|
299
|
+
func(self.chat_id, self.message_id, new_text)
|
|
300
|
+
|
|
301
|
+
try:
|
|
302
|
+
loop = asyncio.get_running_loop()
|
|
303
|
+
if loop.is_running():
|
|
304
|
+
return asyncio.create_task(_edit())
|
|
305
|
+
except RuntimeError:
|
|
306
|
+
return asyncio.run(_edit())
|
|
307
|
+
|
|
308
|
+
def delete(self):
|
|
309
|
+
async def _delete():
|
|
310
|
+
func = self.bot.delete_message
|
|
311
|
+
if inspect.iscoroutinefunction(func):
|
|
312
|
+
await func(self.chat_id, self.message_id)
|
|
313
|
+
else:
|
|
314
|
+
func(self.chat_id, self.message_id)
|
|
315
|
+
try:
|
|
316
|
+
loop = asyncio.get_running_loop()
|
|
317
|
+
if loop.is_running():
|
|
318
|
+
return asyncio.create_task(_delete())
|
|
319
|
+
except RuntimeError:
|
|
320
|
+
return asyncio.run(_delete())
|
|
321
|
+
chat_id = msg.get("chat_id") if isinstance(msg, dict) else getattr(msg, "chat_id", self.chat_id)
|
|
322
|
+
message_id = msg.get("message_id") if isinstance(msg, dict) else getattr(msg, "message_id", self.message_id)
|
|
323
|
+
return Pick(self.bot, chat_id, message_id)
|
|
324
|
+
try:
|
|
325
|
+
loop = asyncio.get_running_loop()
|
|
326
|
+
if loop.is_running():
|
|
327
|
+
return asyncio.create_task(_reply_async())
|
|
328
|
+
except RuntimeError:
|
|
329
|
+
return asyncio.run(_reply_async())
|
|
286
330
|
def answer(self, text: str, **kwargs):
|
|
287
331
|
return self.bot.send_message(
|
|
288
332
|
self.chat_id,
|
rubka/rubino.py
CHANGED
|
@@ -426,8 +426,11 @@ def _req(term, results, lang, start, proxies, timeout):
|
|
|
426
426
|
import random
|
|
427
427
|
|
|
428
428
|
class Bot():
|
|
429
|
-
"""rubino class"""
|
|
429
|
+
"""rubino class Regester m.rubika.ir"""
|
|
430
430
|
def __init__(self,auth,platform="m.rubika.ir",lang_code="fa") -> None:
|
|
431
|
+
"""
|
|
432
|
+
regester m.rubika.ir
|
|
433
|
+
"""
|
|
431
434
|
self.auth=auth
|
|
432
435
|
self.platform=platform
|
|
433
436
|
self.lang_code=lang_code
|
rubka/tv.py
CHANGED
|
@@ -28,6 +28,8 @@ class TV:
|
|
|
28
28
|
- auth: توکن احراز هویت حساب کاربری
|
|
29
29
|
- proxy: پراکسی برای ارسال درخواستها (اختیاری)
|
|
30
30
|
- headers: هدرهای سفارشی برای ارسال درخواستها (اختیاری)
|
|
31
|
+
# نکته:
|
|
32
|
+
https://vod.rubika.ir/
|
|
31
33
|
"""
|
|
32
34
|
self.auth = auth
|
|
33
35
|
self.headers = headers if headers is not None else self.DEFAULT_HEADERS
|
rubka/update.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Any, Dict, List,Optional
|
|
2
2
|
from typing import Union
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
import re
|
|
4
|
+
import re,inspect
|
|
5
5
|
import asyncio
|
|
6
6
|
class File:
|
|
7
7
|
def __init__(self, data: dict):
|
|
@@ -259,20 +259,74 @@ class Message:
|
|
|
259
259
|
self.is_archive = name.endswith((".zip", ".rar", ".7z", ".tar", ".gz"))
|
|
260
260
|
self.is_executable = name.endswith((".exe", ".msi", ".bat", ".sh"))
|
|
261
261
|
self.is_font = name.endswith((".ttf", ".otf", ".woff", ".woff2"))
|
|
262
|
-
self.info = {attr: value for attr, value in vars(self).items()}
|
|
263
262
|
@property
|
|
264
263
|
def session(self):
|
|
265
264
|
if self.chat_id not in self.bot.sessions:
|
|
266
265
|
self.bot.sessions[self.chat_id] = {}
|
|
267
266
|
return self.bot.sessions[self.chat_id]
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
267
|
+
|
|
268
|
+
def reply(self, text: str, delete_after: int = None, **kwargs):
|
|
269
|
+
async def _reply_async():
|
|
270
|
+
send_func = self.bot.send_message
|
|
271
|
+
if inspect.iscoroutinefunction(send_func):
|
|
272
|
+
msg = await send_func(
|
|
273
|
+
self.chat_id,
|
|
274
|
+
text,
|
|
275
|
+
reply_to_message_id=self.message_id,
|
|
276
|
+
delete_after=delete_after,
|
|
277
|
+
**kwargs
|
|
278
|
+
)
|
|
279
|
+
else:
|
|
280
|
+
msg = send_func(
|
|
281
|
+
self.chat_id,
|
|
282
|
+
text,
|
|
283
|
+
reply_to_message_id=self.message_id,
|
|
284
|
+
delete_after=delete_after,
|
|
285
|
+
**kwargs
|
|
286
|
+
)
|
|
287
|
+
class Pick:
|
|
288
|
+
def __init__(self, bot, chat_id, message_id):
|
|
289
|
+
self.bot = bot
|
|
290
|
+
self.chat_id = chat_id
|
|
291
|
+
self.message_id = message_id
|
|
292
|
+
|
|
293
|
+
def edit(self, new_text):
|
|
294
|
+
async def _edit():
|
|
295
|
+
func = self.bot.edit_message_text
|
|
296
|
+
if inspect.iscoroutinefunction(func):
|
|
297
|
+
await func(self.chat_id, self.message_id, new_text)
|
|
298
|
+
else:
|
|
299
|
+
func(self.chat_id, self.message_id, new_text)
|
|
300
|
+
|
|
301
|
+
try:
|
|
302
|
+
loop = asyncio.get_running_loop()
|
|
303
|
+
if loop.is_running():
|
|
304
|
+
return asyncio.create_task(_edit())
|
|
305
|
+
except RuntimeError:
|
|
306
|
+
return asyncio.run(_edit())
|
|
307
|
+
|
|
308
|
+
def delete(self):
|
|
309
|
+
async def _delete():
|
|
310
|
+
func = self.bot.delete_message
|
|
311
|
+
if inspect.iscoroutinefunction(func):
|
|
312
|
+
await func(self.chat_id, self.message_id)
|
|
313
|
+
else:
|
|
314
|
+
func(self.chat_id, self.message_id)
|
|
315
|
+
try:
|
|
316
|
+
loop = asyncio.get_running_loop()
|
|
317
|
+
if loop.is_running():
|
|
318
|
+
return asyncio.create_task(_delete())
|
|
319
|
+
except RuntimeError:
|
|
320
|
+
return asyncio.run(_delete())
|
|
321
|
+
chat_id = msg.get("chat_id") if isinstance(msg, dict) else getattr(msg, "chat_id", self.chat_id)
|
|
322
|
+
message_id = msg.get("message_id") if isinstance(msg, dict) else getattr(msg, "message_id", self.message_id)
|
|
323
|
+
return Pick(self.bot, chat_id, message_id)
|
|
324
|
+
try:
|
|
325
|
+
loop = asyncio.get_running_loop()
|
|
326
|
+
if loop.is_running():
|
|
327
|
+
return asyncio.create_task(_reply_async())
|
|
328
|
+
except RuntimeError:
|
|
329
|
+
return asyncio.run(_reply_async())
|
|
276
330
|
def answer(self, text: str, **kwargs):
|
|
277
331
|
return self.bot.send_message(
|
|
278
332
|
self.chat_id,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Rubka
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.1.2
|
|
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
|
|
@@ -31,6 +31,7 @@ Requires-Dist: Pillow
|
|
|
31
31
|
Requires-Dist: websocket-client
|
|
32
32
|
Requires-Dist: pycryptodome
|
|
33
33
|
Requires-Dist: aiohttp
|
|
34
|
+
Requires-Dist: httpx
|
|
34
35
|
Requires-Dist: tqdm
|
|
35
36
|
Requires-Dist: mutagen
|
|
36
37
|
Requires-Dist: filetype
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
rubka/__init__.py,sha256=P6IBiORfp-GqKHe5LZ-5lldWyG7tnrUYUcAQDUgwXmY,1973
|
|
2
|
-
rubka/api.py,sha256=
|
|
3
|
-
rubka/asynco.py,sha256=
|
|
4
|
-
rubka/button.py,sha256=
|
|
2
|
+
rubka/api.py,sha256=fo4X9MH_HqQmLkRNhjJcJJZOHp5lkFZqitCXs2qL_kc,68891
|
|
3
|
+
rubka/asynco.py,sha256=84qCDieEngvNWBZwFgv-Cu7w8Emvkjru7AUjhswuHcQ,108098
|
|
4
|
+
rubka/button.py,sha256=woSzZVd5MtTqOrP-YgkH5b0GS9y4DuKBsFSc9-KuLnk,13320
|
|
5
5
|
rubka/config.py,sha256=Bck59xkOiqioLv0GkQ1qPGnBXVctz1hKk6LT4h2EPx0,78
|
|
6
|
-
rubka/context.py,sha256
|
|
6
|
+
rubka/context.py,sha256=-oC9h7U_H3CrtqUCDCnFXAvC7zdSmwxlc0CNwL1XLxM,34314
|
|
7
7
|
rubka/decorators.py,sha256=hGwUoE4q2ImrunJIGJ_kzGYYxQf1ueE0isadqraKEts,1157
|
|
8
8
|
rubka/exceptions.py,sha256=DDOGIHEMoliHNW5E7C_s38WZgqqMBv9812fcJGvj7TY,1173
|
|
9
9
|
rubka/filters.py,sha256=DY1bdkpRKIiLtVcy6X3hOnlGPcVOK4HFb3QgmaPx6Oo,12116
|
|
@@ -12,9 +12,9 @@ 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
|
-
rubka/rubino.py,sha256=
|
|
16
|
-
rubka/tv.py,sha256=
|
|
17
|
-
rubka/update.py,sha256
|
|
15
|
+
rubka/rubino.py,sha256=uCNjVk7ZTUo_r8ALWjvGbQHMr4mXDhoaSfAVdoZmHZk,58832
|
|
16
|
+
rubka/tv.py,sha256=4THsAWd5OAOYoSr6ZkWHuJ9rnURFndgXVQVjMqMHTeA,5453
|
|
17
|
+
rubka/update.py,sha256=-oC9h7U_H3CrtqUCDCnFXAvC7zdSmwxlc0CNwL1XLxM,34314
|
|
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-
|
|
41
|
-
rubka-
|
|
42
|
-
rubka-
|
|
43
|
-
rubka-
|
|
44
|
-
rubka-
|
|
40
|
+
rubka-7.1.2.dist-info/METADATA,sha256=ZchdDpS9nxgjR-KdBRc8DV4yFMnm5StlXQ3p_XReUS4,34291
|
|
41
|
+
rubka-7.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
42
|
+
rubka-7.1.2.dist-info/entry_points.txt,sha256=4aESuUmuUOALMUy7Kucv_Gb5YlqhsJmTmdXLlZU9sJ0,46
|
|
43
|
+
rubka-7.1.2.dist-info/top_level.txt,sha256=vy2A4lot11cRMdQS-F4HDCIXL3JK8RKfu7HMDkezJW4,6
|
|
44
|
+
rubka-7.1.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|