sticker-convert 2.8.12__py3-none-any.whl → 2.17.0.0__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.
- sticker_convert/__main__.py +24 -24
- sticker_convert/auth/__init__.py +0 -0
- sticker_convert/auth/auth_base.py +19 -0
- sticker_convert/auth/auth_discord.py +149 -0
- sticker_convert/{utils/auth/get_kakao_auth.py → auth/auth_kakao_android_login.py} +331 -300
- sticker_convert/auth/auth_kakao_desktop_login.py +327 -0
- sticker_convert/auth/auth_kakao_desktop_memdump.py +281 -0
- sticker_convert/{utils/auth/get_line_auth.py → auth/auth_line.py} +98 -80
- sticker_convert/auth/auth_signal.py +139 -0
- sticker_convert/auth/auth_telethon.py +161 -0
- sticker_convert/auth/auth_viber.py +250 -0
- sticker_convert/auth/telegram_api.py +736 -0
- sticker_convert/cli.py +623 -509
- sticker_convert/converter.py +1093 -962
- sticker_convert/definitions.py +11 -0
- sticker_convert/downloaders/download_band.py +111 -0
- sticker_convert/downloaders/download_base.py +171 -130
- sticker_convert/downloaders/download_discord.py +92 -0
- sticker_convert/downloaders/download_kakao.py +417 -255
- sticker_convert/downloaders/download_line.py +484 -472
- sticker_convert/downloaders/download_ogq.py +80 -0
- sticker_convert/downloaders/download_signal.py +108 -92
- sticker_convert/downloaders/download_telegram.py +56 -130
- sticker_convert/downloaders/download_viber.py +121 -95
- sticker_convert/gui.py +788 -795
- sticker_convert/gui_components/frames/comp_frame.py +180 -165
- sticker_convert/gui_components/frames/config_frame.py +156 -113
- sticker_convert/gui_components/frames/control_frame.py +32 -30
- sticker_convert/gui_components/frames/cred_frame.py +232 -162
- sticker_convert/gui_components/frames/input_frame.py +139 -137
- sticker_convert/gui_components/frames/output_frame.py +112 -110
- sticker_convert/gui_components/frames/right_clicker.py +25 -23
- sticker_convert/gui_components/windows/advanced_compression_window.py +757 -715
- sticker_convert/gui_components/windows/base_window.py +7 -2
- sticker_convert/gui_components/windows/discord_get_auth_window.py +79 -0
- sticker_convert/gui_components/windows/kakao_get_auth_window.py +511 -186
- sticker_convert/gui_components/windows/line_get_auth_window.py +94 -102
- sticker_convert/gui_components/windows/signal_get_auth_window.py +84 -135
- sticker_convert/gui_components/windows/viber_get_auth_window.py +168 -0
- sticker_convert/ios-message-stickers-template/.github/FUNDING.yml +3 -3
- sticker_convert/ios-message-stickers-template/.gitignore +0 -0
- sticker_convert/ios-message-stickers-template/README.md +10 -10
- sticker_convert/ios-message-stickers-template/stickers/Info.plist +43 -43
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Info.plist +31 -31
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Contents.json +6 -6
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Contents.json +20 -20
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 1.sticker/Contents.json +9 -9
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 1.sticker/Sticker 1.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 2.sticker/Contents.json +9 -9
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 2.sticker/Sticker 2.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 3.sticker/Contents.json +9 -9
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 3.sticker/Sticker 3.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/App-Store-1024x1024pt.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Contents.json +91 -91
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-App-Store-1024x768pt.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-iPad-67x50pt@2x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-iPad-Pro-74x55pt@2x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-iPhone-60x45pt@2x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-iPhone-60x45pt@3x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages27x20pt@2x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages27x20pt@3x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages32x24pt@2x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages32x24pt@3x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/iPad-Settings-29pt@2x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/iPhone-Settings-29pt@3x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/iPhone-settings-29pt@2x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.pbxproj +364 -364
- sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -7
- sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -8
- sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.xcworkspace/xcuserdata/niklaspeterson.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- sticker_convert/ios-message-stickers-template/stickers.xcodeproj/xcuserdata/niklaspeterson.xcuserdatad/xcschemes/xcschememanagement.plist +14 -14
- sticker_convert/job.py +279 -179
- sticker_convert/job_option.py +15 -2
- sticker_convert/locales/en_US/LC_MESSAGES/base.mo +0 -0
- sticker_convert/locales/ja_JP/LC_MESSAGES/base.mo +0 -0
- sticker_convert/locales/zh_CN/LC_MESSAGES/base.mo +0 -0
- sticker_convert/locales/zh_TW/LC_MESSAGES/base.mo +0 -0
- sticker_convert/py.typed +0 -0
- sticker_convert/resources/NotoColorEmoji.ttf +0 -0
- sticker_convert/resources/compression.json +220 -16
- sticker_convert/resources/emoji.json +527 -77
- sticker_convert/resources/help.ja_JP.json +88 -0
- sticker_convert/resources/help.json +24 -10
- sticker_convert/resources/help.zh_CN.json +88 -0
- sticker_convert/resources/help.zh_TW.json +88 -0
- sticker_convert/resources/input.ja_JP.json +74 -0
- sticker_convert/resources/input.json +121 -71
- sticker_convert/resources/input.zh_CN.json +74 -0
- sticker_convert/resources/input.zh_TW.json +74 -0
- sticker_convert/resources/memdump_linux.sh +25 -0
- sticker_convert/resources/memdump_windows.ps1 +8 -0
- sticker_convert/resources/output.ja_JP.json +38 -0
- sticker_convert/resources/output.json +24 -0
- sticker_convert/resources/output.zh_CN.json +38 -0
- sticker_convert/resources/output.zh_TW.json +38 -0
- sticker_convert/uploaders/compress_wastickers.py +186 -156
- sticker_convert/uploaders/upload_base.py +44 -35
- sticker_convert/uploaders/upload_signal.py +218 -173
- sticker_convert/uploaders/upload_telegram.py +353 -388
- sticker_convert/uploaders/upload_viber.py +178 -0
- sticker_convert/uploaders/xcode_imessage.py +295 -285
- sticker_convert/utils/callback.py +238 -6
- sticker_convert/utils/chrome_remotedebug.py +219 -0
- sticker_convert/utils/chromiums/linux.py +52 -0
- sticker_convert/utils/chromiums/osx.py +68 -0
- sticker_convert/utils/chromiums/windows.py +45 -0
- sticker_convert/utils/emoji.py +28 -0
- sticker_convert/utils/files/json_resources_loader.py +24 -19
- sticker_convert/utils/files/metadata_handler.py +8 -7
- sticker_convert/utils/files/run_bin.py +1 -1
- sticker_convert/utils/media/codec_info.py +99 -67
- sticker_convert/utils/media/format_verify.py +33 -20
- sticker_convert/utils/process.py +231 -0
- sticker_convert/utils/translate.py +108 -0
- sticker_convert/utils/url_detect.py +40 -33
- sticker_convert/version.py +1 -1
- {sticker_convert-2.8.12.dist-info → sticker_convert-2.17.0.0.dist-info}/METADATA +189 -96
- sticker_convert-2.17.0.0.dist-info/RECORD +138 -0
- {sticker_convert-2.8.12.dist-info → sticker_convert-2.17.0.0.dist-info}/WHEEL +1 -1
- sticker_convert/utils/auth/get_signal_auth.py +0 -129
- sticker_convert-2.8.12.dist-info/RECORD +0 -101
- {sticker_convert-2.8.12.dist-info → sticker_convert-2.17.0.0.dist-info}/entry_points.txt +0 -0
- {sticker_convert-2.8.12.dist-info → sticker_convert-2.17.0.0.dist-info/licenses}/LICENSE +0 -0
- {sticker_convert-2.8.12.dist-info → sticker_convert-2.17.0.0.dist-info}/top_level.txt +0 -0
|
@@ -1,300 +1,331 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
import json
|
|
3
|
-
import secrets
|
|
4
|
-
import uuid
|
|
5
|
-
from typing import Any,
|
|
6
|
-
from urllib.parse import parse_qs, urlparse
|
|
7
|
-
|
|
8
|
-
import requests
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
self.
|
|
22
|
-
self.
|
|
23
|
-
self.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
self.
|
|
27
|
-
self.
|
|
28
|
-
self.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
self.
|
|
33
|
-
self.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
self.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
self.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
"
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
)
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
"
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
"
|
|
214
|
-
"
|
|
215
|
-
"
|
|
216
|
-
"
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
"
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
if response_json["status"] != 0:
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
"
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
self.
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
self.
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import json
|
|
3
|
+
import secrets
|
|
4
|
+
import uuid
|
|
5
|
+
from typing import Any, Dict, Optional, Tuple
|
|
6
|
+
from urllib.parse import parse_qs, urlparse
|
|
7
|
+
|
|
8
|
+
import requests
|
|
9
|
+
from bs4 import BeautifulSoup
|
|
10
|
+
|
|
11
|
+
from sticker_convert.auth.auth_base import AuthBase
|
|
12
|
+
from sticker_convert.utils.translate import I
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class AuthKakaoAndroidLogin(AuthBase):
|
|
16
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
17
|
+
self.OK_MSG = I("Got auth_token successfully:\nauth_token={}\n")
|
|
18
|
+
|
|
19
|
+
super().__init__(*args, **kwargs)
|
|
20
|
+
self.username = self.opt_cred.kakao_username
|
|
21
|
+
self.password = self.opt_cred.kakao_password
|
|
22
|
+
self.country_code = self.opt_cred.kakao_country_code
|
|
23
|
+
self.phone_number = self.opt_cred.kakao_phone_number
|
|
24
|
+
|
|
25
|
+
self.device_uuid = secrets.token_hex(32)
|
|
26
|
+
self.device_ssaid = secrets.token_hex(20)
|
|
27
|
+
self.uuid_c = str(uuid.uuid4())
|
|
28
|
+
self.device_info = (
|
|
29
|
+
f"android/30; uuid={self.device_uuid}; ssaid={self.device_ssaid}; "
|
|
30
|
+
+ "model=SDK_GPHONE_X86_64; screen_resolution=1080x1920; sim=310260/1/us; onestore=false; uvc3=null"
|
|
31
|
+
)
|
|
32
|
+
self.app_platform = "android"
|
|
33
|
+
self.app_version_number = self.get_version()
|
|
34
|
+
self.app_language = "en"
|
|
35
|
+
self.app_version = (
|
|
36
|
+
f"{self.app_platform}/{self.app_version_number}/{self.app_language}"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
self.headers = {
|
|
40
|
+
"Host": "katalk.kakao.com",
|
|
41
|
+
"Accept-Language": "en",
|
|
42
|
+
"User-Agent": f"KT/{self.app_version_number} An/11 en",
|
|
43
|
+
"Device-Info": self.device_info,
|
|
44
|
+
"A": self.app_version,
|
|
45
|
+
"C": self.uuid_c,
|
|
46
|
+
"Content-Type": "application/json",
|
|
47
|
+
"Connection": "close",
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
def get_version(self) -> str:
|
|
51
|
+
# It is difficult to get app version number from Google Play
|
|
52
|
+
r = requests.get(
|
|
53
|
+
"https://apkpure.net/kakaotalk-messenger/com.kakao.talk/versions"
|
|
54
|
+
)
|
|
55
|
+
soup = BeautifulSoup(r.text, "html.parser")
|
|
56
|
+
for li in soup.find_all("li"):
|
|
57
|
+
a = li.find("a", class_="dt-version-icon")
|
|
58
|
+
if a is None:
|
|
59
|
+
continue
|
|
60
|
+
if "/kakaotalk-messenger/com.kakao.talk/download/" in a.get("href", ""):
|
|
61
|
+
return a.get("href").split("/")[-1]
|
|
62
|
+
return "25.2.1"
|
|
63
|
+
|
|
64
|
+
def login(self) -> Tuple[bool, str]:
|
|
65
|
+
msg = I("Getting Kakao authorization token by Android login: Logging in")
|
|
66
|
+
self.cb.put(("msg_dynamic", (msg,), None))
|
|
67
|
+
|
|
68
|
+
json_data = {
|
|
69
|
+
"id": self.username,
|
|
70
|
+
"password": self.password,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
response = requests.post(
|
|
74
|
+
"https://katalk.kakao.com/android/account2/login",
|
|
75
|
+
headers=self.headers,
|
|
76
|
+
json=json_data,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
response_json = json.loads(response.text)
|
|
80
|
+
|
|
81
|
+
self.cb.put(("msg_dynamic", (None,), None))
|
|
82
|
+
if response_json["status"] != 0:
|
|
83
|
+
return False, f"Failed at login: {response.text}"
|
|
84
|
+
|
|
85
|
+
self.headers["Ss"] = response.headers["Set-SS"]
|
|
86
|
+
self.country_dicts = response_json["viewData"]["countries"]["all"]
|
|
87
|
+
|
|
88
|
+
return True, ""
|
|
89
|
+
|
|
90
|
+
def get_country_iso(self) -> Tuple[bool, str]:
|
|
91
|
+
self.country_iso = None
|
|
92
|
+
for country_dict in self.country_dicts:
|
|
93
|
+
if country_dict["code"] == self.country_code:
|
|
94
|
+
self.country_iso = country_dict["iso"]
|
|
95
|
+
|
|
96
|
+
if not self.country_iso:
|
|
97
|
+
return False, "Invalid country code"
|
|
98
|
+
|
|
99
|
+
return True, ""
|
|
100
|
+
|
|
101
|
+
def enter_phone(self) -> Tuple[bool, str]:
|
|
102
|
+
msg = I(
|
|
103
|
+
"Getting Kakao authorization token by Android login: Submitting phone number"
|
|
104
|
+
)
|
|
105
|
+
self.cb.put(("msg_dynamic", (msg,), None))
|
|
106
|
+
|
|
107
|
+
json_data: Dict[str, Any] = {
|
|
108
|
+
"countryCode": self.country_code,
|
|
109
|
+
"countryIso": self.country_iso,
|
|
110
|
+
"phoneNumber": self.phone_number,
|
|
111
|
+
"termCodes": [],
|
|
112
|
+
"simPhoneNumber": f"+{self.country_code}{self.phone_number}",
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
response = requests.post(
|
|
116
|
+
"https://katalk.kakao.com/android/account2/phone-number",
|
|
117
|
+
headers=self.headers,
|
|
118
|
+
json=json_data,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
response_json = json.loads(response.text)
|
|
122
|
+
|
|
123
|
+
self.cb.put(("msg_dynamic", (None,), None))
|
|
124
|
+
if response_json["status"] != 0:
|
|
125
|
+
return False, f"Failed at entering phone number: {response.text}"
|
|
126
|
+
|
|
127
|
+
self.verify_method = response_json["view"]
|
|
128
|
+
|
|
129
|
+
if self.verify_method == "passcode":
|
|
130
|
+
return self.verify_receive_sms()
|
|
131
|
+
if self.verify_method == "mo-send":
|
|
132
|
+
dest_number = response_json["viewData"]["moNumber"]
|
|
133
|
+
msg = response_json["viewData"]["moMessage"]
|
|
134
|
+
return self.verify_send_sms(dest_number, msg)
|
|
135
|
+
return False, f"Unknown verification method: {response.text}"
|
|
136
|
+
|
|
137
|
+
def verify_send_sms(self, dest_number: str, verify_msg: str) -> Tuple[bool, str]:
|
|
138
|
+
response = requests.post(
|
|
139
|
+
"https://katalk.kakao.com/android/account2/mo-sent", headers=self.headers
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
response_json = json.loads(response.text)
|
|
143
|
+
|
|
144
|
+
if response_json["status"] != 0:
|
|
145
|
+
return False, f"Failed at confirm sending SMS: {response.text}"
|
|
146
|
+
|
|
147
|
+
prompt = I("Send this SMS message to number {} then press enter:").format(
|
|
148
|
+
dest_number
|
|
149
|
+
)
|
|
150
|
+
self.cb.put(
|
|
151
|
+
(
|
|
152
|
+
"ask_str",
|
|
153
|
+
None,
|
|
154
|
+
{
|
|
155
|
+
"msg": prompt,
|
|
156
|
+
"initialvalue": verify_msg,
|
|
157
|
+
"cli_show_initialvalue": False,
|
|
158
|
+
},
|
|
159
|
+
)
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
response = requests.post(
|
|
163
|
+
"https://katalk.kakao.com/android/account2/mo-confirm", headers=self.headers
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
response_json = json.loads(response.text)
|
|
167
|
+
|
|
168
|
+
if response_json["status"] != 0:
|
|
169
|
+
return False, f"Failed at verifying SMS sent: {response.text}"
|
|
170
|
+
|
|
171
|
+
if response_json.get("reason") or "error" in response_json.get("message", ""):
|
|
172
|
+
return False, f"Failed at verifying SMS sent: {response.text}"
|
|
173
|
+
|
|
174
|
+
self.confirm_url = response_json.get("viewData", {}).get("url")
|
|
175
|
+
|
|
176
|
+
return True, ""
|
|
177
|
+
|
|
178
|
+
def verify_receive_sms(self) -> Tuple[bool, str]:
|
|
179
|
+
msg = I("Enter passcode received from SMS:")
|
|
180
|
+
passcode = self.cb.put(("ask_str", (msg,), None))
|
|
181
|
+
|
|
182
|
+
json_data = {
|
|
183
|
+
"passcode": passcode,
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
response = requests.post(
|
|
187
|
+
"https://katalk.kakao.com/android/account2/passcode",
|
|
188
|
+
headers=self.headers,
|
|
189
|
+
json=json_data,
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
response_json = json.loads(response.text)
|
|
193
|
+
|
|
194
|
+
self.cb.put(("msg_dynamic", (None,), None))
|
|
195
|
+
if response_json["status"] != 0:
|
|
196
|
+
return False, f"Failed at verifying passcode: {response.text}"
|
|
197
|
+
|
|
198
|
+
self.confirm_url = response_json.get("viewData", {}).get("url")
|
|
199
|
+
|
|
200
|
+
return True, ""
|
|
201
|
+
|
|
202
|
+
def confirm_device_change(self) -> Tuple[bool, str]:
|
|
203
|
+
msg = I(
|
|
204
|
+
"Getting Kakao authorization token by Android login: Confirm device change"
|
|
205
|
+
)
|
|
206
|
+
self.cb.put(("msg_dynamic", (msg,), None))
|
|
207
|
+
|
|
208
|
+
confirm_url_parsed = urlparse(self.confirm_url) # type: ignore
|
|
209
|
+
confirm_url_qs = parse_qs(confirm_url_parsed.query) # type: ignore
|
|
210
|
+
session_token: str = confirm_url_qs["sessionToken"][0] # type: ignore
|
|
211
|
+
|
|
212
|
+
headers_browser = {
|
|
213
|
+
"Host": "katalk.kakao.com",
|
|
214
|
+
"Accept": "*/*",
|
|
215
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
216
|
+
"User-Agent": "Mozilla/5.0 (Linux; Android 11; Android SDK built for x86 Build/RSR1.210210.001.A1; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/83.0.4103.106 Mobile Safari/537.36;KAKAOTALK 2410030",
|
|
217
|
+
"Content-Type": "application/json",
|
|
218
|
+
"Origin": "https://katalk.kakao.com",
|
|
219
|
+
"Sec-Fetch-Site": "same-origin",
|
|
220
|
+
"Sec-Fetch-Mode": "cors",
|
|
221
|
+
"Sec-Fetch-Dest": "empty",
|
|
222
|
+
"Referer": self.confirm_url,
|
|
223
|
+
"Accept-Language": "en-US,en;q=0.9",
|
|
224
|
+
"Connection": "close",
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
json_data: Dict[str, str] = {
|
|
228
|
+
"decision": "continue",
|
|
229
|
+
"lang": self.app_language,
|
|
230
|
+
"sessionToken": session_token,
|
|
231
|
+
"appVersion": self.app_version_number,
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
response = requests.post(
|
|
235
|
+
"https://katalk.kakao.com/android/account2/confirm-device-change",
|
|
236
|
+
headers=headers_browser,
|
|
237
|
+
json=json_data,
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
response_json = json.loads(response.text)
|
|
241
|
+
|
|
242
|
+
self.cb.put(("msg_dynamic", (None,), None))
|
|
243
|
+
if response_json["status"] != 0:
|
|
244
|
+
return False, f"Failed at confirm device change: {response.text}"
|
|
245
|
+
|
|
246
|
+
return True, ""
|
|
247
|
+
|
|
248
|
+
def passcode_callback(self) -> Tuple[bool, str]:
|
|
249
|
+
msg = I("Getting Kakao authorization token by Android login: Passcode callback")
|
|
250
|
+
self.cb.put(("msg_dynamic", (msg,), None))
|
|
251
|
+
|
|
252
|
+
response = requests.get(
|
|
253
|
+
"https://katalk.kakao.com/android/account2/passcode/callback",
|
|
254
|
+
headers=self.headers,
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
response_json = json.loads(response.text)
|
|
258
|
+
|
|
259
|
+
self.cb.put(("msg_dynamic", (None,), None))
|
|
260
|
+
if response_json["status"] != 0:
|
|
261
|
+
return False, f"Failed at passcode callback: {response.text}"
|
|
262
|
+
|
|
263
|
+
return True, ""
|
|
264
|
+
|
|
265
|
+
def skip_restoration(self) -> Tuple[bool, str]:
|
|
266
|
+
msg = I("Getting Kakao authorization token by Android login: Skip restoration")
|
|
267
|
+
self.cb.put(("msg_dynamic", (msg,), None))
|
|
268
|
+
|
|
269
|
+
response = requests.post(
|
|
270
|
+
"https://katalk.kakao.com/android/account2/skip-restoration",
|
|
271
|
+
headers=self.headers,
|
|
272
|
+
)
|
|
273
|
+
response_json = json.loads(response.text)
|
|
274
|
+
|
|
275
|
+
if response_json["status"] != 0:
|
|
276
|
+
return False, f"Failed at skip restoration: {response.text}"
|
|
277
|
+
|
|
278
|
+
self.nickname = response_json.get("viewData", {}).get("nickname")
|
|
279
|
+
|
|
280
|
+
self.cb.put(("msg_dynamic", (None,), None))
|
|
281
|
+
if self.nickname is None:
|
|
282
|
+
return False, f"Failed at passcode callback: {response.text}"
|
|
283
|
+
|
|
284
|
+
return True, ""
|
|
285
|
+
|
|
286
|
+
def get_profile(self) -> Tuple[bool, str]:
|
|
287
|
+
msg = I("Getting Kakao authorization token by Android login: Get profile")
|
|
288
|
+
self.cb.put(("msg_dynamic", (msg,), None))
|
|
289
|
+
|
|
290
|
+
json_data = {
|
|
291
|
+
"nickname": self.nickname,
|
|
292
|
+
"profileImageFlag": 1,
|
|
293
|
+
"friendAutomation": True,
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
response = requests.post(
|
|
297
|
+
"https://katalk.kakao.com/android/account2/profile",
|
|
298
|
+
headers=self.headers,
|
|
299
|
+
json=json_data,
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
response_json = json.loads(response.text)
|
|
303
|
+
|
|
304
|
+
self.cb.put(("msg_dynamic", (None,), None))
|
|
305
|
+
if response_json["status"] != 0:
|
|
306
|
+
return False, f"Failed at get profile: {response.text}"
|
|
307
|
+
|
|
308
|
+
self.access_token = response_json["signupData"]["oauth2Token"]["accessToken"]
|
|
309
|
+
|
|
310
|
+
return True, ""
|
|
311
|
+
|
|
312
|
+
def get_cred(self) -> Tuple[Optional[str], str]:
|
|
313
|
+
auth_token = None
|
|
314
|
+
|
|
315
|
+
steps = (
|
|
316
|
+
self.login,
|
|
317
|
+
self.get_country_iso,
|
|
318
|
+
self.enter_phone,
|
|
319
|
+
self.confirm_device_change,
|
|
320
|
+
self.passcode_callback,
|
|
321
|
+
self.skip_restoration,
|
|
322
|
+
self.get_profile,
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
for step in steps:
|
|
326
|
+
success, msg = step()
|
|
327
|
+
if not success:
|
|
328
|
+
return None, msg
|
|
329
|
+
|
|
330
|
+
auth_token = self.access_token + "-" + self.device_uuid
|
|
331
|
+
return auth_token, self.OK_MSG.format(auth_token)
|