sticker-convert 2.9.4__py3-none-any.whl → 2.10.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 +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.
|