Rubka 7.2.8__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.
Files changed (45) hide show
  1. rubka/__init__.py +79 -0
  2. rubka/adaptorrubka/__init__.py +4 -0
  3. rubka/adaptorrubka/client/__init__.py +1 -0
  4. rubka/adaptorrubka/client/client.py +60 -0
  5. rubka/adaptorrubka/crypto/__init__.py +1 -0
  6. rubka/adaptorrubka/crypto/crypto.py +82 -0
  7. rubka/adaptorrubka/enums.py +36 -0
  8. rubka/adaptorrubka/exceptions.py +22 -0
  9. rubka/adaptorrubka/methods/__init__.py +1 -0
  10. rubka/adaptorrubka/methods/methods.py +90 -0
  11. rubka/adaptorrubka/network/__init__.py +3 -0
  12. rubka/adaptorrubka/network/helper.py +22 -0
  13. rubka/adaptorrubka/network/network.py +221 -0
  14. rubka/adaptorrubka/network/socket.py +31 -0
  15. rubka/adaptorrubka/sessions/__init__.py +1 -0
  16. rubka/adaptorrubka/sessions/sessions.py +72 -0
  17. rubka/adaptorrubka/types/__init__.py +1 -0
  18. rubka/adaptorrubka/types/socket/__init__.py +1 -0
  19. rubka/adaptorrubka/types/socket/message.py +187 -0
  20. rubka/adaptorrubka/utils/__init__.py +2 -0
  21. rubka/adaptorrubka/utils/configs.py +18 -0
  22. rubka/adaptorrubka/utils/utils.py +251 -0
  23. rubka/api.py +1723 -0
  24. rubka/asynco.py +2541 -0
  25. rubka/button.py +404 -0
  26. rubka/config.py +3 -0
  27. rubka/context.py +1077 -0
  28. rubka/decorators.py +30 -0
  29. rubka/exceptions.py +37 -0
  30. rubka/filters.py +330 -0
  31. rubka/helpers.py +1461 -0
  32. rubka/jobs.py +15 -0
  33. rubka/keyboards.py +16 -0
  34. rubka/keypad.py +298 -0
  35. rubka/logger.py +12 -0
  36. rubka/metadata.py +114 -0
  37. rubka/rubino.py +1271 -0
  38. rubka/tv.py +145 -0
  39. rubka/update.py +1038 -0
  40. rubka/utils.py +3 -0
  41. rubka-7.2.8.dist-info/METADATA +1047 -0
  42. rubka-7.2.8.dist-info/RECORD +45 -0
  43. rubka-7.2.8.dist-info/WHEEL +5 -0
  44. rubka-7.2.8.dist-info/entry_points.txt +2 -0
  45. rubka-7.2.8.dist-info/top_level.txt +1 -0
rubka/decorators.py ADDED
@@ -0,0 +1,30 @@
1
+ from typing import Callable, Dict, Any
2
+ import functools
3
+
4
+ def on_message(func: Callable):
5
+ """
6
+ Decorator to handle incoming message updates from Rubika.
7
+ Extracts message details and passes them to decorated function.
8
+ """
9
+ @functools.wraps(func)
10
+ def wrapper(update: Dict[str, Any], bot: 'Robot'):
11
+ message_data = {}
12
+ if 'update' in update and update['update'].get('type') == 'NewMessage':
13
+ msg = update['update']['new_message']
14
+ message_data = {
15
+ 'chat_id': update['update']['chat_id'],
16
+ 'message_id': msg.get('message_id'),
17
+ 'text': msg.get('text'),
18
+ 'sender_id': msg.get('sender_id')
19
+ }
20
+ elif 'inline_message' in update:
21
+ msg = update['inline_message']
22
+ message_data = {
23
+ 'chat_id': msg.get('chat_id'),
24
+ 'message_id': msg.get('message_id'),
25
+ 'text': msg.get('text'),
26
+ 'sender_id': msg.get('sender_id')
27
+ }
28
+ if message_data:
29
+ return func(bot=bot, **message_data)
30
+ return wrapper
rubka/exceptions.py ADDED
@@ -0,0 +1,37 @@
1
+ class APIRequestError(Exception):
2
+ """Base class for all API request errors."""
3
+ def __init__(self, status: str, dev_message: str = None):
4
+ self.status = status
5
+ self.dev_message = dev_message
6
+ msg = f"{self.__class__.__name__}: {status}"
7
+ if dev_message:
8
+ msg += f" | Message : {dev_message}"
9
+ super().__init__(msg)
10
+
11
+
12
+ class InvalidAccessError(APIRequestError):
13
+ """Raised when access is invalid."""
14
+
15
+ class InvalidTokenError(Exception):
16
+ pass
17
+
18
+ class InvalidInputError(APIRequestError):
19
+ """Raised when input is invalid."""
20
+
21
+
22
+ class TooRequestError(APIRequestError):
23
+ """Raised when too many requests are made."""
24
+
25
+
26
+ def raise_for_status(response: dict):
27
+ status = response.get("status")
28
+ dev_message = response.get("dev_message")
29
+
30
+ if status == "INVALID_ACCESS":
31
+ raise InvalidAccessError(status, dev_message)
32
+ elif status == "INVALID_INPUT":
33
+ raise InvalidInputError(status, dev_message)
34
+ elif status == "TOO_REQUEST":
35
+ raise TooRequestError(status, dev_message)
36
+ elif status != "OK":
37
+ raise APIRequestError(status, dev_message)
rubka/filters.py ADDED
@@ -0,0 +1,330 @@
1
+ from typing import Callable,Union
2
+ import re
3
+ class TextFilter:
4
+ def __call__(self, keyword=None):
5
+ if keyword is None:
6
+ return Filter(lambda m: getattr(m, "is_text", False))
7
+ else:
8
+ return Filter(lambda m: getattr(m, "is_text", False) and keyword in getattr(m, "text", ""))
9
+ class Filter:
10
+ def __init__(self, func: Callable):
11
+ self.func = func
12
+
13
+ def __call__(self, message):
14
+ return self.func(message)
15
+
16
+ def __and__(self, other):
17
+ return Filter(lambda m: self(m) and other(m))
18
+
19
+ def __or__(self, other):
20
+ return Filter(lambda m: self(m) or other(m))
21
+
22
+ def __invert__(self):
23
+ return Filter(lambda m: not self(m))
24
+
25
+ def __xor__(self, other):
26
+ return Filter(lambda m: self(m) != other(m))
27
+
28
+ def __eq__(self, other):
29
+ return Filter(lambda m: self(m) == other)
30
+
31
+ def __ne__(self, other):
32
+ return Filter(lambda m: self(m) != other)
33
+
34
+ def __lt__(self, other):
35
+ return Filter(lambda m: self(m) < other)
36
+
37
+ def __le__(self, other):
38
+ return Filter(lambda m: self(m) <= other)
39
+
40
+ def __gt__(self, other):
41
+ return Filter(lambda m: self(m) > other)
42
+
43
+ def __ge__(self, other):
44
+ return Filter(lambda m: self(m) >= other)
45
+
46
+ def __add__(self, other):
47
+ return Filter(lambda m: self(m) + (other(m) if callable(other) else other))
48
+
49
+ def __sub__(self, other):
50
+ return Filter(lambda m: self(m) - (other(m) if callable(other) else other))
51
+
52
+ def __mul__(self, other):
53
+ return Filter(lambda m: self(m) * (other(m) if callable(other) else other))
54
+
55
+ def __truediv__(self, other):
56
+ return Filter(lambda m: self(m) / (other(m) if callable(other) else other))
57
+ class IsCommand(Filter):
58
+ def __init__(self, commands=None):
59
+ if commands is None:
60
+ func = lambda m: getattr(m, "is_command", False)
61
+ else:
62
+ if isinstance(commands, str):
63
+ commands = [commands]
64
+ func = lambda m: getattr(m, "is_command", False) and getattr(m, "text", "").lstrip("/").split()[0] in commands
65
+
66
+ super().__init__(func)
67
+
68
+ def __getattr__(self, name: str):
69
+ return IsCommand([name])
70
+
71
+
72
+ class IsText:
73
+ def __call__(self, text=None):
74
+ if text is None:
75
+ func = lambda m: m.is_text is True and m.is_file is False
76
+ else:
77
+ if isinstance(text, str):
78
+ text = [text]
79
+ func = lambda m: m.is_text is True and m.is_file is False and m.text in text
80
+
81
+ return Filter(func)
82
+ #is_text = Filter(lambda m: getattr(m, "is_text", False))
83
+ is_file = Filter(lambda m: getattr(m, "file", None) is not None)
84
+ is_sticker = Filter(lambda m: getattr(m, "sticker", None) is not None)
85
+ is_contact = Filter(lambda m: getattr(m, "contact_message", None) is not None)
86
+ is_poll = Filter(lambda m: getattr(m, "poll", None) is not None)
87
+ is_location = Filter(lambda m: getattr(m, "location", None) is not None)
88
+ is_live_location = Filter(lambda m: getattr(m, "live_location", None) is not None)
89
+ has_any_media = Filter(lambda m: getattr(m, "has_any_media", False))
90
+ has_media = Filter(lambda m: getattr(m, "has_media", False))
91
+ is_text = IsText()
92
+ is_command = IsCommand()
93
+ is_user = Filter(lambda m: getattr(m, "is_user", False))
94
+ is_private = Filter(lambda m: getattr(m, "is_private", False))
95
+ is_group = Filter(lambda m: getattr(m, "is_group", False))
96
+ is_channel = Filter(lambda m: getattr(m, "is_channel", False))
97
+ is_reply = Filter(lambda m: getattr(m, "is_reply", False))
98
+ is_forwarded = Filter(lambda m: getattr(m, "is_forwarded", False))
99
+ is_edited = Filter(lambda m: getattr(m, "is_edited", False))
100
+ def text(keyword: str):
101
+ return Filter(lambda m: getattr(m, "text", "") and keyword in m.text)
102
+ def text_length(min_len: int = 0, max_len: int = None):
103
+ def _filter(m):
104
+ t = getattr(m, "text", "")
105
+ if not t: return False
106
+ if len(t) < min_len: return False
107
+ if max_len is not None and len(t) > max_len: return False
108
+ return True
109
+ return Filter(_filter)
110
+ def text_regex(pattern: str):
111
+ regex = re.compile(pattern)
112
+ return Filter(lambda m: getattr(m, "text", "") and regex.search(m.text))
113
+ def regex(pattern: str):
114
+ regex = re.compile(pattern)
115
+ return Filter(lambda m: getattr(m, "text", "") and regex.search(m.text))
116
+ def text_startswith(prefix: str):
117
+ return Filter(lambda m: getattr(m, "text", "").startswith(prefix) if getattr(m, "text", None) else False)
118
+ def text_endswith(suffix: str):
119
+ return Filter(lambda m: getattr(m, "text", "").endswith(suffix) if getattr(m, "text", None) else False)
120
+ def text_upper():
121
+ return Filter(lambda m: getattr(m, "text", "").isupper() if getattr(m, "text", None) else False)
122
+ def text_lower():
123
+ return Filter(lambda m: getattr(m, "text", "").islower() if getattr(m, "text", None) else False)
124
+ def text_digit():
125
+ return Filter(lambda m: getattr(m, "text", "").isdigit() if getattr(m, "text", None) else False)
126
+ def text_word_count(min_words: int = 1, max_words: int = None):
127
+ def _filter(m):
128
+ t = getattr(m, "text", "")
129
+ if not t: return False
130
+ wc = len(t.split())
131
+ if wc < min_words: return False
132
+ if max_words is not None and wc > max_words: return False
133
+ return True
134
+ return Filter(_filter)
135
+ def text_contains_any(keywords: list):
136
+ return Filter(lambda m: getattr(m, "text", "") and any(k in m.text for k in keywords))
137
+ def text_equals(value: str):
138
+ return Filter(lambda m: getattr(m, "text", None) == value)
139
+ def text_not_equals(value: str):
140
+ return Filter(lambda m: getattr(m, "text", None) != value)
141
+ def file_size_gt(size: int):
142
+ return Filter(lambda m: m.file and getattr(m.file, "size", 0) > size)
143
+ def file_size_lt(size: int):
144
+ return Filter(lambda m: m.file and getattr(m.file, "size", 0) < size)
145
+ def file_name_contains(substring: str):
146
+ return Filter(lambda m: m.file and substring in getattr(m.file, "file_name", ""))
147
+ def file_extension(ext: str):
148
+ return Filter(lambda m: m.file and getattr(m.file, "file_name", "").endswith(ext))
149
+ def file_id_is(file_id: str):
150
+ return Filter(lambda m: m.file and getattr(m.file, "file_id", None) == file_id)
151
+ def sticker_id_is(sid: str):
152
+ return Filter(lambda m: m.sticker and getattr(m.sticker, "sticker_id", None) == sid)
153
+ def sticker_emoji_is(emoji: str):
154
+ return Filter(lambda m: m.sticker and getattr(m.sticker, "emoji", None) == emoji)
155
+ is_bold = Filter(lambda m: getattr(m, "is_bold", False))
156
+ is_italic = Filter(lambda m: getattr(m, "is_italic", False))
157
+ is_strike = Filter(lambda m: getattr(m, "is_strike", False))
158
+ is_underline = Filter(lambda m: getattr(m, "is_underline", False))
159
+ is_quote = Filter(lambda m: getattr(m, "is_quote", False))
160
+ is_spoiler = Filter(lambda m: getattr(m, "is_spoiler", False))
161
+ is_pre = Filter(lambda m: getattr(m, "is_pre", False))
162
+ is_mono = Filter(lambda m: getattr(m, "is_mono", False))
163
+ is_link_meta = Filter(lambda m: getattr(m, "is_link_meta", False))
164
+ has_metadata = Filter(lambda m: getattr(m, "has_metadata", False))
165
+ meta_links_contain = lambda keyword: Filter(lambda m: any(keyword in link for link in getattr(m, "meta_links", [])))
166
+ meta_link_positions_contain = lambda keyword: Filter(lambda m: any(keyword in link.get("url", "") for link in getattr(m, "meta_link_positions", [])))
167
+ meta_types_include = lambda types: Filter(lambda m: any(t in getattr(m, "meta_types", []) for t in types))
168
+ def poll_question_contains(keyword: str):
169
+ return Filter(lambda m: m.poll and keyword in getattr(m.poll, "question", ""))
170
+ def poll_option_count(min_options: int = 1, max_options: int = None):
171
+ def _filter(m):
172
+ if not getattr(m, "poll", None): return False
173
+ options = getattr(m.poll, "options", [])
174
+ if len(options) < min_options: return False
175
+ if max_options is not None and len(options) > max_options: return False
176
+ return True
177
+ return Filter(_filter)
178
+ def location_within(lat_min, lat_max, long_min, long_max):
179
+ def _filter(m):
180
+ loc = getattr(m, "location", None)
181
+ if not loc: return False
182
+ return lat_min <= getattr(loc, "lat", 0) <= lat_max and long_min <= getattr(loc, "long", 0) <= long_max
183
+ return Filter(_filter)
184
+ def live_location_within(lat_min, lat_max, long_min, long_max):
185
+ def _filter(m):
186
+ loc = getattr(m, "live_location", None)
187
+ if not loc: return False
188
+ return lat_min <= getattr(loc, "lat", 0) <= lat_max and long_min <= getattr(loc, "long", 0) <= long_max
189
+ return Filter(_filter)
190
+ def has_media_types(types: list):
191
+ return Filter(lambda m: any(getattr(m, t, None) for t in types))
192
+
193
+ def message_id_is(mid: str):
194
+ return Filter(lambda m: getattr(m, "message_id", None) == mid)
195
+
196
+ def is_reply_to_user(user_id: str):
197
+ return Filter(lambda m: getattr(m, "reply_to_message_id", None) == user_id)
198
+
199
+ def is_forwarded_from(user_id: str):
200
+ return Filter(lambda m: getattr(m.forwarded_from, "sender_id", None) == user_id if getattr(m, "forwarded_from", None) else False)
201
+
202
+ def edited_text_contains(keyword: str):
203
+ return Filter(lambda m: getattr(m, "edited_text", "") and keyword in m.edited_text)
204
+
205
+ def aux_data_contains(key: str, value):
206
+ return Filter(lambda m: getattr(m.aux_data, key, None) == value if getattr(m, "aux_data", None) else False)
207
+
208
+
209
+
210
+
211
+ def file_attr(attr_name):
212
+ return Filter(lambda m: m.file and getattr(m.file, attr_name, None))
213
+
214
+ def sticker_attr(attr_name):
215
+ return Filter(lambda m: m.sticker and getattr(m.sticker, attr_name, None))
216
+
217
+ def poll_attr(attr_name):
218
+ return Filter(lambda m: m.poll and getattr(m.poll, attr_name, None))
219
+
220
+ def location_attr(attr_name):
221
+ return Filter(lambda m: m.location and getattr(m.location, attr_name, None))
222
+
223
+ def live_location_attr(attr_name):
224
+ return Filter(lambda m: m.live_location and getattr(m.live_location, attr_name, None))
225
+
226
+
227
+
228
+
229
+ file_size = file_attr("size")
230
+ file_name = file_attr("file_name")
231
+ sticker_id = sticker_attr("sticker_id")
232
+ poll_question = poll_attr("question")
233
+ location_lat = location_attr("lat")
234
+ location_long = location_attr("long")
235
+ live_location_lat = live_location_attr("lat")
236
+ live_location_long = live_location_attr("long")
237
+
238
+ _custom_filters = {}
239
+ def chat_title_contains(keyword: str):
240
+
241
+ return Filter(lambda m: getattr(m, "chat", None) and keyword in getattr(m.chat, "title", ""))
242
+
243
+ def chat_title_equals(value: str):
244
+
245
+ return Filter(lambda m: getattr(m, "chat", None) and getattr(m.chat, "title", "") == value)
246
+
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)
259
+ def chat_member_count(min_count: int = 0, max_count: int = None):
260
+
261
+ def _filter(m):
262
+ c = getattr(m, "chat", None)
263
+ if not c: return False
264
+ count = getattr(c, "member_count", 0)
265
+ if count < min_count: return False
266
+ if max_count is not None and count > max_count: return False
267
+ return True
268
+ return Filter(_filter)
269
+
270
+ def chat_type_is(chat_type: str):
271
+
272
+ return Filter(lambda m: getattr(m, "chat", None) and getattr(m.chat, "type", None) == chat_type)
273
+
274
+ def chat_username_contains(keyword: str):
275
+
276
+ return Filter(lambda m: getattr(m, "chat", None) and keyword in getattr(m.chat, "username", ""))
277
+
278
+ def chat_username_equals(value: str):
279
+
280
+ return Filter(lambda m: getattr(m, "chat", None) and getattr(m.chat, "username", "") == value)
281
+
282
+ def chat_has_link():
283
+
284
+ return Filter(lambda m: getattr(m, "chat", None) and getattr(m.chat, "invite_link", None) is not None)
285
+
286
+ def chat_is_private():
287
+
288
+ return Filter(lambda m: getattr(m, "chat", None) and getattr(m.chat, "type", None) in ["group", "channel"])
289
+
290
+ def chat_member_count_gt(count: int):
291
+
292
+ return Filter(lambda m: getattr(m, "chat", None) and getattr(m.chat, "member_count", 0) > count)
293
+
294
+ def chat_member_count_lt(count: int):
295
+
296
+ return Filter(lambda m: getattr(m, "chat", None) and getattr(m.chat, "member_count", 0) < count)
297
+
298
+ def chat_has_username():
299
+
300
+ return Filter(lambda m: getattr(m, "chat", None) and getattr(m.chat, "username", None) is not None)
301
+
302
+ def chat_type_in(types: list):
303
+
304
+ return Filter(lambda m: getattr(m, "chat", None) and getattr(m.chat, "type", None) in types)
305
+
306
+
307
+ def chat_title_regex(pattern: str):
308
+ regex = re.compile(pattern)
309
+ return Filter(lambda m: getattr(m, "chat", None) and regex.search(getattr(m.chat, "title", "")))
310
+
311
+ def chat_username_regex(pattern: str):
312
+ regex = re.compile(pattern)
313
+ return Filter(lambda m: getattr(m, "chat", None) and regex.search(getattr(m.chat, "username", "")))
314
+ def custom(name):
315
+ def wrapper(func):
316
+ _custom_filters[name] = Filter(func)
317
+ return _custom_filters[name]
318
+ return wrapper
319
+
320
+ def get_custom(name):
321
+ return _custom_filters.get(name)
322
+
323
+ def and_(*filters):
324
+ return Filter(lambda m: all(f(m) for f in filters))
325
+
326
+ def or_(*filters):
327
+ return Filter(lambda m: any(f(m) for f in filters))
328
+
329
+ def not_(filter_):
330
+ return Filter(lambda m: not filter_(m))