sticker-convert 2.12.4__py3-none-any.whl → 2.13.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 +1 -0
- sticker_convert/converter.py +61 -58
- sticker_convert/downloaders/download_band.py +110 -0
- sticker_convert/downloaders/download_kakao.py +84 -22
- sticker_convert/gui.py +6 -3
- sticker_convert/gui_components/windows/discord_get_auth_window.py +3 -3
- sticker_convert/gui_components/windows/signal_get_auth_window.py +3 -3
- sticker_convert/gui_components/windows/viber_get_auth_window.py +1 -1
- sticker_convert/job.py +6 -0
- sticker_convert/resources/compression.json +47 -0
- sticker_convert/resources/input.json +10 -0
- sticker_convert/resources/memdump_linux.sh +0 -1
- sticker_convert/utils/auth/get_discord_auth.py +1 -1
- sticker_convert/utils/auth/get_kakao_desktop_auth.py +2 -2
- sticker_convert/utils/auth/get_signal_auth.py +2 -2
- sticker_convert/utils/auth/get_viber_auth.py +1 -1
- sticker_convert/utils/auth/telethon_setup.py +3 -1
- sticker_convert/utils/chrome_remotedebug.py +25 -13
- sticker_convert/utils/media/codec_info.py +1 -1
- sticker_convert/utils/singletons.py +18 -0
- sticker_convert/utils/url_detect.py +3 -0
- sticker_convert/version.py +1 -1
- {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.0.dist-info}/METADATA +32 -24
- {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.0.dist-info}/RECORD +28 -26
- {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.0.dist-info}/WHEEL +1 -1
- {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.0.dist-info}/entry_points.txt +0 -0
- {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.0.dist-info}/licenses/LICENSE +0 -0
- {sticker_convert-2.12.4.dist-info → sticker_convert-2.13.0.dist-info}/top_level.txt +0 -0
sticker_convert/cli.py
CHANGED
@@ -232,6 +232,7 @@ class CLI:
|
|
232
232
|
"telegram": args.download_telegram,
|
233
233
|
"telegram_telethon": args.download_telegram_telethon,
|
234
234
|
"kakao": args.download_kakao,
|
235
|
+
"band": args.download_band,
|
235
236
|
"viber": args.download_viber,
|
236
237
|
"discord": args.download_discord,
|
237
238
|
"discord_emoji": args.download_discord_emoji,
|
sticker_convert/converter.py
CHANGED
@@ -19,6 +19,7 @@ from sticker_convert.utils.chrome_remotedebug import CRD
|
|
19
19
|
from sticker_convert.utils.files.cache_store import CacheStore
|
20
20
|
from sticker_convert.utils.media.codec_info import CodecInfo, rounding
|
21
21
|
from sticker_convert.utils.media.format_verify import FormatVerify
|
22
|
+
from sticker_convert.utils.singletons import singletons
|
22
23
|
|
23
24
|
if TYPE_CHECKING:
|
24
25
|
from av.video.frame import VideoFrame
|
@@ -435,26 +436,30 @@ class StickerConvert:
|
|
435
436
|
width = self.codec_info_orig.res[0]
|
436
437
|
height = self.codec_info_orig.res[1]
|
437
438
|
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
439
|
+
if singletons.objs.get("crd") is None:
|
440
|
+
chrome_path: Optional[str]
|
441
|
+
if self.opt_comp.chromium_path:
|
442
|
+
chrome_path = self.opt_comp.chromium_path
|
443
|
+
else:
|
444
|
+
chrome_path = CRD.get_chrome_path()
|
445
|
+
args = [
|
446
|
+
"--headless",
|
447
|
+
"--kiosk",
|
448
|
+
"--disable-extensions",
|
449
|
+
"--disable-infobars",
|
450
|
+
"--disable-gpu",
|
451
|
+
"--disable-gpu-rasterization",
|
452
|
+
"--hide-scrollbars",
|
453
|
+
"--force-device-scale-factor=1",
|
454
|
+
"about:blank",
|
455
|
+
]
|
456
|
+
if chrome_path is None:
|
457
|
+
raise RuntimeError("[F] Chrome/Chromium required for importing svg")
|
458
|
+
self.cb.put("[W] Importing SVG takes long time")
|
459
|
+
singletons.objs["crd"] = CRD(chrome_path, args=args)
|
460
|
+
singletons.objs["crd"].connect(-1) # type: ignore
|
461
|
+
|
462
|
+
crd = cast(CRD, singletons.objs["crd"])
|
458
463
|
if isinstance(self.in_f, bytes):
|
459
464
|
svg = self.in_f.decode()
|
460
465
|
else:
|
@@ -469,39 +474,35 @@ class StickerConvert:
|
|
469
474
|
svg_tag["height"] = height
|
470
475
|
svg = str(soup)
|
471
476
|
|
472
|
-
crd
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
self.frames_raw.append(np.asarray(crd.screenshot(clip).convert("RGBA")))
|
502
|
-
finally:
|
503
|
-
if crd is not None:
|
504
|
-
crd.close()
|
477
|
+
crd.open_html_str(svg)
|
478
|
+
crd.set_transparent_bg()
|
479
|
+
init_js = 'svg = document.getElementsByTagName("svg")[0];'
|
480
|
+
if self.codec_info_orig.fps > 0:
|
481
|
+
init_js += "svg.pauseAnimations();"
|
482
|
+
init_js += "JSON.stringify(svg.getBoundingClientRect());"
|
483
|
+
bound = json.loads(
|
484
|
+
json.loads(crd.exec_js(init_js))["result"]["result"]["value"]
|
485
|
+
)
|
486
|
+
clip = {
|
487
|
+
"x": bound["x"],
|
488
|
+
"y": bound["y"],
|
489
|
+
"width": width,
|
490
|
+
"height": height,
|
491
|
+
"scale": 1,
|
492
|
+
}
|
493
|
+
|
494
|
+
if self.codec_info_orig.fps > 0:
|
495
|
+
for i in range(self.codec_info_orig.frames):
|
496
|
+
curr_time = (
|
497
|
+
i
|
498
|
+
/ self.codec_info_orig.frames
|
499
|
+
* self.codec_info_orig.duration
|
500
|
+
/ 1000
|
501
|
+
)
|
502
|
+
crd.exec_js(f"svg.setCurrentTime({curr_time})")
|
503
|
+
self.frames_raw.append(np.asarray(crd.screenshot(clip)))
|
504
|
+
else:
|
505
|
+
self.frames_raw.append(np.asarray(crd.screenshot(clip)))
|
505
506
|
|
506
507
|
def _frames_import_pillow(self) -> None:
|
507
508
|
with Image.open(self.in_f) as im:
|
@@ -563,7 +564,7 @@ class StickerConvert:
|
|
563
564
|
container = cast(InputContainer, container)
|
564
565
|
context = container.streams.video[0].codec_context
|
565
566
|
if context.name == "vp8":
|
566
|
-
context =
|
567
|
+
context = CodecContext.create("libvpx", "r")
|
567
568
|
elif context.name == "vp9":
|
568
569
|
context = cast(
|
569
570
|
VideoCodecContext, CodecContext.create("libvpx-vp9", "r")
|
@@ -596,7 +597,12 @@ class StickerConvert:
|
|
596
597
|
else:
|
597
598
|
frame_resized = frame
|
598
599
|
|
599
|
-
|
600
|
+
# yuva420p may cause crash for pyav < 14
|
601
|
+
# Not safe to directly call frame.to_ndarray(format="rgba")
|
602
|
+
# https://github.com/PyAV-Org/PyAV/discussions/1510
|
603
|
+
if int(av.__version__.split(".")[0]) >= 14:
|
604
|
+
rgba_array = frame_resized.to_ndarray(format="rgba")
|
605
|
+
elif frame_resized.format.name == "yuv420p":
|
600
606
|
rgb_array = frame_resized.to_ndarray(format="rgb24")
|
601
607
|
rgba_array = np.dstack(
|
602
608
|
(
|
@@ -608,9 +614,6 @@ class StickerConvert:
|
|
608
614
|
)
|
609
615
|
)
|
610
616
|
else:
|
611
|
-
# yuva420p may cause crash
|
612
|
-
# Not safe to directly call frame.to_ndarray(format="rgba")
|
613
|
-
# https://github.com/laggykiller/sticker-convert/issues/114
|
614
617
|
frame_resized = frame_resized.reformat(
|
615
618
|
format="yuva420p",
|
616
619
|
dst_colorspace=1,
|
@@ -0,0 +1,110 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
from __future__ import annotations
|
3
|
+
|
4
|
+
import json
|
5
|
+
import zipfile
|
6
|
+
from io import BytesIO
|
7
|
+
from pathlib import Path
|
8
|
+
from typing import Any, Dict, Optional, Tuple
|
9
|
+
from urllib.parse import urlparse
|
10
|
+
|
11
|
+
import requests
|
12
|
+
|
13
|
+
from sticker_convert.downloaders.download_base import DownloadBase
|
14
|
+
from sticker_convert.job_option import CredOption, InputOption
|
15
|
+
from sticker_convert.utils.callback import CallbackProtocol, CallbackReturn
|
16
|
+
from sticker_convert.utils.files.metadata_handler import MetadataHandler
|
17
|
+
|
18
|
+
|
19
|
+
class DownloadBand(DownloadBase):
|
20
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
21
|
+
super().__init__(*args, **kwargs)
|
22
|
+
|
23
|
+
def decompress(self, zip_file: bytes) -> int:
|
24
|
+
with zipfile.ZipFile(BytesIO(zip_file)) as zf:
|
25
|
+
self.cb.put("Unzipping...")
|
26
|
+
|
27
|
+
zf_files = zf.namelist()
|
28
|
+
animated = [i for i in zf_files if "animation/" in i]
|
29
|
+
if len(animated) > 0:
|
30
|
+
pack_files = animated
|
31
|
+
else:
|
32
|
+
pack_files = [
|
33
|
+
i
|
34
|
+
for i in zf_files
|
35
|
+
if i.endswith(".meta") is False and "_key" not in i
|
36
|
+
]
|
37
|
+
|
38
|
+
self.cb.put(
|
39
|
+
(
|
40
|
+
"bar",
|
41
|
+
None,
|
42
|
+
{"set_progress_mode": "determinate", "steps": len(pack_files)},
|
43
|
+
)
|
44
|
+
)
|
45
|
+
|
46
|
+
for num, sticker in enumerate(pack_files):
|
47
|
+
data = zf.read(sticker)
|
48
|
+
self.cb.put(f"Read {sticker}")
|
49
|
+
ext = sticker.split(".")[-1]
|
50
|
+
|
51
|
+
out_path = Path(self.out_dir, str(num).zfill(3) + f".{ext}")
|
52
|
+
with open(out_path, "wb") as f:
|
53
|
+
f.write(data)
|
54
|
+
|
55
|
+
self.cb.put("update_bar")
|
56
|
+
|
57
|
+
return len(pack_files)
|
58
|
+
|
59
|
+
def get_metadata(self, pack_no: str) -> Optional[Dict[Any, Any]]:
|
60
|
+
r = requests.get(
|
61
|
+
f"https://sapi.band.us/v1.0.0/get_sticker_info?pack_no={pack_no}"
|
62
|
+
)
|
63
|
+
if r.text:
|
64
|
+
return json.loads(r.text)
|
65
|
+
else:
|
66
|
+
return None
|
67
|
+
|
68
|
+
def download_stickers_band(self) -> Tuple[int, int]:
|
69
|
+
if urlparse(self.url).netloc != "www.band.us" and self.url.isnumeric() is False:
|
70
|
+
self.cb.put("Download failed: Unsupported URL format")
|
71
|
+
return 0, 0
|
72
|
+
|
73
|
+
if self.url.isnumeric():
|
74
|
+
pack_no = self.url
|
75
|
+
else:
|
76
|
+
pack_no = urlparse(self.url).path.split("/")[-1]
|
77
|
+
metadata = self.get_metadata(pack_no)
|
78
|
+
if metadata:
|
79
|
+
self.title = metadata["result_data"]["sticker"]["name"]
|
80
|
+
else:
|
81
|
+
self.cb.put("Download failed: Failed to get metadata")
|
82
|
+
return 0, 0
|
83
|
+
|
84
|
+
MetadataHandler.set_metadata(self.out_dir, title=self.title)
|
85
|
+
|
86
|
+
pack_url = f"http://s.cmstatic.net/band/sticker/v2/{pack_no}/shop/pack"
|
87
|
+
zip_file = self.download_file(pack_url)
|
88
|
+
|
89
|
+
if zip_file:
|
90
|
+
self.cb.put(f"Downloaded {pack_url}")
|
91
|
+
else:
|
92
|
+
self.cb.put(f"Cannot download {pack_url}")
|
93
|
+
return 0, 0
|
94
|
+
|
95
|
+
pack_files_no = self.decompress(zip_file)
|
96
|
+
|
97
|
+
cover_url = f"http://s.cmstatic.net/band/sticker/v2/{pack_no}/shop/main"
|
98
|
+
self.download_file(cover_url, self.out_dir / "cover.png")
|
99
|
+
|
100
|
+
return pack_files_no, pack_files_no
|
101
|
+
|
102
|
+
@staticmethod
|
103
|
+
def start(
|
104
|
+
opt_input: InputOption,
|
105
|
+
opt_cred: Optional[CredOption],
|
106
|
+
cb: CallbackProtocol,
|
107
|
+
cb_return: CallbackReturn,
|
108
|
+
) -> Tuple[int, int]:
|
109
|
+
downloader = DownloadBand(opt_input, opt_cred, cb, cb_return)
|
110
|
+
return downloader.download_stickers_band()
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
4
4
|
import itertools
|
5
5
|
import json
|
6
6
|
from pathlib import Path
|
7
|
-
from typing import Any, List, Optional, Tuple
|
7
|
+
from typing import Any, Dict, List, Optional, Tuple
|
8
8
|
from urllib.parse import urlparse
|
9
9
|
|
10
10
|
import requests
|
@@ -17,6 +17,13 @@ from sticker_convert.utils.media.decrypt_kakao import DecryptKakao
|
|
17
17
|
|
18
18
|
|
19
19
|
class MetadataKakao:
|
20
|
+
@staticmethod
|
21
|
+
def share_link_to_public_link(share_link: str) -> str:
|
22
|
+
# Share link redirect to preview link if use desktop headers
|
23
|
+
headers_desktop = {"User-Agent": "Chrome"}
|
24
|
+
r = requests.get(share_link, headers=headers_desktop, allow_redirects=True)
|
25
|
+
return r.url
|
26
|
+
|
20
27
|
@staticmethod
|
21
28
|
def get_item_code_from_hash(hash: str, auth_token: str) -> Optional[str]:
|
22
29
|
headers = {
|
@@ -40,12 +47,14 @@ class MetadataKakao:
|
|
40
47
|
return item_code
|
41
48
|
|
42
49
|
@staticmethod
|
43
|
-
def
|
50
|
+
def get_item_code_from_search(
|
51
|
+
pack_title: str, search_term: str, by_author: bool, auth_token: str
|
52
|
+
) -> str:
|
44
53
|
headers = {
|
45
54
|
"Authorization": auth_token,
|
46
55
|
}
|
47
56
|
|
48
|
-
data = {"query":
|
57
|
+
data = {"query": search_term}
|
49
58
|
|
50
59
|
response = requests.post(
|
51
60
|
"https://talk-pilsner.kakao.com/emoticon/item_store/instant_search",
|
@@ -54,12 +63,53 @@ class MetadataKakao:
|
|
54
63
|
)
|
55
64
|
|
56
65
|
if response.status_code != 200:
|
57
|
-
return
|
66
|
+
return "auth_error"
|
67
|
+
|
68
|
+
def check_pack_match(pack_info: Dict[str, Any]) -> bool:
|
69
|
+
share_link = pack_info["itemMetaInfo"]["shareData"]["linkUrl"]
|
70
|
+
public_url = MetadataKakao.share_link_to_public_link(share_link)
|
71
|
+
if pack_title == urlparse(public_url).path.split("/")[-1]:
|
72
|
+
return True
|
73
|
+
return False
|
58
74
|
|
59
75
|
response_json = json.loads(response.text)
|
60
|
-
|
76
|
+
for emoticon in response_json["emoticons"]:
|
77
|
+
item_code = emoticon["item_code"]
|
78
|
+
pack_info = MetadataKakao.get_pack_info_authed(item_code, auth_token)
|
79
|
+
if pack_info is None:
|
80
|
+
continue
|
81
|
+
if check_pack_match(pack_info):
|
82
|
+
return item_code
|
83
|
+
if by_author:
|
84
|
+
cid = pack_info["itemMetaInfo"]["itemMetaData"]["cid"]
|
85
|
+
for item_code in MetadataKakao.get_items_by_creator(cid, auth_token):
|
86
|
+
pack_info = MetadataKakao.get_pack_info_authed(
|
87
|
+
item_code, auth_token
|
88
|
+
)
|
89
|
+
if pack_info is None:
|
90
|
+
continue
|
91
|
+
if check_pack_match(pack_info):
|
92
|
+
return item_code
|
61
93
|
|
62
|
-
return
|
94
|
+
return "code_not_found"
|
95
|
+
|
96
|
+
@staticmethod
|
97
|
+
def get_items_by_creator(cid: str, auth_token: str) -> List[str]:
|
98
|
+
headers = {"Authorization": auth_token}
|
99
|
+
|
100
|
+
params = {
|
101
|
+
"itemSort": "NEW",
|
102
|
+
"offset": "0",
|
103
|
+
"size": "30",
|
104
|
+
}
|
105
|
+
|
106
|
+
response = requests.get(
|
107
|
+
f"https://talk-pilsner.kakao.com/emoticon/api/store/v3/creators/{cid}",
|
108
|
+
headers=headers,
|
109
|
+
params=params,
|
110
|
+
)
|
111
|
+
|
112
|
+
return [i["item_id"] for i in json.loads(response.text)["items"]]
|
63
113
|
|
64
114
|
@staticmethod
|
65
115
|
def get_pack_info_unauthed(
|
@@ -119,13 +169,8 @@ class DownloadKakao(DownloadBase):
|
|
119
169
|
hash = urlparse(self.url).path.split("/")[-1]
|
120
170
|
item_code = MetadataKakao.get_item_code_from_hash(hash, self.auth_token)
|
121
171
|
|
122
|
-
|
123
|
-
|
124
|
-
headers_desktop = {"User-Agent": "Chrome"}
|
125
|
-
|
126
|
-
r = requests.get(self.url, headers=headers_desktop, allow_redirects=True)
|
127
|
-
|
128
|
-
self.pack_title = urlparse(r.url).path.split("/")[-1]
|
172
|
+
public_url = MetadataKakao.share_link_to_public_link(self.url)
|
173
|
+
self.pack_title = urlparse(public_url).path.split("/")[-1]
|
129
174
|
pack_info_unauthed = MetadataKakao.get_pack_info_unauthed(self.pack_title)
|
130
175
|
if pack_info_unauthed is None:
|
131
176
|
self.cb.put(
|
@@ -184,14 +229,33 @@ class DownloadKakao(DownloadBase):
|
|
184
229
|
thumbnail_urls = self.pack_info_unauthed["result"]["thumbnailUrls"]
|
185
230
|
|
186
231
|
if self.auth_token:
|
187
|
-
item_code = MetadataKakao.
|
188
|
-
title_ko, self.auth_token
|
232
|
+
item_code = MetadataKakao.get_item_code_from_search(
|
233
|
+
self.pack_title, title_ko, False, self.auth_token
|
189
234
|
)
|
190
|
-
if item_code:
|
235
|
+
if item_code == "auth_error":
|
236
|
+
msg = "Warning: Cannot get item code.\n"
|
237
|
+
msg += "Is auth_token invalid / expired? Try to regenerate it.\n"
|
238
|
+
msg += "Continue to download static stickers instead?"
|
239
|
+
elif item_code == "code_not_found":
|
240
|
+
self.cb.put(
|
241
|
+
"Cannot get item code, trying to search by author name, this may take long time..."
|
242
|
+
)
|
243
|
+
self.cb.put(
|
244
|
+
"Hint: Use share link instead to download more reliably"
|
245
|
+
)
|
246
|
+
if self.author is not None:
|
247
|
+
item_code = MetadataKakao.get_item_code_from_search(
|
248
|
+
self.pack_title, self.author, True, self.auth_token
|
249
|
+
)
|
250
|
+
if item_code == "code_not_found":
|
251
|
+
msg = "Warning: Cannot get item code.\n"
|
252
|
+
msg += "Please use share link instead.\n"
|
253
|
+
msg += "Continue to download static stickers instead?"
|
254
|
+
else:
|
255
|
+
return self.download_animated(item_code)
|
256
|
+
else:
|
191
257
|
return self.download_animated(item_code)
|
192
|
-
|
193
|
-
msg += "Is auth_token invalid / expired? Try to regenerate it.\n"
|
194
|
-
msg += "Continue to download static stickers instead?"
|
258
|
+
|
195
259
|
self.cb.put(("ask_bool", (msg,), None))
|
196
260
|
if self.cb_return:
|
197
261
|
response = self.cb_return.get_response()
|
@@ -249,9 +313,7 @@ class DownloadKakao(DownloadBase):
|
|
249
313
|
if not self.pack_info_unauthed:
|
250
314
|
public_url = None
|
251
315
|
if urlparse(self.url).netloc == "emoticon.kakao.com":
|
252
|
-
|
253
|
-
# Share url would redirect to public url without headers
|
254
|
-
public_url = r.url
|
316
|
+
public_url = MetadataKakao.share_link_to_public_link(self.url)
|
255
317
|
elif urlparse(self.url).netloc == "e.kakao.com":
|
256
318
|
public_url = self.url
|
257
319
|
if public_url:
|
sticker_convert/gui.py
CHANGED
@@ -714,9 +714,9 @@ class GUI(Window):
|
|
714
714
|
set_progress_mode, steps, update_bar, *args, **kwargs
|
715
715
|
)
|
716
716
|
|
717
|
-
def highlight_fields(self):
|
717
|
+
def highlight_fields(self) -> bool:
|
718
718
|
if not self.init_done:
|
719
|
-
return
|
719
|
+
return True
|
720
720
|
|
721
721
|
input_option = self.get_input_name()
|
722
722
|
input_option_display = self.get_input_display_name()
|
@@ -762,7 +762,8 @@ class GUI(Window):
|
|
762
762
|
download_option is None
|
763
763
|
or input_option.startswith(download_option) is False
|
764
764
|
and not (
|
765
|
-
input_option
|
765
|
+
input_option
|
766
|
+
in ("kakao", "band", "line", "discord", "discord_emoji")
|
766
767
|
and url.isnumeric()
|
767
768
|
)
|
768
769
|
):
|
@@ -866,3 +867,5 @@ class GUI(Window):
|
|
866
867
|
else:
|
867
868
|
self.comp_frame.comp_preset_opt.config(bootstyle="secondary") # type: ignore
|
868
869
|
self.output_frame.output_option_opt.config(bootstyle="secondary") # type: ignore
|
870
|
+
|
871
|
+
return True
|
@@ -11,7 +11,7 @@ from sticker_convert.utils.auth.get_discord_auth import GetDiscordAuth
|
|
11
11
|
|
12
12
|
|
13
13
|
class DiscordGetAuthWindow(BaseWindow):
|
14
|
-
def __init__(self, *args: Any, **kwargs: Any):
|
14
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
15
15
|
super(DiscordGetAuthWindow, self).__init__(*args, **kwargs)
|
16
16
|
|
17
17
|
self.title("Get Discord token")
|
@@ -64,10 +64,10 @@ class DiscordGetAuthWindow(BaseWindow):
|
|
64
64
|
|
65
65
|
GUIUtils.finalize_window(self)
|
66
66
|
|
67
|
-
def cb_login(self):
|
67
|
+
def cb_login(self) -> None:
|
68
68
|
Thread(target=self.cb_login_thread, daemon=True).start()
|
69
69
|
|
70
|
-
def cb_login_thread(self, *args: Any):
|
70
|
+
def cb_login_thread(self, *args: Any) -> None:
|
71
71
|
m = GetDiscordAuth(cb_msg=self.gui.cb_msg)
|
72
72
|
discord_token, msg = m.get_cred()
|
73
73
|
if discord_token:
|
@@ -11,7 +11,7 @@ from sticker_convert.utils.auth.get_signal_auth import GetSignalAuth
|
|
11
11
|
|
12
12
|
|
13
13
|
class SignalGetAuthWindow(BaseWindow):
|
14
|
-
def __init__(self, *args: Any, **kwargs: Any):
|
14
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
15
15
|
super(SignalGetAuthWindow, self).__init__(*args, **kwargs)
|
16
16
|
|
17
17
|
self.title("Get Signal uuid and password")
|
@@ -64,10 +64,10 @@ class SignalGetAuthWindow(BaseWindow):
|
|
64
64
|
|
65
65
|
GUIUtils.finalize_window(self)
|
66
66
|
|
67
|
-
def cb_login(self):
|
67
|
+
def cb_login(self) -> None:
|
68
68
|
Thread(target=self.cb_login_thread, daemon=True).start()
|
69
69
|
|
70
|
-
def cb_login_thread(self, *args: Any):
|
70
|
+
def cb_login_thread(self, *args: Any) -> None:
|
71
71
|
m = GetSignalAuth(cb_msg=self.gui.cb_msg, cb_ask_str=self.cb_ask_str_signal)
|
72
72
|
|
73
73
|
uuid, password = m.get_cred()
|
@@ -109,7 +109,7 @@ class ViberGetAuthWindow(BaseWindow):
|
|
109
109
|
|
110
110
|
GUIUtils.finalize_window(self)
|
111
111
|
|
112
|
-
def cb_get_cred(self):
|
112
|
+
def cb_get_cred(self) -> None:
|
113
113
|
Thread(target=self.cb_get_cred_thread, daemon=True).start()
|
114
114
|
|
115
115
|
def cb_get_cred_thread(self) -> None:
|
sticker_convert/job.py
CHANGED
@@ -12,6 +12,7 @@ from typing import Any, Callable, Dict, List, Optional, Tuple
|
|
12
12
|
from urllib.parse import urlparse
|
13
13
|
|
14
14
|
from sticker_convert.converter import StickerConvert
|
15
|
+
from sticker_convert.downloaders.download_band import DownloadBand
|
15
16
|
from sticker_convert.downloaders.download_discord import DownloadDiscord
|
16
17
|
from sticker_convert.downloaders.download_kakao import DownloadKakao
|
17
18
|
from sticker_convert.downloaders.download_line import DownloadLine
|
@@ -28,6 +29,7 @@ from sticker_convert.utils.callback import CallbackReturn, CbQueueType, ResultsL
|
|
28
29
|
from sticker_convert.utils.files.json_resources_loader import OUTPUT_JSON
|
29
30
|
from sticker_convert.utils.files.metadata_handler import MetadataHandler
|
30
31
|
from sticker_convert.utils.media.codec_info import CodecInfo
|
32
|
+
from sticker_convert.utils.singletons import singletons
|
31
33
|
|
32
34
|
|
33
35
|
class Executor:
|
@@ -136,6 +138,7 @@ class Executor:
|
|
136
138
|
|
137
139
|
work_queue.put(None)
|
138
140
|
cb_queue.put("__PROCESS_DONE__")
|
141
|
+
singletons.close()
|
139
142
|
|
140
143
|
def start_workers(self, processes: int = 1) -> None:
|
141
144
|
self.cb_thread_instance = Thread(
|
@@ -564,6 +567,9 @@ class Job:
|
|
564
567
|
if self.opt_input.option == "kakao":
|
565
568
|
downloaders.append(DownloadKakao.start)
|
566
569
|
|
570
|
+
if self.opt_input.option == "band":
|
571
|
+
downloaders.append(DownloadBand.start)
|
572
|
+
|
567
573
|
if self.opt_input.option == "viber":
|
568
574
|
downloaders.append(DownloadViber.start)
|
569
575
|
|
@@ -328,6 +328,53 @@
|
|
328
328
|
"quantize_method": "imagequant",
|
329
329
|
"default_emoji": "😀"
|
330
330
|
},
|
331
|
+
"band": {
|
332
|
+
"size_max": {
|
333
|
+
"img": 0,
|
334
|
+
"vid": 0
|
335
|
+
},
|
336
|
+
"format": {
|
337
|
+
"img": ".png",
|
338
|
+
"vid": ".png"
|
339
|
+
},
|
340
|
+
"fps": {
|
341
|
+
"min": 1,
|
342
|
+
"max": 30,
|
343
|
+
"power": -0.5
|
344
|
+
},
|
345
|
+
"res": {
|
346
|
+
"w": {
|
347
|
+
"min": 100,
|
348
|
+
"max": 370
|
349
|
+
},
|
350
|
+
"h": {
|
351
|
+
"min": 100,
|
352
|
+
"max": 320
|
353
|
+
},
|
354
|
+
"power": 3
|
355
|
+
},
|
356
|
+
"quality": {
|
357
|
+
"min": 10,
|
358
|
+
"max": 95,
|
359
|
+
"power": 5
|
360
|
+
},
|
361
|
+
"color": {
|
362
|
+
"min": 32,
|
363
|
+
"max": 257,
|
364
|
+
"power": 3
|
365
|
+
},
|
366
|
+
"duration": {
|
367
|
+
"min": 83,
|
368
|
+
"max": 4000
|
369
|
+
},
|
370
|
+
"padding_percent": 0,
|
371
|
+
"bg_color": "",
|
372
|
+
"steps": 16,
|
373
|
+
"fake_vid": false,
|
374
|
+
"scale_filter": "bicubic",
|
375
|
+
"quantize_method": "imagequant",
|
376
|
+
"default_emoji": "😀"
|
377
|
+
},
|
331
378
|
"viber": {
|
332
379
|
"size_max": {
|
333
380
|
"img": 0,
|
@@ -59,6 +59,16 @@
|
|
59
59
|
"author": true
|
60
60
|
}
|
61
61
|
},
|
62
|
+
"band": {
|
63
|
+
"full_name": "Download from Naver Band",
|
64
|
+
"help": "Download Naver Band stickers from a URL / ID as input",
|
65
|
+
"example": "Example: https://www.band.us/sticker/xxxx OR 2535",
|
66
|
+
"address_lbls": "URL address / ID",
|
67
|
+
"metadata_provides": {
|
68
|
+
"title": true,
|
69
|
+
"author": false
|
70
|
+
}
|
71
|
+
},
|
62
72
|
"viber": {
|
63
73
|
"full_name": "Download from Viber",
|
64
74
|
"help": "Download viber stickers from a URL as input",
|
@@ -13,7 +13,7 @@ from sticker_convert.utils.process import killall
|
|
13
13
|
|
14
14
|
|
15
15
|
class GetDiscordAuth:
|
16
|
-
def __init__(self, cb_msg: Callable[..., None] = print):
|
16
|
+
def __init__(self, cb_msg: Callable[..., None] = print) -> None:
|
17
17
|
chromedriver_download_dir = CONFIG_DIR / "bin"
|
18
18
|
os.makedirs(chromedriver_download_dir, exist_ok=True)
|
19
19
|
|
@@ -28,10 +28,10 @@ MSG_PERMISSION_ERROR = "Failed to read Kakao process memory"
|
|
28
28
|
|
29
29
|
|
30
30
|
class GetKakaoDesktopAuth:
|
31
|
-
def __init__(self, cb_ask_str: Callable[..., str] = input):
|
31
|
+
def __init__(self, cb_ask_str: Callable[..., str] = input) -> None:
|
32
32
|
self.cb_ask_str = cb_ask_str
|
33
33
|
|
34
|
-
def launch_kakao(self, kakao_bin_path: str):
|
34
|
+
def launch_kakao(self, kakao_bin_path: str) -> None:
|
35
35
|
if platform.system() == "Windows":
|
36
36
|
subprocess.Popen([kakao_bin_path])
|
37
37
|
elif platform.system() == "Darwin":
|
@@ -17,7 +17,7 @@ class GetSignalAuth:
|
|
17
17
|
self,
|
18
18
|
cb_msg: Callable[..., None] = print,
|
19
19
|
cb_ask_str: Callable[..., str] = input,
|
20
|
-
):
|
20
|
+
) -> None:
|
21
21
|
chromedriver_download_dir = CONFIG_DIR / "bin"
|
22
22
|
os.makedirs(chromedriver_download_dir, exist_ok=True)
|
23
23
|
|
@@ -26,7 +26,7 @@ class GetSignalAuth:
|
|
26
26
|
self.cb_ask_str = cb_ask_str
|
27
27
|
self.cb_msg = cb_msg
|
28
28
|
|
29
|
-
def download_signal_desktop(self):
|
29
|
+
def download_signal_desktop(self) -> None:
|
30
30
|
download_url = "https://signal.org/en/download/"
|
31
31
|
|
32
32
|
webbrowser.open(download_url)
|
@@ -28,7 +28,7 @@ MSG_PERMISSION_ERROR = "Failed to read Viber process memory"
|
|
28
28
|
|
29
29
|
|
30
30
|
class GetViberAuth:
|
31
|
-
def __init__(self, cb_ask_str: Callable[..., str] = input):
|
31
|
+
def __init__(self, cb_ask_str: Callable[..., str] = input) -> None:
|
32
32
|
self.cb_ask_str = cb_ask_str
|
33
33
|
|
34
34
|
def relaunch_viber(self, viber_bin_path: str) -> Optional[int]:
|
@@ -22,7 +22,9 @@ Continue when done"""
|
|
22
22
|
|
23
23
|
|
24
24
|
class TelethonSetup:
|
25
|
-
def __init__(
|
25
|
+
def __init__(
|
26
|
+
self, opt_cred: CredOption, cb_ask_str: Callable[..., str] = input
|
27
|
+
) -> None:
|
26
28
|
self.cb_ask_str = cb_ask_str
|
27
29
|
self.opt_cred = opt_cred
|
28
30
|
|
@@ -5,12 +5,12 @@ import json
|
|
5
5
|
import os
|
6
6
|
import platform
|
7
7
|
import shutil
|
8
|
+
import signal
|
8
9
|
import socket
|
9
10
|
import subprocess
|
10
11
|
import time
|
11
12
|
from typing import Any, Dict, List, Optional, Tuple, Union, cast
|
12
13
|
|
13
|
-
import browsers # type: ignore
|
14
14
|
import requests
|
15
15
|
import websocket
|
16
16
|
from PIL import Image
|
@@ -50,7 +50,7 @@ class CRD:
|
|
50
50
|
chrome_bin: str,
|
51
51
|
port: Optional[int] = None,
|
52
52
|
args: Optional[List[str]] = None,
|
53
|
-
):
|
53
|
+
) -> None:
|
54
54
|
if port is None:
|
55
55
|
port = get_free_port()
|
56
56
|
self.port = port
|
@@ -84,6 +84,14 @@ class CRD:
|
|
84
84
|
|
85
85
|
@staticmethod
|
86
86
|
def get_chrome_path() -> Optional[str]:
|
87
|
+
import logging
|
88
|
+
|
89
|
+
import browsers # type: ignore
|
90
|
+
|
91
|
+
# browsers module would turn on info logging
|
92
|
+
logger = logging.getLogger()
|
93
|
+
logger.setLevel(logging.CRITICAL)
|
94
|
+
|
87
95
|
bs: List[Tuple[int, str]] = []
|
88
96
|
for b in browsers.browsers():
|
89
97
|
browser_type = b["browser_type"]
|
@@ -98,7 +106,7 @@ class CRD:
|
|
98
106
|
bs = sorted(bs, key=lambda x: x[0])
|
99
107
|
return bs[0][1]
|
100
108
|
|
101
|
-
def connect(self, target_id: int = 0):
|
109
|
+
def connect(self, target_id: int = 0) -> None:
|
102
110
|
self.cmd_id = 1
|
103
111
|
r = None
|
104
112
|
targets: List[Any] = []
|
@@ -137,7 +145,7 @@ class CRD:
|
|
137
145
|
|
138
146
|
raise RuntimeError("Websocket keep disconnecting")
|
139
147
|
|
140
|
-
def exec_js(self, js: str, context_id: Optional[int] = None):
|
148
|
+
def exec_js(self, js: str, context_id: Optional[int] = None) -> Union[str, bytes]:
|
141
149
|
command: Dict[str, Any] = {
|
142
150
|
"id": self.cmd_id,
|
143
151
|
"method": "Runtime.evaluate",
|
@@ -155,11 +163,11 @@ class CRD:
|
|
155
163
|
}
|
156
164
|
return self.send_cmd(command)
|
157
165
|
|
158
|
-
def screenshot(self, clip: Optional[Dict[str, int]] = None):
|
166
|
+
def screenshot(self, clip: Optional[Dict[str, int]] = None) -> Image.Image:
|
159
167
|
command: Dict[str, Any] = {
|
160
168
|
"id": self.cmd_id,
|
161
169
|
"method": "Page.captureScreenshot",
|
162
|
-
"params": {},
|
170
|
+
"params": {"captureBeyondViewport": True, "optimizeForSpeed": True},
|
163
171
|
}
|
164
172
|
if clip:
|
165
173
|
command["params"]["clip"] = clip
|
@@ -174,11 +182,11 @@ class CRD:
|
|
174
182
|
str, json.loads(r).get("result", {}).get("result", {}).get("value", "")
|
175
183
|
)
|
176
184
|
|
177
|
-
def navigate(self, url: str):
|
185
|
+
def navigate(self, url: str) -> None:
|
178
186
|
command = {"id": self.cmd_id, "method": "Page.navigate", "params": {"url": url}}
|
179
187
|
self.send_cmd(command)
|
180
188
|
|
181
|
-
def open_html_str(self, html: str):
|
189
|
+
def open_html_str(self, html: str) -> None:
|
182
190
|
command: Dict[str, Any] = {
|
183
191
|
"id": self.cmd_id,
|
184
192
|
"method": "Page.navigate",
|
@@ -198,24 +206,28 @@ class CRD:
|
|
198
206
|
}
|
199
207
|
self.send_cmd(command)
|
200
208
|
|
201
|
-
def runtime_enable(self):
|
209
|
+
def runtime_enable(self) -> None:
|
202
210
|
command = {
|
203
211
|
"method": "Runtime.enable",
|
204
212
|
}
|
205
213
|
self.send_cmd(command)
|
206
214
|
|
207
|
-
def runtime_disable(self):
|
215
|
+
def runtime_disable(self) -> None:
|
208
216
|
command = {
|
209
217
|
"method": "Runtime.disable",
|
210
218
|
}
|
211
219
|
self.send_cmd(command)
|
212
220
|
|
213
|
-
def reload(self):
|
221
|
+
def reload(self) -> None:
|
214
222
|
command = {
|
215
223
|
"method": "Page.reload",
|
216
224
|
}
|
217
225
|
self.send_cmd(command)
|
218
226
|
|
219
|
-
def close(self):
|
227
|
+
def close(self) -> None:
|
228
|
+
command = {
|
229
|
+
"method": "Browser.close",
|
230
|
+
}
|
231
|
+
self.send_cmd(command)
|
220
232
|
self.ws.close()
|
221
|
-
self.chrome_proc.
|
233
|
+
os.kill(self.chrome_proc.pid, signal.SIGTERM)
|
@@ -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()
|
sticker_convert/version.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: sticker-convert
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.13.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,7 +366,7 @@ 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
|
369
|
+
Requires-Dist: av>=13.1.0
|
370
370
|
Requires-Dist: beautifulsoup4~=4.13.3
|
371
371
|
Requires-Dist: cryptg~=0.5.0.post0
|
372
372
|
Requires-Dist: rookiepy~=0.5.6
|
@@ -375,8 +375,8 @@ 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
|
379
|
-
Requires-Dist: pybrowsers~=0.
|
378
|
+
Requires-Dist: Pillow~=11.2.1
|
379
|
+
Requires-Dist: pybrowsers~=0.8.0
|
380
380
|
Requires-Dist: pyoxipng~=9.1.0
|
381
381
|
Requires-Dist: python-telegram-bot~=22.0
|
382
382
|
Requires-Dist: psutil~=7.0.0
|
@@ -397,7 +397,7 @@ Dynamic: license-file
|
|
397
397
|
|
398
398
|
- A python script for creating, downloading, converting+compressing and uploading stickers from multiple instant messaging applications.
|
399
399
|
- 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)
|
400
|
+
- 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
401
|
- Supports static and animated stickers, with transparency support
|
402
402
|
|
403
403
|
## Downloads
|
@@ -438,6 +438,7 @@ Dynamic: license-file
|
|
438
438
|
| [WhatsApp](docs/guide_whatsapp.md) | ⭕ (By Android or WhatsApp Web) | ⭕ (Create `.wastickers`, import by Sticker Maker) |
|
439
439
|
| [Line](docs/guide_line.md) | ✅ | 🚫 (Need to submit for manual approval) |
|
440
440
|
| [Kakao](docs/guide_kakao.md) | ✅ (Need 'auth_token' for animated) | 🚫 (Need to submit for manual approval) |
|
441
|
+
| [Band](docs/guide_band.md) | ✅ | 🚫 (Need to submit for manual approval) |
|
441
442
|
| [Viber](docs/guide_viber.md) | ✅ | ✅ (Require `viber_auth`) |
|
442
443
|
| [Discord](docs/guide_discord.md) | ✅ (Require `token`) | 🚫 |
|
443
444
|
| [iMessage](docs/guide_imessage.md) | 🚫 | ⭕ (Create Xcode stickerpack project for sideload) |
|
@@ -464,6 +465,9 @@ Dynamic: license-file
|
|
464
465
|
- Kakao
|
465
466
|
- 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
467
|
- Upload: Not supported. You need to manually submit sticker pack for approval before you can use in app.
|
468
|
+
- Band
|
469
|
+
- 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)
|
470
|
+
- Upload: Not supported. You need to manually submit sticker pack for approval before you can use in app.
|
467
471
|
- Viber
|
468
472
|
- Download: Supported (e.g. `https://stickers.viber.com/pages/example` OR `https://stickers.viber.com/pages/custom-sticker-packs/example`)
|
469
473
|
- Upload: Supported. Viber authentication data required for uploading Viber stickers, which could be fetched from Viber Desktop application automatically.
|
@@ -490,30 +494,27 @@ Dynamic: license-file
|
|
490
494
|
To run in CLI mode, pass on any arguments
|
491
495
|
|
492
496
|
```
|
493
|
-
usage: sticker-convert.py [-h] [--version] [--no-confirm] [--no-progress] [--custom-presets CUSTOM_PRESETS]
|
494
|
-
[--
|
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]
|
497
|
+
usage: sticker-convert.py [-h] [--version] [--no-confirm] [--no-progress] [--custom-presets CUSTOM_PRESETS] [--input-dir INPUT_DIR]
|
498
|
+
[--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
499
|
[--output-dir OUTPUT_DIR] [--author AUTHOR] [--title TITLE]
|
497
500
|
[--export-signal | --export-telegram | --export-telegram-emoji | --export-telegram-telethon | --export-telegram-emoji-telethon | --export-viber | --export-whatsapp | --export-imessage]
|
498
501
|
[--no-compress]
|
499
502
|
[--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
|
-
[--
|
502
|
-
[--res-
|
503
|
-
[--quality-min
|
504
|
-
[--color-min COLOR_MIN] [--color-max COLOR_MAX] [--color-power COLOR_POWER]
|
503
|
+
[--steps STEPS] [--processes PROCESSES] [--fps-min FPS_MIN] [--fps-max FPS_MAX] [--fps-power FPS_POWER]
|
504
|
+
[--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]
|
505
|
+
[--res-h-max RES_H_MAX] [--res-power RES_POWER] [--quality-min QUALITY_MIN] [--quality-max QUALITY_MAX]
|
506
|
+
[--quality-power QUALITY_POWER] [--color-min COLOR_MIN] [--color-max COLOR_MAX] [--color-power COLOR_POWER]
|
505
507
|
[--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
|
-
[--
|
508
|
-
[--
|
509
|
-
[--signal-
|
510
|
-
[--telegram-
|
511
|
-
[--kakao-auth-
|
512
|
-
[--kakao-bin-path KAKAO_BIN_PATH] [--kakao-username KAKAO_USERNAME]
|
508
|
+
[--bg-color BG_COLOR] [--vid-size-max VID_SIZE_MAX] [--img-size-max IMG_SIZE_MAX] [--vid-format VID_FORMAT]
|
509
|
+
[--img-format IMG_FORMAT] [--fake-vid] [--scale-filter SCALE_FILTER] [--quantize-method QUANTIZE_METHOD]
|
510
|
+
[--cache-dir CACHE_DIR] [--chromium-path CHROMIUM_PATH] [--default-emoji DEFAULT_EMOJI] [--signal-uuid SIGNAL_UUID]
|
511
|
+
[--signal-password SIGNAL_PASSWORD] [--signal-get-auth] [--telegram-token TELEGRAM_TOKEN]
|
512
|
+
[--telegram-userid TELEGRAM_USERID] [--telethon-setup] [--kakao-auth-token KAKAO_AUTH_TOKEN] [--kakao-get-auth]
|
513
|
+
[--kakao-get-auth-desktop] [--kakao-bin-path KAKAO_BIN_PATH] [--kakao-username KAKAO_USERNAME]
|
513
514
|
[--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-
|
516
|
-
[--discord-
|
515
|
+
[--kakao-phone-number KAKAO_PHONE_NUMBER] [--line-get-auth] [--line-cookies LINE_COOKIES] [--viber-auth VIBER_AUTH]
|
516
|
+
[--viber-get-auth VIBER_GET_AUTH] [--viber-bin-path VIBER_BIN_PATH] [--discord-get-auth]
|
517
|
+
[--discord-token DISCORD_TOKEN] [--save-cred]
|
517
518
|
|
518
519
|
CLI for stickers-convert
|
519
520
|
|
@@ -552,6 +553,9 @@ Input options:
|
|
552
553
|
Download kakao stickers from a URL / ID as input
|
553
554
|
(Example: https://e.kakao.com/t/xxxxx
|
554
555
|
OR https://emoticon.kakao.com/items/xxxxx OR 4404400)
|
556
|
+
--download-band DOWNLOAD_BAND
|
557
|
+
Download Naver Band stickers from a URL / ID as input
|
558
|
+
(Example: https://www.band.us/sticker/xxxx OR 2535)
|
555
559
|
--download-viber DOWNLOAD_VIBER
|
556
560
|
Download viber stickers from a URL as input
|
557
561
|
(Example: https://stickers.viber.com/pages/example
|
@@ -659,6 +663,10 @@ Compression options:
|
|
659
663
|
--cache-dir CACHE_DIR
|
660
664
|
Set custom cache directory.
|
661
665
|
Useful for debugging, or speed up conversion if cache_dir is on RAM disk.
|
666
|
+
--chromium-path CHROMIUM_PATH
|
667
|
+
Set Chromium(-based)/Chrome browser path.
|
668
|
+
Required for converting from SVG files.
|
669
|
+
Leave blank to auto detect
|
662
670
|
--default-emoji DEFAULT_EMOJI
|
663
671
|
Set the default emoji for uploading Signal and Telegram sticker packs.
|
664
672
|
|
@@ -885,5 +893,5 @@ See [docs/TODO.md](docs/TODO.md)
|
|
885
893
|
- Banner generated from [GitHub Socialify](https://socialify.git.ci/)
|
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.
|
@@ -1,16 +1,17 @@
|
|
1
1
|
sticker_convert/__init__.py,sha256=iQnv6UOOA69c3soAn7ZOnAIubTIQSUxtq1Uhh8xRWvU,102
|
2
2
|
sticker_convert/__main__.py,sha256=elDCMvU27letiYs8jPUpxaCq5puURnvcDuqGsAAb6_w,592
|
3
|
-
sticker_convert/cli.py,sha256=
|
4
|
-
sticker_convert/converter.py,sha256=
|
3
|
+
sticker_convert/cli.py,sha256=2mTp9h9I3sIBpEftfZvPr0vfjaqdvuHD5yFngLi5MwY,22473
|
4
|
+
sticker_convert/converter.py,sha256=BWg42NaRRDxXxo74L5Rh0l2BDkpe2Bh948Trypeg2vA,39758
|
5
5
|
sticker_convert/definitions.py,sha256=BqROmOvqIqw8ANaqZXIxJAXGD0HgjAvCfFouQ4SaWHc,2254
|
6
|
-
sticker_convert/gui.py,sha256=
|
7
|
-
sticker_convert/job.py,sha256=
|
6
|
+
sticker_convert/gui.py,sha256=bd8rMgFaXrn41y6aOHNlD6gPBDleDmiHMsGMZNfz1jk,34239
|
7
|
+
sticker_convert/job.py,sha256=FJiaJEcfMr8GnNfPC3SDcpTs7ytoiAZk6cxUbzsw9IE,28257
|
8
8
|
sticker_convert/job_option.py,sha256=yI_uKWJEAul2XTC6pucz9PfW0iNwwOr0aVC-PAHkMA4,8109
|
9
|
-
sticker_convert/version.py,sha256=
|
9
|
+
sticker_convert/version.py,sha256=bJKod-cGHYLxNjnXLfxixQN8STyD8kVf2ApImRquwfM,47
|
10
10
|
sticker_convert/downloaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
|
+
sticker_convert/downloaders/download_band.py,sha256=JPjwwdxbMXPBM9TXF76wT9mtoDCLssYnrm1iS2C6uVM,3629
|
11
12
|
sticker_convert/downloaders/download_base.py,sha256=MI5pCT_tkfoaFlrD1oNynDj1Rv1CK0APuNVElTEAEis,5110
|
12
13
|
sticker_convert/downloaders/download_discord.py,sha256=6AFpLAYL2hRvVcsqUtzDUC31U66U02ZcnKXDnZRi2jk,3496
|
13
|
-
sticker_convert/downloaders/download_kakao.py,sha256
|
14
|
+
sticker_convert/downloaders/download_kakao.py,sha256=lRmpEcYjHizIRM0uFBDvjMqNEpur0VmOTKAmiir9eB0,15181
|
14
15
|
sticker_convert/downloaders/download_line.py,sha256=c-hTzEarGQP0b-pnPl29NuSKcaZWUeRo_94YpJzz72M,17911
|
15
16
|
sticker_convert/downloaders/download_signal.py,sha256=3wv-BLd4qggly4AdtwV8f3vUpCVZ-8GnoPLoWngY3Pk,3728
|
16
17
|
sticker_convert/downloaders/download_telegram.py,sha256=iGmOcVjU2Ai19t1lyDY2JhQIc--O5XMyNCGXZAA4DVY,2028
|
@@ -29,11 +30,11 @@ sticker_convert/gui_components/frames/right_clicker.py,sha256=dGIvSzEChrkguR80pz
|
|
29
30
|
sticker_convert/gui_components/windows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
30
31
|
sticker_convert/gui_components/windows/advanced_compression_window.py,sha256=djJNyPodBmNhW0vHvdg6xAd7LYkVm9UINMHrRXVmr_k,32718
|
31
32
|
sticker_convert/gui_components/windows/base_window.py,sha256=xBE1peGMPvWsdrFej0CJUVhmQ57GJGvz-cX03nIIhkE,1108
|
32
|
-
sticker_convert/gui_components/windows/discord_get_auth_window.py,sha256=
|
33
|
+
sticker_convert/gui_components/windows/discord_get_auth_window.py,sha256=a9ptBqtpZslQJ87-ZPotcT6gigouIHWAFijfkWv2rZQ,2786
|
33
34
|
sticker_convert/gui_components/windows/kakao_get_auth_window.py,sha256=1nawn_D4wkziW_lROjUJlmVtITAuGt_4uruGMcEr7Oo,11128
|
34
35
|
sticker_convert/gui_components/windows/line_get_auth_window.py,sha256=S4ES_lk2-GDvPokZtYALnUc5zW1VbS4WulNqO9K1aSs,3375
|
35
|
-
sticker_convert/gui_components/windows/signal_get_auth_window.py,sha256=
|
36
|
-
sticker_convert/gui_components/windows/viber_get_auth_window.py,sha256=
|
36
|
+
sticker_convert/gui_components/windows/signal_get_auth_window.py,sha256=d9vWMfrD0s-qI-TmB0796LRvDW64Jh2wmA1mZcRubUw,3126
|
37
|
+
sticker_convert/gui_components/windows/viber_get_auth_window.py,sha256=8EGNohkBZjmTJ_0Rt4XP0zVd1eLraqukNoE84E9d5CA,5191
|
37
38
|
sticker_convert/ios-message-stickers-template/.gitignore,sha256=4uuTph_9eHfqXHUavLOmGOji6aIHOif2bUEU_hCBn4Y,9
|
38
39
|
sticker_convert/ios-message-stickers-template/README.md,sha256=oN0FvJkCWWjSZ3PMrCvY3T1zCsdkZYFgGHAoFh0Kmt8,467
|
39
40
|
sticker_convert/ios-message-stickers-template/.github/FUNDING.yml,sha256=3LlmdSAGDsBA2o_C1iBYTNLwkABnyZuN0zxgPPyd-f8,70
|
@@ -70,11 +71,11 @@ sticker_convert/resources/NotoColorEmoji.ttf,sha256=LurIVaCIA8bSCfjrdO1feYr0bhKL
|
|
70
71
|
sticker_convert/resources/appicon.icns,sha256=FB2DVTOQcFfQNZ9RcyG3z9c9k7eOiI1qw0IJhXMRFg4,5404
|
71
72
|
sticker_convert/resources/appicon.ico,sha256=-ldugcl2Yq2pBRTktnhGKWInpKyWzRjCiPvMr3XPTlc,38078
|
72
73
|
sticker_convert/resources/appicon.png,sha256=6XBEQz7PnerqS43aRkwpWolFG4WvKMuQ-st1ly-_JPg,5265
|
73
|
-
sticker_convert/resources/compression.json,sha256=
|
74
|
+
sticker_convert/resources/compression.json,sha256=wEgtjcDyLEYup53s-SCGu2Wc3UdReWeSj9POWn5PXkk,15184
|
74
75
|
sticker_convert/resources/emoji.json,sha256=q9DRFdVJfm7feZW7ZM6Xa5P1QsMvrn0PbBVU9jKcJKI,422720
|
75
76
|
sticker_convert/resources/help.json,sha256=IDJhDD5plY8_Ze5gnM6rMs6H1-urWo94sEHeGzO5QeU,7364
|
76
|
-
sticker_convert/resources/input.json,sha256=
|
77
|
-
sticker_convert/resources/memdump_linux.sh,sha256=
|
77
|
+
sticker_convert/resources/input.json,sha256=vLP8pVo4Mfh-yLRjy5j1x4SMR1dQC9xCRzQ6RWN_t2E,4213
|
78
|
+
sticker_convert/resources/memdump_linux.sh,sha256=SFKXiE0ztZyGvpFYPOrdQ0wmY3ndgJuqfiofC7BQon0,625
|
78
79
|
sticker_convert/resources/memdump_windows.ps1,sha256=CfyNSSEW3HJOkTu-mKrP3qh5aprN-1VCBfj-R1fELA0,302
|
79
80
|
sticker_convert/resources/output.json,sha256=SC_3vtEBJ79R7q0vy_p33eLsGFEyBsSOai0Hy7mLqG8,2208
|
80
81
|
sticker_convert/uploaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -85,18 +86,19 @@ sticker_convert/uploaders/upload_telegram.py,sha256=WlUyLJlW83XZz6RhA76jHMXA6TNU
|
|
85
86
|
sticker_convert/uploaders/upload_viber.py,sha256=_vOK0UgP7V7ZeFG6pR3sVf3A744Q6J19qzO-2hDvt5w,6583
|
86
87
|
sticker_convert/uploaders/xcode_imessage.py,sha256=iTTT8gDYOTNkKqXeSWUBuWfxu7xeE418t2Z1YQFR5L0,11365
|
87
88
|
sticker_convert/utils/callback.py,sha256=spYUGlklOs1yPZAxoqwOWgR1sdimpfM8a27if3TaVYk,6155
|
88
|
-
sticker_convert/utils/chrome_remotedebug.py,sha256=
|
89
|
+
sticker_convert/utils/chrome_remotedebug.py,sha256=p8D85NDlLiS7Vj2wLLZX7TN6hENe2p5PxVDoeOr_mTE,6902
|
89
90
|
sticker_convert/utils/emoji.py,sha256=AqB26JY-PkYzNwPLReSnqLiQKe-bR9UXnLclAbgubJ8,367
|
90
91
|
sticker_convert/utils/process.py,sha256=EAQZ9WpiKmkvToIv8G1HNY4V7m0jXyyePTmeP2XOZzE,4688
|
91
|
-
sticker_convert/utils/
|
92
|
-
sticker_convert/utils/
|
92
|
+
sticker_convert/utils/singletons.py,sha256=SiV374FxU68DpysGoj_ytU1ErINkeOBbP4s9QTcexeY,357
|
93
|
+
sticker_convert/utils/url_detect.py,sha256=_wmI28hUyngq8TVz1bw7YM90qPLd3bIynawVlbr_lcI,939
|
94
|
+
sticker_convert/utils/auth/get_discord_auth.py,sha256=6qh1BuN-GieSXqJu9WbthLsflrYIGaEgKHGrQoPbO1M,4281
|
93
95
|
sticker_convert/utils/auth/get_kakao_auth.py,sha256=Wok5sp0GGBgTwwlfYB7lVq82ndBAOGTcqsWEaWAXFNE,10760
|
94
|
-
sticker_convert/utils/auth/get_kakao_desktop_auth.py,sha256=
|
96
|
+
sticker_convert/utils/auth/get_kakao_desktop_auth.py,sha256=0qxy1MfLFFDhSaEzWYT3H1GGOUBWDrmRPoonCIt1nuE,8613
|
95
97
|
sticker_convert/utils/auth/get_line_auth.py,sha256=8l8ha2vQmk3rHGvDE7PkcxQXbH3oe62LKbI3qVUtvqc,2196
|
96
|
-
sticker_convert/utils/auth/get_signal_auth.py,sha256=
|
97
|
-
sticker_convert/utils/auth/get_viber_auth.py,sha256=
|
98
|
+
sticker_convert/utils/auth/get_signal_auth.py,sha256=I6od2aj8yl1eLV8S2TtNQEPM77DC7FpkRKex0pXY2II,4580
|
99
|
+
sticker_convert/utils/auth/get_viber_auth.py,sha256=redKrHbCCBWHhOqAQOBIOWQpLM3R7Kr86ArTh7OWI4g,8181
|
98
100
|
sticker_convert/utils/auth/telegram_api.py,sha256=hX9fT0Pp8yMxcKSXLe9Mvy12mQ_rWj-KTyamABI8YWA,24232
|
99
|
-
sticker_convert/utils/auth/telethon_setup.py,sha256=
|
101
|
+
sticker_convert/utils/auth/telethon_setup.py,sha256=vBgRPBU_jXI8sHpYEofvO84F-dObY0TCfFzhHyw3OLI,2994
|
100
102
|
sticker_convert/utils/files/cache_store.py,sha256=etfe614OAhAyrnM5fGeESKq6R88YLNqkqkxSzEmZ0V0,1047
|
101
103
|
sticker_convert/utils/files/json_manager.py,sha256=Vr6pZJdLMkrJJWN99210aduVHb0ILyf0SSTaw4TZqgc,541
|
102
104
|
sticker_convert/utils/files/json_resources_loader.py,sha256=flZFixUXRTrOAhvRQpuSQgmJ69yXL94sxukcowLT1JQ,1049
|
@@ -104,12 +106,12 @@ sticker_convert/utils/files/metadata_handler.py,sha256=TUseSpKsFLoqqFf7YFENzkwDY
|
|
104
106
|
sticker_convert/utils/files/run_bin.py,sha256=C_KKGtMUTajJnKo4Ia9e6WuWCXSQRdGsVPG-r5GXT_I,1784
|
105
107
|
sticker_convert/utils/files/sanitize_filename.py,sha256=HBklPGsHRJjFQUIC5rYTQsUrsuTtezZXIEA8CPhLP8A,2156
|
106
108
|
sticker_convert/utils/media/apple_png_normalize.py,sha256=LbrQhc7LlYX4I9ek4XJsZE4l0MygBA1jB-PFiYLEkzk,3657
|
107
|
-
sticker_convert/utils/media/codec_info.py,sha256=
|
109
|
+
sticker_convert/utils/media/codec_info.py,sha256=HwA6eVh7cLhOlUoR_K9d_wyBRJ_ocGtB3GAyne_iZAU,16483
|
108
110
|
sticker_convert/utils/media/decrypt_kakao.py,sha256=4wq9ZDRnFkx1WmFZnyEogBofiLGsWQM_X69HlA36578,1947
|
109
111
|
sticker_convert/utils/media/format_verify.py,sha256=oM32P186tWe9YxvBQRPr8D3FEmBN3b2rEe_2S_MwxyQ,6236
|
110
|
-
sticker_convert-2.
|
111
|
-
sticker_convert-2.
|
112
|
-
sticker_convert-2.
|
113
|
-
sticker_convert-2.
|
114
|
-
sticker_convert-2.
|
115
|
-
sticker_convert-2.
|
112
|
+
sticker_convert-2.13.0.dist-info/licenses/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
|
113
|
+
sticker_convert-2.13.0.dist-info/METADATA,sha256=P6ZK34jRKvYmFd_2zm-8KAdjewwSJnoSaDN2yy3SR0Q,54352
|
114
|
+
sticker_convert-2.13.0.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
|
115
|
+
sticker_convert-2.13.0.dist-info/entry_points.txt,sha256=MNJ7XyC--ugxi5jS1nzjDLGnxCyLuaGdsVLnJhDHCqs,66
|
116
|
+
sticker_convert-2.13.0.dist-info/top_level.txt,sha256=r9vfnB0l1ZnH5pTH5RvkobnK3Ow9m0RsncaOMAtiAtk,16
|
117
|
+
sticker_convert-2.13.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|