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.
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.