sticker-convert 2.13.3.0__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 -27
- sticker_convert/auth/__init__.py +0 -0
- sticker_convert/auth/auth_base.py +19 -0
- sticker_convert/{utils/auth/get_discord_auth.py → auth/auth_discord.py} +149 -118
- sticker_convert/{utils/auth/get_kakao_auth.py → auth/auth_kakao_android_login.py} +331 -330
- sticker_convert/auth/auth_kakao_desktop_login.py +327 -0
- sticker_convert/{utils/auth/get_kakao_desktop_auth.py → auth/auth_kakao_desktop_memdump.py} +281 -263
- sticker_convert/{utils/auth/get_line_auth.py → auth/auth_line.py} +98 -80
- sticker_convert/{utils/auth/get_signal_auth.py → auth/auth_signal.py} +139 -135
- sticker_convert/auth/auth_telethon.py +161 -0
- sticker_convert/{utils/auth/get_viber_auth.py → auth/auth_viber.py} +250 -235
- sticker_convert/{utils/auth → auth}/telegram_api.py +736 -675
- sticker_convert/cli.py +623 -608
- sticker_convert/converter.py +1093 -1084
- sticker_convert/definitions.py +4 -0
- sticker_convert/downloaders/download_band.py +111 -110
- sticker_convert/downloaders/download_base.py +171 -166
- sticker_convert/downloaders/download_discord.py +92 -91
- sticker_convert/downloaders/download_kakao.py +417 -404
- sticker_convert/downloaders/download_line.py +484 -475
- sticker_convert/downloaders/download_ogq.py +80 -79
- sticker_convert/downloaders/download_signal.py +108 -105
- sticker_convert/downloaders/download_telegram.py +56 -55
- sticker_convert/downloaders/download_viber.py +121 -120
- sticker_convert/gui.py +788 -873
- sticker_convert/gui_components/frames/comp_frame.py +180 -166
- 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 -233
- 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 -757
- sticker_convert/gui_components/windows/base_window.py +7 -2
- sticker_convert/gui_components/windows/discord_get_auth_window.py +79 -82
- sticker_convert/gui_components/windows/kakao_get_auth_window.py +511 -321
- sticker_convert/gui_components/windows/line_get_auth_window.py +94 -102
- sticker_convert/gui_components/windows/signal_get_auth_window.py +84 -89
- sticker_convert/gui_components/windows/viber_get_auth_window.py +168 -168
- sticker_convert/ios-message-stickers-template/.github/FUNDING.yml +3 -3
- 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 2.sticker/Contents.json +9 -9
- 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/iMessage App Icon.stickersiconset/Contents.json +91 -91
- 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/xcuserdata/niklaspeterson.xcuserdatad/xcschemes/xcschememanagement.plist +14 -14
- sticker_convert/job.py +166 -130
- sticker_convert/job_option.py +1 -0
- 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/help.ja_JP.json +88 -0
- sticker_convert/resources/help.json +10 -7
- 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 -121
- sticker_convert/resources/input.zh_CN.json +74 -0
- sticker_convert/resources/input.zh_TW.json +74 -0
- sticker_convert/resources/output.ja_JP.json +38 -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 -177
- sticker_convert/uploaders/upload_base.py +44 -35
- sticker_convert/uploaders/upload_signal.py +218 -203
- sticker_convert/uploaders/upload_telegram.py +353 -338
- sticker_convert/uploaders/upload_viber.py +178 -169
- sticker_convert/uploaders/xcode_imessage.py +295 -286
- sticker_convert/utils/callback.py +238 -6
- sticker_convert/utils/emoji.py +16 -4
- sticker_convert/utils/files/json_resources_loader.py +24 -19
- sticker_convert/utils/files/metadata_handler.py +3 -3
- sticker_convert/utils/translate.py +108 -0
- sticker_convert/utils/url_detect.py +40 -37
- sticker_convert/version.py +1 -1
- {sticker_convert-2.13.3.0.dist-info → sticker_convert-2.17.0.0.dist-info}/METADATA +89 -74
- {sticker_convert-2.13.3.0.dist-info → sticker_convert-2.17.0.0.dist-info}/RECORD +91 -74
- sticker_convert/utils/auth/telethon_setup.py +0 -97
- sticker_convert/utils/singletons.py +0 -18
- {sticker_convert-2.13.3.0.dist-info → sticker_convert-2.17.0.0.dist-info}/WHEEL +0 -0
- {sticker_convert-2.13.3.0.dist-info → sticker_convert-2.17.0.0.dist-info}/entry_points.txt +0 -0
- {sticker_convert-2.13.3.0.dist-info → sticker_convert-2.17.0.0.dist-info}/licenses/LICENSE +0 -0
- {sticker_convert-2.13.3.0.dist-info → sticker_convert-2.17.0.0.dist-info}/top_level.txt +0 -0
|
@@ -1,80 +1,98 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
import json
|
|
3
|
-
import platform
|
|
4
|
-
from http.cookiejar import CookieJar
|
|
5
|
-
from typing import Any, Callable, Dict, List, Optional, Union
|
|
6
|
-
|
|
7
|
-
import requests
|
|
8
|
-
import rookiepy
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import json
|
|
3
|
+
import platform
|
|
4
|
+
from http.cookiejar import CookieJar
|
|
5
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
|
6
|
+
|
|
7
|
+
import requests
|
|
8
|
+
import rookiepy
|
|
9
|
+
|
|
10
|
+
from sticker_convert.auth.auth_base import AuthBase
|
|
11
|
+
from sticker_convert.utils.translate import I
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AuthLine(AuthBase):
|
|
15
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
16
|
+
self.OK_MSG = I("Got Line cookies successfully")
|
|
17
|
+
self.FAIL_MSG = I(
|
|
18
|
+
"Failed to get Line cookies. Have you logged in the web browser?"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
super().__init__(*args, **kwargs)
|
|
22
|
+
|
|
23
|
+
def get_cred(self) -> Tuple[Optional[str], str]:
|
|
24
|
+
msg = I("Getting Line cookies")
|
|
25
|
+
self.cb.put(("msg_dynamic", (msg,), None))
|
|
26
|
+
|
|
27
|
+
browsers: List[Callable[..., Any]] = [
|
|
28
|
+
rookiepy.load, # Supposed to load from any browser, but may fail
|
|
29
|
+
rookiepy.firefox,
|
|
30
|
+
rookiepy.librewolf,
|
|
31
|
+
rookiepy.chrome,
|
|
32
|
+
rookiepy.chromium,
|
|
33
|
+
rookiepy.brave,
|
|
34
|
+
rookiepy.edge,
|
|
35
|
+
rookiepy.opera,
|
|
36
|
+
rookiepy.vivaldi,
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
if platform.system() == "Windows":
|
|
40
|
+
browsers.extend(
|
|
41
|
+
[
|
|
42
|
+
rookiepy.opera_gx,
|
|
43
|
+
rookiepy.internet_explorer,
|
|
44
|
+
]
|
|
45
|
+
)
|
|
46
|
+
elif platform.system() == "Darwin":
|
|
47
|
+
browsers.extend(
|
|
48
|
+
[
|
|
49
|
+
rookiepy.opera_gx,
|
|
50
|
+
rookiepy.safari,
|
|
51
|
+
]
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
cookies_dict = None
|
|
55
|
+
cookies_jar = None
|
|
56
|
+
for browser in browsers:
|
|
57
|
+
try:
|
|
58
|
+
cookies_dict = browser(["store.line.me"])
|
|
59
|
+
cookies_jar = rookiepy.to_cookiejar(cookies_dict)
|
|
60
|
+
|
|
61
|
+
if AuthLine.validate_cookies(cookies_jar):
|
|
62
|
+
break
|
|
63
|
+
|
|
64
|
+
except Exception:
|
|
65
|
+
continue
|
|
66
|
+
|
|
67
|
+
self.cb.put(("msg_dynamic", (None,), None))
|
|
68
|
+
if cookies_dict is None or cookies_jar is None:
|
|
69
|
+
return (
|
|
70
|
+
None,
|
|
71
|
+
self.FAIL_MSG,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
cookies_list = ["%s=%s" % (i["name"], i["value"]) for i in cookies_dict]
|
|
75
|
+
cookies = ";".join(cookies_list)
|
|
76
|
+
|
|
77
|
+
return cookies, self.OK_MSG
|
|
78
|
+
|
|
79
|
+
@staticmethod
|
|
80
|
+
def validate_cookies(cookies: Union[CookieJar, Dict[str, str]]) -> bool:
|
|
81
|
+
headers = {
|
|
82
|
+
"x-requested-with": "XMLHttpRequest",
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
params = {"text": "test"}
|
|
86
|
+
|
|
87
|
+
response = requests.get(
|
|
88
|
+
"https://store.line.me/api/custom-sticker/validate/13782/en",
|
|
89
|
+
params=params,
|
|
90
|
+
cookies=cookies, # type: ignore
|
|
91
|
+
headers=headers,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
response_dict = json.loads(response.text)
|
|
95
|
+
|
|
96
|
+
if response_dict["errorMessage"]:
|
|
97
|
+
return False
|
|
98
|
+
return True
|
|
@@ -1,135 +1,139 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
import json
|
|
3
|
-
import os
|
|
4
|
-
import platform
|
|
5
|
-
import shutil
|
|
6
|
-
import time
|
|
7
|
-
import webbrowser
|
|
8
|
-
from typing import
|
|
9
|
-
|
|
10
|
-
from sticker_convert.
|
|
11
|
-
from sticker_convert.
|
|
12
|
-
from sticker_convert.utils.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
crd
|
|
88
|
-
|
|
89
|
-
# crd.
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
# data
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
#
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
json.loads(r)
|
|
114
|
-
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
json.loads(r)
|
|
128
|
-
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
import platform
|
|
5
|
+
import shutil
|
|
6
|
+
import time
|
|
7
|
+
import webbrowser
|
|
8
|
+
from typing import Any, Optional, Tuple, cast
|
|
9
|
+
|
|
10
|
+
from sticker_convert.auth.auth_base import AuthBase
|
|
11
|
+
from sticker_convert.definitions import CONFIG_DIR
|
|
12
|
+
from sticker_convert.utils.chrome_remotedebug import CRD
|
|
13
|
+
from sticker_convert.utils.process import killall
|
|
14
|
+
from sticker_convert.utils.translate import I
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class AuthSignal(AuthBase):
|
|
18
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
19
|
+
self.MSG_NO_SIGDESK = I(
|
|
20
|
+
"Signal Desktop not detected.\n"
|
|
21
|
+
"Download and install Signal Desktop version\n"
|
|
22
|
+
"After installation, quit Signal Desktop before continuing"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
super().__init__(*args, **kwargs)
|
|
26
|
+
chromedriver_download_dir = CONFIG_DIR / "bin"
|
|
27
|
+
os.makedirs(chromedriver_download_dir, exist_ok=True)
|
|
28
|
+
|
|
29
|
+
self.chromedriver_download_dir = chromedriver_download_dir
|
|
30
|
+
|
|
31
|
+
def download_signal_desktop(self) -> None:
|
|
32
|
+
download_url = "https://signal.org/en/download/"
|
|
33
|
+
|
|
34
|
+
webbrowser.open(download_url)
|
|
35
|
+
|
|
36
|
+
self.cb.put(download_url)
|
|
37
|
+
|
|
38
|
+
self.cb.put(("ask_str", (self.MSG_NO_SIGDESK,), None))
|
|
39
|
+
|
|
40
|
+
def get_signal_bin_path(self) -> Optional[str]:
|
|
41
|
+
signal_paths: Tuple[Optional[str], ...]
|
|
42
|
+
if platform.system() == "Windows":
|
|
43
|
+
signal_paths = (
|
|
44
|
+
os.path.expandvars("%localappdata%/Programs/signal-desktop/Signal.exe"),
|
|
45
|
+
os.path.expandvars(
|
|
46
|
+
"%localappdata%/Programs/signal-desktop-beta/Signal Beta.exe"
|
|
47
|
+
),
|
|
48
|
+
)
|
|
49
|
+
elif platform.system() == "Darwin":
|
|
50
|
+
signal_paths = (
|
|
51
|
+
"/Applications/Signal.app/Contents/MacOS/Signal",
|
|
52
|
+
"/Applications/Signal Beta.app/Contents/MacOS/Signal Beta",
|
|
53
|
+
)
|
|
54
|
+
else:
|
|
55
|
+
signal_paths = (
|
|
56
|
+
shutil.which("signal-desktop"),
|
|
57
|
+
shutil.which("signal-desktop-beta"),
|
|
58
|
+
shutil.which("org.signal.Signal"), # Flatpak
|
|
59
|
+
os.path.expanduser(
|
|
60
|
+
"~/.local/share/flatpak/exports/bin/org.signal.Signal"
|
|
61
|
+
),
|
|
62
|
+
"/var/lib/flatpak/exports/bin/org.signal.Signal",
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
for signal_path in signal_paths:
|
|
66
|
+
if signal_path is not None and os.path.isfile(signal_path):
|
|
67
|
+
return signal_path
|
|
68
|
+
return None
|
|
69
|
+
|
|
70
|
+
def get_cred(self) -> Tuple[Optional[str], Optional[str], str]:
|
|
71
|
+
msg = I("Getting Signal credentials...")
|
|
72
|
+
self.cb.put(("msg_dynamic", (msg,), None))
|
|
73
|
+
signal_bin_path = self.get_signal_bin_path()
|
|
74
|
+
if signal_bin_path is None:
|
|
75
|
+
self.cb.put(("msg_dynamic", (None,), None))
|
|
76
|
+
self.download_signal_desktop()
|
|
77
|
+
return None, None, I("Failed to get uuid and password")
|
|
78
|
+
|
|
79
|
+
if platform.system() == "Windows":
|
|
80
|
+
killall("signal")
|
|
81
|
+
else:
|
|
82
|
+
killall("signal-desktop")
|
|
83
|
+
|
|
84
|
+
crd = CRD(signal_bin_path)
|
|
85
|
+
crd.connect()
|
|
86
|
+
# crd.runtime_enable()
|
|
87
|
+
# crd.reload()
|
|
88
|
+
# while True:
|
|
89
|
+
# r = crd.ws.recv()
|
|
90
|
+
# data = json.loads(r)
|
|
91
|
+
# if data.get("method") == "Runtime.executionContextCreated":
|
|
92
|
+
# print(data)
|
|
93
|
+
# if (data.get("method") == "Runtime.executionContextCreated" and
|
|
94
|
+
# data["params"]["context"]["name"] == "Electron Isolated Context"
|
|
95
|
+
# ):
|
|
96
|
+
# context_id = data["params"]["context"]["id"]
|
|
97
|
+
# break
|
|
98
|
+
# crd.runtime_disable()
|
|
99
|
+
context_id = 2
|
|
100
|
+
|
|
101
|
+
uuid, password = None, None
|
|
102
|
+
while True:
|
|
103
|
+
try:
|
|
104
|
+
r = crd.exec_js(
|
|
105
|
+
"window.reduxStore.getState().items.uuid_id", context_id
|
|
106
|
+
)
|
|
107
|
+
except RuntimeError:
|
|
108
|
+
break
|
|
109
|
+
if (
|
|
110
|
+
json.loads(r).get("result", {}).get("result", {}).get("type", "")
|
|
111
|
+
== "string"
|
|
112
|
+
):
|
|
113
|
+
uuid = cast(str, json.loads(r)["result"]["result"]["value"])
|
|
114
|
+
break
|
|
115
|
+
time.sleep(1)
|
|
116
|
+
while True:
|
|
117
|
+
try:
|
|
118
|
+
r = crd.exec_js(
|
|
119
|
+
"window.reduxStore.getState().items.password", context_id
|
|
120
|
+
)
|
|
121
|
+
except RuntimeError:
|
|
122
|
+
break
|
|
123
|
+
if (
|
|
124
|
+
json.loads(r).get("result", {}).get("result", {}).get("type", "")
|
|
125
|
+
== "string"
|
|
126
|
+
):
|
|
127
|
+
password = cast(str, json.loads(r)["result"]["result"]["value"])
|
|
128
|
+
break
|
|
129
|
+
time.sleep(1)
|
|
130
|
+
|
|
131
|
+
crd.close()
|
|
132
|
+
self.cb.put(("msg_dynamic", (None,), None))
|
|
133
|
+
return (
|
|
134
|
+
uuid,
|
|
135
|
+
password,
|
|
136
|
+
I("Got uuid and password successfully:\nuuid={}\npassword={}").format(
|
|
137
|
+
uuid, password
|
|
138
|
+
),
|
|
139
|
+
)
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
from typing import Any, Optional, Tuple
|
|
3
|
+
|
|
4
|
+
import anyio
|
|
5
|
+
from telethon import TelegramClient # type: ignore
|
|
6
|
+
from telethon.errors import RPCError, SessionPasswordNeededError # type: ignore
|
|
7
|
+
|
|
8
|
+
from sticker_convert.auth.auth_base import AuthBase
|
|
9
|
+
from sticker_convert.definitions import CONFIG_DIR
|
|
10
|
+
from sticker_convert.utils.translate import I
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AuthTelethon(AuthBase):
|
|
14
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
15
|
+
self.GUIDE_MSG = I(
|
|
16
|
+
"1. Visit {telegram_api_url}\n"
|
|
17
|
+
"2. Login using your phone number\n"
|
|
18
|
+
'3. Go to "API development tools"\n'
|
|
19
|
+
"4. Fill form\n"
|
|
20
|
+
"- App title: sticker-convert\n"
|
|
21
|
+
"- Short name: sticker-convert\n"
|
|
22
|
+
"- URL: www.telegram.org\n"
|
|
23
|
+
"- Platform: Desktop\n"
|
|
24
|
+
"- Description: sticker-convert\n"
|
|
25
|
+
"5. Note down api_id and api_hash\n"
|
|
26
|
+
"Continue when done"
|
|
27
|
+
)
|
|
28
|
+
self.TELEGRAM_API_URL = "https://my.telegram.org"
|
|
29
|
+
self.OK_MSG = I("Telethon setup successful")
|
|
30
|
+
self.FAIL_MSG = I("Telethon setup failed")
|
|
31
|
+
|
|
32
|
+
super().__init__(*args, **kwargs)
|
|
33
|
+
|
|
34
|
+
async def signin_async(
|
|
35
|
+
self, try_sign_in: bool = True
|
|
36
|
+
) -> Tuple[bool, TelegramClient, int, str, str]:
|
|
37
|
+
client = TelegramClient(
|
|
38
|
+
CONFIG_DIR / f"telethon-{self.opt_cred.telethon_api_id}.session",
|
|
39
|
+
self.opt_cred.telethon_api_id,
|
|
40
|
+
self.opt_cred.telethon_api_hash,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
await client.connect()
|
|
44
|
+
authed = await client.is_user_authorized()
|
|
45
|
+
if authed is False and try_sign_in is True:
|
|
46
|
+
error_msg = ""
|
|
47
|
+
while True:
|
|
48
|
+
msg = error_msg + I("Enter phone number: ")
|
|
49
|
+
phone_number = self.cb.put(("ask_str", (msg,), None))
|
|
50
|
+
if phone_number == "":
|
|
51
|
+
return False, client, 0, "", self.FAIL_MSG
|
|
52
|
+
try:
|
|
53
|
+
await client.send_code_request(phone_number)
|
|
54
|
+
break
|
|
55
|
+
except RPCError as e:
|
|
56
|
+
error_msg = f"Error: {e}\n"
|
|
57
|
+
|
|
58
|
+
error_msg = ""
|
|
59
|
+
while True:
|
|
60
|
+
msg = error_msg + I("Enter code: ")
|
|
61
|
+
code = self.cb.put(("ask_str", (msg,), None))
|
|
62
|
+
if code == "":
|
|
63
|
+
return False, client, 0, "", self.FAIL_MSG
|
|
64
|
+
try:
|
|
65
|
+
await client.sign_in(phone_number, code)
|
|
66
|
+
break
|
|
67
|
+
except SessionPasswordNeededError:
|
|
68
|
+
password = self.cb.put(
|
|
69
|
+
(
|
|
70
|
+
"ask_str",
|
|
71
|
+
None,
|
|
72
|
+
{"question": "Enter password: ", "password": True},
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
try:
|
|
76
|
+
await client.sign_in(password=password)
|
|
77
|
+
break
|
|
78
|
+
except RPCError as e:
|
|
79
|
+
error_msg = f"Error: {e}\n"
|
|
80
|
+
except RPCError as e:
|
|
81
|
+
error_msg = f"Error: {e}\n"
|
|
82
|
+
authed = await client.is_user_authorized()
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
authed,
|
|
86
|
+
client,
|
|
87
|
+
self.opt_cred.telethon_api_id,
|
|
88
|
+
self.opt_cred.telethon_api_hash,
|
|
89
|
+
self.OK_MSG if authed else self.FAIL_MSG,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
def guide(self) -> None:
|
|
93
|
+
self.cb.put(
|
|
94
|
+
(
|
|
95
|
+
"msg_block",
|
|
96
|
+
(self.GUIDE_MSG.format(telegram_api_url=self.TELEGRAM_API_URL),),
|
|
97
|
+
None,
|
|
98
|
+
)
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
def get_api_info(self) -> bool:
|
|
102
|
+
api_id_ask = I("Enter api_id: ")
|
|
103
|
+
wrong_hint = ""
|
|
104
|
+
|
|
105
|
+
while True:
|
|
106
|
+
telethon_api_id = self.cb.put(
|
|
107
|
+
(
|
|
108
|
+
"ask_str",
|
|
109
|
+
None,
|
|
110
|
+
{
|
|
111
|
+
"question": wrong_hint + api_id_ask,
|
|
112
|
+
"initialvalue": str(self.opt_cred.telethon_api_id),
|
|
113
|
+
},
|
|
114
|
+
)
|
|
115
|
+
)
|
|
116
|
+
if telethon_api_id == "":
|
|
117
|
+
return False
|
|
118
|
+
elif telethon_api_id.isnumeric():
|
|
119
|
+
self.opt_cred.telethon_api_id = int(telethon_api_id)
|
|
120
|
+
break
|
|
121
|
+
else:
|
|
122
|
+
wrong_hint = I("Error: api_id should be numeric\n")
|
|
123
|
+
|
|
124
|
+
msg = I("Enter api_hash: ")
|
|
125
|
+
self.opt_cred.telethon_api_hash = self.cb.put(
|
|
126
|
+
(
|
|
127
|
+
"ask_str",
|
|
128
|
+
None,
|
|
129
|
+
{"question": msg, "initialvalue": self.opt_cred.telethon_api_hash},
|
|
130
|
+
)
|
|
131
|
+
)
|
|
132
|
+
if self.opt_cred.telethon_api_hash == "":
|
|
133
|
+
return False
|
|
134
|
+
return True
|
|
135
|
+
|
|
136
|
+
async def start_async(
|
|
137
|
+
self, check_auth_only: bool = False
|
|
138
|
+
) -> Tuple[bool, Optional[TelegramClient], int, str, str]:
|
|
139
|
+
if self.opt_cred.telethon_api_id != 0 and self.opt_cred.telethon_api_hash != "":
|
|
140
|
+
success, client, api_id, api_hash, msg = await self.signin_async(
|
|
141
|
+
try_sign_in=False
|
|
142
|
+
)
|
|
143
|
+
if check_auth_only:
|
|
144
|
+
client.disconnect()
|
|
145
|
+
if success is True:
|
|
146
|
+
return success, client, api_id, api_hash, msg
|
|
147
|
+
|
|
148
|
+
self.guide()
|
|
149
|
+
cred_valid = self.get_api_info()
|
|
150
|
+
if cred_valid:
|
|
151
|
+
success, client, api_id, api_hash, msg = await self.signin_async()
|
|
152
|
+
if check_auth_only:
|
|
153
|
+
client.disconnect()
|
|
154
|
+
return success, client, api_id, api_hash, msg
|
|
155
|
+
else:
|
|
156
|
+
return False, None, 0, "", self.FAIL_MSG
|
|
157
|
+
|
|
158
|
+
def start(
|
|
159
|
+
self, check_auth_only: bool = False
|
|
160
|
+
) -> Tuple[bool, Optional[TelegramClient], int, str, str]:
|
|
161
|
+
return anyio.run(self.start_async, check_auth_only)
|