sticker-convert 2.12.4__py3-none-any.whl → 2.13.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. sticker_convert/cli.py +3 -0
  2. sticker_convert/converter.py +61 -58
  3. sticker_convert/downloaders/download_band.py +110 -0
  4. sticker_convert/downloaders/download_kakao.py +84 -22
  5. sticker_convert/downloaders/download_line.py +8 -4
  6. sticker_convert/gui.py +6 -3
  7. sticker_convert/gui_components/windows/advanced_compression_window.py +1 -1
  8. sticker_convert/gui_components/windows/discord_get_auth_window.py +3 -3
  9. sticker_convert/gui_components/windows/kakao_get_auth_window.py +25 -4
  10. sticker_convert/gui_components/windows/signal_get_auth_window.py +3 -3
  11. sticker_convert/gui_components/windows/viber_get_auth_window.py +16 -1
  12. sticker_convert/job.py +6 -0
  13. sticker_convert/resources/compression.json +47 -0
  14. sticker_convert/resources/help.json +1 -1
  15. sticker_convert/resources/input.json +10 -0
  16. sticker_convert/resources/memdump_linux.sh +0 -1
  17. sticker_convert/utils/auth/get_discord_auth.py +2 -2
  18. sticker_convert/utils/auth/get_kakao_desktop_auth.py +38 -43
  19. sticker_convert/utils/auth/get_signal_auth.py +2 -2
  20. sticker_convert/utils/auth/get_viber_auth.py +3 -5
  21. sticker_convert/utils/auth/telegram_api.py +3 -1
  22. sticker_convert/utils/auth/telethon_setup.py +21 -8
  23. sticker_convert/utils/chrome_remotedebug.py +27 -29
  24. sticker_convert/utils/chromiums/linux.py +52 -0
  25. sticker_convert/utils/chromiums/osx.py +68 -0
  26. sticker_convert/utils/chromiums/windows.py +45 -0
  27. sticker_convert/utils/media/codec_info.py +1 -1
  28. sticker_convert/utils/process.py +152 -108
  29. sticker_convert/utils/singletons.py +18 -0
  30. sticker_convert/utils/url_detect.py +3 -0
  31. sticker_convert/version.py +1 -1
  32. {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.1.0.dist-info}/METADATA +37 -29
  33. {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.1.0.dist-info}/RECORD +37 -32
  34. {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.1.0.dist-info}/WHEEL +1 -1
  35. {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.1.0.dist-info}/entry_points.txt +0 -0
  36. {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.1.0.dist-info}/licenses/LICENSE +0 -0
  37. {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.1.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env python3
2
+ import glob
3
+ import os
4
+ import plistlib
5
+ import subprocess
6
+ from typing import Optional
7
+
8
+ # Adopted from https://github.com/roniemartinez/browsers/blob/master/browsers/osx.py
9
+
10
+ OSX_CHROMIUMS_BUNDLE_LIST = (
11
+ # browser name, bundle ID, version string
12
+ ("chrome", "com.google.Chrome", "CFBundleShortVersionString"),
13
+ ("chrome-beta", "com.google.Chrome.beta", "CFBundleShortVersionString"),
14
+ ("chrome-canary", "com.google.Chrome.canary", "CFBundleShortVersionString"),
15
+ ("chrome-dev", "com.google.Chrome.dev", "CFBundleShortVersionString"),
16
+ ("chrome-test", "com.google.chrome.for.testing", "CFBundleShortVersionString"),
17
+ ("chromium", "org.chromium.Chromium", "CFBundleShortVersionString"),
18
+ ("msedge", "com.microsoft.edgemac", "CFBundleShortVersionString"),
19
+ ("msedge-beta", "com.microsoft.edgemac.Beta", "CFBundleShortVersionString"),
20
+ ("msedge-dev", "com.microsoft.edgemac.Dev", "CFBundleShortVersionString"),
21
+ ("msedge-canary", "com.microsoft.edgemac.Canary", "CFBundleShortVersionString"),
22
+ ("brave", "com.brave.Browser", "CFBundleVersion"),
23
+ ("brave-beta", "com.brave.Browser.beta", "CFBundleVersion"),
24
+ ("brave-dev", "com.brave.Browser.dev", "CFBundleVersion"),
25
+ ("brave-nightly", "com.brave.Browser.nightly", "CFBundleVersion"),
26
+ ("opera", "com.operasoftware.Opera", "CFBundleVersion"),
27
+ ("opera-beta", "com.operasoftware.OperaNext", "CFBundleVersion"),
28
+ ("opera-developer", "com.operasoftware.OperaDeveloper", "CFBundleVersion"),
29
+ ("opera-gx", "com.operasoftware.OperaGX", "CFBundleVersion"),
30
+ ("opera-neon", "com.opera.Neon", "CFBundleShortVersionString"),
31
+ ("duckduckgo", "com.duckduckgo.macos.browser", "CFBundleShortVersionString"),
32
+ ("epic", "com.hiddenreflex.Epic", "CFBundleShortVersionString"),
33
+ ("vivaldi", "com.vivaldi.Vivaldi", "CFBundleShortVersionString"),
34
+ ("yandex", "ru.yandex.desktop.yandex-browser", "CFBundleShortVersionString"),
35
+ )
36
+
37
+ OSX_CHROMIUMS_BUNDLE_DICT = {item[1]: item for item in OSX_CHROMIUMS_BUNDLE_LIST}
38
+
39
+
40
+ def get_chromium_path() -> Optional[str]:
41
+ for _, bundle_id, _ in OSX_CHROMIUMS_BUNDLE_LIST:
42
+ app_dirs = subprocess.getoutput(
43
+ f'mdfind "kMDItemCFBundleIdentifier == {bundle_id}"'
44
+ ).splitlines()
45
+ for app_dir in app_dirs:
46
+ plist_path = os.path.join(app_dir, "Contents/Info.plist")
47
+
48
+ with open(plist_path, "rb") as f:
49
+ plist = plistlib.load(f)
50
+ executable_name = plist["CFBundleExecutable"]
51
+ executable = os.path.join(app_dir, "Contents/MacOS", executable_name)
52
+ return executable
53
+
54
+ # Naively iterate /Applications folder in case the above check fails
55
+ for plist_path in glob.glob("/Applications/*.app/Contents/Info.plist"):
56
+ with open(plist_path, "rb") as f:
57
+ plist = plistlib.load(f)
58
+ bundle_id = plist.get("CFBundleIdentifier")
59
+ if bundle_id not in OSX_CHROMIUMS_BUNDLE_DICT:
60
+ continue
61
+
62
+ app_dir = os.path.dirname(os.path.dirname(plist_path))
63
+ executable_name = plist["CFBundleExecutable"]
64
+ executable = os.path.join(app_dir, "Contents/MacOS", executable_name)
65
+
66
+ return executable
67
+
68
+ return None
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env python3
2
+ import os
3
+ from typing import Optional
4
+
5
+ # Not adopting approach of reading registry like https://github.com/roniemartinez/browsers
6
+ # As trigger antivirus
7
+
8
+ PF32 = os.environ.get("PROGRAMW6432")
9
+ PF64 = os.environ.get("PROGRAMFILES")
10
+ LAD = os.environ.get("LOCALAPPDATA")
11
+
12
+ WINDOWS_CHROMIUMS_PATHS = (
13
+ f"{PF64}\\Google\\Chrome\\Application\\chrome.exe", # chromium
14
+ f"{PF32}\\Google\\Chrome\\Application\\chrome.exe", # chromium
15
+ f"{LAD}\\Google\\Chrome SxS\\Application\\chrome.exe", # chromium-canary
16
+ f"{PF64}\\Opera\\opera.exe", # opera
17
+ f"{PF32}\\Opera\\opera.exe", # opera
18
+ f"{LAD}\\Programs\\Opera\\opera.exe", # opera
19
+ f"{LAD}\\Programs\\Opera\\launcher.exe", # opera
20
+ f"{LAD}\\Programs\\Opera Beta\\opera.exe", # opera-beta
21
+ f"{LAD}\\Programs\\Opera Beta\\launcher.exe", # opera-beta
22
+ f"{LAD}\\Programs\\Opera Developer\\opera.exe", # opera-developer
23
+ f"{LAD}\\Programs\\Opera Developer\\launcher.exe", # opera-developer
24
+ f"{PF64}\\Microsoft\\Edge\\Application\\msedge.exe", # msedge
25
+ f"{PF32}\\Microsoft\\Edge\\Application\\msedge.exe", # msedge
26
+ f"{PF64}\\Microsoft\\Edge Beta\\Application\\msedge.exe", # msedge-beta
27
+ f"{PF32}\\Microsoft\\Edge Beta\\Application\\msedge.exe", # msedge-beta
28
+ f"{PF64}\\Microsoft\\Edge Dev\\Application\\msedge.exe", # msedge-dev
29
+ f"{PF32}\\Microsoft\\Edge Dev\\Application\\msedge.exe", # msedge-dev
30
+ f"{LAD}\\Microsoft\\Edge SxS\\Application\\msedge.exe", # msedge-canary
31
+ f"{PF64}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe", # brave
32
+ f"{PF32}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe", # brave
33
+ f"{PF64}\\BraveSoftware\\Brave-Browser-Beta\\Application\\brave.exe", # brave-beta
34
+ f"{PF32}\\BraveSoftware\\Brave-Browser-Beta\\Application\\brave.exe", # brave-beta
35
+ f"{PF64}\\BraveSoftware\\Brave-Browser-Nightly\\Application\\brave.exe", # brave-nightly
36
+ f"{PF32}\\BraveSoftware\\Brave-Browser-Nightly\\Application\\brave.exe", # brave-nightly
37
+ )
38
+
39
+
40
+ def get_chromium_path() -> Optional[str]:
41
+ for path in WINDOWS_CHROMIUMS_PATHS:
42
+ if os.path.exists(path):
43
+ return path
44
+
45
+ return None
@@ -20,7 +20,7 @@ from sticker_convert.definitions import SVG_DEFAULT_HEIGHT, SVG_DEFAULT_WIDTH, S
20
20
  warnings.filterwarnings("ignore", category=XMLParsedAsHTMLWarning)
21
21
 
22
22
 
23
- def lcm(a: int, b: int):
23
+ def lcm(a: int, b: int) -> int:
24
24
  return abs(a * b) // gcd(a, b)
25
25
 
26
26
 
@@ -5,17 +5,20 @@ import shutil
5
5
  import subprocess
6
6
  import time
7
7
  from getpass import getpass
8
- from typing import Callable, Optional, Tuple
8
+ from io import BytesIO
9
+ from typing import Callable, Optional, Union
10
+ from zipfile import ZipFile
9
11
 
10
12
  import psutil
13
+ import requests
11
14
 
12
- from sticker_convert.definitions import ROOT_DIR
15
+ from sticker_convert.definitions import CONFIG_DIR, ROOT_DIR
13
16
 
14
17
 
15
18
  def killall(name: str) -> bool:
16
19
  result = False
17
20
 
18
- for proc in psutil.process_iter():
21
+ for proc in psutil.process_iter(): # type: ignore
19
22
  if name in proc.name().lower():
20
23
  proc.kill()
21
24
  result = True
@@ -24,7 +27,7 @@ def killall(name: str) -> bool:
24
27
 
25
28
 
26
29
  def find_pid_by_name(name: str) -> Optional[int]:
27
- for proc in psutil.process_iter():
30
+ for proc in psutil.process_iter(): # type: ignore
28
31
  if name in proc.name().lower():
29
32
  return proc.pid
30
33
 
@@ -65,123 +68,164 @@ elif platform.system() == "Linux":
65
68
  return True if "may run the following commands" in s else False
66
69
 
67
70
 
68
- def 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)
71
+ def _get_mem_win_procdump(
72
+ pid: Union[str, int],
73
+ pw_func: Optional[Callable[..., str]] = None,
74
+ is_wine: bool = False,
75
+ ) -> Optional[bytes]:
76
+ procdump_dir = CONFIG_DIR / "ProcDump"
77
+ procdump_bin = procdump_dir / "procdump.exe"
78
+ if procdump_bin.is_file() is False:
79
+ r = requests.get("https://download.sysinternals.com/files/Procdump.zip")
80
+ if r.ok is False:
81
+ return None
82
+ with ZipFile(BytesIO(r.content)) as zf:
83
+ zf.extractall(procdump_dir)
84
+
85
+ if procdump_bin.is_file() is False:
86
+ return None
87
+
88
+ if is_wine:
89
+ cmd = ["wine"]
90
+ dump_fpath = f"/tmp/memdump.{pid}.dmp"
91
+ else:
92
+ cmd = []
93
+ dump_fpath = os.path.expandvars(f"%temp%/memdump.{pid}.dmp")
94
+ cmd += [str(procdump_bin), "-accepteula", "-ma", str(pid), dump_fpath]
95
+
96
+ subprocess.run(cmd)
97
+
98
+ with open(dump_fpath, "rb") as f:
99
+ s = f.read()
100
+ os.remove(dump_fpath)
101
+
102
+ return s
103
+
104
+
105
+ def _get_mem_win_builtin(
106
+ pid: Union[str, int], pw_func: Optional[Callable[..., str]] = None
107
+ ) -> Optional[bytes]:
108
+ from pathlib import WindowsPath
109
+
110
+ memdump_ps_path = str(WindowsPath(ROOT_DIR / "resources/memdump_windows.ps1"))
111
+ arglist = f'-NoProfile -ExecutionPolicy Bypass -File "{memdump_ps_path}" {pid}'
112
+ dump_fpath = os.path.expandvars(f"%temp%/memdump.{pid}.dmp")
113
+
114
+ cmd = [
115
+ "powershell",
116
+ "-NoProfile",
117
+ "-ExecutionPolicy",
118
+ "Bypass",
119
+ "-Command",
120
+ f"Start-Process -Verb RunAs powershell -ArgumentList '{arglist}'",
121
+ ]
122
+
123
+ subprocess.run(cmd, capture_output=True, text=True)
124
+
125
+ while True:
126
+ try:
127
+ with open(dump_fpath, "rb") as f:
128
+ s = f.read()
129
+ if len(s) != 0:
109
130
  break
110
- except PermissionError:
111
- pass
112
-
113
- return s, ""
131
+ time.sleep(1)
132
+ except (FileNotFoundError, PermissionError):
133
+ pass
114
134
 
115
- elif platform.system() == "Darwin":
135
+ while True:
136
+ try:
137
+ os.remove(dump_fpath)
138
+ break
139
+ except PermissionError:
140
+ pass
116
141
 
117
- def get_mem(
118
- pid: int, pw_func: Optional[Callable[..., str]] = None
119
- ) -> Tuple[Optional[bytes], str]:
120
- subprocess.run(
142
+ return s
143
+
144
+
145
+ def _get_mem_darwin(
146
+ pid: Union[str, int], pw_func: Optional[Callable[..., str]] = None
147
+ ) -> Optional[bytes]:
148
+ subprocess.run(
149
+ [
150
+ "lldb",
151
+ "--attach-pid",
152
+ str(pid),
153
+ "-o",
154
+ f"process save-core /tmp/memdump.{pid}.dmp",
155
+ "-o",
156
+ "quit",
157
+ ],
158
+ stdout=subprocess.DEVNULL,
159
+ stderr=subprocess.DEVNULL,
160
+ )
161
+
162
+ with open(f"/tmp/memdump.{pid}.dmp", "rb") as f:
163
+ s = f.read()
164
+
165
+ os.remove(f"/tmp/memdump.{pid}.dmp")
166
+
167
+ return s
168
+
169
+
170
+ def _get_mem_linux(
171
+ pid: Union[str, int], pw_func: Optional[Callable[..., str]] = None
172
+ ) -> Optional[bytes]:
173
+ memdump_sh_path = (ROOT_DIR / "resources/memdump_linux.sh").as_posix()
174
+
175
+ s = subprocess.run(
176
+ [
177
+ memdump_sh_path,
178
+ str(pid),
179
+ ],
180
+ capture_output=True,
181
+ ).stdout
182
+
183
+ if len(s) > 1000:
184
+ pass
185
+ elif shutil.which("pkexec") and os.getenv("DISPLAY"):
186
+ s = subprocess.run(
121
187
  [
122
- "lldb",
123
- "--attach-pid",
188
+ "pkexec",
189
+ memdump_sh_path,
124
190
  str(pid),
125
- "-o",
126
- f"process save-core /tmp/memdump.{pid}.dmp",
127
- "-o",
128
- "quit",
129
191
  ],
130
- stdout=subprocess.DEVNULL,
131
- stderr=subprocess.DEVNULL,
192
+ capture_output=True,
193
+ ).stdout
194
+ else:
195
+ prompt = "Enter sudo password: "
196
+ if pw_func:
197
+ sudo_password = pw_func(prompt)
198
+ else:
199
+ sudo_password = getpass(prompt)
200
+ sudo_password_pipe = subprocess.Popen(
201
+ ("echo", sudo_password), stdout=subprocess.PIPE
132
202
  )
133
-
134
- with open(f"/tmp/memdump.{pid}.dmp", "rb") as f:
135
- s = f.read()
136
-
137
- os.remove(f"/tmp/memdump.{pid}.dmp")
138
-
139
- return s, ""
140
-
141
- else:
142
-
143
- def get_mem(
144
- pid: int, pw_func: Optional[Callable[..., str]] = None
145
- ) -> Tuple[Optional[bytes], str]:
146
- memdump_sh_path = (ROOT_DIR / "resources/memdump_linux.sh").as_posix()
147
-
148
203
  s = subprocess.run(
149
204
  [
205
+ "sudo",
206
+ "-S",
150
207
  memdump_sh_path,
151
208
  str(pid),
152
209
  ],
153
210
  capture_output=True,
211
+ stdin=sudo_password_pipe.stdout,
154
212
  ).stdout
155
213
 
156
- 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
214
+ return s
215
+
216
+
217
+ def get_mem(
218
+ pid: Union[str, int],
219
+ pw_func: Optional[Callable[..., str]] = None,
220
+ is_wine: bool = False,
221
+ ) -> Optional[bytes]:
222
+ if is_wine or platform.system() == "Windows":
223
+ dump = _get_mem_win_procdump(pid, pw_func, is_wine)
224
+ if dump is not None or is_wine:
225
+ return dump
167
226
  else:
168
- 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, ""
227
+ return _get_mem_win_builtin(pid, pw_func)
228
+ elif platform.system() == "Darwin":
229
+ return _get_mem_darwin(pid, pw_func)
230
+ else:
231
+ return _get_mem_linux(pid, pw_func)
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env python3
2
+ from typing import Any, Dict, Protocol
3
+
4
+
5
+ class SingletonProtocol(Protocol):
6
+ def close(self) -> Any: ...
7
+
8
+
9
+ class Singletons:
10
+ def __init__(self) -> None:
11
+ self.objs: Dict[str, SingletonProtocol] = {}
12
+
13
+ def close(self) -> None:
14
+ for obj in self.objs.values():
15
+ obj.close()
16
+
17
+
18
+ singletons = Singletons()
@@ -25,6 +25,9 @@ class UrlDetect:
25
25
  if domain in ("e.kakao.com", "emoticon.kakao.com"):
26
26
  return "kakao"
27
27
 
28
+ if domain == "www.band.us":
29
+ return "band"
30
+
28
31
  if domain == "stickers.viber.com":
29
32
  return "viber"
30
33
 
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
- __version__ = "2.12.4"
3
+ __version__ = "2.13.1.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sticker-convert
3
- Version: 2.12.4
3
+ Version: 2.13.1.0
4
4
  Summary: Convert (animated) stickers to/from WhatsApp, Telegram, Signal, Line, Kakao, Viber, Discord, iMessage. Written in Python.
5
5
  Author-email: laggykiller <chaudominic2@gmail.com>
6
6
  Maintainer-email: laggykiller <chaudominic2@gmail.com>
@@ -366,8 +366,8 @@ License-File: LICENSE
366
366
  Requires-Dist: aiolimiter~=1.2.1
367
367
  Requires-Dist: anyio~=4.9.0
368
368
  Requires-Dist: apngasm_python~=1.3.2
369
- Requires-Dist: av~=13.1.0
370
- Requires-Dist: beautifulsoup4~=4.13.3
369
+ Requires-Dist: av>=13.1.0
370
+ Requires-Dist: beautifulsoup4~=4.13.4
371
371
  Requires-Dist: cryptg~=0.5.0.post0
372
372
  Requires-Dist: rookiepy~=0.5.6
373
373
  Requires-Dist: httpx~=0.28.1
@@ -375,17 +375,16 @@ Requires-Dist: imagequant~=1.1.4
375
375
  Requires-Dist: memory-tempfile~=2.2.3
376
376
  Requires-Dist: mergedeep~=1.3.4
377
377
  Requires-Dist: numpy>=1.22.4
378
- Requires-Dist: Pillow~=11.1.0
379
- Requires-Dist: pybrowsers~=0.7.0
378
+ Requires-Dist: Pillow~=11.2.1
380
379
  Requires-Dist: pyoxipng~=9.1.0
381
- Requires-Dist: python-telegram-bot~=22.0
380
+ Requires-Dist: python-telegram-bot~=22.1
382
381
  Requires-Dist: psutil~=7.0.0
383
382
  Requires-Dist: PyMemoryEditor~=1.5.22
384
383
  Requires-Dist: requests~=2.32.3
385
384
  Requires-Dist: rlottie_python~=1.3.7
386
385
  Requires-Dist: signalstickers-client-fork-laggykiller~=3.3.0.post2
387
386
  Requires-Dist: socksio~=1.0.0
388
- Requires-Dist: telethon~=1.39.0
387
+ Requires-Dist: telethon~=1.40.0
389
388
  Requires-Dist: tqdm~=4.67.1
390
389
  Requires-Dist: ttkbootstrap-fork-laggykiller~=1.5.1
391
390
  Requires-Dist: websocket_client~=1.8.0
@@ -397,12 +396,12 @@ Dynamic: license-file
397
396
 
398
397
  - A python script for creating, downloading, converting+compressing and uploading stickers from multiple instant messaging applications.
399
398
  - With GUI and CLI that runs on Windows, MacOS and Linux
400
- - Currently supports Signal, Telegram, WhatsApp (Create .wastickers), Line (Download only), Kakao (Download only), Viber, Discord (Download only), iMessage (Create Xcode sticker pack project)
399
+ - Currently supports Signal, Telegram, WhatsApp (Create .wastickers), Line (Download only), Kakao (Download only), Naver Band (Download only), Viber, Discord (Download only), iMessage (Create Xcode sticker pack project)
401
400
  - Supports static and animated stickers, with transparency support
402
401
 
403
402
  ## Downloads
404
403
  - [Pre-compiled releases](https://github.com/laggykiller/sticker-convert/releases) for Windows, MacOS and Linux (As AppImage).
405
- - Windows: Unzip the downloaded file and run `sticker-convert.exe`
404
+ - Windows: Unzip the downloaded file and run `sticker-convert.exe`, or download msi file for installation
406
405
  - MacOS: Unzip the downloaded file, hold control and open `hold_control_and_click_open_me.command` for the first time, then `sticker-convert.app` in the future
407
406
  - Linux:
408
407
  - AppImage: `chmod +x` the downloaded AppImage and run it
@@ -438,6 +437,7 @@ Dynamic: license-file
438
437
  | [WhatsApp](docs/guide_whatsapp.md) | ⭕ (By Android or WhatsApp Web) | ⭕ (Create `.wastickers`, import by Sticker Maker) |
439
438
  | [Line](docs/guide_line.md) | ✅ | 🚫 (Need to submit for manual approval) |
440
439
  | [Kakao](docs/guide_kakao.md) | ✅ (Need 'auth_token' for animated) | 🚫 (Need to submit for manual approval) |
440
+ | [Band](docs/guide_band.md) | ✅ | 🚫 (Need to submit for manual approval) |
441
441
  | [Viber](docs/guide_viber.md) | ✅ | ✅ (Require `viber_auth`) |
442
442
  | [Discord](docs/guide_discord.md) | ✅ (Require `token`) | 🚫 |
443
443
  | [iMessage](docs/guide_imessage.md) | 🚫 | ⭕ (Create Xcode stickerpack project for sideload) |
@@ -464,6 +464,9 @@ Dynamic: license-file
464
464
  - Kakao
465
465
  - Download: Supported (e.g. `https://e.kakao.com/t/xxxxx` OR `https://emoticon.kakao.com/items/xxxxx` OR `4404400`). It is rather complicated, learn more from [docs/guide_kakao.md](docs/guide_kakao.md)
466
466
  - Upload: Not supported. You need to manually submit sticker pack for approval before you can use in app.
467
+ - Band
468
+ - Download: Supported (e.g. `https://www.band.us/sticker/xxxx` OR 2535). Learn how to get share link from [docs/guide_band.md](docs/guide_band.md)
469
+ - Upload: Not supported. You need to manually submit sticker pack for approval before you can use in app.
467
470
  - Viber
468
471
  - Download: Supported (e.g. `https://stickers.viber.com/pages/example` OR `https://stickers.viber.com/pages/custom-sticker-packs/example`)
469
472
  - Upload: Supported. Viber authentication data required for uploading Viber stickers, which could be fetched from Viber Desktop application automatically.
@@ -490,30 +493,27 @@ Dynamic: license-file
490
493
  To run in CLI mode, pass on any arguments
491
494
 
492
495
  ```
493
- usage: sticker-convert.py [-h] [--version] [--no-confirm] [--no-progress] [--custom-presets CUSTOM_PRESETS]
494
- [--input-dir INPUT_DIR]
495
- [--download-auto DOWNLOAD_AUTO | --download-signal DOWNLOAD_SIGNAL | --download-telegram DOWNLOAD_TELEGRAM | --download-telegram-telethon DOWNLOAD_TELEGRAM_TELETHON | --download-line DOWNLOAD_LINE | --download-kakao DOWNLOAD_KAKAO | --download-viber DOWNLOAD_VIBER | --download-discord DOWNLOAD_DISCORD | --download-discord-emoji DOWNLOAD_DISCORD_EMOJI]
496
+ usage: sticker-convert.py [-h] [--version] [--no-confirm] [--no-progress] [--custom-presets CUSTOM_PRESETS] [--input-dir INPUT_DIR]
497
+ [--download-auto DOWNLOAD_AUTO | --download-signal DOWNLOAD_SIGNAL | --download-telegram DOWNLOAD_TELEGRAM | --download-telegram-telethon DOWNLOAD_TELEGRAM_TELETHON | --download-line DOWNLOAD_LINE | --download-kakao DOWNLOAD_KAKAO | --download-band DOWNLOAD_BAND | --download-viber DOWNLOAD_VIBER | --download-discord DOWNLOAD_DISCORD | --download-discord-emoji DOWNLOAD_DISCORD_EMOJI]
496
498
  [--output-dir OUTPUT_DIR] [--author AUTHOR] [--title TITLE]
497
499
  [--export-signal | --export-telegram | --export-telegram-emoji | --export-telegram-telethon | --export-telegram-emoji-telethon | --export-viber | --export-whatsapp | --export-imessage]
498
500
  [--no-compress]
499
501
  [--preset {auto,signal,telegram,telegram_emoji,whatsapp,line,kakao,viber,discord,discord_emoji,imessage_small,imessage_medium,imessage_large,custom}]
500
- [--steps STEPS] [--processes PROCESSES] [--fps-min FPS_MIN] [--fps-max FPS_MAX]
501
- [--fps-power FPS_POWER] [--res-min RES_MIN] [--res-max RES_MAX] [--res-w-min RES_W_MIN]
502
- [--res-w-max RES_W_MAX] [--res-h-min RES_H_MIN] [--res-h-max RES_H_MAX] [--res-power RES_POWER]
503
- [--quality-min QUALITY_MIN] [--quality-max QUALITY_MAX] [--quality-power QUALITY_POWER]
504
- [--color-min COLOR_MIN] [--color-max COLOR_MAX] [--color-power COLOR_POWER]
502
+ [--steps STEPS] [--processes PROCESSES] [--fps-min FPS_MIN] [--fps-max FPS_MAX] [--fps-power FPS_POWER]
503
+ [--res-min RES_MIN] [--res-max RES_MAX] [--res-w-min RES_W_MIN] [--res-w-max RES_W_MAX] [--res-h-min RES_H_MIN]
504
+ [--res-h-max RES_H_MAX] [--res-power RES_POWER] [--quality-min QUALITY_MIN] [--quality-max QUALITY_MAX]
505
+ [--quality-power QUALITY_POWER] [--color-min COLOR_MIN] [--color-max COLOR_MAX] [--color-power COLOR_POWER]
505
506
  [--duration-min DURATION_MIN] [--duration-max DURATION_MAX] [--padding-percent PADDING_PERCENT]
506
- [--bg-color BG_COLOR] [--vid-size-max VID_SIZE_MAX] [--img-size-max IMG_SIZE_MAX]
507
- [--vid-format VID_FORMAT] [--img-format IMG_FORMAT] [--fake-vid] [--scale-filter SCALE_FILTER]
508
- [--quantize-method QUANTIZE_METHOD] [--cache-dir CACHE_DIR] [--default-emoji DEFAULT_EMOJI]
509
- [--signal-uuid SIGNAL_UUID] [--signal-password SIGNAL_PASSWORD] [--signal-get-auth]
510
- [--telegram-token TELEGRAM_TOKEN] [--telegram-userid TELEGRAM_USERID] [--telethon-setup]
511
- [--kakao-auth-token KAKAO_AUTH_TOKEN] [--kakao-get-auth] [--kakao-get-auth-desktop]
512
- [--kakao-bin-path KAKAO_BIN_PATH] [--kakao-username KAKAO_USERNAME]
507
+ [--bg-color BG_COLOR] [--vid-size-max VID_SIZE_MAX] [--img-size-max IMG_SIZE_MAX] [--vid-format VID_FORMAT]
508
+ [--img-format IMG_FORMAT] [--fake-vid] [--scale-filter SCALE_FILTER] [--quantize-method QUANTIZE_METHOD]
509
+ [--cache-dir CACHE_DIR] [--chromium-path CHROMIUM_PATH] [--default-emoji DEFAULT_EMOJI] [--signal-uuid SIGNAL_UUID]
510
+ [--signal-password SIGNAL_PASSWORD] [--signal-get-auth] [--telegram-token TELEGRAM_TOKEN]
511
+ [--telegram-userid TELEGRAM_USERID] [--telethon-setup] [--kakao-auth-token KAKAO_AUTH_TOKEN] [--kakao-get-auth]
512
+ [--kakao-get-auth-desktop] [--kakao-bin-path KAKAO_BIN_PATH] [--kakao-username KAKAO_USERNAME]
513
513
  [--kakao-password KAKAO_PASSWORD] [--kakao-country-code KAKAO_COUNTRY_CODE]
514
- [--kakao-phone-number KAKAO_PHONE_NUMBER] [--line-get-auth] [--line-cookies LINE_COOKIES]
515
- [--viber-auth VIBER_AUTH] [--viber-get-auth VIBER_GET_AUTH] [--viber-bin-path VIBER_BIN_PATH]
516
- [--discord-get-auth] [--discord-token DISCORD_TOKEN] [--save-cred]
514
+ [--kakao-phone-number KAKAO_PHONE_NUMBER] [--line-get-auth] [--line-cookies LINE_COOKIES] [--viber-auth VIBER_AUTH]
515
+ [--viber-get-auth VIBER_GET_AUTH] [--viber-bin-path VIBER_BIN_PATH] [--discord-get-auth]
516
+ [--discord-token DISCORD_TOKEN] [--save-cred]
517
517
 
518
518
  CLI for stickers-convert
519
519
 
@@ -552,6 +552,9 @@ Input options:
552
552
  Download kakao stickers from a URL / ID as input
553
553
  (Example: https://e.kakao.com/t/xxxxx
554
554
  OR https://emoticon.kakao.com/items/xxxxx OR 4404400)
555
+ --download-band DOWNLOAD_BAND
556
+ Download Naver Band stickers from a URL / ID as input
557
+ (Example: https://www.band.us/sticker/xxxx OR 2535)
555
558
  --download-viber DOWNLOAD_VIBER
556
559
  Download viber stickers from a URL as input
557
560
  (Example: https://stickers.viber.com/pages/example
@@ -659,6 +662,10 @@ Compression options:
659
662
  --cache-dir CACHE_DIR
660
663
  Set custom cache directory.
661
664
  Useful for debugging, or speed up conversion if cache_dir is on RAM disk.
665
+ --chromium-path CHROMIUM_PATH
666
+ Set Chromium(-based)/Chrome browser path.
667
+ Required for converting from SVG files.
668
+ Leave blank to auto detect
662
669
  --default-emoji DEFAULT_EMOJI
663
670
  Set the default emoji for uploading Signal and Telegram sticker packs.
664
671
 
@@ -678,7 +685,6 @@ Credentials options:
678
685
  --kakao-get-auth Generate Kakao auth_token by simulating login. Kakao username, password, country code and phone number are also required.
679
686
  --kakao-get-auth-desktop
680
687
  Get Kakao auth_token from Kakao Desktop application.
681
- (Only working on Windows.)
682
688
  --kakao-bin-path KAKAO_BIN_PATH
683
689
  Set Kakao Desktop application path for launching and getting auth_token.
684
690
  Useful for portable installation.
@@ -881,9 +887,11 @@ See [docs/TODO.md](docs/TODO.md)
881
887
  - Information about Line stickers: https://github.com/doubleplusc/Line-sticker-downloader
882
888
  - Information about Kakao animated stickers: https://gist.github.com/chitacan/9802668
883
889
  - Downloading and decrypting Kakao animated stickers: https://github.com/blluv/KakaoTalkEmoticonDownloader
890
+ - Finding browser executable paths: https://github.com/roniemartinez/browsers
884
891
  - Application icon taken from [Icons8](https://icons8.com/)
885
892
  - Banner generated from [GitHub Socialify](https://socialify.git.ci/)
893
+ - Free code signing on Windows provided by [SignPath.io](https://about.signpath.io/), certificate by [SignPath Foundation](https://signpath.org/)
886
894
 
887
895
  ## DISCLAIMER
888
- - The author of this repo is NOT affiliated with Signal, Telegram, WhatsApp, Line, Kakao, Viber, Discord, iMessage or Sticker Maker.
896
+ - The author of this repo is NOT affiliated with Signal, Telegram, WhatsApp, Line, Kakao, Naver Band, Viber, Discord, iMessage or Sticker Maker.
889
897
  - The author of this repo is NOT repsonsible for any legal consequences and loss incurred from using this repo.