sticker-convert 2.6.4__py3-none-any.whl → 2.7.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/cli.py +6 -11
- sticker_convert/gui_components/windows/signal_get_auth_window.py +42 -52
- sticker_convert/utils/auth/get_signal_auth.py +77 -308
- sticker_convert/utils/callback.py +0 -1
- sticker_convert/version.py +1 -1
- {sticker_convert-2.6.4.dist-info → sticker_convert-2.7.0.dist-info}/METADATA +4 -4
- {sticker_convert-2.6.4.dist-info → sticker_convert-2.7.0.dist-info}/RECORD +11 -11
- {sticker_convert-2.6.4.dist-info → sticker_convert-2.7.0.dist-info}/LICENSE +0 -0
- {sticker_convert-2.6.4.dist-info → sticker_convert-2.7.0.dist-info}/WHEEL +0 -0
- {sticker_convert-2.6.4.dist-info → sticker_convert-2.7.0.dist-info}/entry_points.txt +0 -0
- {sticker_convert-2.6.4.dist-info → sticker_convert-2.7.0.dist-info}/top_level.txt +0 -0
sticker_convert/cli.py
CHANGED
@@ -435,20 +435,15 @@ class CLI:
|
|
435
435
|
self.cb.msg(f"Got auth_token successfully: {auth_token}")
|
436
436
|
|
437
437
|
if args.signal_get_auth:
|
438
|
-
m = GetSignalAuth(
|
438
|
+
m = GetSignalAuth()
|
439
439
|
|
440
|
-
uuid, password =
|
441
|
-
while True:
|
442
|
-
uuid, password = m.get_cred()
|
440
|
+
uuid, password, msg = m.get_cred()
|
443
441
|
|
444
|
-
|
445
|
-
|
446
|
-
|
442
|
+
if uuid and password:
|
443
|
+
opt_cred.signal_uuid = uuid
|
444
|
+
opt_cred.signal_password = password
|
447
445
|
|
448
|
-
|
449
|
-
f"Got uuid and password successfully: {uuid}, {password}"
|
450
|
-
)
|
451
|
-
break
|
446
|
+
self.cb.msg(msg)
|
452
447
|
|
453
448
|
if args.line_get_auth:
|
454
449
|
m = GetLineAuth()
|
@@ -1,9 +1,9 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
2
|
from functools import partial
|
3
|
-
from
|
3
|
+
from subprocess import Popen
|
4
4
|
from typing import Any
|
5
5
|
|
6
|
-
from ttkbootstrap import Button, Frame, Label
|
6
|
+
from ttkbootstrap import Button, Frame, Label # type: ignore
|
7
7
|
|
8
8
|
from sticker_convert.gui_components.gui_utils import GUIUtils
|
9
9
|
from sticker_convert.gui_components.windows.base_window import BaseWindow
|
@@ -20,74 +20,64 @@ class SignalGetAuthWindow(BaseWindow):
|
|
20
20
|
self.cb_ask_str_signal = partial(self.gui.cb_ask_str, parent=self)
|
21
21
|
|
22
22
|
self.frame_info = Frame(self.scrollable_frame)
|
23
|
-
self.
|
23
|
+
self.frame_btns = Frame(self.scrollable_frame)
|
24
24
|
|
25
25
|
self.frame_info.grid(column=0, row=0, sticky="news", padx=3, pady=3)
|
26
|
-
self.
|
26
|
+
self.frame_btns.grid(column=0, row=1, sticky="news", padx=3, pady=3)
|
27
27
|
|
28
28
|
# Info frame
|
29
|
-
self.
|
29
|
+
self.explanation_lbl = Label(
|
30
30
|
self.frame_info,
|
31
|
-
text="Please install Signal Desktop
|
32
|
-
justify="left",
|
33
|
-
anchor="w",
|
34
|
-
)
|
35
|
-
self.explanation2_lbl = Label(
|
36
|
-
self.frame_info,
|
37
|
-
text="After installation, you need to login to Signal Desktop",
|
38
|
-
justify="left",
|
39
|
-
anchor="w",
|
40
|
-
)
|
41
|
-
self.explanation3_lbl = Label(
|
42
|
-
self.frame_info,
|
43
|
-
text="uuid and password will be automatically fetched",
|
31
|
+
text="Please install Signal Desktop and login first.",
|
44
32
|
justify="left",
|
45
33
|
anchor="w",
|
46
34
|
)
|
47
35
|
|
48
|
-
self.
|
36
|
+
self.explanation_lbl.grid(
|
49
37
|
column=0, row=0, columnspan=3, sticky="w", padx=3, pady=3
|
50
38
|
)
|
51
|
-
self.explanation2_lbl.grid(
|
52
|
-
column=0, row=1, columnspan=3, sticky="w", padx=3, pady=3
|
53
|
-
)
|
54
|
-
self.explanation3_lbl.grid(
|
55
|
-
column=0, row=2, columnspan=3, sticky="w", padx=3, pady=3
|
56
|
-
)
|
57
39
|
|
58
40
|
# Start button frame
|
41
|
+
self.launch_btn = Button(
|
42
|
+
self.frame_btns, text="Launch Signal Desktop", command=self.cb_launch_signal
|
43
|
+
)
|
44
|
+
|
59
45
|
self.login_btn = Button(
|
60
|
-
self.
|
46
|
+
self.frame_btns, text="Get uuid and password", command=self.cb_login
|
61
47
|
)
|
62
48
|
|
49
|
+
self.launch_btn.pack()
|
63
50
|
self.login_btn.pack()
|
64
51
|
|
65
52
|
GUIUtils.finalize_window(self)
|
66
53
|
|
67
54
|
def cb_login(self):
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
55
|
+
m = GetSignalAuth()
|
56
|
+
uuid, password, msg = m.get_cred()
|
57
|
+
|
58
|
+
if uuid and password:
|
59
|
+
if not self.gui.creds.get("signal"):
|
60
|
+
self.gui.creds["signal"] = {}
|
61
|
+
self.gui.creds["signal"]["uuid"] = uuid
|
62
|
+
self.gui.creds["signal"]["password"] = password
|
63
|
+
self.gui.signal_uuid_var.set(uuid)
|
64
|
+
self.gui.signal_password_var.set(password)
|
65
|
+
|
66
|
+
self.gui.save_creds()
|
67
|
+
self.gui.highlight_fields()
|
68
|
+
|
69
|
+
self.cb_msg_block_signal(msg)
|
70
|
+
|
71
|
+
def cb_launch_signal(self):
|
72
|
+
m = GetSignalAuth()
|
73
|
+
signal_bin_path, signal_user_data_dir = m.get_signal_desktop()
|
74
|
+
if signal_bin_path:
|
75
|
+
Popen(
|
76
|
+
[
|
77
|
+
signal_bin_path,
|
78
|
+
"--no-sandbox",
|
79
|
+
f"--user-data-dir={signal_user_data_dir}",
|
80
|
+
]
|
81
|
+
)
|
82
|
+
else:
|
83
|
+
self.cb_msg_block_signal("Error: Signal Desktop not installed.")
|
@@ -1,245 +1,15 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
|
-
import io
|
3
|
-
import json
|
4
2
|
import os
|
3
|
+
import json
|
5
4
|
import platform
|
6
5
|
import shutil
|
7
|
-
import
|
8
|
-
import string
|
9
|
-
import webbrowser
|
10
|
-
import zipfile
|
6
|
+
from sqlcipher3 import dbapi2 as sqlite3
|
11
7
|
from pathlib import Path
|
12
|
-
from typing import
|
13
|
-
|
14
|
-
import requests
|
15
|
-
from selenium import webdriver
|
16
|
-
from selenium.common.exceptions import JavascriptException
|
17
|
-
from selenium.webdriver.chrome.service import Service
|
18
|
-
|
19
|
-
from sticker_convert.definitions import CONFIG_DIR
|
20
|
-
from sticker_convert.utils.files.run_bin import RunBin
|
21
|
-
|
22
|
-
|
23
|
-
# https://stackoverflow.com/a/17197027
|
24
|
-
def strings(filename: str, min: int = 4) -> Generator[str, None, None]:
|
25
|
-
with open(filename, "r", errors="ignore") as f:
|
26
|
-
result = ""
|
27
|
-
for c in f.read():
|
28
|
-
if c in string.printable:
|
29
|
-
result += c
|
30
|
-
continue
|
31
|
-
if len(result) >= min:
|
32
|
-
yield result
|
33
|
-
result = ""
|
34
|
-
if len(result) >= min: # catch result at EOF
|
35
|
-
yield result
|
8
|
+
from typing import Optional
|
36
9
|
|
37
10
|
|
38
11
|
class GetSignalAuth:
|
39
|
-
def
|
40
|
-
self,
|
41
|
-
signal_bin_version: str = "beta",
|
42
|
-
cb_msg: Callable[..., None] = print,
|
43
|
-
cb_ask_str: Callable[..., str] = input,
|
44
|
-
):
|
45
|
-
chromedriver_download_dir = CONFIG_DIR / "bin"
|
46
|
-
os.makedirs(chromedriver_download_dir, exist_ok=True)
|
47
|
-
|
48
|
-
self.signal_bin_version = signal_bin_version
|
49
|
-
self.chromedriver_download_dir = chromedriver_download_dir
|
50
|
-
|
51
|
-
self.cb_ask_str = cb_ask_str
|
52
|
-
self.cb_msg = cb_msg
|
53
|
-
|
54
|
-
def download_signal_desktop(self, download_url: str, signal_bin_path: str):
|
55
|
-
webbrowser.open(download_url)
|
56
|
-
|
57
|
-
self.cb_msg(download_url)
|
58
|
-
|
59
|
-
prompt = "Signal Desktop not detected.\n"
|
60
|
-
prompt += "Download and install Signal Desktop BETA version\n"
|
61
|
-
prompt += "After installation, quit Signal Desktop before continuing"
|
62
|
-
while not (Path(signal_bin_path).is_file() or shutil.which(signal_bin_path)):
|
63
|
-
if self.cb_ask_str != input:
|
64
|
-
self.cb_ask_str(
|
65
|
-
prompt, initialvalue=download_url, cli_show_initialvalue=False
|
66
|
-
)
|
67
|
-
else:
|
68
|
-
input(prompt)
|
69
|
-
|
70
|
-
def get_signal_chromedriver_version(self, electron_bin_path: str) -> Optional[str]:
|
71
|
-
if RunBin.get_bin("strings", silent=True):
|
72
|
-
status, output_str = RunBin.run_cmd(
|
73
|
-
cmd_list=["strings", electron_bin_path], silence=True
|
74
|
-
)
|
75
|
-
if status is False:
|
76
|
-
return None
|
77
|
-
ss = output_str.split("\n")
|
78
|
-
else:
|
79
|
-
ss = strings(electron_bin_path)
|
80
|
-
|
81
|
-
for s in ss:
|
82
|
-
if "Chrome/" in s and " Electron/" in s:
|
83
|
-
major_version = s.replace("Chrome/", "").split(".", 1)[0]
|
84
|
-
if major_version.isnumeric():
|
85
|
-
return major_version
|
86
|
-
|
87
|
-
return None
|
88
|
-
|
89
|
-
def get_local_chromedriver(
|
90
|
-
self, chromedriver_download_dir: Path
|
91
|
-
) -> tuple[Optional[Path], Optional[str]]:
|
92
|
-
local_chromedriver_version = None
|
93
|
-
if platform.system() == "Windows":
|
94
|
-
chromedriver_name = "chromedriver.exe"
|
95
|
-
else:
|
96
|
-
chromedriver_name = "chromedriver"
|
97
|
-
chromedriver_path = Path(chromedriver_download_dir, chromedriver_name).resolve()
|
98
|
-
if not chromedriver_path.is_file():
|
99
|
-
chromedriver_which = shutil.which("chromedriver")
|
100
|
-
if chromedriver_which:
|
101
|
-
chromedriver_path = Path(chromedriver_which)
|
102
|
-
|
103
|
-
if chromedriver_path:
|
104
|
-
status, output_str = RunBin.run_cmd(
|
105
|
-
cmd_list=[str(chromedriver_path), "-v"], silence=True
|
106
|
-
)
|
107
|
-
if status is False:
|
108
|
-
local_chromedriver_version = None
|
109
|
-
local_chromedriver_version = output_str.split(" ")[1].split(".", 1)[0]
|
110
|
-
else:
|
111
|
-
local_chromedriver_version = None
|
112
|
-
|
113
|
-
return chromedriver_path, local_chromedriver_version
|
114
|
-
|
115
|
-
def download_chromedriver(
|
116
|
-
self, major_version: str, chromedriver_download_dir: Path
|
117
|
-
) -> Optional[Path]:
|
118
|
-
if platform.system() == "Windows":
|
119
|
-
chromedriver_platform = "win32"
|
120
|
-
if "64" in platform.architecture()[0]:
|
121
|
-
chromedriver_platform_new = "win64"
|
122
|
-
else:
|
123
|
-
chromedriver_platform_new = "win32"
|
124
|
-
elif platform.system() == "Darwin":
|
125
|
-
if platform.processor().lower() == "arm64":
|
126
|
-
chromedriver_platform = "mac_arm64"
|
127
|
-
chromedriver_platform_new = "mac-arm64"
|
128
|
-
else:
|
129
|
-
chromedriver_platform = "mac64"
|
130
|
-
chromedriver_platform_new = "mac-x64"
|
131
|
-
else:
|
132
|
-
chromedriver_platform = "linux64"
|
133
|
-
chromedriver_platform_new = "linux64"
|
134
|
-
|
135
|
-
chromedriver_url = None
|
136
|
-
chromedriver_version_url = f"https://chromedriver.storage.googleapis.com/LATEST_RELEASE_{major_version}"
|
137
|
-
r = requests.get(chromedriver_version_url)
|
138
|
-
if r.ok:
|
139
|
-
new_chrome = False
|
140
|
-
chromedriver_version = r.text
|
141
|
-
chromedriver_url = f"https://chromedriver.storage.googleapis.com/{chromedriver_version}/chromedriver_{chromedriver_platform}.zip"
|
142
|
-
else:
|
143
|
-
new_chrome = True
|
144
|
-
r = requests.get(
|
145
|
-
"https://googlechromelabs.github.io/chrome-for-testing/latest-versions-per-milestone-with-downloads.json"
|
146
|
-
)
|
147
|
-
versions_dict = json.loads(r.text)
|
148
|
-
chromedriver_list = (
|
149
|
-
versions_dict.get("milestones", {})
|
150
|
-
.get(major_version, {})
|
151
|
-
.get("downloads", {})
|
152
|
-
.get("chromedriver", {})
|
153
|
-
)
|
154
|
-
|
155
|
-
chromedriver_url = None
|
156
|
-
for i in chromedriver_list:
|
157
|
-
if i.get("platform") == chromedriver_platform_new:
|
158
|
-
chromedriver_url = i.get("url")
|
159
|
-
|
160
|
-
if not chromedriver_url:
|
161
|
-
return None
|
162
|
-
|
163
|
-
if platform.system() == "Windows":
|
164
|
-
chromedriver_name = "chromedriver.exe"
|
165
|
-
else:
|
166
|
-
chromedriver_name = "chromedriver"
|
167
|
-
|
168
|
-
if new_chrome:
|
169
|
-
chromedriver_zip_path = (
|
170
|
-
f"chromedriver-{chromedriver_platform_new}/{chromedriver_name}"
|
171
|
-
)
|
172
|
-
else:
|
173
|
-
chromedriver_zip_path = chromedriver_name
|
174
|
-
|
175
|
-
chromedriver_path = Path(chromedriver_download_dir, chromedriver_name).resolve()
|
176
|
-
|
177
|
-
with io.BytesIO() as f:
|
178
|
-
f.write(requests.get(chromedriver_url).content) # type: ignore
|
179
|
-
with zipfile.ZipFile(f, "r") as z, open(chromedriver_path, "wb+") as g:
|
180
|
-
g.write(z.read(chromedriver_zip_path))
|
181
|
-
|
182
|
-
if platform.system() != "Windows":
|
183
|
-
st = os.stat(chromedriver_path)
|
184
|
-
os.chmod(chromedriver_path, st.st_mode | stat.S_IEXEC)
|
185
|
-
|
186
|
-
return chromedriver_path
|
187
|
-
|
188
|
-
def killall_signal(self):
|
189
|
-
if platform.system() == "Windows":
|
190
|
-
os.system('taskkill /F /im "Signal.exe"')
|
191
|
-
os.system('taskkill /F /im "Signal Beta.exe"')
|
192
|
-
else:
|
193
|
-
RunBin.run_cmd(cmd_list=["killall", "signal-desktop"], silence=True)
|
194
|
-
RunBin.run_cmd(cmd_list=["killall", "signal-desktop-beta"], silence=True)
|
195
|
-
|
196
|
-
def launch_signal(
|
197
|
-
self, signal_bin_path: str, signal_user_data_dir: str, chromedriver_path: str
|
198
|
-
):
|
199
|
-
options = webdriver.ChromeOptions()
|
200
|
-
options.binary_location = signal_bin_path
|
201
|
-
options.add_argument(f"user-data-dir={signal_user_data_dir}") # type: ignore
|
202
|
-
options.add_argument("no-sandbox") # type: ignore
|
203
|
-
service = Service(executable_path=chromedriver_path)
|
204
|
-
|
205
|
-
self.driver = webdriver.Chrome(options=options, service=service)
|
206
|
-
|
207
|
-
def get_cred(self) -> tuple[Optional[str], Optional[str]]:
|
208
|
-
success = self.launch_signal_desktop()
|
209
|
-
|
210
|
-
if not success:
|
211
|
-
return None, None
|
212
|
-
|
213
|
-
# https://stackoverflow.com/a/73456344
|
214
|
-
uuid: Optional[str] = None
|
215
|
-
password: Optional[str] = None
|
216
|
-
try:
|
217
|
-
if self.signal_bin_version == "prod":
|
218
|
-
uuid = self.driver.execute_script( # type: ignore
|
219
|
-
"return window.reduxStore.getState().items.uuid_id"
|
220
|
-
)
|
221
|
-
password = self.driver.execute_script( # type: ignore
|
222
|
-
"return window.reduxStore.getState().items.password"
|
223
|
-
)
|
224
|
-
else:
|
225
|
-
uuid = self.driver.execute_script( # type: ignore
|
226
|
-
"return window.SignalDebug.getReduxState().items.uuid_id"
|
227
|
-
)
|
228
|
-
password = self.driver.execute_script( # type: ignore
|
229
|
-
"return window.SignalDebug.getReduxState().items.password"
|
230
|
-
)
|
231
|
-
except JavascriptException:
|
232
|
-
pass
|
233
|
-
|
234
|
-
assert isinstance(uuid, str)
|
235
|
-
assert isinstance(password, str)
|
236
|
-
return uuid, password
|
237
|
-
|
238
|
-
def close(self):
|
239
|
-
self.cb_msg("Closing Signal Desktop")
|
240
|
-
self.driver.quit()
|
241
|
-
|
242
|
-
def launch_signal_desktop(self) -> bool:
|
12
|
+
def get_signal_desktop(self) -> tuple[Optional[str], Optional[str]]:
|
243
13
|
if platform.system() == "Windows":
|
244
14
|
signal_bin_path_prod = os.path.expandvars(
|
245
15
|
"%localappdata%/Programs/signal-desktop/Signal.exe"
|
@@ -253,8 +23,6 @@ class GetSignalAuth:
|
|
253
23
|
signal_user_data_dir_beta = os.path.abspath(
|
254
24
|
os.path.expandvars("%appdata%/Signal Beta")
|
255
25
|
)
|
256
|
-
electron_bin_path_prod = signal_bin_path_prod
|
257
|
-
electron_bin_path_beta = signal_bin_path_beta
|
258
26
|
elif platform.system() == "Darwin":
|
259
27
|
signal_bin_path_prod = "/Applications/Signal.app/Contents/MacOS/Signal"
|
260
28
|
signal_bin_path_beta = (
|
@@ -266,81 +34,82 @@ class GetSignalAuth:
|
|
266
34
|
signal_user_data_dir_beta = os.path.expanduser(
|
267
35
|
"~/Library/Application Support/Signal Beta"
|
268
36
|
)
|
269
|
-
electron_bin_path_prod = "/Applications/Signal.app/Contents/Frameworks/Electron Framework.framework/Electron Framework"
|
270
|
-
electron_bin_path_beta = "/Applications/Signal Beta.app/Contents/Frameworks/Electron Framework.framework/Electron Framework"
|
271
37
|
else:
|
272
|
-
signal_bin_path_prod
|
273
|
-
|
38
|
+
if not (signal_bin_path_prod := shutil.which("signal-desktop")): # type: ignore
|
39
|
+
signal_bin_path_prod = "signal-desktop"
|
40
|
+
if not (signal_bin_path_beta := shutil.which("signal-desktop-beta")): # type: ignore
|
41
|
+
signal_bin_path_beta = "signal-desktop-beta"
|
274
42
|
signal_user_data_dir_prod = os.path.expanduser("~/.config/Signal")
|
275
43
|
signal_user_data_dir_beta = os.path.expanduser("~/.config/Signal Beta")
|
276
|
-
electron_bin_path_prod = signal_bin_path_prod
|
277
|
-
electron_bin_path_beta = signal_bin_path_beta
|
278
44
|
|
279
|
-
if
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
signal_download_url = "https://signal.org/en/download/"
|
45
|
+
if Path(signal_bin_path_prod).is_file():
|
46
|
+
return signal_bin_path_prod, signal_user_data_dir_prod
|
47
|
+
elif Path(signal_bin_path_beta).is_file():
|
48
|
+
return signal_bin_path_beta, signal_user_data_dir_beta
|
284
49
|
else:
|
285
|
-
|
286
|
-
signal_user_data_dir = signal_user_data_dir_beta
|
287
|
-
electron_bin_path = electron_bin_path_beta
|
288
|
-
signal_download_url = (
|
289
|
-
"https://support.signal.org/hc/en-us/articles/360007318471-Signal-Beta"
|
290
|
-
)
|
291
|
-
|
292
|
-
if not (Path(signal_bin_path).is_file() or shutil.which(signal_bin_path)):
|
293
|
-
success = self.download_signal_desktop(signal_download_url, signal_bin_path)
|
294
|
-
|
295
|
-
if not success:
|
296
|
-
return False
|
297
|
-
|
298
|
-
electron_bin_path = (
|
299
|
-
shutil.which(electron_bin_path)
|
300
|
-
if not Path(electron_bin_path).is_file()
|
301
|
-
else electron_bin_path
|
302
|
-
)
|
303
|
-
if not electron_bin_path:
|
304
|
-
self.cb_msg("Cannot find Electron Framework inside Signal installation")
|
305
|
-
return False
|
306
|
-
|
307
|
-
signal_bin_path = (
|
308
|
-
signal_bin_path
|
309
|
-
if not shutil.which(signal_bin_path)
|
310
|
-
else shutil.which(signal_bin_path)
|
311
|
-
)
|
312
|
-
if not signal_bin_path:
|
313
|
-
self.cb_msg("Cannot find Signal installation")
|
314
|
-
return False
|
315
|
-
|
316
|
-
major_version = self.get_signal_chromedriver_version(electron_bin_path)
|
317
|
-
if major_version:
|
318
|
-
self.cb_msg(f"Signal Desktop is using chrome version {major_version}")
|
319
|
-
else:
|
320
|
-
self.cb_msg("Unable to determine Signal Desktop chrome version")
|
321
|
-
return False
|
322
|
-
|
323
|
-
chromedriver_path, local_chromedriver_version = self.get_local_chromedriver(
|
324
|
-
chromedriver_download_dir=self.chromedriver_download_dir
|
325
|
-
)
|
326
|
-
if chromedriver_path and local_chromedriver_version == major_version:
|
327
|
-
self.cb_msg(
|
328
|
-
f"Found chromedriver version {local_chromedriver_version}, skip downloading"
|
329
|
-
)
|
330
|
-
else:
|
331
|
-
chromedriver_path = self.download_chromedriver(
|
332
|
-
major_version, chromedriver_download_dir=self.chromedriver_download_dir
|
333
|
-
)
|
334
|
-
if not chromedriver_path:
|
335
|
-
self.cb_msg("Unable to download suitable chromedriver")
|
336
|
-
return False
|
337
|
-
|
338
|
-
self.cb_msg("Killing all Signal Desktop processes")
|
339
|
-
self.killall_signal()
|
340
|
-
|
341
|
-
self.cb_msg("Starting Signal Desktop with Selenium")
|
342
|
-
self.launch_signal(
|
343
|
-
signal_bin_path, signal_user_data_dir, str(chromedriver_path)
|
344
|
-
)
|
50
|
+
return None, None
|
345
51
|
|
346
|
-
|
52
|
+
def get_cred(self) -> tuple[Optional[str], Optional[str], str]:
|
53
|
+
signal_bin_path, signal_user_data_dir = self.get_signal_desktop()
|
54
|
+
|
55
|
+
if not (signal_bin_path and signal_user_data_dir):
|
56
|
+
msg = "Signal Desktop not detected.\n"
|
57
|
+
msg += "Download and install Signal Desktop,\n"
|
58
|
+
msg += "then login to Signal Desktop and try again."
|
59
|
+
|
60
|
+
return None, None, msg
|
61
|
+
|
62
|
+
signal_config = Path(signal_user_data_dir, "config.json")
|
63
|
+
|
64
|
+
if not signal_config.is_file():
|
65
|
+
msg = "Signal Desktop installed,\n"
|
66
|
+
msg += "but it's config file not found.\n"
|
67
|
+
msg += "Please login to Signal Desktop and try again.\n"
|
68
|
+
msg += "\n"
|
69
|
+
msg += f"{signal_bin_path=}\n"
|
70
|
+
msg += f"{signal_user_data_dir=}\n"
|
71
|
+
return None, None, msg
|
72
|
+
|
73
|
+
with open(signal_config) as f:
|
74
|
+
config = json.load(f)
|
75
|
+
key = config.get("key")
|
76
|
+
db_key = f"x'{key}'"
|
77
|
+
|
78
|
+
signal_database = Path(signal_user_data_dir, "sql/db.sqlite")
|
79
|
+
|
80
|
+
if not signal_database.is_file():
|
81
|
+
msg = "Signal Desktop installed,\n"
|
82
|
+
msg += "but database file not found.\n"
|
83
|
+
msg += "Please login to Signal Desktop and try again.\n"
|
84
|
+
msg += "\n"
|
85
|
+
msg += f"{signal_bin_path=}\n"
|
86
|
+
msg += f"{signal_user_data_dir=}\n"
|
87
|
+
return None, None, msg
|
88
|
+
|
89
|
+
db_conn = sqlite3.connect(signal_database.as_posix()) # type: ignore
|
90
|
+
db_cursor = db_conn.cursor()
|
91
|
+
db_cursor.execute(f'PRAGMA key="{db_key}"')
|
92
|
+
db_cursor.execute("SELECT * FROM items")
|
93
|
+
result = db_cursor.fetchall()
|
94
|
+
db_conn.close()
|
95
|
+
|
96
|
+
uuid_id = None
|
97
|
+
password = None
|
98
|
+
for r in result:
|
99
|
+
if "uuid_id" in r:
|
100
|
+
uuid_id = json.loads(r[1])["value"]
|
101
|
+
if "password" in r:
|
102
|
+
password = json.loads(r[1])["value"]
|
103
|
+
if uuid_id and password:
|
104
|
+
msg = "Got uuid and password successfully:\n"
|
105
|
+
msg += f"{uuid_id=}\n"
|
106
|
+
msg += f"{password=}"
|
107
|
+
return uuid_id, password, msg
|
108
|
+
|
109
|
+
msg = "Signal Desktop installed and Database found,\n"
|
110
|
+
msg += "but uuid and password not found.\n"
|
111
|
+
msg += "Please login to Signal Desktop and try again.\n"
|
112
|
+
msg += "\n"
|
113
|
+
msg += f"{signal_bin_path=}\n"
|
114
|
+
msg += f"{signal_user_data_dir=}\n"
|
115
|
+
return None, None, msg
|
sticker_convert/version.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
|
-
__version__ = "2.
|
2
|
+
__version__ = "2.7.0"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sticker-convert
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.7.0
|
4
4
|
Summary: Convert (animated) stickers to/from WhatsApp, Telegram, Signal, Line, Kakao, iMessage. Written in Python.
|
5
5
|
Author-email: laggykiller <chaudominic2@gmail.com>
|
6
6
|
Maintainer-email: laggykiller <chaudominic2@gmail.com>
|
@@ -370,15 +370,15 @@ Requires-Dist: beautifulsoup4 ~=4.12.3
|
|
370
370
|
Requires-Dist: rookiepy ~=0.3.6
|
371
371
|
Requires-Dist: imagequant ~=1.1.1
|
372
372
|
Requires-Dist: memory-tempfile ~=2.2.3
|
373
|
-
Requires-Dist: numpy ~=1.26.
|
373
|
+
Requires-Dist: numpy ~=1.26.4
|
374
374
|
Requires-Dist: Pillow ~=10.2.0
|
375
375
|
Requires-Dist: pyoxipng ~=9.0.0
|
376
376
|
Requires-Dist: python-telegram-bot ~=20.5
|
377
377
|
Requires-Dist: requests ~=2.31.0
|
378
378
|
Requires-Dist: rlottie-python ~=1.2.1
|
379
|
-
Requires-Dist: selenium ~=4.17.2
|
380
379
|
Requires-Dist: signalstickers-client ~=3.3.0
|
381
|
-
Requires-Dist:
|
380
|
+
Requires-Dist: sqlcipher3-wheels ~=0.5.2.post0
|
381
|
+
Requires-Dist: tqdm ~=4.66.2
|
382
382
|
Requires-Dist: ttkbootstrap-fork-laggykiller ~=1.5.1
|
383
383
|
Requires-Dist: webp ~=0.3.0
|
384
384
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
sticker_convert/__init__.py,sha256=ZVbMC58kjlCUoBtJA0q9WQLLsqewlMaorkjZpAEAu5U,101
|
2
2
|
sticker_convert/__main__.py,sha256=hoYnwaH4RGBjx4EA6gwbOviTjy5dhtPkeBbl3QsjNe8,453
|
3
|
-
sticker_convert/cli.py,sha256=
|
3
|
+
sticker_convert/cli.py,sha256=oVSIYoitgBj9w-UmUYap7A7NHbyjEqaJnsH-BpOvRrQ,17090
|
4
4
|
sticker_convert/converter.py,sha256=wRC4_tD-oF-7QQX34ghswQNIYPvSnLUluRMxO2M8EQk,30609
|
5
5
|
sticker_convert/definitions.py,sha256=Cci0bh9zSnoNKBmGreT7mkzUoM8SLj_92LqV5ByrkOw,2153
|
6
6
|
sticker_convert/gui.py,sha256=luVKNIu46tBWdh8r6N736VwPBU94JdMZ0BrlifpqxBw,29659
|
7
7
|
sticker_convert/job.py,sha256=3eBLPBPXvoy1T40kZUc1NZqkzbhcmlRC1E28EFLjfww,26017
|
8
8
|
sticker_convert/job_option.py,sha256=kmtENOsV_oNUseGkOvCm63M_-oS67dBUookmAfzmGDs,7462
|
9
|
-
sticker_convert/version.py,sha256=
|
9
|
+
sticker_convert/version.py,sha256=ySq2Yy1nCsMLqIerpu9ZZgE1g0LeRXNnj-F1h3hBlh0,45
|
10
10
|
sticker_convert/downloaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
11
|
sticker_convert/downloaders/download_base.py,sha256=gmPtg4fcA5RkJ4TCVMdjZHWweiAqE8rucA_tW1U9kbw,3289
|
12
12
|
sticker_convert/downloaders/download_kakao.py,sha256=iiGKIJVw4XGW_K3MDDdDIbunOs8YSm0LW4To96V2Zv8,8879
|
@@ -29,7 +29,7 @@ sticker_convert/gui_components/windows/advanced_compression_window.py,sha256=FSA
|
|
29
29
|
sticker_convert/gui_components/windows/base_window.py,sha256=F0b0Z7hRgTR6nB0TebZPZAJyowqnDhVMfv7345_UWmQ,1068
|
30
30
|
sticker_convert/gui_components/windows/kakao_get_auth_window.py,sha256=DPg96jK0MNFLZQNOLw8wzcxKOA_XgaJU1wyrWMb2g40,7118
|
31
31
|
sticker_convert/gui_components/windows/line_get_auth_window.py,sha256=QfuBCX8vSjWAGeVaGMWXmFxeGp4YeNA_o-hZmZCpJHE,3369
|
32
|
-
sticker_convert/gui_components/windows/signal_get_auth_window.py,sha256=
|
32
|
+
sticker_convert/gui_components/windows/signal_get_auth_window.py,sha256=ZLSb4XlUZ-KVOrpusU2jm7nflJsH8CX49K11GRwdk70,2736
|
33
33
|
sticker_convert/ios-message-stickers-template/.gitignore,sha256=4uuTph_9eHfqXHUavLOmGOji6aIHOif2bUEU_hCBn4Y,9
|
34
34
|
sticker_convert/ios-message-stickers-template/README.md,sha256=oN0FvJkCWWjSZ3PMrCvY3T1zCsdkZYFgGHAoFh0Kmt8,467
|
35
35
|
sticker_convert/ios-message-stickers-template/.github/FUNDING.yml,sha256=3LlmdSAGDsBA2o_C1iBYTNLwkABnyZuN0zxgPPyd-f8,70
|
@@ -77,11 +77,11 @@ sticker_convert/uploaders/upload_base.py,sha256=ccV3GK05gYdrLWjBNSxWxazrS7slx50l
|
|
77
77
|
sticker_convert/uploaders/upload_signal.py,sha256=d1ZnTtlIHi5lSSTfzr3sdC365vqggHeuB1LrwI3tgBA,6521
|
78
78
|
sticker_convert/uploaders/upload_telegram.py,sha256=SSNBtml_swIxeUYvR390SSb78yEBsVr0gT_1qOF70_g,11689
|
79
79
|
sticker_convert/uploaders/xcode_imessage.py,sha256=7poimysdi5pSN72rGmz-KWKV4JzrqF5UwMNChdHqSAE,13424
|
80
|
-
sticker_convert/utils/callback.py,sha256=
|
80
|
+
sticker_convert/utils/callback.py,sha256=eisrZBNCLs1UAmAgOeCmQ4gvTdHfoHoH0VHEVn08uKY,5263
|
81
81
|
sticker_convert/utils/url_detect.py,sha256=qu4Yav6r5Ca1X5seFiu--gnMX3VASRSbkBnlljHgCYI,793
|
82
82
|
sticker_convert/utils/auth/get_kakao_auth.py,sha256=jleZR7GRpPfWU5EgxUx3ROod0jDI40pablO-5Ev_XuQ,9839
|
83
83
|
sticker_convert/utils/auth/get_line_auth.py,sha256=5pAGVQwMmdBC6pVsOtih0kFDc8GGwBMmYwoTJpAe9H8,2426
|
84
|
-
sticker_convert/utils/auth/get_signal_auth.py,sha256=
|
84
|
+
sticker_convert/utils/auth/get_signal_auth.py,sha256=H3o7-Pd9UH7Mnfzo8W5HQP-T9evEEW77mF5KsM6gJfg,4600
|
85
85
|
sticker_convert/utils/files/cache_store.py,sha256=PsZhzOrLhTBB87z1LsGKt713P8qn845-Jiyqv5z5c5c,1021
|
86
86
|
sticker_convert/utils/files/json_manager.py,sha256=VbsbMKuLu2bN0lMuaeIXB7o9nqdTyqEteDVHKtVPEqs,553
|
87
87
|
sticker_convert/utils/files/metadata_handler.py,sha256=eUG-hYyUF0gvW2ofAXIFAZqJuKVSqCNOdXAocCw3NUk,9784
|
@@ -91,9 +91,9 @@ sticker_convert/utils/media/apple_png_normalize.py,sha256=28sxUlh9-dg9GmCf6wvWs0
|
|
91
91
|
sticker_convert/utils/media/codec_info.py,sha256=tA_hjQIoO4RK1AK-bNceA6uteztzgUydCds-5YEJn-I,11823
|
92
92
|
sticker_convert/utils/media/decrypt_kakao.py,sha256=0zk5ybSmePRJ_eYl-oVyRZs6dV_Sk9mgKI-oTpd9gsY,1924
|
93
93
|
sticker_convert/utils/media/format_verify.py,sha256=iXTTKIA-HfMZ3bfuJXFNnFDWEiqtDdzDk7PznpeDR1Q,5585
|
94
|
-
sticker_convert-2.
|
95
|
-
sticker_convert-2.
|
96
|
-
sticker_convert-2.
|
97
|
-
sticker_convert-2.
|
98
|
-
sticker_convert-2.
|
99
|
-
sticker_convert-2.
|
94
|
+
sticker_convert-2.7.0.dist-info/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
|
95
|
+
sticker_convert-2.7.0.dist-info/METADATA,sha256=2a5WvfEE758ClsGijv0aeCF2PgLvb16om2Kkd8iHKco,47812
|
96
|
+
sticker_convert-2.7.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
97
|
+
sticker_convert-2.7.0.dist-info/entry_points.txt,sha256=MNJ7XyC--ugxi5jS1nzjDLGnxCyLuaGdsVLnJhDHCqs,66
|
98
|
+
sticker_convert-2.7.0.dist-info/top_level.txt,sha256=r9vfnB0l1ZnH5pTH5RvkobnK3Ow9m0RsncaOMAtiAtk,16
|
99
|
+
sticker_convert-2.7.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|