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.
Files changed (35) hide show
  1. sticker_convert/cli.py +26 -13
  2. sticker_convert/downloaders/download_base.py +20 -23
  3. sticker_convert/downloaders/download_discord.py +91 -0
  4. sticker_convert/downloaders/download_kakao.py +3 -4
  5. sticker_convert/downloaders/download_line.py +3 -4
  6. sticker_convert/downloaders/download_signal.py +3 -4
  7. sticker_convert/downloaders/download_telegram.py +3 -4
  8. sticker_convert/downloaders/download_viber.py +3 -4
  9. sticker_convert/gui.py +15 -3
  10. sticker_convert/gui_components/frames/cred_frame.py +22 -1
  11. sticker_convert/gui_components/windows/discord_get_auth_window.py +82 -0
  12. sticker_convert/gui_components/windows/signal_get_auth_window.py +39 -85
  13. sticker_convert/job.py +11 -1
  14. sticker_convert/job_option.py +2 -0
  15. sticker_convert/resources/compression.json +94 -0
  16. sticker_convert/resources/help.json +2 -1
  17. sticker_convert/resources/input.json +20 -0
  18. sticker_convert/uploaders/upload_signal.py +5 -4
  19. sticker_convert/uploaders/upload_telegram.py +11 -10
  20. sticker_convert/utils/auth/get_discord_auth.py +115 -0
  21. sticker_convert/utils/auth/get_signal_auth.py +115 -114
  22. sticker_convert/utils/auth/get_viber_auth.py +10 -214
  23. sticker_convert/utils/chrome_remotedebug.py +152 -0
  24. sticker_convert/utils/emoji.py +16 -0
  25. sticker_convert/utils/files/run_bin.py +1 -1
  26. sticker_convert/utils/media/codec_info.py +45 -60
  27. sticker_convert/utils/process.py +187 -0
  28. sticker_convert/utils/url_detect.py +3 -0
  29. sticker_convert/version.py +1 -1
  30. {sticker_convert-2.9.4.dist-info → sticker_convert-2.10.0.dist-info}/METADATA +40 -42
  31. {sticker_convert-2.9.4.dist-info → sticker_convert-2.10.0.dist-info}/RECORD +35 -29
  32. {sticker_convert-2.9.4.dist-info → sticker_convert-2.10.0.dist-info}/LICENSE +0 -0
  33. {sticker_convert-2.9.4.dist-info → sticker_convert-2.10.0.dist-info}/WHEEL +0 -0
  34. {sticker_convert-2.9.4.dist-info → sticker_convert-2.10.0.dist-info}/entry_points.txt +0 -0
  35. {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 == ".tgs":
91
- fps, frames = CodecInfo._get_file_fps_frames_tgs(file)
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 == ".tgs":
118
- return CodecInfo._get_file_fps_tgs(file)
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 == ".tgs":
145
- return CodecInfo._get_file_frames_tgs(file)
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 == ".tgs":
172
- fps, frames = CodecInfo._get_file_fps_frames_tgs(file)
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 _get_file_fps_tgs(file: Union[Path, bytes]) -> int:
188
- from rlottie_python.rlottie_wrapper import LottieAnimation
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
- if isinstance(file, Path):
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 _get_file_frames_tgs(file: Union[Path, bytes]) -> int:
203
- from rlottie_python.rlottie_wrapper import LottieAnimation
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
- with gzip.open(BytesIO(file)) as f:
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 _get_file_fps_frames_tgs(file: Union[Path, bytes]) -> Tuple[int, int]:
218
- from rlottie_python.rlottie_wrapper import LottieAnimation
219
-
220
- if isinstance(file, Path):
221
- with LottieAnimation.from_tgs(file.as_posix()) as anim:
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 == ".tgs":
412
- from rlottie_python.rlottie_wrapper import LottieAnimation
413
-
414
- if isinstance(file, Path):
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, ""
@@ -30,4 +30,7 @@ class UrlDetect:
30
30
  if domain == "stickers.viber.com":
31
31
  return "viber"
32
32
 
33
+ if domain == "discord.com":
34
+ return "discord"
35
+
33
36
  return None
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
- __version__ = "2.9.4"
3
+ __version__ = "2.10.0"
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sticker-convert
3
- Version: 2.9.4
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: sqlcipher3-wheels ~=0.5.2.post1
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
- ![imgs/banner.png](imgs/banner.png)
392
+ ![imgs/banner.png](https://socialify.git.ci/laggykiller/sticker-convert/image?description=1&font=Inter&logo=https%3A%2F%2Fgithub.com%2Flaggykiller%2Fsticker-convert%2Fblob%2Fmaster%2Fsrc%2Fsticker_convert%2Fresources%2Fappicon.png%3Fraw%3Dtrue&name=1&owner=1&theme=Dark)
392
393
  ![imgs/screenshot](imgs/screenshot.png)
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 (e.g. `https://telegram.me/addstickers/xxxxx`)
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
- [--input-dir INPUT_DIR]
486
- [--download-auto DOWNLOAD_AUTO | --download-signal DOWNLOAD_SIGNAL | --download-telegram DOWNLOAD_TELEGRAM | --download-line DOWNLOAD_LINE | --download-kakao DOWNLOAD_KAKAO | --download-viber DOWNLOAD_VIBER]
487
- [--output-dir OUTPUT_DIR] [--author AUTHOR] [--title TITLE]
488
- [--export-signal | --export-telegram | --export-telegram-emoji | --export-whatsapp | --export-viber | --export-imessage]
489
- [--no-compress]
490
- [--preset {auto,signal,telegram,telegram_emoji,whatsapp,line,kakao,viber,imessage_small,imessage_medium,imessage_large,custom}]
491
- [--steps STEPS] [--processes PROCESSES] [--fps-min FPS_MIN] [--fps-max FPS_MAX]
492
- [--fps-power FPS_POWER] [--res-min RES_MIN] [--res-max RES_MAX] [--res-w-min RES_W_MIN]
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.