sticker-convert 2.9.1__py3-none-any.whl → 2.9.3__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- sticker_convert/downloaders/download_base.py +2 -2
- sticker_convert/downloaders/download_kakao.py +48 -140
- sticker_convert/gui_components/frames/cred_frame.py +2 -0
- sticker_convert/version.py +1 -1
- {sticker_convert-2.9.1.dist-info → sticker_convert-2.9.3.dist-info}/METADATA +9 -8
- {sticker_convert-2.9.1.dist-info → sticker_convert-2.9.3.dist-info}/RECORD +10 -10
- {sticker_convert-2.9.1.dist-info → sticker_convert-2.9.3.dist-info}/WHEEL +1 -1
- {sticker_convert-2.9.1.dist-info → sticker_convert-2.9.3.dist-info}/LICENSE +0 -0
- {sticker_convert-2.9.1.dist-info → sticker_convert-2.9.3.dist-info}/entry_points.txt +0 -0
- {sticker_convert-2.9.1.dist-info → sticker_convert-2.9.3.dist-info}/top_level.txt +0 -0
@@ -92,10 +92,10 @@ class DownloadBase:
|
|
92
92
|
response = requests.get(
|
93
93
|
url, stream=True, allow_redirects=True, **kwargs
|
94
94
|
)
|
95
|
-
total_length = int(response.headers.get("content-length")) # type: ignore
|
96
|
-
|
97
95
|
if not response.ok:
|
98
96
|
return b""
|
97
|
+
total_length = int(response.headers.get("content-length")) # type: ignore
|
98
|
+
|
99
99
|
self.cb.put(f"Downloading {url}")
|
100
100
|
|
101
101
|
if show_progress:
|
@@ -3,16 +3,13 @@ from __future__ import annotations
|
|
3
3
|
|
4
4
|
import itertools
|
5
5
|
import json
|
6
|
-
import re
|
7
|
-
import zipfile
|
8
|
-
from io import BytesIO
|
9
6
|
from pathlib import Path
|
10
7
|
from typing import Any, List, Optional, Tuple, cast
|
11
8
|
from urllib.parse import urlparse
|
12
9
|
|
13
10
|
import requests
|
14
11
|
from bs4 import BeautifulSoup
|
15
|
-
from
|
12
|
+
from py_mini_racer import MiniRacer
|
16
13
|
|
17
14
|
from sticker_convert.downloaders.download_base import DownloadBase
|
18
15
|
from sticker_convert.job_option import CredOption
|
@@ -20,94 +17,27 @@ from sticker_convert.utils.callback import CallbackProtocol, CallbackReturn
|
|
20
17
|
from sticker_convert.utils.files.metadata_handler import MetadataHandler
|
21
18
|
from sticker_convert.utils.media.decrypt_kakao import DecryptKakao
|
22
19
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
return -1
|
20
|
+
JSINJECT = """
|
21
|
+
class osclass {
|
22
|
+
android = true;
|
23
|
+
}
|
24
|
+
class uaclass {
|
25
|
+
os = new osclass();
|
26
|
+
}
|
27
|
+
class util {
|
28
|
+
static userAgent() {
|
29
|
+
return new uaclass();
|
30
|
+
}
|
31
|
+
}
|
32
|
+
class daumtools {
|
33
|
+
static web2app(dataDict) {
|
34
|
+
return dataDict['urlScheme'];
|
35
|
+
}
|
36
|
+
}
|
37
|
+
"""
|
42
38
|
|
43
39
|
|
44
40
|
class MetadataKakao:
|
45
|
-
@staticmethod
|
46
|
-
def get_info_from_share_link(url: str) -> Tuple[Optional[str], Optional[str]]:
|
47
|
-
headers = {"User-Agent": "Android"}
|
48
|
-
|
49
|
-
response = requests.get(url, headers=headers)
|
50
|
-
soup = BeautifulSoup(response.content.decode("utf-8", "ignore"), "html.parser")
|
51
|
-
|
52
|
-
pack_title_tag = soup.find("title") # type: ignore
|
53
|
-
if not pack_title_tag:
|
54
|
-
return None, None
|
55
|
-
|
56
|
-
pack_title: str = pack_title_tag.string # type: ignore
|
57
|
-
|
58
|
-
app_scheme_link_tag = soup.find("a", id="app_scheme_link") # type: ignore
|
59
|
-
assert isinstance(app_scheme_link_tag, Tag)
|
60
|
-
|
61
|
-
item_code_fake = cast(str, app_scheme_link_tag["data-i"])
|
62
|
-
|
63
|
-
js = ""
|
64
|
-
for script_tag in soup.find_all("script"):
|
65
|
-
js = script_tag.string
|
66
|
-
if js and "emoticonDeepLink" in js:
|
67
|
-
break
|
68
|
-
if "emoticonDeepLink" not in js:
|
69
|
-
return None, None
|
70
|
-
|
71
|
-
func_start_pos = js.find("function emoticonDeepLink(")
|
72
|
-
js = js[func_start_pos:]
|
73
|
-
bracket_start_pos = js.find("{")
|
74
|
-
func_end_pos = search_bracket(js[bracket_start_pos:]) + bracket_start_pos
|
75
|
-
js = js[bracket_start_pos + 1 : func_end_pos]
|
76
|
-
js = js.split(";")[0]
|
77
|
-
|
78
|
-
minus_num_regex = re.search(r"\-(.*?)\^", js)
|
79
|
-
if not minus_num_regex:
|
80
|
-
return None, None
|
81
|
-
minus_num_str = minus_num_regex.group(1)
|
82
|
-
if not minus_num_str.isnumeric():
|
83
|
-
return None, None
|
84
|
-
minus_num = int(minus_num_str)
|
85
|
-
|
86
|
-
xor_num_regex = re.search(r"\^(.*?)\)", js)
|
87
|
-
if not xor_num_regex:
|
88
|
-
return None, None
|
89
|
-
xor_num_str = xor_num_regex.group(1)
|
90
|
-
if not xor_num_str.isnumeric():
|
91
|
-
return None, None
|
92
|
-
xor_num = int(xor_num_str)
|
93
|
-
|
94
|
-
item_code = str(int(item_code_fake) - minus_num ^ xor_num)
|
95
|
-
|
96
|
-
# https://github.com/Nuitka/Nuitka/issues/385
|
97
|
-
# js2py not working if compiled by nuitka
|
98
|
-
# web2app_start_pos = js.find("daumtools.web2app(")
|
99
|
-
# js = js[:web2app_start_pos] + "return a;}"
|
100
|
-
# get_item_code = js2py.eval_js(js) # type: ignore
|
101
|
-
# kakao_scheme_link = cast(
|
102
|
-
# str,
|
103
|
-
# get_item_code(
|
104
|
-
# "kakaotalk://store/emoticon/${i}?referer=share_link", item_code_fake
|
105
|
-
# ),
|
106
|
-
# )
|
107
|
-
# item_code = urlparse(kakao_scheme_link).path.split("/")[-1]
|
108
|
-
|
109
|
-
return pack_title, item_code
|
110
|
-
|
111
41
|
@staticmethod
|
112
42
|
def get_item_code(title_ko: str, auth_token: str) -> Optional[str]:
|
113
43
|
headers = {
|
@@ -177,15 +107,41 @@ class DownloadKakao(DownloadBase):
|
|
177
107
|
self.pack_info_unauthed: Optional[dict[str, Any]] = None
|
178
108
|
self.pack_info_authed: Optional[dict[str, Any]] = None
|
179
109
|
|
110
|
+
def get_info_from_share_link(self, url: str) -> Tuple[Optional[str], Optional[str]]:
|
111
|
+
headers = {"User-Agent": "Android"}
|
112
|
+
|
113
|
+
response = requests.get(url, headers=headers)
|
114
|
+
soup = BeautifulSoup(response.content.decode("utf-8", "ignore"), "html.parser")
|
115
|
+
|
116
|
+
pack_title_tag = soup.find("title") # type: ignore
|
117
|
+
if not pack_title_tag:
|
118
|
+
return None, None
|
119
|
+
|
120
|
+
pack_title: str = pack_title_tag.string # type: ignore
|
121
|
+
|
122
|
+
js = ""
|
123
|
+
for script_tag in soup.find_all("script"):
|
124
|
+
js = script_tag.string
|
125
|
+
if js and "daumtools.web2app" in js:
|
126
|
+
break
|
127
|
+
if "daumtools.web2app" not in js:
|
128
|
+
return None, None
|
129
|
+
|
130
|
+
js = JSINJECT + js
|
131
|
+
|
132
|
+
ctx = MiniRacer()
|
133
|
+
kakao_url = cast(str, ctx.eval(js))
|
134
|
+
item_code = urlparse(kakao_url).path.split("/")[2]
|
135
|
+
|
136
|
+
return pack_title, item_code
|
137
|
+
|
180
138
|
def download_stickers_kakao(self) -> bool:
|
181
139
|
self.auth_token = None
|
182
140
|
if self.opt_cred:
|
183
141
|
self.auth_token = self.opt_cred.kakao_auth_token
|
184
142
|
|
185
143
|
if urlparse(self.url).netloc == "emoticon.kakao.com":
|
186
|
-
self.pack_title, item_code =
|
187
|
-
self.url
|
188
|
-
)
|
144
|
+
self.pack_title, item_code = self.get_info_from_share_link(self.url)
|
189
145
|
|
190
146
|
if item_code:
|
191
147
|
return self.download_animated(item_code)
|
@@ -268,14 +224,6 @@ class DownloadKakao(DownloadBase):
|
|
268
224
|
self.out_dir, title=self.pack_title, author=self.author
|
269
225
|
)
|
270
226
|
|
271
|
-
success = self.download_animated_zip(item_code)
|
272
|
-
if not success:
|
273
|
-
self.cb.put("Trying to download one by one")
|
274
|
-
success = self.download_animated_files(item_code)
|
275
|
-
|
276
|
-
return success
|
277
|
-
|
278
|
-
def download_animated_files(self, item_code: str) -> bool:
|
279
227
|
play_exts = [".webp", ".gif", ".png", ""]
|
280
228
|
play_types = ["emot", "emoji", ""] # emot = normal; emoji = mini
|
281
229
|
play_path_format = None
|
@@ -376,46 +324,6 @@ class DownloadKakao(DownloadBase):
|
|
376
324
|
|
377
325
|
return True
|
378
326
|
|
379
|
-
def download_animated_zip(self, item_code: str) -> bool:
|
380
|
-
pack_url = f"http://item.kakaocdn.net/dw/{item_code}.file_pack.zip"
|
381
|
-
|
382
|
-
zip_file = self.download_file(pack_url)
|
383
|
-
if zip_file:
|
384
|
-
self.cb.put(f"Downloaded {pack_url}")
|
385
|
-
else:
|
386
|
-
self.cb.put(f"Cannot download {pack_url}")
|
387
|
-
return False
|
388
|
-
|
389
|
-
with zipfile.ZipFile(BytesIO(zip_file)) as zf:
|
390
|
-
self.cb.put("Unzipping...")
|
391
|
-
self.cb.put(
|
392
|
-
(
|
393
|
-
"bar",
|
394
|
-
None,
|
395
|
-
{"set_progress_mode": "determinate", "steps": len(zf.namelist())},
|
396
|
-
)
|
397
|
-
)
|
398
|
-
|
399
|
-
for num, f_path in enumerate(sorted(zf.namelist())):
|
400
|
-
ext = Path(f_path).suffix
|
401
|
-
|
402
|
-
if ext in (".gif", ".webp"):
|
403
|
-
data = DecryptKakao.xor_data(zf.read(f_path))
|
404
|
-
self.cb.put(f"Decrypted {f_path}")
|
405
|
-
else:
|
406
|
-
data = zf.read(f_path)
|
407
|
-
self.cb.put(f"Read {f_path}")
|
408
|
-
|
409
|
-
out_path = Path(self.out_dir, str(num).zfill(3) + ext)
|
410
|
-
with open(out_path, "wb") as f:
|
411
|
-
f.write(data)
|
412
|
-
|
413
|
-
self.cb.put("update_bar")
|
414
|
-
|
415
|
-
self.cb.put(f"Finished getting {pack_url}")
|
416
|
-
|
417
|
-
return True
|
418
|
-
|
419
327
|
@staticmethod
|
420
328
|
def start(
|
421
329
|
url: str,
|
sticker_convert/version.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sticker-convert
|
3
|
-
Version: 2.9.
|
3
|
+
Version: 2.9.3
|
4
4
|
Summary: Convert (animated) stickers to/from WhatsApp, Telegram, Signal, Line, Kakao, Viber, iMessage. Written in Python.
|
5
5
|
Author-email: laggykiller <chaudominic2@gmail.com>
|
6
6
|
Maintainer-email: laggykiller <chaudominic2@gmail.com>
|
@@ -367,17 +367,18 @@ License-File: LICENSE
|
|
367
367
|
Requires-Dist: aiolimiter ~=1.1.0
|
368
368
|
Requires-Dist: anyio ~=4.4.0
|
369
369
|
Requires-Dist: apngasm-python ~=1.3.1
|
370
|
-
Requires-Dist: av ~=12.
|
370
|
+
Requires-Dist: av ~=12.2.0
|
371
371
|
Requires-Dist: beautifulsoup4 ~=4.12.3
|
372
|
-
Requires-Dist: rookiepy ~=0.5.
|
372
|
+
Requires-Dist: rookiepy ~=0.5.2
|
373
373
|
Requires-Dist: imagequant ~=1.1.1
|
374
374
|
Requires-Dist: memory-tempfile ~=2.2.3
|
375
375
|
Requires-Dist: mergedeep ~=1.3.4
|
376
|
+
Requires-Dist: mini-racer ~=0.12.4
|
376
377
|
Requires-Dist: numpy >=1.22.4
|
377
|
-
Requires-Dist: Pillow ~=10.
|
378
|
+
Requires-Dist: Pillow ~=10.4.0
|
378
379
|
Requires-Dist: pyoxipng ~=9.0.0
|
379
380
|
Requires-Dist: python-telegram-bot ~=21.3
|
380
|
-
Requires-Dist: psutil ~=
|
381
|
+
Requires-Dist: psutil ~=6.0.0
|
381
382
|
Requires-Dist: PyMemoryEditor ~=1.5.22
|
382
383
|
Requires-Dist: requests ~=2.32.3
|
383
384
|
Requires-Dist: rlottie-python ~=1.3.6
|
@@ -392,7 +393,7 @@ Requires-Dist: ttkbootstrap-fork-laggykiller ~=1.5.1
|
|
392
393
|
|
393
394
|
- A python script for creating, downloading, converting+compressing and uploading stickers from multiple instant messaging applications.
|
394
395
|
- With GUI and CLI that runs on Windows, MacOS and Linux
|
395
|
-
- Currently supports Signal, Telegram, WhatsApp (Create .wastickers), Line (Download only), Kakao (Download only), Viber
|
396
|
+
- Currently supports Signal, Telegram, WhatsApp (Create .wastickers), Line (Download only), Kakao (Download only), Viber, iMessage (Create Xcode sticker pack project)
|
396
397
|
- Supports static and animated stickers, with transparency support
|
397
398
|
|
398
399
|
## Downloads
|
@@ -430,7 +431,7 @@ Requires-Dist: ttkbootstrap-fork-laggykiller ~=1.5.1
|
|
430
431
|
| [WhatsApp](docs/guide_whatsapp.md) | ⭕ (By Android or WhatsApp Web) | ⭕ (Create `.wastickers`, import by Sticker Maker) |
|
431
432
|
| [Line](docs/guide_line.md) | ✅ | 🚫 (Need to submit for manual approval) |
|
432
433
|
| [Kakao](docs/guide_kakao.md) | ✅ (Need 'share link' for animated) | 🚫 (Need to submit for manual approval) |
|
433
|
-
| [Viber](docs/guide_viber.md) | ✅ |
|
434
|
+
| [Viber](docs/guide_viber.md) | ✅ | ✅ (Require `viber_auth`) |
|
434
435
|
| [iMessage](docs/guide_imessage.md) | 🚫 | ⭕ (Create Xcode stickerpack project for sideload) |
|
435
436
|
|
436
437
|
✅ = Supported ⭕ = Partially supported 🚫 = Not supported
|
@@ -459,7 +460,7 @@ Requires-Dist: ttkbootstrap-fork-laggykiller ~=1.5.1
|
|
459
460
|
- Upload: Not supported. You need to manually submit sticker pack for approval before you can use in app.
|
460
461
|
- Viber
|
461
462
|
- Download: Supported (e.g. `https://stickers.viber.com/pages/example` OR `https://stickers.viber.com/pages/custom-sticker-packs/example`)
|
462
|
-
- Upload:
|
463
|
+
- Upload: Supported. Viber authentication data required for uploading Viber stickers, which could be fetched from Viber Desktop application automatically.
|
463
464
|
- iMessage
|
464
465
|
- Download: Not supported.
|
465
466
|
- Upload: The program can create Xcode project for iMessage sticker pack, which could then be compiled and sideloaded using Xcode.
|
@@ -6,10 +6,10 @@ sticker_convert/definitions.py,sha256=ZhP2ALCEud-w9ZZD4c3TDG9eHGPZyaAL7zPUsJAbjt
|
|
6
6
|
sticker_convert/gui.py,sha256=hZOp2SyEYKbCRm9SRTItBqEk724SHtSqK_Txo0wpL8Q,31194
|
7
7
|
sticker_convert/job.py,sha256=4C2WwB3PFldacqI8UPnM10thM087VLEl9wn6P9_LtS0,26128
|
8
8
|
sticker_convert/job_option.py,sha256=yFwHEhW8Gzp9dfiXakkCREfejAIJhiOxwD4Wlg9jcPk,7805
|
9
|
-
sticker_convert/version.py,sha256
|
9
|
+
sticker_convert/version.py,sha256=-3orOmwxQLXzeq93BjsCFkrDamN1_r5Ng80gy5-PF0w,46
|
10
10
|
sticker_convert/downloaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
|
-
sticker_convert/downloaders/download_base.py,sha256=
|
12
|
-
sticker_convert/downloaders/download_kakao.py,sha256=
|
11
|
+
sticker_convert/downloaders/download_base.py,sha256=WGEtri16p6GCG7hhQ603pKS8efoB72oCBHTuJ_RVmG0,4041
|
12
|
+
sticker_convert/downloaders/download_kakao.py,sha256=kE3LikphcFrFjAf-eJhmkj0Ko_JG9QpWFTp_YiWEzRA,11605
|
13
13
|
sticker_convert/downloaders/download_line.py,sha256=9WzOWujTbZdAqBi52k21OUEfRmcV1loCaJiDmg6dklw,17853
|
14
14
|
sticker_convert/downloaders/download_signal.py,sha256=PfwscdbcEd_5C3Ecs0F8Qc8si1sLzLodAdnsHVwXgac,3063
|
15
15
|
sticker_convert/downloaders/download_telegram.py,sha256=jufMqc78aXOPDr7fQf9ykkNyhQ7KVCp4gRBxs09NgMo,4614
|
@@ -20,7 +20,7 @@ sticker_convert/gui_components/frames/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCe
|
|
20
20
|
sticker_convert/gui_components/frames/comp_frame.py,sha256=9k_UntKKi2G_g0byzoj1rdTqOq7q9mcnXiy799bYnr0,7257
|
21
21
|
sticker_convert/gui_components/frames/config_frame.py,sha256=b3X4QAnGpde0OhthXHmjSyU_Yb5tYRUFXmy04Yi8Zmo,4316
|
22
22
|
sticker_convert/gui_components/frames/control_frame.py,sha256=_XiOJ9JPUfiysDghGG04sEVLrXG9TMVlDZ60W0LhYVI,835
|
23
|
-
sticker_convert/gui_components/frames/cred_frame.py,sha256=
|
23
|
+
sticker_convert/gui_components/frames/cred_frame.py,sha256=AJHxxBdEa-xOteevVBsSfAHtcJklU3pu2TqvZny9o4w,7527
|
24
24
|
sticker_convert/gui_components/frames/input_frame.py,sha256=5Vz1d6J1jkofvvzm43DxeIW_CjWfxa2QPYFnkAAiAfM,5040
|
25
25
|
sticker_convert/gui_components/frames/output_frame.py,sha256=n2WLk22h61DoZli8WbFhd-h2CqWAebDXnBa051JBuOc,4260
|
26
26
|
sticker_convert/gui_components/frames/progress_frame.py,sha256=LWUZg_iL7iiNTfu7N5Ct_pklZdghxihENi7DP9YozOE,4915
|
@@ -98,9 +98,9 @@ sticker_convert/utils/media/apple_png_normalize.py,sha256=LbrQhc7LlYX4I9ek4XJsZE
|
|
98
98
|
sticker_convert/utils/media/codec_info.py,sha256=1QfW3wgZ5vOk7T4XtLHYvJK1x8RbASRPSvhKEPkcu9A,15747
|
99
99
|
sticker_convert/utils/media/decrypt_kakao.py,sha256=4wq9ZDRnFkx1WmFZnyEogBofiLGsWQM_X69HlA36578,1947
|
100
100
|
sticker_convert/utils/media/format_verify.py,sha256=MH68GLJfXeL8WFT8emtj355K5BLAtUX64tQ59nugx2c,5673
|
101
|
-
sticker_convert-2.9.
|
102
|
-
sticker_convert-2.9.
|
103
|
-
sticker_convert-2.9.
|
104
|
-
sticker_convert-2.9.
|
105
|
-
sticker_convert-2.9.
|
106
|
-
sticker_convert-2.9.
|
101
|
+
sticker_convert-2.9.3.dist-info/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
|
102
|
+
sticker_convert-2.9.3.dist-info/METADATA,sha256=AhL6yrezU5-qhw5E2euXRDGz9fRplznnme-gVs4O0bo,51023
|
103
|
+
sticker_convert-2.9.3.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
|
104
|
+
sticker_convert-2.9.3.dist-info/entry_points.txt,sha256=MNJ7XyC--ugxi5jS1nzjDLGnxCyLuaGdsVLnJhDHCqs,66
|
105
|
+
sticker_convert-2.9.3.dist-info/top_level.txt,sha256=r9vfnB0l1ZnH5pTH5RvkobnK3Ow9m0RsncaOMAtiAtk,16
|
106
|
+
sticker_convert-2.9.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|