sticker-convert 2.9.4__py3-none-any.whl → 2.10.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- sticker_convert/cli.py +26 -13
- sticker_convert/downloaders/download_base.py +20 -23
- sticker_convert/downloaders/download_discord.py +91 -0
- sticker_convert/downloaders/download_kakao.py +3 -4
- sticker_convert/downloaders/download_line.py +3 -4
- sticker_convert/downloaders/download_signal.py +3 -4
- sticker_convert/downloaders/download_telegram.py +3 -4
- sticker_convert/downloaders/download_viber.py +3 -4
- sticker_convert/gui.py +15 -3
- sticker_convert/gui_components/frames/cred_frame.py +22 -1
- sticker_convert/gui_components/windows/discord_get_auth_window.py +82 -0
- sticker_convert/gui_components/windows/signal_get_auth_window.py +39 -85
- sticker_convert/job.py +11 -1
- sticker_convert/job_option.py +2 -0
- sticker_convert/resources/compression.json +94 -0
- sticker_convert/resources/help.json +2 -1
- sticker_convert/resources/input.json +20 -0
- sticker_convert/uploaders/upload_signal.py +5 -4
- sticker_convert/uploaders/upload_telegram.py +11 -10
- sticker_convert/utils/auth/get_discord_auth.py +115 -0
- sticker_convert/utils/auth/get_signal_auth.py +115 -114
- sticker_convert/utils/auth/get_viber_auth.py +10 -214
- sticker_convert/utils/chrome_remotedebug.py +152 -0
- sticker_convert/utils/emoji.py +16 -0
- sticker_convert/utils/files/run_bin.py +1 -1
- sticker_convert/utils/media/codec_info.py +45 -60
- sticker_convert/utils/process.py +187 -0
- sticker_convert/utils/url_detect.py +3 -0
- sticker_convert/version.py +1 -1
- {sticker_convert-2.9.4.dist-info → sticker_convert-2.10.0.dist-info}/METADATA +40 -42
- {sticker_convert-2.9.4.dist-info → sticker_convert-2.10.0.dist-info}/RECORD +35 -29
- {sticker_convert-2.9.4.dist-info → sticker_convert-2.10.0.dist-info}/LICENSE +0 -0
- {sticker_convert-2.9.4.dist-info → sticker_convert-2.10.0.dist-info}/WHEEL +0 -0
- {sticker_convert-2.9.4.dist-info → sticker_convert-2.10.0.dist-info}/entry_points.txt +0 -0
- {sticker_convert-2.9.4.dist-info → sticker_convert-2.10.0.dist-info}/top_level.txt +0 -0
@@ -14,7 +14,7 @@ class RunBin:
|
|
14
14
|
if Path(executable).is_file():
|
15
15
|
return executable
|
16
16
|
|
17
|
-
if platform.system() == "Windows":
|
17
|
+
if platform.system() == "Windows" and executable.endswith(".exe") is False:
|
18
18
|
executable = executable + ".exe"
|
19
19
|
|
20
20
|
which_result = shutil.which(executable)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
2
|
from __future__ import annotations
|
3
3
|
|
4
|
+
import json
|
4
5
|
import mmap
|
5
6
|
from decimal import ROUND_HALF_UP, Decimal
|
6
7
|
from fractions import Fraction
|
@@ -10,6 +11,7 @@ from pathlib import Path
|
|
10
11
|
from typing import BinaryIO, List, Optional, Tuple, Union, cast
|
11
12
|
|
12
13
|
from PIL import Image, UnidentifiedImageError
|
14
|
+
from rlottie_python.rlottie_wrapper import LottieAnimation
|
13
15
|
|
14
16
|
|
15
17
|
def lcm(a: int, b: int):
|
@@ -61,6 +63,24 @@ def durations_gcd(*durations: Union[int, float]) -> Union[float, Fraction]:
|
|
61
63
|
return Fraction(gcd(*durations), 1) # type: ignore
|
62
64
|
|
63
65
|
|
66
|
+
def open_lottie(file: Union[Path, bytes]) -> LottieAnimation:
|
67
|
+
if isinstance(file, Path):
|
68
|
+
if file.suffix == ".tgs":
|
69
|
+
return LottieAnimation.from_tgs(file.as_posix())
|
70
|
+
else:
|
71
|
+
return LottieAnimation.from_file(file.as_posix())
|
72
|
+
else:
|
73
|
+
import gzip
|
74
|
+
|
75
|
+
try:
|
76
|
+
with gzip.open(BytesIO(file)) as f:
|
77
|
+
data = f.read().decode(encoding="utf-8")
|
78
|
+
except gzip.BadGzipFile:
|
79
|
+
data = json.loads(file.decode())
|
80
|
+
|
81
|
+
return LottieAnimation.from_data(data)
|
82
|
+
|
83
|
+
|
64
84
|
class CodecInfo:
|
65
85
|
def __init__(
|
66
86
|
self, file: Union[Path, bytes], file_ext: Optional[str] = None
|
@@ -87,8 +107,8 @@ class CodecInfo:
|
|
87
107
|
if not file_ext and isinstance(file, Path):
|
88
108
|
file_ext = CodecInfo.get_file_ext(file)
|
89
109
|
|
90
|
-
if file_ext
|
91
|
-
fps, frames = CodecInfo.
|
110
|
+
if file_ext in (".tgs", ".json", ".lottie"):
|
111
|
+
fps, frames = CodecInfo._get_file_fps_frames_lottie(file)
|
92
112
|
if fps > 0:
|
93
113
|
duration = int(frames / fps * 1000)
|
94
114
|
else:
|
@@ -114,8 +134,8 @@ class CodecInfo:
|
|
114
134
|
if not file_ext and isinstance(file, Path):
|
115
135
|
file_ext = CodecInfo.get_file_ext(file)
|
116
136
|
|
117
|
-
if file_ext
|
118
|
-
return CodecInfo.
|
137
|
+
if file_ext in (".tgs", ".json", ".lottie"):
|
138
|
+
return CodecInfo._get_file_fps_lottie(file)
|
119
139
|
elif file_ext == ".webp":
|
120
140
|
fps, _, _, _ = CodecInfo._get_file_fps_frames_duration_webp(file)
|
121
141
|
return fps
|
@@ -141,8 +161,8 @@ class CodecInfo:
|
|
141
161
|
if not file_ext and isinstance(file, Path):
|
142
162
|
file_ext = CodecInfo.get_file_ext(file)
|
143
163
|
|
144
|
-
if file_ext
|
145
|
-
return CodecInfo.
|
164
|
+
if file_ext in (".tgs", ".json", ".lottie"):
|
165
|
+
return CodecInfo._get_file_frames_lottie(file)
|
146
166
|
if file_ext in (".gif", ".webp", ".png", ".apng"):
|
147
167
|
_, frames, _ = CodecInfo._get_file_fps_frames_duration_pillow(
|
148
168
|
file, frames_only=True
|
@@ -168,8 +188,8 @@ class CodecInfo:
|
|
168
188
|
if not file_ext and isinstance(file, Path):
|
169
189
|
file_ext = CodecInfo.get_file_ext(file)
|
170
190
|
|
171
|
-
if file_ext
|
172
|
-
fps, frames = CodecInfo.
|
191
|
+
if file_ext in (".tgs", ".json", ".lottie"):
|
192
|
+
fps, frames = CodecInfo._get_file_fps_frames_lottie(file)
|
173
193
|
if fps > 0:
|
174
194
|
duration = int(frames / fps * 1000)
|
175
195
|
else:
|
@@ -184,51 +204,25 @@ class CodecInfo:
|
|
184
204
|
return duration
|
185
205
|
|
186
206
|
@staticmethod
|
187
|
-
def
|
188
|
-
|
207
|
+
def _get_file_fps_lottie(file: Union[Path, bytes]) -> int:
|
208
|
+
anim = open_lottie(file)
|
209
|
+
fps = anim.lottie_animation_get_framerate()
|
189
210
|
|
190
|
-
|
191
|
-
with LottieAnimation.from_tgs(file.as_posix()) as anim:
|
192
|
-
return anim.lottie_animation_get_framerate()
|
193
|
-
else:
|
194
|
-
import gzip
|
195
|
-
|
196
|
-
with gzip.open(BytesIO(file)) as f:
|
197
|
-
data = f.read().decode(encoding="utf-8")
|
198
|
-
with LottieAnimation.from_data(data) as anim:
|
199
|
-
return anim.lottie_animation_get_framerate()
|
211
|
+
return fps
|
200
212
|
|
201
213
|
@staticmethod
|
202
|
-
def
|
203
|
-
|
204
|
-
|
205
|
-
if isinstance(file, Path):
|
206
|
-
with LottieAnimation.from_tgs(file.as_posix()) as anim:
|
207
|
-
return anim.lottie_animation_get_totalframe()
|
208
|
-
else:
|
209
|
-
import gzip
|
214
|
+
def _get_file_frames_lottie(file: Union[Path, bytes]) -> int:
|
215
|
+
anim = open_lottie(file)
|
216
|
+
frames = anim.lottie_animation_get_totalframe()
|
210
217
|
|
211
|
-
|
212
|
-
data = f.read().decode(encoding="utf-8")
|
213
|
-
with LottieAnimation.from_data(data) as anim:
|
214
|
-
return anim.lottie_animation_get_totalframe()
|
218
|
+
return frames
|
215
219
|
|
216
220
|
@staticmethod
|
217
|
-
def
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
fps = anim.lottie_animation_get_framerate()
|
223
|
-
frames = anim.lottie_animation_get_totalframe()
|
224
|
-
else:
|
225
|
-
import gzip
|
226
|
-
|
227
|
-
with gzip.open(BytesIO(file)) as f:
|
228
|
-
data = f.read().decode(encoding="utf-8")
|
229
|
-
with LottieAnimation.from_data(data) as anim:
|
230
|
-
fps = anim.lottie_animation_get_framerate()
|
231
|
-
frames = anim.lottie_animation_get_totalframe()
|
221
|
+
def _get_file_fps_frames_lottie(file: Union[Path, bytes]) -> Tuple[int, int]:
|
222
|
+
anim = open_lottie(file)
|
223
|
+
fps = anim.lottie_animation_get_framerate()
|
224
|
+
frames = anim.lottie_animation_get_totalframe()
|
225
|
+
anim.lottie_animation_destroy()
|
232
226
|
|
233
227
|
return fps, frames
|
234
228
|
|
@@ -408,19 +402,10 @@ class CodecInfo:
|
|
408
402
|
if not file_ext and isinstance(file, Path):
|
409
403
|
file_ext = CodecInfo.get_file_ext(file)
|
410
404
|
|
411
|
-
if file_ext
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
with LottieAnimation.from_tgs(file.as_posix()) as anim:
|
416
|
-
width, height = anim.lottie_animation_get_size()
|
417
|
-
else:
|
418
|
-
import gzip
|
419
|
-
|
420
|
-
with gzip.open(BytesIO(file)) as f:
|
421
|
-
data = f.read().decode(encoding="utf-8")
|
422
|
-
with LottieAnimation.from_data(data) as anim:
|
423
|
-
width, height = anim.lottie_animation_get_size()
|
405
|
+
if file_ext in (".tgs", ".json", ".lottie"):
|
406
|
+
anim = open_lottie(file)
|
407
|
+
width, height = anim.lottie_animation_get_size()
|
408
|
+
anim.lottie_animation_destroy()
|
424
409
|
elif file_ext in (".webp", ".png", ".apng"):
|
425
410
|
with Image.open(file) as im:
|
426
411
|
width = im.width
|
@@ -0,0 +1,187 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
import os
|
3
|
+
import platform
|
4
|
+
import shutil
|
5
|
+
import subprocess
|
6
|
+
import time
|
7
|
+
from getpass import getpass
|
8
|
+
from typing import Callable, Optional, Tuple
|
9
|
+
|
10
|
+
import psutil
|
11
|
+
|
12
|
+
from sticker_convert.definitions import ROOT_DIR
|
13
|
+
|
14
|
+
|
15
|
+
def killall(name: str) -> bool:
|
16
|
+
result = False
|
17
|
+
|
18
|
+
for proc in psutil.process_iter():
|
19
|
+
if name in proc.name().lower():
|
20
|
+
proc.kill()
|
21
|
+
result = True
|
22
|
+
|
23
|
+
return result
|
24
|
+
|
25
|
+
|
26
|
+
def find_pid_by_name(name: str) -> Optional[int]:
|
27
|
+
for proc in psutil.process_iter():
|
28
|
+
if name in proc.name().lower():
|
29
|
+
return proc.pid
|
30
|
+
|
31
|
+
return None
|
32
|
+
|
33
|
+
|
34
|
+
def check_admin() -> bool:
|
35
|
+
return True
|
36
|
+
|
37
|
+
|
38
|
+
if platform.system() == "Windows":
|
39
|
+
|
40
|
+
def check_admin() -> bool:
|
41
|
+
username = os.getenv("username")
|
42
|
+
if username is None:
|
43
|
+
return False
|
44
|
+
|
45
|
+
s = subprocess.run(
|
46
|
+
["net", "user", username],
|
47
|
+
capture_output=True,
|
48
|
+
text=True,
|
49
|
+
).stdout
|
50
|
+
|
51
|
+
return True if "*Administrators" in s else False
|
52
|
+
|
53
|
+
elif platform.system() == "Linux":
|
54
|
+
|
55
|
+
def check_admin() -> bool:
|
56
|
+
if shutil.which("sudo") is None:
|
57
|
+
return True
|
58
|
+
|
59
|
+
s = subprocess.run(
|
60
|
+
["sudo", "-l"],
|
61
|
+
capture_output=True,
|
62
|
+
text=True,
|
63
|
+
).stdout
|
64
|
+
|
65
|
+
return True if "may run the following commands" in s else False
|
66
|
+
|
67
|
+
|
68
|
+
def get_mem(
|
69
|
+
pid: int, pw_func: Optional[Callable[..., str]] = None
|
70
|
+
) -> Tuple[Optional[bytes], str]:
|
71
|
+
return b"", ""
|
72
|
+
|
73
|
+
|
74
|
+
if platform.system() == "Windows":
|
75
|
+
|
76
|
+
def get_mem(
|
77
|
+
pid: int, pw_func: Optional[Callable[..., str]] = None
|
78
|
+
) -> Tuple[Optional[bytes], str]:
|
79
|
+
from pathlib import WindowsPath
|
80
|
+
|
81
|
+
memdump_ps_path = str(WindowsPath(ROOT_DIR / "resources/memdump_windows.ps1"))
|
82
|
+
arglist = f'-NoProfile -ExecutionPolicy Bypass -File "{memdump_ps_path}" {pid}'
|
83
|
+
dump_fpath = os.path.expandvars(f"%temp%/memdump.bin.{pid}")
|
84
|
+
|
85
|
+
cmd = [
|
86
|
+
"powershell",
|
87
|
+
"-NoProfile",
|
88
|
+
"-ExecutionPolicy",
|
89
|
+
"Bypass",
|
90
|
+
"-Command",
|
91
|
+
f"Start-Process -Verb RunAs powershell -ArgumentList '{arglist}'",
|
92
|
+
]
|
93
|
+
|
94
|
+
subprocess.run(cmd, capture_output=True, text=True)
|
95
|
+
|
96
|
+
while True:
|
97
|
+
try:
|
98
|
+
with open(dump_fpath, "rb") as f:
|
99
|
+
s = f.read()
|
100
|
+
if len(s) != 0:
|
101
|
+
break
|
102
|
+
time.sleep(1)
|
103
|
+
except (FileNotFoundError, PermissionError):
|
104
|
+
pass
|
105
|
+
|
106
|
+
while True:
|
107
|
+
try:
|
108
|
+
os.remove(dump_fpath)
|
109
|
+
break
|
110
|
+
except PermissionError:
|
111
|
+
pass
|
112
|
+
|
113
|
+
return s, ""
|
114
|
+
|
115
|
+
elif platform.system() == "Darwin":
|
116
|
+
|
117
|
+
def get_mem(
|
118
|
+
pid: int, pw_func: Optional[Callable[..., str]] = None
|
119
|
+
) -> Tuple[Optional[bytes], str]:
|
120
|
+
subprocess.run(
|
121
|
+
[
|
122
|
+
"lldb",
|
123
|
+
"--attach-pid",
|
124
|
+
str(pid),
|
125
|
+
"-o",
|
126
|
+
f"process save-core /tmp/memdump.{pid}.dmp",
|
127
|
+
"-o",
|
128
|
+
"quit",
|
129
|
+
],
|
130
|
+
stdout=subprocess.DEVNULL,
|
131
|
+
stderr=subprocess.DEVNULL,
|
132
|
+
)
|
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
|
+
s = subprocess.run(
|
149
|
+
[
|
150
|
+
memdump_sh_path,
|
151
|
+
str(pid),
|
152
|
+
],
|
153
|
+
capture_output=True,
|
154
|
+
).stdout
|
155
|
+
|
156
|
+
if len(s) > 1000:
|
157
|
+
pass
|
158
|
+
elif shutil.which("pkexec") and os.getenv("DISPLAY"):
|
159
|
+
s = subprocess.run(
|
160
|
+
[
|
161
|
+
"pkexec",
|
162
|
+
memdump_sh_path,
|
163
|
+
str(pid),
|
164
|
+
],
|
165
|
+
capture_output=True,
|
166
|
+
).stdout
|
167
|
+
else:
|
168
|
+
prompt = "Enter sudo password: "
|
169
|
+
if pw_func:
|
170
|
+
sudo_password = pw_func(prompt)
|
171
|
+
else:
|
172
|
+
sudo_password = getpass(prompt)
|
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, ""
|
sticker_convert/version.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sticker-convert
|
3
|
-
Version: 2.
|
4
|
-
Summary: Convert (animated) stickers to/from WhatsApp, Telegram, Signal, Line, Kakao, Viber, iMessage. Written in Python.
|
3
|
+
Version: 2.10.0
|
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>
|
7
7
|
License: GNU GENERAL PUBLIC LICENSE
|
@@ -349,7 +349,7 @@ Project-URL: Source, https://github.com/laggykiller/sticker-convert
|
|
349
349
|
Project-URL: Documentation, https://github.com/laggykiller/sticker-convert
|
350
350
|
Project-URL: Tracker, https://github.com/laggykiller/sticker-convert/issues
|
351
351
|
Project-URL: Repository, https://github.com/laggykiller/sticker-convert
|
352
|
-
Keywords: telegram,line,tgs,whatsapp,kakao,signal,imessage,wastickers,viber
|
352
|
+
Keywords: telegram,line,tgs,whatsapp,kakao,signal,imessage,wastickers,viber,discord
|
353
353
|
Classifier: Development Status :: 5 - Production/Stable
|
354
354
|
Classifier: Intended Audience :: End Users/Desktop
|
355
355
|
Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion
|
@@ -370,6 +370,7 @@ Requires-Dist: apngasm-python ~=1.3.1
|
|
370
370
|
Requires-Dist: av ~=12.3.0
|
371
371
|
Requires-Dist: beautifulsoup4 ~=4.12.3
|
372
372
|
Requires-Dist: rookiepy ~=0.5.2
|
373
|
+
Requires-Dist: httpx ~=0.27.0
|
373
374
|
Requires-Dist: imagequant ~=1.1.1
|
374
375
|
Requires-Dist: memory-tempfile ~=2.2.3
|
375
376
|
Requires-Dist: mergedeep ~=1.3.4
|
@@ -383,17 +384,17 @@ Requires-Dist: PyMemoryEditor ~=1.5.22
|
|
383
384
|
Requires-Dist: requests ~=2.32.3
|
384
385
|
Requires-Dist: rlottie-python ~=1.3.6
|
385
386
|
Requires-Dist: signalstickers-client-fork-laggykiller ~=3.3.0.post2
|
386
|
-
Requires-Dist:
|
387
|
-
Requires-Dist: tqdm ~=4.66.4
|
387
|
+
Requires-Dist: tqdm ~=4.66.5
|
388
388
|
Requires-Dist: ttkbootstrap-fork-laggykiller ~=1.5.1
|
389
|
+
Requires-Dist: websocket-client ~=1.8.0
|
389
390
|
|
390
391
|
# sticker-convert
|
391
|
-

|
392
393
|

|
393
394
|
|
394
395
|
- A python script for creating, downloading, converting+compressing and uploading stickers from multiple instant messaging applications.
|
395
396
|
- With GUI and CLI that runs on Windows, MacOS and Linux
|
396
|
-
- Currently supports Signal, Telegram, WhatsApp (Create .wastickers), Line (Download only), Kakao (Download only), Viber, iMessage (Create Xcode sticker pack project)
|
397
|
+
- Currently supports Signal, Telegram, WhatsApp (Create .wastickers), Line (Download only), Kakao (Download only), Viber, Discord (Download only), iMessage (Create Xcode sticker pack project)
|
397
398
|
- Supports static and animated stickers, with transparency support
|
398
399
|
|
399
400
|
## Downloads
|
@@ -432,6 +433,7 @@ Requires-Dist: ttkbootstrap-fork-laggykiller ~=1.5.1
|
|
432
433
|
| [Line](docs/guide_line.md) | ✅ | 🚫 (Need to submit for manual approval) |
|
433
434
|
| [Kakao](docs/guide_kakao.md) | ✅ (Need 'share link' for animated) | 🚫 (Need to submit for manual approval) |
|
434
435
|
| [Viber](docs/guide_viber.md) | ✅ | ✅ (Require `viber_auth`) |
|
436
|
+
| [Discord](docs/guide_discord.md) | ✅ (Required `token`) | 🚫 |
|
435
437
|
| [iMessage](docs/guide_imessage.md) | 🚫 | ⭕ (Create Xcode stickerpack project for sideload) |
|
436
438
|
|
437
439
|
✅ = Supported ⭕ = Partially supported 🚫 = Not supported
|
@@ -441,14 +443,14 @@ Requires-Dist: ttkbootstrap-fork-laggykiller ~=1.5.1
|
|
441
443
|
- Upload: Supported
|
442
444
|
- `uuid` and `password` are needed if you want to automatically upload the pack with the program. View FAQ for more information.
|
443
445
|
- Alternatively, you may use Signal Desktop to manually upload and create sticker pack with the output of this prorgam.
|
444
|
-
- Telegram
|
445
|
-
- Download: Supported for both stickers and custom emoji, but require bot token
|
446
|
+
- Telegram
|
447
|
+
- Download: Supported (e.g. `https://telegram.me/addstickers/xxxxx`) for both stickers and custom emoji, but require bot token.
|
446
448
|
- Upload: Supported for both stickers and custom emoji, but require bot token and user_id. Alternatively, you may manually upload and create sticker pack with the output of this program.
|
447
449
|
- WhatsApp
|
448
|
-
- Download: You have to manually find sticker packs / extract from your phone or from WhatsApp Web
|
450
|
+
- Download: You have to manually find sticker packs / extract from your phone or from WhatsApp Web.
|
449
451
|
- Android Phone: Inside `/storage/emulated/0/Whatsapp/media/Whatsapp Stickers` OR `/storage/emulated/0/Android/media/com.whatsapp/WhatsApp/Media/WhatsApp Stickers`
|
450
452
|
- Any: Go to WhatsApp Web, right click on sticker and click "Save image as..."
|
451
|
-
- Upload: The program can create .wastickers file, which could then be imported into WhatsApp via a third-party app named 'Sticker Maker' (The author of this repo is NOT affiliated with Sticker Maker). View FAQ for more information
|
453
|
+
- Upload: The program can create .wastickers file, which could then be imported into WhatsApp via a third-party app named 'Sticker Maker' (The author of this repo is NOT affiliated with Sticker Maker). View FAQ for more information.
|
452
454
|
- Line
|
453
455
|
- Download: Supported (e.g. `https://store.line.me/stickershop/product/1234/en` OR `line://shop/detail/1234` OR `1234`)
|
454
456
|
- Search on official site: https://store.line.me/stickershop
|
@@ -461,6 +463,9 @@ Requires-Dist: ttkbootstrap-fork-laggykiller ~=1.5.1
|
|
461
463
|
- Viber
|
462
464
|
- Download: Supported (e.g. `https://stickers.viber.com/pages/example` OR `https://stickers.viber.com/pages/custom-sticker-packs/example`)
|
463
465
|
- Upload: Supported. Viber authentication data required for uploading Viber stickers, which could be fetched from Viber Desktop application automatically.
|
466
|
+
- Discord
|
467
|
+
- Download: Supported (e.g. `https://discord.com/channels/169256939211980800/@home` OR `169256939211980800`), but require user token.
|
468
|
+
- Upload: Not supported.
|
464
469
|
- iMessage
|
465
470
|
- Download: Not supported.
|
466
471
|
- Upload: The program can create Xcode project for iMessage sticker pack, which could then be compiled and sideloaded using Xcode.
|
@@ -481,31 +486,15 @@ Requires-Dist: ttkbootstrap-fork-laggykiller ~=1.5.1
|
|
481
486
|
To run in CLI mode, pass on any arguments
|
482
487
|
|
483
488
|
```
|
484
|
-
usage: sticker-convert.py [-h] [--version] [--no-confirm] [--no-progress] [--custom-presets CUSTOM_PRESETS]
|
485
|
-
[--
|
486
|
-
[--
|
487
|
-
[--
|
488
|
-
[--
|
489
|
-
[--
|
490
|
-
[--
|
491
|
-
[--
|
492
|
-
[--
|
493
|
-
[--res-w-max RES_W_MAX] [--res-h-min RES_H_MIN] [--res-h-max RES_H_MAX]
|
494
|
-
[--res-power RES_POWER] [--quality-min QUALITY_MIN] [--quality-max QUALITY_MAX]
|
495
|
-
[--quality-power QUALITY_POWER] [--color-min COLOR_MIN] [--color-max COLOR_MAX]
|
496
|
-
[--color-power COLOR_POWER] [--duration-min DURATION_MIN] [--duration-max DURATION_MAX]
|
497
|
-
[--padding-percent PADDING_PERCENT] [--bg-color BG_COLOR] [--vid-size-max VID_SIZE_MAX]
|
498
|
-
[--img-size-max IMG_SIZE_MAX] [--vid-format VID_FORMAT] [--img-format IMG_FORMAT]
|
499
|
-
[--fake-vid] [--scale-filter SCALE_FILTER] [--quantize-method QUANTIZE_METHOD]
|
500
|
-
[--cache-dir CACHE_DIR] [--default-emoji DEFAULT_EMOJI] [--signal-uuid SIGNAL_UUID]
|
501
|
-
[--signal-password SIGNAL_PASSWORD] [--signal-get-auth]
|
502
|
-
[--signal-data-dir SIGNAL_DATA_DIR] [--telegram-token TELEGRAM_TOKEN]
|
503
|
-
[--telegram-userid TELEGRAM_USERID] [--kakao-auth-token KAKAO_AUTH_TOKEN]
|
504
|
-
[--kakao-get-auth] [--kakao-username KAKAO_USERNAME] [--kakao-password KAKAO_PASSWORD]
|
505
|
-
[--kakao-country-code KAKAO_COUNTRY_CODE] [--kakao-phone-number KAKAO_PHONE_NUMBER]
|
506
|
-
[--line-get-auth] [--line-cookies LINE_COOKIES] [--viber-auth VIBER_AUTH]
|
507
|
-
[--viber-get-auth VIBER_GET_AUTH] [--viber-bin-path VIBER_BIN_PATH]
|
508
|
-
[--save-cred SAVE_CRED]
|
489
|
+
usage: sticker-convert.py [-h] [--version] [--no-confirm] [--no-progress] [--custom-presets CUSTOM_PRESETS] [--input-dir INPUT_DIR]
|
490
|
+
[--download-auto DOWNLOAD_AUTO | --download-signal DOWNLOAD_SIGNAL | --download-telegram DOWNLOAD_TELEGRAM | --download-line DOWNLOAD_LINE | --download-kakao DOWNLOAD_KAKAO | --download-viber DOWNLOAD_VIBER | --download-discord DOWNLOAD_DISCORD | --download-discord-emoji DOWNLOAD_DISCORD_EMOJI]
|
491
|
+
[--output-dir OUTPUT_DIR] [--author AUTHOR] [--title TITLE] [--export-signal | --export-telegram | --export-telegram-emoji | --export-viber | --export-whatsapp | --export-imessage] [--no-compress]
|
492
|
+
[--preset {auto,signal,telegram,telegram_emoji,whatsapp,line,kakao,viber,discord,discord_emoji,imessage_small,imessage_medium,imessage_large,custom}] [--steps STEPS] [--processes PROCESSES] [--fps-min FPS_MIN] [--fps-max FPS_MAX] [--fps-power FPS_POWER]
|
493
|
+
[--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] [--res-h-max RES_H_MAX] [--res-power RES_POWER] [--quality-min QUALITY_MIN] [--quality-max QUALITY_MAX] [--quality-power QUALITY_POWER]
|
494
|
+
[--color-min COLOR_MIN] [--color-max COLOR_MAX] [--color-power COLOR_POWER] [--duration-min DURATION_MIN] [--duration-max DURATION_MAX] [--padding-percent PADDING_PERCENT] [--bg-color BG_COLOR] [--vid-size-max VID_SIZE_MAX] [--img-size-max IMG_SIZE_MAX]
|
495
|
+
[--vid-format VID_FORMAT] [--img-format IMG_FORMAT] [--fake-vid] [--scale-filter SCALE_FILTER] [--quantize-method QUANTIZE_METHOD] [--cache-dir CACHE_DIR] [--default-emoji DEFAULT_EMOJI] [--signal-uuid SIGNAL_UUID] [--signal-password SIGNAL_PASSWORD] [--signal-get-auth]
|
496
|
+
[--telegram-token TELEGRAM_TOKEN] [--telegram-userid TELEGRAM_USERID] [--kakao-auth-token KAKAO_AUTH_TOKEN] [--kakao-get-auth] [--kakao-username KAKAO_USERNAME] [--kakao-password KAKAO_PASSWORD] [--kakao-country-code KAKAO_COUNTRY_CODE]
|
497
|
+
[--kakao-phone-number KAKAO_PHONE_NUMBER] [--line-get-auth] [--line-cookies LINE_COOKIES] [--viber-auth VIBER_AUTH] [--viber-get-auth VIBER_GET_AUTH] [--viber-bin-path VIBER_BIN_PATH] [--discord-get-auth] [--discord-token DISCORD_TOKEN] [--save-cred SAVE_CRED]
|
509
498
|
|
510
499
|
CLI for stickers-convert
|
511
500
|
|
@@ -544,6 +533,14 @@ Input options:
|
|
544
533
|
Download viber stickers from a URL as input
|
545
534
|
(Example: https://stickers.viber.com/pages/example
|
546
535
|
OR https://stickers.viber.com/pages/custom-sticker-packs/example)
|
536
|
+
--download-discord DOWNLOAD_DISCORD
|
537
|
+
Download discord stickers from a channel URL / ID as input
|
538
|
+
(Example: https://discord.com/channels/169256939211980800/@home
|
539
|
+
OR 169256939211980800)
|
540
|
+
--download-discord-emoji DOWNLOAD_DISCORD_EMOJI
|
541
|
+
Download discord emojis from a channel URL / ID as input
|
542
|
+
(Example: https://discord.com/channels/169256939211980800/@home
|
543
|
+
OR 169256939211980800)
|
547
544
|
|
548
545
|
Output options:
|
549
546
|
--output-dir OUTPUT_DIR
|
@@ -554,13 +551,13 @@ Output options:
|
|
554
551
|
--export-telegram Upload to Telegram
|
555
552
|
--export-telegram-emoji
|
556
553
|
Upload to Telegram (Custom emoji)
|
557
|
-
--export-whatsapp Create a .wastickers file for uploading to WhatsApp
|
558
554
|
--export-viber Upload to Viber
|
555
|
+
--export-whatsapp Create a .wastickers file for uploading to WhatsApp
|
559
556
|
--export-imessage Create Xcode project for importing to iMessage
|
560
557
|
|
561
558
|
Compression options:
|
562
559
|
--no-compress Do not compress files. Useful for only downloading stickers.
|
563
|
-
--preset {auto,signal,telegram,telegram_emoji,whatsapp,line,kakao,viber,imessage_small,imessage_medium,imessage_large,custom}
|
560
|
+
--preset {auto,signal,telegram,telegram_emoji,whatsapp,line,kakao,viber,discord,discord_emoji,imessage_small,imessage_medium,imessage_large,custom}
|
564
561
|
Apply preset for compression.
|
565
562
|
--steps STEPS Set number of divisions between min and max settings.
|
566
563
|
Steps higher = Slower but yields file more closer to the specified file size limit.
|
@@ -644,9 +641,6 @@ Credentials options:
|
|
644
641
|
--signal-password SIGNAL_PASSWORD
|
645
642
|
Set Signal password. Required for uploading Signal stickers.
|
646
643
|
--signal-get-auth Generate Signal uuid and password.
|
647
|
-
--signal-data-dir SIGNAL_DATA_DIR
|
648
|
-
Optionally specify Signal data directory
|
649
|
-
for getting uuid and password. Useful for portable Signal.
|
650
644
|
--telegram-token TELEGRAM_TOKEN
|
651
645
|
Set Telegram token. Required for uploading and downloading Telegram stickers.
|
652
646
|
--telegram-userid TELEGRAM_USERID
|
@@ -682,6 +676,9 @@ Credentials options:
|
|
682
676
|
--viber-bin-path VIBER_BIN_PATH
|
683
677
|
Specify location of Viber Desktop application.
|
684
678
|
Useful for portable installation.
|
679
|
+
--discord-get-auth Get Discord token.
|
680
|
+
--discord-token DISCORD_TOKEN
|
681
|
+
Set Discord token. Required for downloading Discord stickers and emojis.
|
685
682
|
--save-cred SAVE_CRED
|
686
683
|
Save Signal and Telegram credentials.
|
687
684
|
```
|
@@ -794,6 +791,7 @@ See [docs/COMPILING.md](docs/COMPILING.md)
|
|
794
791
|
- [Line](docs/guide_line.md)
|
795
792
|
- [Kakao](docs/guide_kakao.md)
|
796
793
|
- [Viber](docs/guide_viber.md)
|
794
|
+
- [Discord](docs/guide_discord.md)
|
797
795
|
- [iMessage](docs/guide_imessage.md)
|
798
796
|
|
799
797
|
### Conversion is slow
|
@@ -854,5 +852,5 @@ See [docs/TODO.md](docs/TODO.md)
|
|
854
852
|
- Banner generated from [GitHub Socialify](https://socialify.git.ci/)
|
855
853
|
|
856
854
|
## DISCLAIMER
|
857
|
-
- The author of this repo is NOT affiliated with Signal, Telegram, WhatsApp, Line, Kakao, Viber, iMessage or Sticker Maker.
|
855
|
+
- The author of this repo is NOT affiliated with Signal, Telegram, WhatsApp, Line, Kakao, Viber, Discord, iMessage or Sticker Maker.
|
858
856
|
- The author of this repo is NOT repsonsible for any legal consequences and loss incurred from using this repo.
|