Rubka 2.11.13__py3-none-any.whl → 7.1.17__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 +72 -3
- rubka/adaptorrubka/__init__.py +4 -0
- rubka/adaptorrubka/client/__init__.py +1 -0
- rubka/adaptorrubka/client/client.py +60 -0
- rubka/adaptorrubka/crypto/__init__.py +1 -0
- rubka/adaptorrubka/crypto/crypto.py +82 -0
- rubka/adaptorrubka/enums.py +36 -0
- rubka/adaptorrubka/exceptions.py +22 -0
- rubka/adaptorrubka/methods/__init__.py +1 -0
- rubka/adaptorrubka/methods/methods.py +90 -0
- rubka/adaptorrubka/network/__init__.py +3 -0
- rubka/adaptorrubka/network/helper.py +22 -0
- rubka/adaptorrubka/network/network.py +221 -0
- rubka/adaptorrubka/network/socket.py +31 -0
- rubka/adaptorrubka/sessions/__init__.py +1 -0
- rubka/adaptorrubka/sessions/sessions.py +72 -0
- rubka/adaptorrubka/types/__init__.py +1 -0
- rubka/adaptorrubka/types/socket/__init__.py +1 -0
- rubka/adaptorrubka/types/socket/message.py +187 -0
- rubka/adaptorrubka/utils/__init__.py +2 -0
- rubka/adaptorrubka/utils/configs.py +18 -0
- rubka/adaptorrubka/utils/utils.py +251 -0
- rubka/api.py +1450 -95
- rubka/asynco.py +2515 -0
- rubka/button.py +404 -0
- rubka/context.py +744 -34
- rubka/exceptions.py +35 -1
- rubka/filters.py +321 -0
- rubka/helpers.py +1461 -0
- rubka/keypad.py +255 -5
- rubka/metadata.py +117 -0
- rubka/rubino.py +1231 -0
- rubka/tv.py +145 -0
- rubka/update.py +1038 -0
- rubka-7.1.17.dist-info/METADATA +1048 -0
- rubka-7.1.17.dist-info/RECORD +45 -0
- rubka-7.1.17.dist-info/entry_points.txt +2 -0
- rubka-2.11.13.dist-info/METADATA +0 -315
- rubka-2.11.13.dist-info/RECORD +0 -15
- {rubka-2.11.13.dist-info → rubka-7.1.17.dist-info}/WHEEL +0 -0
- {rubka-2.11.13.dist-info → rubka-7.1.17.dist-info}/top_level.txt +0 -0
rubka/keypad.py
CHANGED
|
@@ -1,18 +1,268 @@
|
|
|
1
1
|
from typing import Dict
|
|
2
2
|
|
|
3
|
+
from typing import Dict, List, Optional, Union
|
|
4
|
+
from typing import Dict, List, Optional
|
|
5
|
+
|
|
3
6
|
class InlineBuilder:
|
|
4
7
|
def __init__(self):
|
|
5
|
-
self.rows = []
|
|
8
|
+
self.rows: List[Dict] = []
|
|
6
9
|
|
|
7
|
-
def row(self, *buttons: Dict
|
|
10
|
+
def row(self, *buttons: Dict) -> "InlineBuilder":
|
|
11
|
+
"""
|
|
12
|
+
افزودن یک ردیف دکمه به کیبورد
|
|
13
|
+
حداقل یک دکمه باید داده شود.
|
|
14
|
+
"""
|
|
15
|
+
if not buttons:
|
|
16
|
+
raise ValueError("حداقل یک دکمه باید به row داده شود")
|
|
8
17
|
self.rows.append({"buttons": list(buttons)})
|
|
9
18
|
return self
|
|
10
19
|
|
|
11
|
-
def
|
|
12
|
-
return {"id": id, "type":
|
|
20
|
+
def button_simple(self, id: str, text: str) -> Dict:
|
|
21
|
+
return {"id": id, "type": "Simple", "button_text": text}
|
|
22
|
+
|
|
23
|
+
def button_selection(self, id: str, text: str, selection: Dict) -> Dict:
|
|
24
|
+
"""
|
|
25
|
+
selection: dict با فیلدهای:
|
|
26
|
+
- selection_id (str)
|
|
27
|
+
- search_type (str) [ButtonSelectionSearchEnum: None, Local, Api]
|
|
28
|
+
- get_type (str) [ButtonSelectionGetEnum: Local, Api]
|
|
29
|
+
- items (list of ButtonSelectionItem)
|
|
30
|
+
- is_multi_selection (bool)
|
|
31
|
+
- columns_count (str)
|
|
32
|
+
- title (str)
|
|
33
|
+
"""
|
|
34
|
+
return {
|
|
35
|
+
"id": id,
|
|
36
|
+
"type": "Selection",
|
|
37
|
+
"button_text": text,
|
|
38
|
+
"button_selection": selection
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
def button_calendar(self, id: str, title: str, type_: str,
|
|
42
|
+
default_value: Optional[str] = None,
|
|
43
|
+
min_year: Optional[str] = None,
|
|
44
|
+
max_year: Optional[str] = None) -> Dict:
|
|
45
|
+
"""
|
|
46
|
+
type_: ButtonCalendarTypeEnum = "DatePersian" | "DateGregorian"
|
|
47
|
+
"""
|
|
48
|
+
calendar = {
|
|
49
|
+
"title": title,
|
|
50
|
+
"type": type_,
|
|
51
|
+
}
|
|
52
|
+
if default_value:
|
|
53
|
+
calendar["default_value"] = default_value
|
|
54
|
+
if min_year:
|
|
55
|
+
calendar["min_year"] = min_year
|
|
56
|
+
if max_year:
|
|
57
|
+
calendar["max_year"] = max_year
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
"id": id,
|
|
61
|
+
"type": "Calendar",
|
|
62
|
+
"button_text": title,
|
|
63
|
+
"button_calendar": calendar
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
def button_number_picker(self, id: str, title: str, min_value: str, max_value: str,
|
|
67
|
+
default_value: Optional[str] = None) -> Dict:
|
|
68
|
+
picker = {
|
|
69
|
+
"title": title,
|
|
70
|
+
"min_value": min_value,
|
|
71
|
+
"max_value": max_value,
|
|
72
|
+
}
|
|
73
|
+
if default_value:
|
|
74
|
+
picker["default_value"] = default_value
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
"id": id,
|
|
78
|
+
"type": "NumberPicker",
|
|
79
|
+
"button_text": title,
|
|
80
|
+
"button_number_picker": picker
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
def button_string_picker(self, id: str, title: Optional[str], items: List[str],
|
|
84
|
+
default_value: Optional[str] = None) -> Dict:
|
|
85
|
+
picker = {
|
|
86
|
+
"items": items
|
|
87
|
+
}
|
|
88
|
+
if default_value:
|
|
89
|
+
picker["default_value"] = default_value
|
|
90
|
+
if title:
|
|
91
|
+
picker["title"] = title
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
"id": id,
|
|
95
|
+
"type": "StringPicker",
|
|
96
|
+
"button_text": title if title else "انتخاب",
|
|
97
|
+
"button_string_picker": picker
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
def button_location(self, id: str, type_: str, location_image_url: str,
|
|
101
|
+
default_pointer_location: Optional[Dict] = None,
|
|
102
|
+
default_map_location: Optional[Dict] = None,
|
|
103
|
+
title: Optional[str] = None) -> Dict:
|
|
104
|
+
"""
|
|
105
|
+
type_: ButtonLocationTypeEnum = "Picker" | "View"
|
|
106
|
+
location_image_url: str آدرس عکس دکمه موقعیت
|
|
107
|
+
default_pointer_location و default_map_location هر کدام دیکشنری Location (latitude, longitude)
|
|
108
|
+
"""
|
|
109
|
+
loc = {
|
|
110
|
+
"type": type_,
|
|
111
|
+
"location_image_url": location_image_url,
|
|
112
|
+
}
|
|
113
|
+
if default_pointer_location:
|
|
114
|
+
loc["default_pointer_location"] = default_pointer_location
|
|
115
|
+
if default_map_location:
|
|
116
|
+
loc["default_map_location"] = default_map_location
|
|
117
|
+
if title:
|
|
118
|
+
loc["title"] = title
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
"id": id,
|
|
122
|
+
"type": "Location",
|
|
123
|
+
"button_text": title if title else "موقعیت مکانی",
|
|
124
|
+
"button_location": loc
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
def button_textbox(self, id: str, title: Optional[str],
|
|
128
|
+
type_line: str, type_keypad: str,
|
|
129
|
+
place_holder: Optional[str] = None,
|
|
130
|
+
default_value: Optional[str] = None) -> Dict:
|
|
131
|
+
"""
|
|
132
|
+
type_line: ButtonTextboxTypeLineEnum = "SingleLine" | "MultiLine"
|
|
133
|
+
type_keypad: ButtonTextboxTypeKeypadEnum = "String" | "Number"
|
|
134
|
+
"""
|
|
135
|
+
textbox = {
|
|
136
|
+
"type_line": type_line,
|
|
137
|
+
"type_keypad": type_keypad
|
|
138
|
+
}
|
|
139
|
+
if place_holder:
|
|
140
|
+
textbox["place_holder"] = place_holder
|
|
141
|
+
if default_value:
|
|
142
|
+
textbox["default_value"] = default_value
|
|
143
|
+
if title:
|
|
144
|
+
textbox["title"] = title
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
"id": id,
|
|
148
|
+
"type": "Textbox",
|
|
149
|
+
"button_text": title if title else "متن",
|
|
150
|
+
"button_textbox": textbox
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
def button_payment(self, id: str, title: str, amount: int, description: Optional[str] = None) -> Dict:
|
|
154
|
+
"""
|
|
155
|
+
نمونهای ساده برای دکمه پرداخت (مقدار و توضیح دلخواه)
|
|
156
|
+
"""
|
|
157
|
+
payment = {
|
|
158
|
+
"title": title,
|
|
159
|
+
"amount": amount
|
|
160
|
+
}
|
|
161
|
+
if description:
|
|
162
|
+
payment["description"] = description
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
"id": id,
|
|
166
|
+
"type": "Payment",
|
|
167
|
+
"button_text": title,
|
|
168
|
+
"button_payment": payment
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
def button_camera_image(self, id: str, title: str) -> Dict:
|
|
172
|
+
return {
|
|
173
|
+
"id": id,
|
|
174
|
+
"type": "CameraImage",
|
|
175
|
+
"button_text": title
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
def button_camera_video(self, id: str, title: str) -> Dict:
|
|
179
|
+
return {
|
|
180
|
+
"id": id,
|
|
181
|
+
"type": "CameraVideo",
|
|
182
|
+
"button_text": title
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
def button_gallery_image(self, id: str, title: str) -> Dict:
|
|
186
|
+
return {
|
|
187
|
+
"id": id,
|
|
188
|
+
"type": "GalleryImage",
|
|
189
|
+
"button_text": title
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
def button_gallery_video(self, id: str, title: str) -> Dict:
|
|
193
|
+
return {
|
|
194
|
+
"id": id,
|
|
195
|
+
"type": "GalleryVideo",
|
|
196
|
+
"button_text": title
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
def button_file(self, id: str, title: str) -> Dict:
|
|
200
|
+
return {
|
|
201
|
+
"id": id,
|
|
202
|
+
"type": "File",
|
|
203
|
+
"button_text": title
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
def button_audio(self, id: str, title: str) -> Dict:
|
|
207
|
+
return {
|
|
208
|
+
"id": id,
|
|
209
|
+
"type": "Audio",
|
|
210
|
+
"button_text": title
|
|
211
|
+
}
|
|
13
212
|
|
|
14
|
-
def
|
|
213
|
+
def button_record_audio(self, id: str, title: str) -> Dict:
|
|
214
|
+
return {
|
|
215
|
+
"id": id,
|
|
216
|
+
"type": "RecordAudio",
|
|
217
|
+
"button_text": title
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
def button_my_phone_number(self, id: str, title: str) -> Dict:
|
|
221
|
+
return {
|
|
222
|
+
"id": id,
|
|
223
|
+
"type": "MyPhoneNumber",
|
|
224
|
+
"button_text": title
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
def button_my_location(self, id: str, title: str) -> Dict:
|
|
228
|
+
return {
|
|
229
|
+
"id": id,
|
|
230
|
+
"type": "MyLocation",
|
|
231
|
+
"button_text": title
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
def button_link(self, id: str, title: str, url: str) -> Dict:
|
|
235
|
+
return {
|
|
236
|
+
"id": id,
|
|
237
|
+
"type": "Link",
|
|
238
|
+
"button_text": title,
|
|
239
|
+
"url": url
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
def button_ask_my_phone_number(self, id: str, title: str) -> Dict:
|
|
243
|
+
return {
|
|
244
|
+
"id": id,
|
|
245
|
+
"type": "AskMyPhoneNumber",
|
|
246
|
+
"button_text": title
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
def button_ask_location(self, id: str, title: str) -> Dict:
|
|
250
|
+
return {
|
|
251
|
+
"id": id,
|
|
252
|
+
"type": "AskLocation",
|
|
253
|
+
"button_text": title
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
def button_barcode(self, id: str, title: str) -> Dict:
|
|
257
|
+
return {
|
|
258
|
+
"id": id,
|
|
259
|
+
"type": "Barcode",
|
|
260
|
+
"button_text": title
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
def build(self) -> Dict:
|
|
15
264
|
return {"rows": self.rows}
|
|
265
|
+
|
|
16
266
|
from typing import List, Dict, Optional
|
|
17
267
|
|
|
18
268
|
class ChatKeypadBuilder:
|
rubka/metadata.py
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import Any, Dict, List
|
|
3
|
+
import markdownify
|
|
4
|
+
def _normalize_multiline_quote(text: str) -> str:
|
|
5
|
+
lines = text.splitlines()
|
|
6
|
+
normalized_lines = []
|
|
7
|
+
quote_block = []
|
|
8
|
+
|
|
9
|
+
for line in lines + [""]:
|
|
10
|
+
if line.startswith(">"):quote_block.append(line[1:].strip())
|
|
11
|
+
else:
|
|
12
|
+
if quote_block:
|
|
13
|
+
normalized_lines.append("$" + "\n".join(quote_block) + "$")
|
|
14
|
+
quote_block = []
|
|
15
|
+
normalized_lines.append(line)
|
|
16
|
+
return "\n".join(normalized_lines).strip()
|
|
17
|
+
|
|
18
|
+
class Track_parsed:
|
|
19
|
+
_PATT = re.compile(
|
|
20
|
+
r"(?P<pre>```(?P<pre_c>[\s\S]*?)```)"
|
|
21
|
+
r"|(?P<bold>\*\*(?P<bold_c>.*?)\*\*)"
|
|
22
|
+
r"|(?P<mono>`(?P<mono_c>.*?)`)"
|
|
23
|
+
r"|(?P<italic>__(?P<italic_c>.*?)__)"
|
|
24
|
+
r"|(?P<underline>--(?P<underline_c>.*?)--)"
|
|
25
|
+
r"|(?P<link>\[(?P<link_text>.*?)\]\((?P<link_url>\S+?)\))"
|
|
26
|
+
r"|(?P<quote>\$(?P<quote_c>[\s\S]*?)\$)"
|
|
27
|
+
r"|(?P<quote_md>^>(?P<quote_md_c>.*?)(?:\n|$))"
|
|
28
|
+
r"|(?P<strike>~~(?P<strike_c>.*?)~~)"
|
|
29
|
+
r"|(?P<spoiler>\|\|(?P<spoiler_c>.*?)\|\|)",
|
|
30
|
+
flags=re.DOTALL,
|
|
31
|
+
)
|
|
32
|
+
_TYPE_MAP = {
|
|
33
|
+
"pre": "Pre",
|
|
34
|
+
"bold": "Bold",
|
|
35
|
+
"mono": "Mono",
|
|
36
|
+
"italic": "Italic",
|
|
37
|
+
"underline": "Underline",
|
|
38
|
+
"strike": "Strike",
|
|
39
|
+
"spoiler": "Spoiler",
|
|
40
|
+
"quote": "Quote",
|
|
41
|
+
"quote_md": "Quote",
|
|
42
|
+
"link": "Link",
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def _utf16_len_java_style(s: str) -> int:
|
|
47
|
+
return len(s.encode("utf-16-be")) // 2
|
|
48
|
+
|
|
49
|
+
@staticmethod
|
|
50
|
+
def _html2md(src: str) -> str:
|
|
51
|
+
src = re.sub(r'<i>(.*?)</i>', r'||\1||', src, flags=re.DOTALL)
|
|
52
|
+
src = re.sub(r'<span class="spoiler">(.*?)</span>', r'||\1||', src, flags=re.DOTALL)
|
|
53
|
+
src = markdownify.markdownify(html=src).strip()
|
|
54
|
+
src = src.replace("@@SPOILER@@", "||")
|
|
55
|
+
return src
|
|
56
|
+
|
|
57
|
+
def transcribe(self, src: str, mode: str = "MARKDOWN") -> Dict[str, Any]:
|
|
58
|
+
if mode and mode.upper() == "HTML":
|
|
59
|
+
src = self._html2md(src)
|
|
60
|
+
src = _normalize_multiline_quote(src)
|
|
61
|
+
|
|
62
|
+
payload_parts: List[Dict[str, Any]] = []
|
|
63
|
+
|
|
64
|
+
normalized_text = src
|
|
65
|
+
byte_offset = 0
|
|
66
|
+
char_offset = 0
|
|
67
|
+
|
|
68
|
+
matches = list(self._PATT.finditer(src))
|
|
69
|
+
for m in matches:
|
|
70
|
+
whole = m.group(0)
|
|
71
|
+
start, end = m.span()
|
|
72
|
+
adj_from = self._utf16_len_java_style(src[:start]) - byte_offset
|
|
73
|
+
adj_char_from = start - char_offset
|
|
74
|
+
|
|
75
|
+
gname = m.lastgroup
|
|
76
|
+
if not gname:
|
|
77
|
+
continue
|
|
78
|
+
|
|
79
|
+
if gname == "link":
|
|
80
|
+
inner = m.group("link_text") or ""
|
|
81
|
+
link_href = m.group("link_url")
|
|
82
|
+
else:
|
|
83
|
+
inner = m.group(f"{gname}_c") or ""
|
|
84
|
+
link_href = None
|
|
85
|
+
if gname in ["quote", "quote_md", "bold", "italic", "underline", "spoiler", "strike"]:
|
|
86
|
+
inner_metadata = self.transcribe(inner, mode="MARKDOWN")
|
|
87
|
+
inner = inner_metadata["text"]
|
|
88
|
+
if "metadata" in inner_metadata:
|
|
89
|
+
for part in inner_metadata["metadata"]["meta_data_parts"]:
|
|
90
|
+
part["from_index"] += adj_from
|
|
91
|
+
payload_parts.append(part)
|
|
92
|
+
if inner == "":
|
|
93
|
+
continue
|
|
94
|
+
content_utf16_len = self._utf16_len_java_style(inner)
|
|
95
|
+
part: Dict[str, Any] = {
|
|
96
|
+
"type": self._TYPE_MAP.get(gname, "Unknown"),
|
|
97
|
+
"from_index": adj_from,
|
|
98
|
+
"length": content_utf16_len,
|
|
99
|
+
}
|
|
100
|
+
if link_href:
|
|
101
|
+
part["link_url"] = link_href
|
|
102
|
+
payload_parts.append(part)
|
|
103
|
+
normalized_text = (
|
|
104
|
+
normalized_text[:adj_char_from] + inner + normalized_text[end - char_offset :]
|
|
105
|
+
)
|
|
106
|
+
byte_offset += self._utf16_len_java_style(whole) - content_utf16_len
|
|
107
|
+
char_offset += (end - start) - len(inner)
|
|
108
|
+
|
|
109
|
+
result: Dict[str, Any] = {"text": normalized_text.strip()}
|
|
110
|
+
if payload_parts:
|
|
111
|
+
result["metadata"] = {"meta_data_parts": payload_parts}
|
|
112
|
+
|
|
113
|
+
return result
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def parse(self, text: str, parse_mode: str = "MARKDOWN") -> Dict[str, Any]:
|
|
117
|
+
return self.transcribe(text, mode=parse_mode)
|