sticker-convert 2.13.0__py3-none-any.whl → 2.13.1.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 +2 -0
- sticker_convert/converter.py +1 -1
- sticker_convert/downloaders/download_line.py +8 -4
- sticker_convert/gui_components/windows/advanced_compression_window.py +1 -1
- sticker_convert/gui_components/windows/kakao_get_auth_window.py +25 -4
- sticker_convert/gui_components/windows/viber_get_auth_window.py +15 -0
- sticker_convert/resources/help.json +1 -1
- sticker_convert/utils/auth/get_discord_auth.py +1 -1
- sticker_convert/utils/auth/get_kakao_desktop_auth.py +36 -41
- sticker_convert/utils/auth/get_viber_auth.py +2 -4
- sticker_convert/utils/auth/telegram_api.py +3 -1
- sticker_convert/utils/auth/telethon_setup.py +18 -7
- sticker_convert/utils/chrome_remotedebug.py +9 -23
- 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/process.py +152 -108
- sticker_convert/version.py +1 -1
- {sticker_convert-2.13.0.dist-info → sticker_convert-2.13.1.0.dist-info}/METADATA +7 -7
- {sticker_convert-2.13.0.dist-info → sticker_convert-2.13.1.0.dist-info}/RECORD +24 -21
- {sticker_convert-2.13.0.dist-info → sticker_convert-2.13.1.0.dist-info}/WHEEL +1 -1
- {sticker_convert-2.13.0.dist-info → sticker_convert-2.13.1.0.dist-info}/entry_points.txt +0 -0
- {sticker_convert-2.13.0.dist-info → sticker_convert-2.13.1.0.dist-info}/licenses/LICENSE +0 -0
- {sticker_convert-2.13.0.dist-info → sticker_convert-2.13.1.0.dist-info}/top_level.txt +0 -0
sticker_convert/cli.py
CHANGED
sticker_convert/converter.py
CHANGED
@@ -77,7 +77,7 @@ class MetadataLine:
|
|
77
77
|
@staticmethod
|
78
78
|
def get_metadata_sticon(
|
79
79
|
pack_id: str, region: str
|
80
|
-
) -> Optional[Tuple[str, str, List[Dict[str, Any]], str, bool]]:
|
80
|
+
) -> Optional[Tuple[str, str, List[Dict[str, Any]], str, bool, bool]]:
|
81
81
|
pack_meta_r = requests.get(
|
82
82
|
f"https://stickershop.line-scdn.net/sticonshop/v1/{pack_id}/sticon/iphone/meta.json"
|
83
83
|
)
|
@@ -114,14 +114,15 @@ class MetadataLine:
|
|
114
114
|
files = pack_meta["orders"]
|
115
115
|
|
116
116
|
resource_type = pack_meta.get("sticonResourceType")
|
117
|
+
has_animation = True if resource_type == "ANIMATION" else False
|
117
118
|
has_sound = False
|
118
119
|
|
119
|
-
return title, author, files, resource_type, has_sound
|
120
|
+
return title, author, files, resource_type, has_animation, has_sound
|
120
121
|
|
121
122
|
@staticmethod
|
122
123
|
def get_metadata_stickers(
|
123
124
|
pack_id: str, region: str
|
124
|
-
) -> Optional[Tuple[str, str, List[Dict[str, Any]], str, bool]]:
|
125
|
+
) -> Optional[Tuple[str, str, List[Dict[str, Any]], str, bool, bool]]:
|
125
126
|
pack_meta_r = requests.get(
|
126
127
|
f"https://stickershop.line-scdn.net/stickershop/v1/product/{pack_id}/android/productInfo.meta"
|
127
128
|
)
|
@@ -153,9 +154,10 @@ class MetadataLine:
|
|
153
154
|
files = pack_meta["stickers"]
|
154
155
|
|
155
156
|
resource_type = pack_meta.get("stickerResourceType")
|
157
|
+
has_animation = pack_meta.get("hasAnimation")
|
156
158
|
has_sound = pack_meta.get("hasSound")
|
157
159
|
|
158
|
-
return title, author, files, resource_type, has_sound
|
160
|
+
return title, author, files, resource_type, has_animation, has_sound
|
159
161
|
|
160
162
|
|
161
163
|
class DownloadLine(DownloadBase):
|
@@ -207,6 +209,7 @@ class DownloadLine(DownloadBase):
|
|
207
209
|
if (
|
208
210
|
self.resource_type in ("ANIMATION", "ANIMATION_SOUND", "POPUP")
|
209
211
|
or self.has_sound is True
|
212
|
+
or self.has_animation is True
|
210
213
|
):
|
211
214
|
pack_url = f"https://stickershop.line-scdn.net/stickershop/v1/product/{self.pack_id}/iphone/stickerpack@2x.zip"
|
212
215
|
elif self.resource_type == "PER_STICKER_TEXT":
|
@@ -419,6 +422,7 @@ class DownloadLine(DownloadBase):
|
|
419
422
|
self.author,
|
420
423
|
self.pack_files,
|
421
424
|
self.resource_type,
|
425
|
+
self.has_animation,
|
422
426
|
self.has_sound,
|
423
427
|
) = metadata
|
424
428
|
else:
|
@@ -609,7 +609,7 @@ class AdvancedCompressionWindow(BaseWindow):
|
|
609
609
|
)[1]
|
610
610
|
if color:
|
611
611
|
self.gui.bg_color_var.set(color.replace("#", "") + "00")
|
612
|
-
self.lift()
|
612
|
+
self.lift() # type: ignore
|
613
613
|
self.attributes("-topmost", True) # type: ignore
|
614
614
|
self.attributes("-topmost", False) # type: ignore
|
615
615
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
|
+
import platform
|
2
3
|
from functools import partial
|
3
4
|
from threading import Thread
|
4
5
|
from typing import Any, Optional
|
@@ -51,6 +52,20 @@ class KakaoGetAuthWindow(BaseWindow):
|
|
51
52
|
justify="left",
|
52
53
|
anchor="w",
|
53
54
|
)
|
55
|
+
if platform.system() != "Darwin":
|
56
|
+
self.explanation1_4_lbl = Label(
|
57
|
+
self.frame_from_desktop,
|
58
|
+
text="Note: This will download ProcDump and read memory of KakaoTalk Desktop",
|
59
|
+
justify="left",
|
60
|
+
anchor="w",
|
61
|
+
)
|
62
|
+
else:
|
63
|
+
self.explanation1_4_lbl = Label(
|
64
|
+
self.frame_from_desktop,
|
65
|
+
text="Note: This will read memory of KakaoTalk Desktop",
|
66
|
+
justify="left",
|
67
|
+
anchor="w",
|
68
|
+
)
|
54
69
|
self.kakao_bin_path_lbl = Label(
|
55
70
|
self.frame_from_desktop,
|
56
71
|
text="Kakao app path (Optional):",
|
@@ -85,10 +100,13 @@ class KakaoGetAuthWindow(BaseWindow):
|
|
85
100
|
self.explanation1_3_lbl.grid(
|
86
101
|
column=0, row=2, columnspan=2, sticky="w", padx=3, pady=3
|
87
102
|
)
|
88
|
-
self.
|
89
|
-
|
90
|
-
|
91
|
-
self.
|
103
|
+
self.explanation1_4_lbl.grid(
|
104
|
+
column=0, row=3, columnspan=2, sticky="w", padx=3, pady=3
|
105
|
+
)
|
106
|
+
self.kakao_bin_path_lbl.grid(column=0, row=4, sticky="w", padx=3, pady=3)
|
107
|
+
self.kakao_bin_path_entry.grid(column=1, row=4, sticky="w", padx=3, pady=3)
|
108
|
+
self.launch_desktop_btn.grid(column=0, row=5, columnspan=2, padx=3, pady=3)
|
109
|
+
self.get_auth_desktop_btn.grid(column=0, row=6, columnspan=2, padx=3, pady=3)
|
92
110
|
|
93
111
|
# Method 2 frame
|
94
112
|
self.explanation2_1_lbl = Label(
|
@@ -277,6 +295,8 @@ class KakaoGetAuthWindow(BaseWindow):
|
|
277
295
|
|
278
296
|
def cb_from_desktop_thread(self, *_: Any) -> None:
|
279
297
|
self.gui.save_creds()
|
298
|
+
self.gui.cb_msg("Getting auth_token, this may take a minute...")
|
299
|
+
self.gui.cb_bar("indeterminate")
|
280
300
|
m = GetKakaoDesktopAuth(
|
281
301
|
cb_ask_str=self.cb_ask_str_kakao,
|
282
302
|
)
|
@@ -298,3 +318,4 @@ class KakaoGetAuthWindow(BaseWindow):
|
|
298
318
|
self.gui.highlight_fields()
|
299
319
|
|
300
320
|
self.cb_msg_block_kakao(msg)
|
321
|
+
self.gui.cb_bar("clear")
|
@@ -59,10 +59,25 @@ class ViberGetAuthWindow(BaseWindow):
|
|
59
59
|
justify="left",
|
60
60
|
anchor="w",
|
61
61
|
)
|
62
|
+
if platform.system() != "Darwin":
|
63
|
+
self.explanation_lbl3 = Label(
|
64
|
+
self.frame_info,
|
65
|
+
text="Note: This will download ProcDump and read memory of Viber Desktop",
|
66
|
+
justify="left",
|
67
|
+
anchor="w",
|
68
|
+
)
|
69
|
+
else:
|
70
|
+
self.explanation_lbl3 = Label(
|
71
|
+
self.frame_info,
|
72
|
+
text="Note: This will read memory of Viber Desktop",
|
73
|
+
justify="left",
|
74
|
+
anchor="w",
|
75
|
+
)
|
62
76
|
|
63
77
|
self.explanation_lbl0.grid(column=0, row=0, sticky="w", padx=3, pady=3)
|
64
78
|
self.explanation_lbl1.grid(column=0, row=1, sticky="w", padx=3, pady=3)
|
65
79
|
self.explanation_lbl2.grid(column=0, row=2, sticky="w", padx=3, pady=3)
|
80
|
+
self.explanation_lbl3.grid(column=0, row=3, sticky="w", padx=3, pady=3)
|
66
81
|
|
67
82
|
# Start button frame
|
68
83
|
self.launch_btn = Button(
|
@@ -64,7 +64,7 @@
|
|
64
64
|
"telethon_setup": "Setup Telethon",
|
65
65
|
"kakao_auth_token": "Set Kakao auth_token. Required for downloading animated stickers from https://e.kakao.com/t/xxxxx",
|
66
66
|
"kakao_get_auth": "Generate Kakao auth_token by simulating login. Kakao username, password, country code and phone number are also required.",
|
67
|
-
"kakao_get_auth_desktop": "Get Kakao auth_token from Kakao Desktop application
|
67
|
+
"kakao_get_auth_desktop": "Get Kakao auth_token from Kakao Desktop application.",
|
68
68
|
"kakao_bin_path": "Set Kakao Desktop application path for launching and getting auth_token.\nUseful for portable installation.",
|
69
69
|
"kakao_username": "Set Kakao username, which is email or phone number used for signing up Kakao account\nExample: +447700900142\nRequired for generating Kakao auth_token.",
|
70
70
|
"kakao_password": "Set Kakao password (Password of Kakao account).\nRequired for generating Kakao auth_token.",
|
@@ -1,5 +1,4 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
|
-
import importlib.util
|
3
2
|
import os
|
4
3
|
import platform
|
5
4
|
import re
|
@@ -8,9 +7,9 @@ import time
|
|
8
7
|
from functools import partial
|
9
8
|
from getpass import getpass
|
10
9
|
from pathlib import Path
|
11
|
-
from typing import Callable,
|
10
|
+
from typing import Callable, Optional, Tuple, Union, cast
|
12
11
|
|
13
|
-
from sticker_convert.utils.process import
|
12
|
+
from sticker_convert.utils.process import find_pid_by_name, get_mem, killall
|
14
13
|
|
15
14
|
MSG_NO_BIN = """Kakao Desktop not detected.
|
16
15
|
Download and install Kakao Desktop,
|
@@ -97,13 +96,20 @@ class GetKakaoDesktopAuth:
|
|
97
96
|
self, kakao_bin_path: str, relaunch: bool = True
|
98
97
|
) -> Tuple[Optional[str], str]:
|
99
98
|
auth_token = None
|
100
|
-
|
101
|
-
if
|
102
|
-
|
99
|
+
kakao_pid: Union[str, int, None]
|
100
|
+
if platform.system() == "Windows":
|
101
|
+
is_wine = False
|
102
|
+
if relaunch:
|
103
|
+
kakao_pid = self.relaunch_kakao(kakao_bin_path)
|
104
|
+
else:
|
105
|
+
kakao_pid = find_pid_by_name("kakaotalk")
|
106
|
+
if kakao_pid is None:
|
107
|
+
return None, MSG_LAUNCH_FAIL
|
103
108
|
else:
|
104
|
-
|
105
|
-
|
106
|
-
|
109
|
+
is_wine = True
|
110
|
+
kakao_pid = "KakaoTalk.exe"
|
111
|
+
if relaunch and self.relaunch_kakao(kakao_bin_path) is None:
|
112
|
+
return None, MSG_LAUNCH_FAIL
|
107
113
|
|
108
114
|
if self.cb_ask_str == input:
|
109
115
|
pw_func = getpass
|
@@ -111,10 +117,10 @@ class GetKakaoDesktopAuth:
|
|
111
117
|
pw_func = partial(
|
112
118
|
self.cb_ask_str, initialvalue="", cli_show_initialvalue=False
|
113
119
|
)
|
114
|
-
s
|
120
|
+
s = get_mem(kakao_pid, pw_func, is_wine)
|
115
121
|
|
116
122
|
if s is None:
|
117
|
-
return None,
|
123
|
+
return None, "Failed to dump memory"
|
118
124
|
|
119
125
|
auth_token = None
|
120
126
|
for i in re.finditer(b"authorization: ", s):
|
@@ -140,6 +146,13 @@ class GetKakaoDesktopAuth:
|
|
140
146
|
return auth_token, msg
|
141
147
|
|
142
148
|
def get_auth_darwin(self, kakao_bin_path: str) -> Tuple[Optional[str], str]:
|
149
|
+
csrutil_status = subprocess.run(
|
150
|
+
["csrutil", "status"], capture_output=True, text=True
|
151
|
+
).stdout
|
152
|
+
|
153
|
+
if "enabled" in csrutil_status:
|
154
|
+
return None, MSG_SIP_ENABLED
|
155
|
+
|
143
156
|
killall("kakaotalk")
|
144
157
|
|
145
158
|
subprocess.run(
|
@@ -205,9 +218,10 @@ class GetKakaoDesktopAuth:
|
|
205
218
|
elif platform.system() == "Darwin":
|
206
219
|
kakao_bin_path = "/Applications/KakaoTalk.app"
|
207
220
|
else:
|
208
|
-
|
209
|
-
|
210
|
-
|
221
|
+
wineprefix = os.environ.get("WINEPREFIX")
|
222
|
+
if not (wineprefix and Path(wineprefix).exists()):
|
223
|
+
wineprefix = os.path.expanduser("~/.wine")
|
224
|
+
kakao_bin_path = f"{wineprefix}/drive_c/Program Files (x86)/Kakao/KakaoTalk/KakaoTalk.exe"
|
211
225
|
|
212
226
|
if Path(kakao_bin_path).exists():
|
213
227
|
return kakao_bin_path
|
@@ -220,7 +234,7 @@ class GetKakaoDesktopAuth:
|
|
220
234
|
) -> Tuple[Optional[str], str]:
|
221
235
|
# get_auth_by_dump()
|
222
236
|
# + Fast
|
223
|
-
# - Requires admin
|
237
|
+
# - Requires downloading procdump, or builtin method that needs admin
|
224
238
|
|
225
239
|
# get_auth_by_pme()
|
226
240
|
# + No admin (If have permission to read process)
|
@@ -233,32 +247,13 @@ class GetKakaoDesktopAuth:
|
|
233
247
|
if not kakao_bin_path:
|
234
248
|
return None, MSG_NO_BIN
|
235
249
|
|
236
|
-
if platform.system()
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
msg = ""
|
242
|
-
|
243
|
-
pme_present = importlib.util.find_spec("PyMemoryEditor") is not None
|
244
|
-
methods.append(self.get_auth_by_dump)
|
245
|
-
if pme_present:
|
246
|
-
methods.append(self.get_auth_by_pme)
|
247
|
-
if check_admin() is False:
|
248
|
-
methods.reverse()
|
249
|
-
|
250
|
-
for method in methods:
|
251
|
-
kakao_auth, msg = method(kakao_bin_path, relaunch)
|
252
|
-
relaunch = False
|
253
|
-
if kakao_auth is not None:
|
254
|
-
break
|
255
|
-
else:
|
256
|
-
csrutil_status = subprocess.run(
|
257
|
-
["csrutil", "status"], capture_output=True, text=True
|
258
|
-
).stdout
|
259
|
-
|
260
|
-
if "enabled" in csrutil_status:
|
261
|
-
return None, MSG_SIP_ENABLED
|
250
|
+
if platform.system() == "Windows":
|
251
|
+
kakao_auth, msg = self.get_auth_by_dump(kakao_bin_path)
|
252
|
+
if kakao_auth is None:
|
253
|
+
kakao_auth, msg = self.get_auth_by_pme(kakao_bin_path, False)
|
254
|
+
elif platform.system() == "Darwin":
|
262
255
|
kakao_auth, msg = self.get_auth_darwin(kakao_bin_path)
|
256
|
+
else:
|
257
|
+
kakao_auth, msg = self.get_auth_by_dump(kakao_bin_path)
|
263
258
|
|
264
259
|
return kakao_auth, msg
|
@@ -130,10 +130,10 @@ class GetViberAuth:
|
|
130
130
|
pw_func = partial(
|
131
131
|
self.cb_ask_str, initialvalue="", cli_show_initialvalue=False
|
132
132
|
)
|
133
|
-
s
|
133
|
+
s = get_mem(viber_pid, pw_func)
|
134
134
|
|
135
135
|
if s is None:
|
136
|
-
return None,
|
136
|
+
return None, "Failed to dump memory"
|
137
137
|
|
138
138
|
member_id_addr = s.find(b"X-Viber-Auth-Mid: ")
|
139
139
|
m_token_addr = s.find(b"X-Viber-Auth-Token: ")
|
@@ -217,8 +217,6 @@ class GetViberAuth:
|
|
217
217
|
methods.append(self.get_auth_by_dump)
|
218
218
|
if pme_present:
|
219
219
|
methods.append(self.get_auth_by_pme)
|
220
|
-
if check_admin() is False:
|
221
|
-
methods.reverse()
|
222
220
|
else:
|
223
221
|
if not os.path.isfile("/.dockerenv"):
|
224
222
|
methods.append(self.get_auth_by_dump)
|
@@ -342,10 +342,12 @@ class TelethonAPI(TelegramAPI):
|
|
342
342
|
self.cb = cb
|
343
343
|
self.cb_return = cb_return
|
344
344
|
|
345
|
-
success,
|
345
|
+
success, client, _, _ = await TelethonSetup(
|
346
346
|
self.opt_cred, self.cb_ask_str
|
347
347
|
).start_async()
|
348
348
|
|
349
|
+
if success is True and client is not None:
|
350
|
+
self.client = client
|
349
351
|
return success
|
350
352
|
|
351
353
|
async def exit(self) -> None:
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
|
-
from typing import Callable, Tuple
|
2
|
+
from typing import Callable, Optional, Tuple
|
3
3
|
|
4
4
|
import anyio
|
5
5
|
from telethon import TelegramClient # type: ignore
|
@@ -58,28 +58,39 @@ class TelethonSetup:
|
|
58
58
|
def guide(self) -> None:
|
59
59
|
self.cb_ask_str(GUIDE_MSG)
|
60
60
|
|
61
|
-
def get_api_info(self) ->
|
61
|
+
def get_api_info(self) -> bool:
|
62
62
|
api_id_ask = "Enter api_id: "
|
63
63
|
wrong_hint = ""
|
64
|
+
|
64
65
|
while True:
|
65
66
|
telethon_api_id = self.cb_ask_str(wrong_hint + api_id_ask)
|
66
|
-
if telethon_api_id
|
67
|
+
if telethon_api_id == "":
|
68
|
+
return False
|
69
|
+
elif telethon_api_id.isnumeric():
|
67
70
|
self.opt_cred.telethon_api_id = int(telethon_api_id)
|
68
71
|
break
|
69
72
|
else:
|
70
73
|
wrong_hint = "Error: api_id should be numeric\n"
|
74
|
+
|
71
75
|
self.opt_cred.telethon_api_hash = self.cb_ask_str("Enter api_hash: ")
|
76
|
+
if self.opt_cred.telethon_api_hash == "":
|
77
|
+
return False
|
78
|
+
return True
|
72
79
|
|
73
80
|
def signin(self) -> Tuple[bool, TelegramClient, int, str]:
|
74
81
|
return anyio.run(self.signin_async)
|
75
82
|
|
76
|
-
def start(self) -> Tuple[bool, TelegramClient, int, str]:
|
83
|
+
def start(self) -> Tuple[bool, Optional[TelegramClient], int, str]:
|
84
|
+
cred_valid = False
|
77
85
|
if self.opt_cred.telethon_api_id == 0 or self.opt_cred.telethon_api_hash == "":
|
78
86
|
self.guide()
|
79
|
-
self.get_api_info()
|
80
|
-
|
87
|
+
cred_valid = self.get_api_info()
|
88
|
+
if cred_valid:
|
89
|
+
return self.signin()
|
90
|
+
else:
|
91
|
+
return False, None, 0, ""
|
81
92
|
|
82
|
-
async def start_async(self) -> Tuple[bool, TelegramClient, int, str]:
|
93
|
+
async def start_async(self) -> Tuple[bool, Optional[TelegramClient], int, str]:
|
83
94
|
if self.opt_cred.telethon_api_id == 0 or self.opt_cred.telethon_api_hash == "":
|
84
95
|
self.guide()
|
85
96
|
self.get_api_info()
|
@@ -9,7 +9,7 @@ import signal
|
|
9
9
|
import socket
|
10
10
|
import subprocess
|
11
11
|
import time
|
12
|
-
from typing import Any, Dict, List, Optional,
|
12
|
+
from typing import Any, Dict, List, Optional, Union, cast
|
13
13
|
|
14
14
|
import requests
|
15
15
|
import websocket
|
@@ -83,28 +83,14 @@ class CRD:
|
|
83
83
|
self.chrome_proc = subprocess.Popen(launch_cmd)
|
84
84
|
|
85
85
|
@staticmethod
|
86
|
-
def
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
bs: List[Tuple[int, str]] = []
|
96
|
-
for b in browsers.browsers():
|
97
|
-
browser_type = b["browser_type"]
|
98
|
-
path = b["path"]
|
99
|
-
try:
|
100
|
-
rank = BROWSER_PREF.index(browser_type)
|
101
|
-
except ValueError:
|
102
|
-
continue
|
103
|
-
bs.append((rank, path))
|
104
|
-
if len(bs) == 0:
|
105
|
-
return None
|
106
|
-
bs = sorted(bs, key=lambda x: x[0])
|
107
|
-
return bs[0][1]
|
86
|
+
def get_chromium_path() -> Optional[str]:
|
87
|
+
if platform.system() == "Windows":
|
88
|
+
from sticker_convert.utils.chromiums.windows import get_chromium_path
|
89
|
+
elif platform.system() == "Darwin":
|
90
|
+
from sticker_convert.utils.chromiums.osx import get_chromium_path
|
91
|
+
else:
|
92
|
+
from sticker_convert.utils.chromiums.linux import get_chromium_path
|
93
|
+
return get_chromium_path()
|
108
94
|
|
109
95
|
def connect(self, target_id: int = 0) -> None:
|
110
96
|
self.cmd_id = 1
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
import configparser
|
3
|
+
import os
|
4
|
+
import re
|
5
|
+
from typing import Optional
|
6
|
+
|
7
|
+
# Adopted from https://github.com/roniemartinez/browsers/blob/master/browsers/linux.py
|
8
|
+
|
9
|
+
LINUX_DESKTOP_ENTRY_LIST = (
|
10
|
+
("chrome", ("google-chrome",)),
|
11
|
+
("chromium", ("chromium", "chromium_chromium")),
|
12
|
+
("brave", ("brave-browser", "brave_brave")),
|
13
|
+
("brave-beta", ("brave-browser-beta",)),
|
14
|
+
("brave-nightly", ("brave-browser-nightly",)),
|
15
|
+
("msedge", ("microsoft-edge",)),
|
16
|
+
("opera", ("opera_opera",)),
|
17
|
+
("opera-beta", ("opera-beta_opera-beta",)),
|
18
|
+
("opera-developer", ("opera-developer_opera-developer",)),
|
19
|
+
("vivaldi", ("vivaldi_vivaldi-stable",)),
|
20
|
+
)
|
21
|
+
|
22
|
+
# $XDG_DATA_HOME and $XDG_DATA_DIRS are not always set
|
23
|
+
XDG_DATA_LOCATIONS = (
|
24
|
+
"~/.local/share/applications",
|
25
|
+
"/usr/share/applications",
|
26
|
+
"/var/lib/snapd/desktop/applications",
|
27
|
+
)
|
28
|
+
|
29
|
+
VERSION_PATTERN = re.compile(
|
30
|
+
r"\b(\S+\.\S+)\b"
|
31
|
+
) # simple pattern assuming all version strings have a dot on them
|
32
|
+
|
33
|
+
|
34
|
+
def get_chromium_path() -> Optional[str]:
|
35
|
+
for _, desktop_entries in LINUX_DESKTOP_ENTRY_LIST:
|
36
|
+
for application_dir in XDG_DATA_LOCATIONS:
|
37
|
+
for desktop_entry in desktop_entries:
|
38
|
+
path = os.path.join(application_dir, f"{desktop_entry}.desktop")
|
39
|
+
|
40
|
+
if not os.path.isfile(path):
|
41
|
+
continue
|
42
|
+
|
43
|
+
config = configparser.ConfigParser(interpolation=None)
|
44
|
+
config.read(path, encoding="utf-8")
|
45
|
+
executable_path = config.get("Desktop Entry", "Exec")
|
46
|
+
|
47
|
+
if executable_path.lower().endswith(" %u"):
|
48
|
+
executable_path = executable_path[:-3].strip()
|
49
|
+
|
50
|
+
return executable_path
|
51
|
+
|
52
|
+
return None
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
import glob
|
3
|
+
import os
|
4
|
+
import plistlib
|
5
|
+
import subprocess
|
6
|
+
from typing import Optional
|
7
|
+
|
8
|
+
# Adopted from https://github.com/roniemartinez/browsers/blob/master/browsers/osx.py
|
9
|
+
|
10
|
+
OSX_CHROMIUMS_BUNDLE_LIST = (
|
11
|
+
# browser name, bundle ID, version string
|
12
|
+
("chrome", "com.google.Chrome", "CFBundleShortVersionString"),
|
13
|
+
("chrome-beta", "com.google.Chrome.beta", "CFBundleShortVersionString"),
|
14
|
+
("chrome-canary", "com.google.Chrome.canary", "CFBundleShortVersionString"),
|
15
|
+
("chrome-dev", "com.google.Chrome.dev", "CFBundleShortVersionString"),
|
16
|
+
("chrome-test", "com.google.chrome.for.testing", "CFBundleShortVersionString"),
|
17
|
+
("chromium", "org.chromium.Chromium", "CFBundleShortVersionString"),
|
18
|
+
("msedge", "com.microsoft.edgemac", "CFBundleShortVersionString"),
|
19
|
+
("msedge-beta", "com.microsoft.edgemac.Beta", "CFBundleShortVersionString"),
|
20
|
+
("msedge-dev", "com.microsoft.edgemac.Dev", "CFBundleShortVersionString"),
|
21
|
+
("msedge-canary", "com.microsoft.edgemac.Canary", "CFBundleShortVersionString"),
|
22
|
+
("brave", "com.brave.Browser", "CFBundleVersion"),
|
23
|
+
("brave-beta", "com.brave.Browser.beta", "CFBundleVersion"),
|
24
|
+
("brave-dev", "com.brave.Browser.dev", "CFBundleVersion"),
|
25
|
+
("brave-nightly", "com.brave.Browser.nightly", "CFBundleVersion"),
|
26
|
+
("opera", "com.operasoftware.Opera", "CFBundleVersion"),
|
27
|
+
("opera-beta", "com.operasoftware.OperaNext", "CFBundleVersion"),
|
28
|
+
("opera-developer", "com.operasoftware.OperaDeveloper", "CFBundleVersion"),
|
29
|
+
("opera-gx", "com.operasoftware.OperaGX", "CFBundleVersion"),
|
30
|
+
("opera-neon", "com.opera.Neon", "CFBundleShortVersionString"),
|
31
|
+
("duckduckgo", "com.duckduckgo.macos.browser", "CFBundleShortVersionString"),
|
32
|
+
("epic", "com.hiddenreflex.Epic", "CFBundleShortVersionString"),
|
33
|
+
("vivaldi", "com.vivaldi.Vivaldi", "CFBundleShortVersionString"),
|
34
|
+
("yandex", "ru.yandex.desktop.yandex-browser", "CFBundleShortVersionString"),
|
35
|
+
)
|
36
|
+
|
37
|
+
OSX_CHROMIUMS_BUNDLE_DICT = {item[1]: item for item in OSX_CHROMIUMS_BUNDLE_LIST}
|
38
|
+
|
39
|
+
|
40
|
+
def get_chromium_path() -> Optional[str]:
|
41
|
+
for _, bundle_id, _ in OSX_CHROMIUMS_BUNDLE_LIST:
|
42
|
+
app_dirs = subprocess.getoutput(
|
43
|
+
f'mdfind "kMDItemCFBundleIdentifier == {bundle_id}"'
|
44
|
+
).splitlines()
|
45
|
+
for app_dir in app_dirs:
|
46
|
+
plist_path = os.path.join(app_dir, "Contents/Info.plist")
|
47
|
+
|
48
|
+
with open(plist_path, "rb") as f:
|
49
|
+
plist = plistlib.load(f)
|
50
|
+
executable_name = plist["CFBundleExecutable"]
|
51
|
+
executable = os.path.join(app_dir, "Contents/MacOS", executable_name)
|
52
|
+
return executable
|
53
|
+
|
54
|
+
# Naively iterate /Applications folder in case the above check fails
|
55
|
+
for plist_path in glob.glob("/Applications/*.app/Contents/Info.plist"):
|
56
|
+
with open(plist_path, "rb") as f:
|
57
|
+
plist = plistlib.load(f)
|
58
|
+
bundle_id = plist.get("CFBundleIdentifier")
|
59
|
+
if bundle_id not in OSX_CHROMIUMS_BUNDLE_DICT:
|
60
|
+
continue
|
61
|
+
|
62
|
+
app_dir = os.path.dirname(os.path.dirname(plist_path))
|
63
|
+
executable_name = plist["CFBundleExecutable"]
|
64
|
+
executable = os.path.join(app_dir, "Contents/MacOS", executable_name)
|
65
|
+
|
66
|
+
return executable
|
67
|
+
|
68
|
+
return None
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
import os
|
3
|
+
from typing import Optional
|
4
|
+
|
5
|
+
# Not adopting approach of reading registry like https://github.com/roniemartinez/browsers
|
6
|
+
# As trigger antivirus
|
7
|
+
|
8
|
+
PF32 = os.environ.get("PROGRAMW6432")
|
9
|
+
PF64 = os.environ.get("PROGRAMFILES")
|
10
|
+
LAD = os.environ.get("LOCALAPPDATA")
|
11
|
+
|
12
|
+
WINDOWS_CHROMIUMS_PATHS = (
|
13
|
+
f"{PF64}\\Google\\Chrome\\Application\\chrome.exe", # chromium
|
14
|
+
f"{PF32}\\Google\\Chrome\\Application\\chrome.exe", # chromium
|
15
|
+
f"{LAD}\\Google\\Chrome SxS\\Application\\chrome.exe", # chromium-canary
|
16
|
+
f"{PF64}\\Opera\\opera.exe", # opera
|
17
|
+
f"{PF32}\\Opera\\opera.exe", # opera
|
18
|
+
f"{LAD}\\Programs\\Opera\\opera.exe", # opera
|
19
|
+
f"{LAD}\\Programs\\Opera\\launcher.exe", # opera
|
20
|
+
f"{LAD}\\Programs\\Opera Beta\\opera.exe", # opera-beta
|
21
|
+
f"{LAD}\\Programs\\Opera Beta\\launcher.exe", # opera-beta
|
22
|
+
f"{LAD}\\Programs\\Opera Developer\\opera.exe", # opera-developer
|
23
|
+
f"{LAD}\\Programs\\Opera Developer\\launcher.exe", # opera-developer
|
24
|
+
f"{PF64}\\Microsoft\\Edge\\Application\\msedge.exe", # msedge
|
25
|
+
f"{PF32}\\Microsoft\\Edge\\Application\\msedge.exe", # msedge
|
26
|
+
f"{PF64}\\Microsoft\\Edge Beta\\Application\\msedge.exe", # msedge-beta
|
27
|
+
f"{PF32}\\Microsoft\\Edge Beta\\Application\\msedge.exe", # msedge-beta
|
28
|
+
f"{PF64}\\Microsoft\\Edge Dev\\Application\\msedge.exe", # msedge-dev
|
29
|
+
f"{PF32}\\Microsoft\\Edge Dev\\Application\\msedge.exe", # msedge-dev
|
30
|
+
f"{LAD}\\Microsoft\\Edge SxS\\Application\\msedge.exe", # msedge-canary
|
31
|
+
f"{PF64}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe", # brave
|
32
|
+
f"{PF32}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe", # brave
|
33
|
+
f"{PF64}\\BraveSoftware\\Brave-Browser-Beta\\Application\\brave.exe", # brave-beta
|
34
|
+
f"{PF32}\\BraveSoftware\\Brave-Browser-Beta\\Application\\brave.exe", # brave-beta
|
35
|
+
f"{PF64}\\BraveSoftware\\Brave-Browser-Nightly\\Application\\brave.exe", # brave-nightly
|
36
|
+
f"{PF32}\\BraveSoftware\\Brave-Browser-Nightly\\Application\\brave.exe", # brave-nightly
|
37
|
+
)
|
38
|
+
|
39
|
+
|
40
|
+
def get_chromium_path() -> Optional[str]:
|
41
|
+
for path in WINDOWS_CHROMIUMS_PATHS:
|
42
|
+
if os.path.exists(path):
|
43
|
+
return path
|
44
|
+
|
45
|
+
return None
|
sticker_convert/utils/process.py
CHANGED
@@ -5,17 +5,20 @@ import shutil
|
|
5
5
|
import subprocess
|
6
6
|
import time
|
7
7
|
from getpass import getpass
|
8
|
-
from
|
8
|
+
from io import BytesIO
|
9
|
+
from typing import Callable, Optional, Union
|
10
|
+
from zipfile import ZipFile
|
9
11
|
|
10
12
|
import psutil
|
13
|
+
import requests
|
11
14
|
|
12
|
-
from sticker_convert.definitions import ROOT_DIR
|
15
|
+
from sticker_convert.definitions import CONFIG_DIR, ROOT_DIR
|
13
16
|
|
14
17
|
|
15
18
|
def killall(name: str) -> bool:
|
16
19
|
result = False
|
17
20
|
|
18
|
-
for proc in psutil.process_iter():
|
21
|
+
for proc in psutil.process_iter(): # type: ignore
|
19
22
|
if name in proc.name().lower():
|
20
23
|
proc.kill()
|
21
24
|
result = True
|
@@ -24,7 +27,7 @@ def killall(name: str) -> bool:
|
|
24
27
|
|
25
28
|
|
26
29
|
def find_pid_by_name(name: str) -> Optional[int]:
|
27
|
-
for proc in psutil.process_iter():
|
30
|
+
for proc in psutil.process_iter(): # type: ignore
|
28
31
|
if name in proc.name().lower():
|
29
32
|
return proc.pid
|
30
33
|
|
@@ -65,123 +68,164 @@ elif platform.system() == "Linux":
|
|
65
68
|
return True if "may run the following commands" in s else False
|
66
69
|
|
67
70
|
|
68
|
-
def
|
69
|
-
pid:
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
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
|
-
|
71
|
+
def _get_mem_win_procdump(
|
72
|
+
pid: Union[str, int],
|
73
|
+
pw_func: Optional[Callable[..., str]] = None,
|
74
|
+
is_wine: bool = False,
|
75
|
+
) -> Optional[bytes]:
|
76
|
+
procdump_dir = CONFIG_DIR / "ProcDump"
|
77
|
+
procdump_bin = procdump_dir / "procdump.exe"
|
78
|
+
if procdump_bin.is_file() is False:
|
79
|
+
r = requests.get("https://download.sysinternals.com/files/Procdump.zip")
|
80
|
+
if r.ok is False:
|
81
|
+
return None
|
82
|
+
with ZipFile(BytesIO(r.content)) as zf:
|
83
|
+
zf.extractall(procdump_dir)
|
84
|
+
|
85
|
+
if procdump_bin.is_file() is False:
|
86
|
+
return None
|
87
|
+
|
88
|
+
if is_wine:
|
89
|
+
cmd = ["wine"]
|
90
|
+
dump_fpath = f"/tmp/memdump.{pid}.dmp"
|
91
|
+
else:
|
92
|
+
cmd = []
|
93
|
+
dump_fpath = os.path.expandvars(f"%temp%/memdump.{pid}.dmp")
|
94
|
+
cmd += [str(procdump_bin), "-accepteula", "-ma", str(pid), dump_fpath]
|
95
|
+
|
96
|
+
subprocess.run(cmd)
|
97
|
+
|
98
|
+
with open(dump_fpath, "rb") as f:
|
99
|
+
s = f.read()
|
100
|
+
os.remove(dump_fpath)
|
101
|
+
|
102
|
+
return s
|
103
|
+
|
104
|
+
|
105
|
+
def _get_mem_win_builtin(
|
106
|
+
pid: Union[str, int], pw_func: Optional[Callable[..., str]] = None
|
107
|
+
) -> Optional[bytes]:
|
108
|
+
from pathlib import WindowsPath
|
109
|
+
|
110
|
+
memdump_ps_path = str(WindowsPath(ROOT_DIR / "resources/memdump_windows.ps1"))
|
111
|
+
arglist = f'-NoProfile -ExecutionPolicy Bypass -File "{memdump_ps_path}" {pid}'
|
112
|
+
dump_fpath = os.path.expandvars(f"%temp%/memdump.{pid}.dmp")
|
113
|
+
|
114
|
+
cmd = [
|
115
|
+
"powershell",
|
116
|
+
"-NoProfile",
|
117
|
+
"-ExecutionPolicy",
|
118
|
+
"Bypass",
|
119
|
+
"-Command",
|
120
|
+
f"Start-Process -Verb RunAs powershell -ArgumentList '{arglist}'",
|
121
|
+
]
|
122
|
+
|
123
|
+
subprocess.run(cmd, capture_output=True, text=True)
|
124
|
+
|
125
|
+
while True:
|
126
|
+
try:
|
127
|
+
with open(dump_fpath, "rb") as f:
|
128
|
+
s = f.read()
|
129
|
+
if len(s) != 0:
|
109
130
|
break
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
return s, ""
|
131
|
+
time.sleep(1)
|
132
|
+
except (FileNotFoundError, PermissionError):
|
133
|
+
pass
|
114
134
|
|
115
|
-
|
135
|
+
while True:
|
136
|
+
try:
|
137
|
+
os.remove(dump_fpath)
|
138
|
+
break
|
139
|
+
except PermissionError:
|
140
|
+
pass
|
116
141
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
142
|
+
return s
|
143
|
+
|
144
|
+
|
145
|
+
def _get_mem_darwin(
|
146
|
+
pid: Union[str, int], pw_func: Optional[Callable[..., str]] = None
|
147
|
+
) -> Optional[bytes]:
|
148
|
+
subprocess.run(
|
149
|
+
[
|
150
|
+
"lldb",
|
151
|
+
"--attach-pid",
|
152
|
+
str(pid),
|
153
|
+
"-o",
|
154
|
+
f"process save-core /tmp/memdump.{pid}.dmp",
|
155
|
+
"-o",
|
156
|
+
"quit",
|
157
|
+
],
|
158
|
+
stdout=subprocess.DEVNULL,
|
159
|
+
stderr=subprocess.DEVNULL,
|
160
|
+
)
|
161
|
+
|
162
|
+
with open(f"/tmp/memdump.{pid}.dmp", "rb") as f:
|
163
|
+
s = f.read()
|
164
|
+
|
165
|
+
os.remove(f"/tmp/memdump.{pid}.dmp")
|
166
|
+
|
167
|
+
return s
|
168
|
+
|
169
|
+
|
170
|
+
def _get_mem_linux(
|
171
|
+
pid: Union[str, int], pw_func: Optional[Callable[..., str]] = None
|
172
|
+
) -> Optional[bytes]:
|
173
|
+
memdump_sh_path = (ROOT_DIR / "resources/memdump_linux.sh").as_posix()
|
174
|
+
|
175
|
+
s = subprocess.run(
|
176
|
+
[
|
177
|
+
memdump_sh_path,
|
178
|
+
str(pid),
|
179
|
+
],
|
180
|
+
capture_output=True,
|
181
|
+
).stdout
|
182
|
+
|
183
|
+
if len(s) > 1000:
|
184
|
+
pass
|
185
|
+
elif shutil.which("pkexec") and os.getenv("DISPLAY"):
|
186
|
+
s = subprocess.run(
|
121
187
|
[
|
122
|
-
"
|
123
|
-
|
188
|
+
"pkexec",
|
189
|
+
memdump_sh_path,
|
124
190
|
str(pid),
|
125
|
-
"-o",
|
126
|
-
f"process save-core /tmp/memdump.{pid}.dmp",
|
127
|
-
"-o",
|
128
|
-
"quit",
|
129
191
|
],
|
130
|
-
|
131
|
-
|
192
|
+
capture_output=True,
|
193
|
+
).stdout
|
194
|
+
else:
|
195
|
+
prompt = "Enter sudo password: "
|
196
|
+
if pw_func:
|
197
|
+
sudo_password = pw_func(prompt)
|
198
|
+
else:
|
199
|
+
sudo_password = getpass(prompt)
|
200
|
+
sudo_password_pipe = subprocess.Popen(
|
201
|
+
("echo", sudo_password), stdout=subprocess.PIPE
|
132
202
|
)
|
133
|
-
|
134
|
-
with open(f"/tmp/memdump.{pid}.dmp", "rb") as f:
|
135
|
-
s = f.read()
|
136
|
-
|
137
|
-
os.remove(f"/tmp/memdump.{pid}.dmp")
|
138
|
-
|
139
|
-
return s, ""
|
140
|
-
|
141
|
-
else:
|
142
|
-
|
143
|
-
def get_mem(
|
144
|
-
pid: int, pw_func: Optional[Callable[..., str]] = None
|
145
|
-
) -> Tuple[Optional[bytes], str]:
|
146
|
-
memdump_sh_path = (ROOT_DIR / "resources/memdump_linux.sh").as_posix()
|
147
|
-
|
148
203
|
s = subprocess.run(
|
149
204
|
[
|
205
|
+
"sudo",
|
206
|
+
"-S",
|
150
207
|
memdump_sh_path,
|
151
208
|
str(pid),
|
152
209
|
],
|
153
210
|
capture_output=True,
|
211
|
+
stdin=sudo_password_pipe.stdout,
|
154
212
|
).stdout
|
155
213
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
214
|
+
return s
|
215
|
+
|
216
|
+
|
217
|
+
def get_mem(
|
218
|
+
pid: Union[str, int],
|
219
|
+
pw_func: Optional[Callable[..., str]] = None,
|
220
|
+
is_wine: bool = False,
|
221
|
+
) -> Optional[bytes]:
|
222
|
+
if is_wine or platform.system() == "Windows":
|
223
|
+
dump = _get_mem_win_procdump(pid, pw_func, is_wine)
|
224
|
+
if dump is not None or is_wine:
|
225
|
+
return dump
|
167
226
|
else:
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
sudo_password_pipe = subprocess.Popen(
|
174
|
-
("echo", sudo_password), stdout=subprocess.PIPE
|
175
|
-
)
|
176
|
-
s = subprocess.run(
|
177
|
-
[
|
178
|
-
"sudo",
|
179
|
-
"-S",
|
180
|
-
memdump_sh_path,
|
181
|
-
str(pid),
|
182
|
-
],
|
183
|
-
capture_output=True,
|
184
|
-
stdin=sudo_password_pipe.stdout,
|
185
|
-
).stdout
|
186
|
-
|
187
|
-
return s, ""
|
227
|
+
return _get_mem_win_builtin(pid, pw_func)
|
228
|
+
elif platform.system() == "Darwin":
|
229
|
+
return _get_mem_darwin(pid, pw_func)
|
230
|
+
else:
|
231
|
+
return _get_mem_linux(pid, pw_func)
|
sticker_convert/version.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: sticker-convert
|
3
|
-
Version: 2.13.0
|
3
|
+
Version: 2.13.1.0
|
4
4
|
Summary: Convert (animated) stickers to/from WhatsApp, Telegram, Signal, Line, Kakao, Viber, Discord, iMessage. Written in Python.
|
5
5
|
Author-email: laggykiller <chaudominic2@gmail.com>
|
6
6
|
Maintainer-email: laggykiller <chaudominic2@gmail.com>
|
@@ -367,7 +367,7 @@ Requires-Dist: aiolimiter~=1.2.1
|
|
367
367
|
Requires-Dist: anyio~=4.9.0
|
368
368
|
Requires-Dist: apngasm_python~=1.3.2
|
369
369
|
Requires-Dist: av>=13.1.0
|
370
|
-
Requires-Dist: beautifulsoup4~=4.13.
|
370
|
+
Requires-Dist: beautifulsoup4~=4.13.4
|
371
371
|
Requires-Dist: cryptg~=0.5.0.post0
|
372
372
|
Requires-Dist: rookiepy~=0.5.6
|
373
373
|
Requires-Dist: httpx~=0.28.1
|
@@ -376,16 +376,15 @@ Requires-Dist: memory-tempfile~=2.2.3
|
|
376
376
|
Requires-Dist: mergedeep~=1.3.4
|
377
377
|
Requires-Dist: numpy>=1.22.4
|
378
378
|
Requires-Dist: Pillow~=11.2.1
|
379
|
-
Requires-Dist: pybrowsers~=0.8.0
|
380
379
|
Requires-Dist: pyoxipng~=9.1.0
|
381
|
-
Requires-Dist: python-telegram-bot~=22.
|
380
|
+
Requires-Dist: python-telegram-bot~=22.1
|
382
381
|
Requires-Dist: psutil~=7.0.0
|
383
382
|
Requires-Dist: PyMemoryEditor~=1.5.22
|
384
383
|
Requires-Dist: requests~=2.32.3
|
385
384
|
Requires-Dist: rlottie_python~=1.3.7
|
386
385
|
Requires-Dist: signalstickers-client-fork-laggykiller~=3.3.0.post2
|
387
386
|
Requires-Dist: socksio~=1.0.0
|
388
|
-
Requires-Dist: telethon~=1.
|
387
|
+
Requires-Dist: telethon~=1.40.0
|
389
388
|
Requires-Dist: tqdm~=4.67.1
|
390
389
|
Requires-Dist: ttkbootstrap-fork-laggykiller~=1.5.1
|
391
390
|
Requires-Dist: websocket_client~=1.8.0
|
@@ -402,7 +401,7 @@ Dynamic: license-file
|
|
402
401
|
|
403
402
|
## Downloads
|
404
403
|
- [Pre-compiled releases](https://github.com/laggykiller/sticker-convert/releases) for Windows, MacOS and Linux (As AppImage).
|
405
|
-
- Windows: Unzip the downloaded file and run `sticker-convert.exe
|
404
|
+
- Windows: Unzip the downloaded file and run `sticker-convert.exe`, or download msi file for installation
|
406
405
|
- MacOS: Unzip the downloaded file, hold control and open `hold_control_and_click_open_me.command` for the first time, then `sticker-convert.app` in the future
|
407
406
|
- Linux:
|
408
407
|
- AppImage: `chmod +x` the downloaded AppImage and run it
|
@@ -686,7 +685,6 @@ Credentials options:
|
|
686
685
|
--kakao-get-auth Generate Kakao auth_token by simulating login. Kakao username, password, country code and phone number are also required.
|
687
686
|
--kakao-get-auth-desktop
|
688
687
|
Get Kakao auth_token from Kakao Desktop application.
|
689
|
-
(Only working on Windows.)
|
690
688
|
--kakao-bin-path KAKAO_BIN_PATH
|
691
689
|
Set Kakao Desktop application path for launching and getting auth_token.
|
692
690
|
Useful for portable installation.
|
@@ -889,8 +887,10 @@ See [docs/TODO.md](docs/TODO.md)
|
|
889
887
|
- Information about Line stickers: https://github.com/doubleplusc/Line-sticker-downloader
|
890
888
|
- Information about Kakao animated stickers: https://gist.github.com/chitacan/9802668
|
891
889
|
- Downloading and decrypting Kakao animated stickers: https://github.com/blluv/KakaoTalkEmoticonDownloader
|
890
|
+
- Finding browser executable paths: https://github.com/roniemartinez/browsers
|
892
891
|
- Application icon taken from [Icons8](https://icons8.com/)
|
893
892
|
- Banner generated from [GitHub Socialify](https://socialify.git.ci/)
|
893
|
+
- Free code signing on Windows provided by [SignPath.io](https://about.signpath.io/), certificate by [SignPath Foundation](https://signpath.org/)
|
894
894
|
|
895
895
|
## DISCLAIMER
|
896
896
|
- The author of this repo is NOT affiliated with Signal, Telegram, WhatsApp, Line, Kakao, Naver Band, Viber, Discord, iMessage or Sticker Maker.
|
@@ -1,18 +1,18 @@
|
|
1
1
|
sticker_convert/__init__.py,sha256=iQnv6UOOA69c3soAn7ZOnAIubTIQSUxtq1Uhh8xRWvU,102
|
2
2
|
sticker_convert/__main__.py,sha256=elDCMvU27letiYs8jPUpxaCq5puURnvcDuqGsAAb6_w,592
|
3
|
-
sticker_convert/cli.py,sha256=
|
4
|
-
sticker_convert/converter.py,sha256=
|
3
|
+
sticker_convert/cli.py,sha256=JdfZe4-GGFoa8vkNaUwCtwzmypCfMNaPZuhzHpmLBpM,22544
|
4
|
+
sticker_convert/converter.py,sha256=6_FGXW-S6t2xs56fid49z2FaEc1VFtJ-jJOA-SUKSH8,39760
|
5
5
|
sticker_convert/definitions.py,sha256=BqROmOvqIqw8ANaqZXIxJAXGD0HgjAvCfFouQ4SaWHc,2254
|
6
6
|
sticker_convert/gui.py,sha256=bd8rMgFaXrn41y6aOHNlD6gPBDleDmiHMsGMZNfz1jk,34239
|
7
7
|
sticker_convert/job.py,sha256=FJiaJEcfMr8GnNfPC3SDcpTs7ytoiAZk6cxUbzsw9IE,28257
|
8
8
|
sticker_convert/job_option.py,sha256=yI_uKWJEAul2XTC6pucz9PfW0iNwwOr0aVC-PAHkMA4,8109
|
9
|
-
sticker_convert/version.py,sha256=
|
9
|
+
sticker_convert/version.py,sha256=IqHvkpNtjDMGeiZS1r9gF2cyof0NHldraqS5R5rrq10,49
|
10
10
|
sticker_convert/downloaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
11
|
sticker_convert/downloaders/download_band.py,sha256=JPjwwdxbMXPBM9TXF76wT9mtoDCLssYnrm1iS2C6uVM,3629
|
12
12
|
sticker_convert/downloaders/download_base.py,sha256=MI5pCT_tkfoaFlrD1oNynDj1Rv1CK0APuNVElTEAEis,5110
|
13
13
|
sticker_convert/downloaders/download_discord.py,sha256=6AFpLAYL2hRvVcsqUtzDUC31U66U02ZcnKXDnZRi2jk,3496
|
14
14
|
sticker_convert/downloaders/download_kakao.py,sha256=lRmpEcYjHizIRM0uFBDvjMqNEpur0VmOTKAmiir9eB0,15181
|
15
|
-
sticker_convert/downloaders/download_line.py,sha256=
|
15
|
+
sticker_convert/downloaders/download_line.py,sha256=751-g6BH0ITwNlYNsZuBxyB92Q8f3o6Qv9VHmHDoLps,18161
|
16
16
|
sticker_convert/downloaders/download_signal.py,sha256=3wv-BLd4qggly4AdtwV8f3vUpCVZ-8GnoPLoWngY3Pk,3728
|
17
17
|
sticker_convert/downloaders/download_telegram.py,sha256=iGmOcVjU2Ai19t1lyDY2JhQIc--O5XMyNCGXZAA4DVY,2028
|
18
18
|
sticker_convert/downloaders/download_viber.py,sha256=SFnyaVEd_33J1KvRhcHDJqnLKGsbLMeA2NomVHm2ulM,4226
|
@@ -28,13 +28,13 @@ sticker_convert/gui_components/frames/output_frame.py,sha256=n2WLk22h61DoZli8WbF
|
|
28
28
|
sticker_convert/gui_components/frames/progress_frame.py,sha256=LWUZg_iL7iiNTfu7N5Ct_pklZdghxihENi7DP9YozOE,4915
|
29
29
|
sticker_convert/gui_components/frames/right_clicker.py,sha256=dGIvSzEChrkguR80pzUemBNJ39uzJjVJQKeDNUoW3Gk,721
|
30
30
|
sticker_convert/gui_components/windows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
31
|
-
sticker_convert/gui_components/windows/advanced_compression_window.py,sha256=
|
31
|
+
sticker_convert/gui_components/windows/advanced_compression_window.py,sha256=il1ZenzjZuL94MFOTR3vfCCTlZ7BIZfsVmC16CLLwI4,32734
|
32
32
|
sticker_convert/gui_components/windows/base_window.py,sha256=xBE1peGMPvWsdrFej0CJUVhmQ57GJGvz-cX03nIIhkE,1108
|
33
33
|
sticker_convert/gui_components/windows/discord_get_auth_window.py,sha256=a9ptBqtpZslQJ87-ZPotcT6gigouIHWAFijfkWv2rZQ,2786
|
34
|
-
sticker_convert/gui_components/windows/kakao_get_auth_window.py,sha256=
|
34
|
+
sticker_convert/gui_components/windows/kakao_get_auth_window.py,sha256=9YfzuKQE6bjfqFxkpCa4XxMnw2T1UPPI_A6Z8E75J_M,11953
|
35
35
|
sticker_convert/gui_components/windows/line_get_auth_window.py,sha256=S4ES_lk2-GDvPokZtYALnUc5zW1VbS4WulNqO9K1aSs,3375
|
36
36
|
sticker_convert/gui_components/windows/signal_get_auth_window.py,sha256=d9vWMfrD0s-qI-TmB0796LRvDW64Jh2wmA1mZcRubUw,3126
|
37
|
-
sticker_convert/gui_components/windows/viber_get_auth_window.py,sha256=
|
37
|
+
sticker_convert/gui_components/windows/viber_get_auth_window.py,sha256=DI-RayYAfk6ig7NlGy97ulYgZZs77S8CEDIUJdtGDwI,5787
|
38
38
|
sticker_convert/ios-message-stickers-template/.gitignore,sha256=4uuTph_9eHfqXHUavLOmGOji6aIHOif2bUEU_hCBn4Y,9
|
39
39
|
sticker_convert/ios-message-stickers-template/README.md,sha256=oN0FvJkCWWjSZ3PMrCvY3T1zCsdkZYFgGHAoFh0Kmt8,467
|
40
40
|
sticker_convert/ios-message-stickers-template/.github/FUNDING.yml,sha256=3LlmdSAGDsBA2o_C1iBYTNLwkABnyZuN0zxgPPyd-f8,70
|
@@ -73,7 +73,7 @@ sticker_convert/resources/appicon.ico,sha256=-ldugcl2Yq2pBRTktnhGKWInpKyWzRjCiPv
|
|
73
73
|
sticker_convert/resources/appicon.png,sha256=6XBEQz7PnerqS43aRkwpWolFG4WvKMuQ-st1ly-_JPg,5265
|
74
74
|
sticker_convert/resources/compression.json,sha256=wEgtjcDyLEYup53s-SCGu2Wc3UdReWeSj9POWn5PXkk,15184
|
75
75
|
sticker_convert/resources/emoji.json,sha256=q9DRFdVJfm7feZW7ZM6Xa5P1QsMvrn0PbBVU9jKcJKI,422720
|
76
|
-
sticker_convert/resources/help.json,sha256=
|
76
|
+
sticker_convert/resources/help.json,sha256=28m5oMhybN3yg7EhmjBlPJq1HtHYa0joG355Ie1Zn10,7336
|
77
77
|
sticker_convert/resources/input.json,sha256=vLP8pVo4Mfh-yLRjy5j1x4SMR1dQC9xCRzQ6RWN_t2E,4213
|
78
78
|
sticker_convert/resources/memdump_linux.sh,sha256=SFKXiE0ztZyGvpFYPOrdQ0wmY3ndgJuqfiofC7BQon0,625
|
79
79
|
sticker_convert/resources/memdump_windows.ps1,sha256=CfyNSSEW3HJOkTu-mKrP3qh5aprN-1VCBfj-R1fELA0,302
|
@@ -86,19 +86,22 @@ sticker_convert/uploaders/upload_telegram.py,sha256=WlUyLJlW83XZz6RhA76jHMXA6TNU
|
|
86
86
|
sticker_convert/uploaders/upload_viber.py,sha256=_vOK0UgP7V7ZeFG6pR3sVf3A744Q6J19qzO-2hDvt5w,6583
|
87
87
|
sticker_convert/uploaders/xcode_imessage.py,sha256=iTTT8gDYOTNkKqXeSWUBuWfxu7xeE418t2Z1YQFR5L0,11365
|
88
88
|
sticker_convert/utils/callback.py,sha256=spYUGlklOs1yPZAxoqwOWgR1sdimpfM8a27if3TaVYk,6155
|
89
|
-
sticker_convert/utils/chrome_remotedebug.py,sha256=
|
89
|
+
sticker_convert/utils/chrome_remotedebug.py,sha256=moFj-Uz_bBy4-wXFET80sdwkzNC4PW8LMwwrU8yKOg8,6642
|
90
90
|
sticker_convert/utils/emoji.py,sha256=AqB26JY-PkYzNwPLReSnqLiQKe-bR9UXnLclAbgubJ8,367
|
91
|
-
sticker_convert/utils/process.py,sha256=
|
91
|
+
sticker_convert/utils/process.py,sha256=y_W-D9zkxAEfPvYJZTKxNtNHxmuK0NldpDXu-OdGR1M,5704
|
92
92
|
sticker_convert/utils/singletons.py,sha256=SiV374FxU68DpysGoj_ytU1ErINkeOBbP4s9QTcexeY,357
|
93
93
|
sticker_convert/utils/url_detect.py,sha256=_wmI28hUyngq8TVz1bw7YM90qPLd3bIynawVlbr_lcI,939
|
94
|
-
sticker_convert/utils/auth/get_discord_auth.py,sha256=
|
94
|
+
sticker_convert/utils/auth/get_discord_auth.py,sha256=8H9Z0c7pl6JjzkP8lo0-lCFnBAT5Eql-LYc6M92FY_k,4283
|
95
95
|
sticker_convert/utils/auth/get_kakao_auth.py,sha256=Wok5sp0GGBgTwwlfYB7lVq82ndBAOGTcqsWEaWAXFNE,10760
|
96
|
-
sticker_convert/utils/auth/get_kakao_desktop_auth.py,sha256=
|
96
|
+
sticker_convert/utils/auth/get_kakao_desktop_auth.py,sha256=a-P0sXXjZRnGwqcdgGZc_idnAvUXYx0EMCKpUXOuqJo,8659
|
97
97
|
sticker_convert/utils/auth/get_line_auth.py,sha256=8l8ha2vQmk3rHGvDE7PkcxQXbH3oe62LKbI3qVUtvqc,2196
|
98
98
|
sticker_convert/utils/auth/get_signal_auth.py,sha256=I6od2aj8yl1eLV8S2TtNQEPM77DC7FpkRKex0pXY2II,4580
|
99
|
-
sticker_convert/utils/auth/get_viber_auth.py,sha256=
|
100
|
-
sticker_convert/utils/auth/telegram_api.py,sha256=
|
101
|
-
sticker_convert/utils/auth/telethon_setup.py,sha256=
|
99
|
+
sticker_convert/utils/auth/get_viber_auth.py,sha256=aQiv1JI2RKiPVoo_JjbjcWwsUr2OK2FXMsFLPb3TtGU,8123
|
100
|
+
sticker_convert/utils/auth/telegram_api.py,sha256=MAWNFA6Ttn-aO1g_waeIZkc4AMUH_Atds2x8-jhhQIU,24311
|
101
|
+
sticker_convert/utils/auth/telethon_setup.py,sha256=7VtsSM3n8qrN_VXV8hBaNSmApxgIPCa84Z08fRr43eQ,3309
|
102
|
+
sticker_convert/utils/chromiums/linux.py,sha256=voWOxQVNy2icGDQfnZEa-2Nwrv-Qmuvt0v1L65hKnY8,1719
|
103
|
+
sticker_convert/utils/chromiums/osx.py,sha256=ET6_uWZDbPCIN-GihMmjNcva0-WAyn0fA2-SzNn5wcU,3255
|
104
|
+
sticker_convert/utils/chromiums/windows.py,sha256=wOyEQIQNV3_Nb2m44aFJh6QJj16cDpNmD1NxnVNlkrk,2188
|
102
105
|
sticker_convert/utils/files/cache_store.py,sha256=etfe614OAhAyrnM5fGeESKq6R88YLNqkqkxSzEmZ0V0,1047
|
103
106
|
sticker_convert/utils/files/json_manager.py,sha256=Vr6pZJdLMkrJJWN99210aduVHb0ILyf0SSTaw4TZqgc,541
|
104
107
|
sticker_convert/utils/files/json_resources_loader.py,sha256=flZFixUXRTrOAhvRQpuSQgmJ69yXL94sxukcowLT1JQ,1049
|
@@ -109,9 +112,9 @@ sticker_convert/utils/media/apple_png_normalize.py,sha256=LbrQhc7LlYX4I9ek4XJsZE
|
|
109
112
|
sticker_convert/utils/media/codec_info.py,sha256=HwA6eVh7cLhOlUoR_K9d_wyBRJ_ocGtB3GAyne_iZAU,16483
|
110
113
|
sticker_convert/utils/media/decrypt_kakao.py,sha256=4wq9ZDRnFkx1WmFZnyEogBofiLGsWQM_X69HlA36578,1947
|
111
114
|
sticker_convert/utils/media/format_verify.py,sha256=oM32P186tWe9YxvBQRPr8D3FEmBN3b2rEe_2S_MwxyQ,6236
|
112
|
-
sticker_convert-2.13.0.dist-info/licenses/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
|
113
|
-
sticker_convert-2.13.0.dist-info/METADATA,sha256=
|
114
|
-
sticker_convert-2.13.0.dist-info/WHEEL,sha256=
|
115
|
-
sticker_convert-2.13.0.dist-info/entry_points.txt,sha256=MNJ7XyC--ugxi5jS1nzjDLGnxCyLuaGdsVLnJhDHCqs,66
|
116
|
-
sticker_convert-2.13.0.dist-info/top_level.txt,sha256=r9vfnB0l1ZnH5pTH5RvkobnK3Ow9m0RsncaOMAtiAtk,16
|
117
|
-
sticker_convert-2.13.0.dist-info/RECORD,,
|
115
|
+
sticker_convert-2.13.1.0.dist-info/licenses/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
|
116
|
+
sticker_convert-2.13.1.0.dist-info/METADATA,sha256=HS8RD0rAFH3H34wZn7ilCqeVEa0p8L0QOYik4EB_dIY,54533
|
117
|
+
sticker_convert-2.13.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
118
|
+
sticker_convert-2.13.1.0.dist-info/entry_points.txt,sha256=MNJ7XyC--ugxi5jS1nzjDLGnxCyLuaGdsVLnJhDHCqs,66
|
119
|
+
sticker_convert-2.13.1.0.dist-info/top_level.txt,sha256=r9vfnB0l1ZnH5pTH5RvkobnK3Ow9m0RsncaOMAtiAtk,16
|
120
|
+
sticker_convert-2.13.1.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|