sticker-convert 2.12.4__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 +3 -0
- sticker_convert/converter.py +61 -58
- sticker_convert/downloaders/download_band.py +110 -0
- sticker_convert/downloaders/download_kakao.py +84 -22
- sticker_convert/downloaders/download_line.py +8 -4
- sticker_convert/gui.py +6 -3
- sticker_convert/gui_components/windows/advanced_compression_window.py +1 -1
- sticker_convert/gui_components/windows/discord_get_auth_window.py +3 -3
- sticker_convert/gui_components/windows/kakao_get_auth_window.py +25 -4
- sticker_convert/gui_components/windows/signal_get_auth_window.py +3 -3
- sticker_convert/gui_components/windows/viber_get_auth_window.py +16 -1
- sticker_convert/job.py +6 -0
- sticker_convert/resources/compression.json +47 -0
- sticker_convert/resources/help.json +1 -1
- sticker_convert/resources/input.json +10 -0
- sticker_convert/resources/memdump_linux.sh +0 -1
- sticker_convert/utils/auth/get_discord_auth.py +2 -2
- sticker_convert/utils/auth/get_kakao_desktop_auth.py +38 -43
- sticker_convert/utils/auth/get_signal_auth.py +2 -2
- sticker_convert/utils/auth/get_viber_auth.py +3 -5
- sticker_convert/utils/auth/telegram_api.py +3 -1
- sticker_convert/utils/auth/telethon_setup.py +21 -8
- sticker_convert/utils/chrome_remotedebug.py +27 -29
- 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/media/codec_info.py +1 -1
- sticker_convert/utils/process.py +152 -108
- sticker_convert/utils/singletons.py +18 -0
- sticker_convert/utils/url_detect.py +3 -0
- sticker_convert/version.py +1 -1
- {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.1.0.dist-info}/METADATA +37 -29
- {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.1.0.dist-info}/RECORD +37 -32
- {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.1.0.dist-info}/WHEEL +1 -1
- {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.1.0.dist-info}/entry_points.txt +0 -0
- {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.1.0.dist-info}/licenses/LICENSE +0 -0
- {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.1.0.dist-info}/top_level.txt +0 -0
@@ -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)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
from typing import Any, Dict, Protocol
|
3
|
+
|
4
|
+
|
5
|
+
class SingletonProtocol(Protocol):
|
6
|
+
def close(self) -> Any: ...
|
7
|
+
|
8
|
+
|
9
|
+
class Singletons:
|
10
|
+
def __init__(self) -> None:
|
11
|
+
self.objs: Dict[str, SingletonProtocol] = {}
|
12
|
+
|
13
|
+
def close(self) -> None:
|
14
|
+
for obj in self.objs.values():
|
15
|
+
obj.close()
|
16
|
+
|
17
|
+
|
18
|
+
singletons = Singletons()
|
sticker_convert/version.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: sticker-convert
|
3
|
-
Version: 2.
|
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>
|
@@ -366,8 +366,8 @@ License-File: LICENSE
|
|
366
366
|
Requires-Dist: aiolimiter~=1.2.1
|
367
367
|
Requires-Dist: anyio~=4.9.0
|
368
368
|
Requires-Dist: apngasm_python~=1.3.2
|
369
|
-
Requires-Dist: av
|
370
|
-
Requires-Dist: beautifulsoup4~=4.13.
|
369
|
+
Requires-Dist: av>=13.1.0
|
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
|
@@ -375,17 +375,16 @@ Requires-Dist: imagequant~=1.1.4
|
|
375
375
|
Requires-Dist: memory-tempfile~=2.2.3
|
376
376
|
Requires-Dist: mergedeep~=1.3.4
|
377
377
|
Requires-Dist: numpy>=1.22.4
|
378
|
-
Requires-Dist: Pillow~=11.1
|
379
|
-
Requires-Dist: pybrowsers~=0.7.0
|
378
|
+
Requires-Dist: Pillow~=11.2.1
|
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
|
@@ -397,12 +396,12 @@ Dynamic: license-file
|
|
397
396
|
|
398
397
|
- A python script for creating, downloading, converting+compressing and uploading stickers from multiple instant messaging applications.
|
399
398
|
- With GUI and CLI that runs on Windows, MacOS and Linux
|
400
|
-
- Currently supports Signal, Telegram, WhatsApp (Create .wastickers), Line (Download only), Kakao (Download only), Viber, Discord (Download only), iMessage (Create Xcode sticker pack project)
|
399
|
+
- Currently supports Signal, Telegram, WhatsApp (Create .wastickers), Line (Download only), Kakao (Download only), Naver Band (Download only), Viber, Discord (Download only), iMessage (Create Xcode sticker pack project)
|
401
400
|
- Supports static and animated stickers, with transparency support
|
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
|
@@ -438,6 +437,7 @@ Dynamic: license-file
|
|
438
437
|
| [WhatsApp](docs/guide_whatsapp.md) | ⭕ (By Android or WhatsApp Web) | ⭕ (Create `.wastickers`, import by Sticker Maker) |
|
439
438
|
| [Line](docs/guide_line.md) | ✅ | 🚫 (Need to submit for manual approval) |
|
440
439
|
| [Kakao](docs/guide_kakao.md) | ✅ (Need 'auth_token' for animated) | 🚫 (Need to submit for manual approval) |
|
440
|
+
| [Band](docs/guide_band.md) | ✅ | 🚫 (Need to submit for manual approval) |
|
441
441
|
| [Viber](docs/guide_viber.md) | ✅ | ✅ (Require `viber_auth`) |
|
442
442
|
| [Discord](docs/guide_discord.md) | ✅ (Require `token`) | 🚫 |
|
443
443
|
| [iMessage](docs/guide_imessage.md) | 🚫 | ⭕ (Create Xcode stickerpack project for sideload) |
|
@@ -464,6 +464,9 @@ Dynamic: license-file
|
|
464
464
|
- Kakao
|
465
465
|
- Download: Supported (e.g. `https://e.kakao.com/t/xxxxx` OR `https://emoticon.kakao.com/items/xxxxx` OR `4404400`). It is rather complicated, learn more from [docs/guide_kakao.md](docs/guide_kakao.md)
|
466
466
|
- Upload: Not supported. You need to manually submit sticker pack for approval before you can use in app.
|
467
|
+
- Band
|
468
|
+
- Download: Supported (e.g. `https://www.band.us/sticker/xxxx` OR 2535). Learn how to get share link from [docs/guide_band.md](docs/guide_band.md)
|
469
|
+
- Upload: Not supported. You need to manually submit sticker pack for approval before you can use in app.
|
467
470
|
- Viber
|
468
471
|
- Download: Supported (e.g. `https://stickers.viber.com/pages/example` OR `https://stickers.viber.com/pages/custom-sticker-packs/example`)
|
469
472
|
- Upload: Supported. Viber authentication data required for uploading Viber stickers, which could be fetched from Viber Desktop application automatically.
|
@@ -490,30 +493,27 @@ Dynamic: license-file
|
|
490
493
|
To run in CLI mode, pass on any arguments
|
491
494
|
|
492
495
|
```
|
493
|
-
usage: sticker-convert.py [-h] [--version] [--no-confirm] [--no-progress] [--custom-presets CUSTOM_PRESETS]
|
494
|
-
[--
|
495
|
-
[--download-auto DOWNLOAD_AUTO | --download-signal DOWNLOAD_SIGNAL | --download-telegram DOWNLOAD_TELEGRAM | --download-telegram-telethon DOWNLOAD_TELEGRAM_TELETHON | --download-line DOWNLOAD_LINE | --download-kakao DOWNLOAD_KAKAO | --download-viber DOWNLOAD_VIBER | --download-discord DOWNLOAD_DISCORD | --download-discord-emoji DOWNLOAD_DISCORD_EMOJI]
|
496
|
+
usage: sticker-convert.py [-h] [--version] [--no-confirm] [--no-progress] [--custom-presets CUSTOM_PRESETS] [--input-dir INPUT_DIR]
|
497
|
+
[--download-auto DOWNLOAD_AUTO | --download-signal DOWNLOAD_SIGNAL | --download-telegram DOWNLOAD_TELEGRAM | --download-telegram-telethon DOWNLOAD_TELEGRAM_TELETHON | --download-line DOWNLOAD_LINE | --download-kakao DOWNLOAD_KAKAO | --download-band DOWNLOAD_BAND | --download-viber DOWNLOAD_VIBER | --download-discord DOWNLOAD_DISCORD | --download-discord-emoji DOWNLOAD_DISCORD_EMOJI]
|
496
498
|
[--output-dir OUTPUT_DIR] [--author AUTHOR] [--title TITLE]
|
497
499
|
[--export-signal | --export-telegram | --export-telegram-emoji | --export-telegram-telethon | --export-telegram-emoji-telethon | --export-viber | --export-whatsapp | --export-imessage]
|
498
500
|
[--no-compress]
|
499
501
|
[--preset {auto,signal,telegram,telegram_emoji,whatsapp,line,kakao,viber,discord,discord_emoji,imessage_small,imessage_medium,imessage_large,custom}]
|
500
|
-
[--steps STEPS] [--processes PROCESSES] [--fps-min FPS_MIN] [--fps-max FPS_MAX]
|
501
|
-
[--
|
502
|
-
[--res-
|
503
|
-
[--quality-min
|
504
|
-
[--color-min COLOR_MIN] [--color-max COLOR_MAX] [--color-power COLOR_POWER]
|
502
|
+
[--steps STEPS] [--processes PROCESSES] [--fps-min FPS_MIN] [--fps-max FPS_MAX] [--fps-power FPS_POWER]
|
503
|
+
[--res-min RES_MIN] [--res-max RES_MAX] [--res-w-min RES_W_MIN] [--res-w-max RES_W_MAX] [--res-h-min RES_H_MIN]
|
504
|
+
[--res-h-max RES_H_MAX] [--res-power RES_POWER] [--quality-min QUALITY_MIN] [--quality-max QUALITY_MAX]
|
505
|
+
[--quality-power QUALITY_POWER] [--color-min COLOR_MIN] [--color-max COLOR_MAX] [--color-power COLOR_POWER]
|
505
506
|
[--duration-min DURATION_MIN] [--duration-max DURATION_MAX] [--padding-percent PADDING_PERCENT]
|
506
|
-
[--bg-color BG_COLOR] [--vid-size-max VID_SIZE_MAX] [--img-size-max IMG_SIZE_MAX]
|
507
|
-
[--
|
508
|
-
[--
|
509
|
-
[--signal-
|
510
|
-
[--telegram-
|
511
|
-
[--kakao-auth-
|
512
|
-
[--kakao-bin-path KAKAO_BIN_PATH] [--kakao-username KAKAO_USERNAME]
|
507
|
+
[--bg-color BG_COLOR] [--vid-size-max VID_SIZE_MAX] [--img-size-max IMG_SIZE_MAX] [--vid-format VID_FORMAT]
|
508
|
+
[--img-format IMG_FORMAT] [--fake-vid] [--scale-filter SCALE_FILTER] [--quantize-method QUANTIZE_METHOD]
|
509
|
+
[--cache-dir CACHE_DIR] [--chromium-path CHROMIUM_PATH] [--default-emoji DEFAULT_EMOJI] [--signal-uuid SIGNAL_UUID]
|
510
|
+
[--signal-password SIGNAL_PASSWORD] [--signal-get-auth] [--telegram-token TELEGRAM_TOKEN]
|
511
|
+
[--telegram-userid TELEGRAM_USERID] [--telethon-setup] [--kakao-auth-token KAKAO_AUTH_TOKEN] [--kakao-get-auth]
|
512
|
+
[--kakao-get-auth-desktop] [--kakao-bin-path KAKAO_BIN_PATH] [--kakao-username KAKAO_USERNAME]
|
513
513
|
[--kakao-password KAKAO_PASSWORD] [--kakao-country-code KAKAO_COUNTRY_CODE]
|
514
|
-
[--kakao-phone-number KAKAO_PHONE_NUMBER] [--line-get-auth] [--line-cookies LINE_COOKIES]
|
515
|
-
[--viber-
|
516
|
-
[--discord-
|
514
|
+
[--kakao-phone-number KAKAO_PHONE_NUMBER] [--line-get-auth] [--line-cookies LINE_COOKIES] [--viber-auth VIBER_AUTH]
|
515
|
+
[--viber-get-auth VIBER_GET_AUTH] [--viber-bin-path VIBER_BIN_PATH] [--discord-get-auth]
|
516
|
+
[--discord-token DISCORD_TOKEN] [--save-cred]
|
517
517
|
|
518
518
|
CLI for stickers-convert
|
519
519
|
|
@@ -552,6 +552,9 @@ Input options:
|
|
552
552
|
Download kakao stickers from a URL / ID as input
|
553
553
|
(Example: https://e.kakao.com/t/xxxxx
|
554
554
|
OR https://emoticon.kakao.com/items/xxxxx OR 4404400)
|
555
|
+
--download-band DOWNLOAD_BAND
|
556
|
+
Download Naver Band stickers from a URL / ID as input
|
557
|
+
(Example: https://www.band.us/sticker/xxxx OR 2535)
|
555
558
|
--download-viber DOWNLOAD_VIBER
|
556
559
|
Download viber stickers from a URL as input
|
557
560
|
(Example: https://stickers.viber.com/pages/example
|
@@ -659,6 +662,10 @@ Compression options:
|
|
659
662
|
--cache-dir CACHE_DIR
|
660
663
|
Set custom cache directory.
|
661
664
|
Useful for debugging, or speed up conversion if cache_dir is on RAM disk.
|
665
|
+
--chromium-path CHROMIUM_PATH
|
666
|
+
Set Chromium(-based)/Chrome browser path.
|
667
|
+
Required for converting from SVG files.
|
668
|
+
Leave blank to auto detect
|
662
669
|
--default-emoji DEFAULT_EMOJI
|
663
670
|
Set the default emoji for uploading Signal and Telegram sticker packs.
|
664
671
|
|
@@ -678,7 +685,6 @@ Credentials options:
|
|
678
685
|
--kakao-get-auth Generate Kakao auth_token by simulating login. Kakao username, password, country code and phone number are also required.
|
679
686
|
--kakao-get-auth-desktop
|
680
687
|
Get Kakao auth_token from Kakao Desktop application.
|
681
|
-
(Only working on Windows.)
|
682
688
|
--kakao-bin-path KAKAO_BIN_PATH
|
683
689
|
Set Kakao Desktop application path for launching and getting auth_token.
|
684
690
|
Useful for portable installation.
|
@@ -881,9 +887,11 @@ See [docs/TODO.md](docs/TODO.md)
|
|
881
887
|
- Information about Line stickers: https://github.com/doubleplusc/Line-sticker-downloader
|
882
888
|
- Information about Kakao animated stickers: https://gist.github.com/chitacan/9802668
|
883
889
|
- Downloading and decrypting Kakao animated stickers: https://github.com/blluv/KakaoTalkEmoticonDownloader
|
890
|
+
- Finding browser executable paths: https://github.com/roniemartinez/browsers
|
884
891
|
- Application icon taken from [Icons8](https://icons8.com/)
|
885
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/)
|
886
894
|
|
887
895
|
## DISCLAIMER
|
888
|
-
- The author of this repo is NOT affiliated with Signal, Telegram, WhatsApp, Line, Kakao, Viber, Discord, iMessage or Sticker Maker.
|
896
|
+
- The author of this repo is NOT affiliated with Signal, Telegram, WhatsApp, Line, Kakao, Naver Band, Viber, Discord, iMessage or Sticker Maker.
|
889
897
|
- The author of this repo is NOT repsonsible for any legal consequences and loss incurred from using this repo.
|