sticker-convert 2.1.5__py3-none-any.whl → 2.1.7__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/__init__.py +1 -1
- sticker_convert/__main__.py +7 -4
- sticker_convert/cli.py +42 -32
- sticker_convert/converter.py +432 -0
- sticker_convert/downloaders/download_base.py +40 -16
- sticker_convert/downloaders/download_kakao.py +103 -136
- sticker_convert/downloaders/download_line.py +30 -12
- sticker_convert/downloaders/download_signal.py +48 -32
- sticker_convert/downloaders/download_telegram.py +71 -26
- sticker_convert/gui.py +79 -130
- sticker_convert/{gui_frames → gui_components/frames}/comp_frame.py +2 -3
- sticker_convert/{gui_frames → gui_components/frames}/config_frame.py +3 -4
- sticker_convert/{gui_frames → gui_components/frames}/control_frame.py +2 -2
- sticker_convert/{gui_frames → gui_components/frames}/cred_frame.py +4 -4
- sticker_convert/{gui_frames → gui_components/frames}/input_frame.py +4 -4
- sticker_convert/{gui_frames → gui_components/frames}/output_frame.py +3 -3
- sticker_convert/{gui_frames → gui_components/frames}/progress_frame.py +1 -1
- sticker_convert/{utils → gui_components}/gui_utils.py +38 -21
- sticker_convert/{gui_windows → gui_components/windows}/advanced_compression_window.py +3 -2
- sticker_convert/{gui_windows → gui_components/windows}/base_window.py +3 -2
- sticker_convert/{gui_windows → gui_components/windows}/kakao_get_auth_window.py +3 -3
- sticker_convert/{gui_windows → gui_components/windows}/line_get_auth_window.py +2 -2
- sticker_convert/{gui_windows → gui_components/windows}/signal_get_auth_window.py +2 -2
- sticker_convert/{flow.py → job.py} +91 -102
- sticker_convert/job_option.py +301 -0
- sticker_convert/resources/compression.json +1 -1
- sticker_convert/uploaders/compress_wastickers.py +95 -74
- sticker_convert/uploaders/upload_base.py +16 -4
- sticker_convert/uploaders/upload_signal.py +100 -62
- sticker_convert/uploaders/upload_telegram.py +168 -128
- sticker_convert/uploaders/xcode_imessage.py +202 -132
- sticker_convert/{auth → utils/auth}/get_kakao_auth.py +7 -5
- sticker_convert/{auth → utils/auth}/get_line_auth.py +6 -5
- sticker_convert/{auth → utils/auth}/get_signal_auth.py +1 -1
- sticker_convert/utils/fake_cb_msg.py +5 -2
- sticker_convert/utils/{cache_store.py → files/cache_store.py} +7 -3
- sticker_convert/utils/files/dir_utils.py +64 -0
- sticker_convert/utils/{json_manager.py → files/json_manager.py} +5 -4
- sticker_convert/utils/files/metadata_handler.py +226 -0
- sticker_convert/utils/files/run_bin.py +58 -0
- sticker_convert/utils/{apple_png_normalize.py → media/apple_png_normalize.py} +23 -20
- sticker_convert/utils/{codec_info.py → media/codec_info.py} +41 -35
- sticker_convert/utils/media/decrypt_kakao.py +68 -0
- sticker_convert/utils/media/format_verify.py +184 -0
- sticker_convert/utils/url_detect.py +16 -14
- {sticker_convert-2.1.5.dist-info → sticker_convert-2.1.7.dist-info}/METADATA +11 -11
- {sticker_convert-2.1.5.dist-info → sticker_convert-2.1.7.dist-info}/RECORD +52 -50
- {sticker_convert-2.1.5.dist-info → sticker_convert-2.1.7.dist-info}/WHEEL +1 -1
- sticker_convert/utils/converter.py +0 -399
- sticker_convert/utils/curr_dir.py +0 -70
- sticker_convert/utils/format_verify.py +0 -188
- sticker_convert/utils/metadata_handler.py +0 -190
- sticker_convert/utils/run_bin.py +0 -46
- /sticker_convert/{gui_frames → gui_components/frames}/right_clicker.py +0 -0
- {sticker_convert-2.1.5.dist-info → sticker_convert-2.1.7.dist-info}/LICENSE +0 -0
- {sticker_convert-2.1.5.dist-info → sticker_convert-2.1.7.dist-info}/entry_points.txt +0 -0
- {sticker_convert-2.1.5.dist-info → sticker_convert-2.1.7.dist-info}/top_level.txt +0 -0
@@ -4,57 +4,53 @@ import copy
|
|
4
4
|
from typing import Optional
|
5
5
|
|
6
6
|
import anyio
|
7
|
-
from signalstickers_client import StickersClient
|
8
|
-
from signalstickers_client.models import LocalStickerPack, Sticker
|
9
|
-
|
7
|
+
from signalstickers_client import StickersClient # type: ignore
|
8
|
+
from signalstickers_client.models import LocalStickerPack, Sticker # type: ignore
|
9
|
+
|
10
|
+
from .upload_base import UploadBase # type: ignore
|
11
|
+
from ..utils.files.metadata_handler import MetadataHandler # type: ignore
|
12
|
+
from ..converter import StickerConvert # type: ignore
|
13
|
+
from ..utils.media.format_verify import FormatVerify # type: ignore
|
14
|
+
from ..utils.media.codec_info import CodecInfo # type: ignore
|
15
|
+
from ..job_option import CompOption, OutputOption, CredOption # type: ignore
|
10
16
|
|
11
|
-
from .upload_base import UploadBase # type: ignore
|
12
|
-
from ..utils.metadata_handler import MetadataHandler # type: ignore
|
13
|
-
from ..utils.converter import StickerConvert # type: ignore
|
14
|
-
from ..utils.format_verify import FormatVerify # type: ignore
|
15
|
-
from ..utils.codec_info import CodecInfo # type: ignore
|
16
17
|
|
17
18
|
class UploadSignal(UploadBase):
|
18
19
|
def __init__(self, *args, **kwargs):
|
19
20
|
super(UploadSignal, self).__init__(*args, **kwargs)
|
20
|
-
|
21
|
-
base_spec = {
|
22
|
-
"size_max": {
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
'w': {
|
28
|
-
'max': 512
|
29
|
-
},
|
30
|
-
'h': {
|
31
|
-
'max': 512
|
32
|
-
}
|
33
|
-
},
|
34
|
-
'duration': {
|
35
|
-
'max': 3000
|
36
|
-
},
|
37
|
-
'square': True
|
38
|
-
}
|
21
|
+
|
22
|
+
base_spec = CompOption({
|
23
|
+
"size_max": {"img": 300000, "vid": 300000},
|
24
|
+
"res": {"max": 512},
|
25
|
+
"duration": {"max": 3000},
|
26
|
+
"square": True,
|
27
|
+
})
|
39
28
|
|
40
29
|
self.png_spec = copy.deepcopy(base_spec)
|
30
|
+
self.png_spec.format_vid = '.apng'
|
41
31
|
|
42
32
|
self.webp_spec = copy.deepcopy(base_spec)
|
43
|
-
self.webp_spec
|
33
|
+
self.webp_spec.format_img = '.webp'
|
34
|
+
self.webp_spec.animated = False
|
35
|
+
|
36
|
+
self.opt_comp_merged = copy.deepcopy(self.opt_comp)
|
37
|
+
self.opt_comp_merged.merge(base_spec)
|
44
38
|
|
45
|
-
self.opt_comp_merged = merge({}, self.opt_comp, base_spec)
|
46
|
-
|
47
39
|
@staticmethod
|
48
40
|
async def upload_pack(pack: LocalStickerPack, uuid: str, password: str):
|
49
41
|
async with StickersClient(uuid, password) as client:
|
50
42
|
pack_id, pack_key = await client.upload_pack(pack)
|
51
43
|
|
52
|
-
result =
|
44
|
+
result = (
|
45
|
+
f"https://signal.art/addstickers/#pack_id={pack_id}&pack_key={pack_key}"
|
46
|
+
)
|
53
47
|
return result
|
54
|
-
|
55
|
-
def add_stickers_to_pack(
|
48
|
+
|
49
|
+
def add_stickers_to_pack(
|
50
|
+
self, pack: LocalStickerPack, stickers: list[str], emoji_dict: dict
|
51
|
+
):
|
56
52
|
for src in stickers:
|
57
|
-
self.cb_msg(f
|
53
|
+
self.cb_msg(f"Verifying {src} for uploading to signal")
|
58
54
|
|
59
55
|
src_full_name = os.path.split(src)[-1]
|
60
56
|
src_name = os.path.splitext(src_full_name)[0]
|
@@ -65,21 +61,25 @@ class UploadSignal(UploadBase):
|
|
65
61
|
|
66
62
|
emoji = emoji_dict.get(src_name, None)
|
67
63
|
if not emoji:
|
68
|
-
self.cb_msg(
|
64
|
+
self.cb_msg(
|
65
|
+
f"Warning: Cannot find emoji for file {src_full_name}, skip uploading this file..."
|
66
|
+
)
|
69
67
|
continue
|
70
68
|
sticker.emoji = emoji[:1]
|
71
69
|
|
72
|
-
if ext ==
|
70
|
+
if ext == ".webp":
|
73
71
|
spec_choice = self.webp_spec
|
74
72
|
else:
|
75
73
|
spec_choice = self.png_spec
|
76
|
-
|
74
|
+
|
77
75
|
if not FormatVerify.check_file(src, spec=spec_choice):
|
78
76
|
if self.fake_vid or CodecInfo.is_anim(src):
|
79
|
-
dst =
|
77
|
+
dst = "bytes.apng"
|
80
78
|
else:
|
81
|
-
dst =
|
82
|
-
_, _, sticker.image_data, _ = StickerConvert(
|
79
|
+
dst = "bytes.png"
|
80
|
+
_, _, sticker.image_data, _ = StickerConvert(
|
81
|
+
src, dst, self.opt_comp_merged, self.cb_msg
|
82
|
+
).convert()
|
83
83
|
else:
|
84
84
|
with open(src, "rb") as f:
|
85
85
|
sticker.image_data = f.read()
|
@@ -89,45 +89,83 @@ class UploadSignal(UploadBase):
|
|
89
89
|
def upload_stickers_signal(self) -> list[str]:
|
90
90
|
urls = []
|
91
91
|
|
92
|
-
if not self.opt_cred.
|
93
|
-
self.cb_msg(
|
92
|
+
if not self.opt_cred.signal_uuid:
|
93
|
+
self.cb_msg("uuid required for uploading to Signal")
|
94
94
|
return urls
|
95
|
-
if not self.opt_cred.
|
96
|
-
self.cb_msg(
|
95
|
+
if not self.opt_cred.signal_password:
|
96
|
+
self.cb_msg("password required for uploading to Signal")
|
97
97
|
return urls
|
98
|
-
|
99
|
-
title, author, emoji_dict = MetadataHandler.get_metadata(
|
98
|
+
|
99
|
+
title, author, emoji_dict = MetadataHandler.get_metadata(
|
100
|
+
self.in_dir,
|
101
|
+
title=self.opt_output.title,
|
102
|
+
author=self.opt_output.author,
|
103
|
+
)
|
100
104
|
if title == None:
|
101
|
-
raise TypeError(f
|
105
|
+
raise TypeError(f"title cannot be {title}")
|
102
106
|
if author == None:
|
103
|
-
raise TypeError(f
|
107
|
+
raise TypeError(f"author cannot be {author}")
|
104
108
|
if emoji_dict == None:
|
105
|
-
msg_block =
|
106
|
-
msg_block += f
|
107
|
-
msg_block +=
|
108
|
-
|
109
|
-
|
109
|
+
msg_block = "emoji.txt is required for uploading signal stickers\n"
|
110
|
+
msg_block += f"emoji.txt generated for you in {self.in_dir}\n"
|
111
|
+
msg_block += (
|
112
|
+
f'Default emoji is set to {self.opt_comp.default_emoji}.\n'
|
113
|
+
)
|
114
|
+
msg_block += "Please edit emoji.txt now, then continue"
|
115
|
+
MetadataHandler.generate_emoji_file(
|
116
|
+
dir=self.in_dir, default_emoji=self.opt_comp.default_emoji
|
117
|
+
)
|
110
118
|
|
111
119
|
self.cb_msg_block(msg_block)
|
112
120
|
|
113
|
-
title, author, emoji_dict = MetadataHandler.get_metadata(
|
114
|
-
|
115
|
-
|
121
|
+
title, author, emoji_dict = MetadataHandler.get_metadata(
|
122
|
+
self.in_dir,
|
123
|
+
title=self.opt_output.title,
|
124
|
+
author=self.opt_output.author,
|
125
|
+
)
|
126
|
+
|
127
|
+
packs = MetadataHandler.split_sticker_packs(
|
128
|
+
self.in_dir, title=title, file_per_pack=200, separate_image_anim=False
|
129
|
+
)
|
116
130
|
for pack_title, stickers in packs.items():
|
117
|
-
self.cb_msg(f'Uploading pack {pack_title}')
|
118
131
|
pack = LocalStickerPack()
|
119
132
|
pack.title = pack_title
|
120
133
|
pack.author = author
|
121
134
|
|
122
135
|
self.add_stickers_to_pack(pack, stickers, emoji_dict)
|
123
|
-
|
136
|
+
self.cb_msg(f"Uploading pack {pack_title}")
|
137
|
+
result = anyio.run(
|
138
|
+
UploadSignal.upload_pack,
|
139
|
+
pack,
|
140
|
+
self.opt_cred.signal_uuid,
|
141
|
+
self.opt_cred.signal_password,
|
142
|
+
)
|
124
143
|
|
125
144
|
self.cb_msg(result)
|
126
145
|
urls.append(result)
|
127
|
-
|
146
|
+
|
128
147
|
return urls
|
129
148
|
|
130
149
|
@staticmethod
|
131
|
-
def start(
|
132
|
-
|
133
|
-
|
150
|
+
def start(
|
151
|
+
opt_output: OutputOption,
|
152
|
+
opt_comp: CompOption,
|
153
|
+
opt_cred: CredOption,
|
154
|
+
cb_msg=print,
|
155
|
+
cb_msg_block=input,
|
156
|
+
cb_ask_bool=input,
|
157
|
+
cb_bar=None,
|
158
|
+
out_dir: Optional[str] = None,
|
159
|
+
**kwargs,
|
160
|
+
) -> list[str]:
|
161
|
+
exporter = UploadSignal(
|
162
|
+
opt_output,
|
163
|
+
opt_comp,
|
164
|
+
opt_cred,
|
165
|
+
cb_msg,
|
166
|
+
cb_msg_block,
|
167
|
+
cb_ask_bool,
|
168
|
+
cb_bar,
|
169
|
+
out_dir,
|
170
|
+
)
|
171
|
+
return exporter.upload_stickers_signal()
|
@@ -7,123 +7,112 @@ from typing import Optional
|
|
7
7
|
import anyio
|
8
8
|
from telegram import Bot, InputSticker
|
9
9
|
from telegram.error import TelegramError
|
10
|
-
from mergedeep import merge # type: ignore
|
11
10
|
|
12
|
-
from .upload_base import UploadBase
|
13
|
-
from ..
|
14
|
-
from ..utils.metadata_handler import MetadataHandler
|
15
|
-
from ..utils.format_verify import FormatVerify
|
11
|
+
from .upload_base import UploadBase # type: ignore
|
12
|
+
from ..converter import StickerConvert # type: ignore
|
13
|
+
from ..utils.files.metadata_handler import MetadataHandler # type: ignore
|
14
|
+
from ..utils.media.format_verify import FormatVerify # type: ignore
|
15
|
+
from ..job_option import CompOption, OutputOption, CredOption # type: ignore
|
16
|
+
|
16
17
|
|
17
18
|
class UploadTelegram(UploadBase):
|
18
19
|
def __init__(self, *args, **kwargs):
|
19
20
|
super(UploadTelegram, self).__init__(*args, **kwargs)
|
20
|
-
|
21
|
-
base_spec = {
|
22
|
-
"size_max": {
|
23
|
-
|
24
|
-
|
25
|
-
}
|
26
|
-
|
27
|
-
'w': {
|
28
|
-
'min': 512,
|
29
|
-
'max': 512
|
30
|
-
},
|
31
|
-
'h': {
|
32
|
-
'min': 512,
|
33
|
-
'max': 512
|
34
|
-
}
|
35
|
-
},
|
36
|
-
'square': True,
|
37
|
-
'duration': {
|
38
|
-
'max': 3000
|
39
|
-
},
|
40
|
-
'fps': {}
|
41
|
-
}
|
21
|
+
|
22
|
+
base_spec = CompOption({
|
23
|
+
"size_max": {"img": 512000, "vid": 256000},
|
24
|
+
"res": 512,
|
25
|
+
"square": True,
|
26
|
+
"duration": {"max": 3000}
|
27
|
+
})
|
42
28
|
|
43
29
|
self.png_spec = copy.deepcopy(base_spec)
|
44
|
-
self.png_spec
|
45
|
-
self.png_spec
|
30
|
+
self.png_spec.format = ".png"
|
31
|
+
self.png_spec.animated = False
|
46
32
|
|
47
33
|
self.tgs_spec = copy.deepcopy(base_spec)
|
48
|
-
self.tgs_spec
|
49
|
-
self.tgs_spec
|
50
|
-
self.tgs_spec
|
51
|
-
self.tgs_spec
|
52
|
-
self.tgs_spec
|
34
|
+
self.tgs_spec.format = ".tgs"
|
35
|
+
self.tgs_spec.fps_min = 60
|
36
|
+
self.tgs_spec.fps_max = 60
|
37
|
+
self.tgs_spec.size_max_img = 64000
|
38
|
+
self.tgs_spec.size_max_vid = 64000
|
53
39
|
|
54
40
|
self.webm_spec = copy.deepcopy(base_spec)
|
55
|
-
self.webm_spec
|
56
|
-
self.webm_spec
|
57
|
-
self.webm_spec
|
58
|
-
|
59
|
-
self.opt_comp_merged =
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
'min': 100,
|
69
|
-
'max': 100
|
70
|
-
},
|
71
|
-
'h': {
|
72
|
-
'min': 100,
|
73
|
-
'max': 100
|
74
|
-
}
|
75
|
-
},
|
76
|
-
'square': True,
|
77
|
-
'duration': {
|
78
|
-
'max': 3000
|
79
|
-
},
|
80
|
-
'fps': {}
|
81
|
-
}
|
41
|
+
self.webm_spec.format = ".webm"
|
42
|
+
self.webm_spec.fps_max = 30
|
43
|
+
self.webm_spec.animated = None if self.fake_vid else True
|
44
|
+
|
45
|
+
self.opt_comp_merged = copy.deepcopy(self.opt_comp)
|
46
|
+
self.opt_comp_merged.merge(base_spec)
|
47
|
+
|
48
|
+
base_cover_spec = CompOption({
|
49
|
+
"size_max": {"img": 128000, "vid": 32000},
|
50
|
+
"res": 100,
|
51
|
+
"square": True,
|
52
|
+
"duration": {"max": 3000}
|
53
|
+
})
|
82
54
|
|
83
55
|
self.png_cover_spec = copy.deepcopy(base_cover_spec)
|
84
|
-
self.png_cover_spec
|
85
|
-
self.png_cover_spec
|
56
|
+
self.png_cover_spec.format = ".png"
|
57
|
+
self.png_cover_spec.animated = False
|
86
58
|
|
87
59
|
self.tgs_cover_spec = copy.deepcopy(base_cover_spec)
|
88
|
-
self.tgs_cover_spec
|
89
|
-
self.tgs_cover_spec
|
90
|
-
self.tgs_cover_spec
|
60
|
+
self.tgs_cover_spec.format = ".tgs"
|
61
|
+
self.tgs_cover_spec.fps_min = 60
|
62
|
+
self.tgs_cover_spec.fps_max = 60
|
91
63
|
|
92
64
|
self.webm_cover_spec = copy.deepcopy(base_cover_spec)
|
93
|
-
self.webm_cover_spec
|
94
|
-
self.webm_cover_spec
|
95
|
-
self.webm_cover_spec
|
65
|
+
self.webm_cover_spec.format = ".webm"
|
66
|
+
self.webm_cover_spec.fps_max = 30
|
67
|
+
self.webm_cover_spec.animated = True
|
68
|
+
|
69
|
+
self.opt_comp_cover_merged = copy.deepcopy(self.opt_comp)
|
70
|
+
self.opt_comp_cover_merged.merge(base_spec)
|
96
71
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
bot = Bot(self.opt_cred
|
72
|
+
async def upload_pack(
|
73
|
+
self, pack_title: str, stickers: list[str], emoji_dict: dict[str, str]
|
74
|
+
) -> str:
|
75
|
+
bot = Bot(self.opt_cred.telegram_token)
|
101
76
|
|
102
77
|
async with bot:
|
103
|
-
pack_short_name =
|
104
|
-
|
105
|
-
|
78
|
+
pack_short_name = (
|
79
|
+
pack_title.replace(" ", "_") + "_by_" + bot.name.replace("@", "")
|
80
|
+
)
|
81
|
+
pack_short_name = re.sub(
|
82
|
+
"[^0-9a-zA-Z]+", "_", pack_short_name
|
83
|
+
) # name used in url, only alphanum and underscore only
|
84
|
+
|
106
85
|
try:
|
107
|
-
sticker_set = await bot.get_sticker_set(
|
86
|
+
sticker_set = await bot.get_sticker_set(
|
87
|
+
pack_short_name,
|
88
|
+
read_timeout=30,
|
89
|
+
write_timeout=30,
|
90
|
+
connect_timeout=30,
|
91
|
+
pool_timeout=30,
|
92
|
+
)
|
108
93
|
await bot.get_sticker_set(pack_short_name)
|
109
94
|
pack_exists = True
|
110
95
|
except TelegramError:
|
111
96
|
pack_exists = False
|
112
97
|
|
113
98
|
if pack_exists == True:
|
114
|
-
response = self.cb_ask_bool(
|
99
|
+
response = self.cb_ask_bool(
|
100
|
+
f"Warning: Pack {pack_short_name} already exists.\nDelete all stickers in pack?"
|
101
|
+
)
|
115
102
|
if response == True:
|
116
|
-
self.cb_msg(f
|
103
|
+
self.cb_msg(f"Deleting all stickers from pack {pack_short_name}")
|
117
104
|
try:
|
118
105
|
for i in sticker_set.stickers:
|
119
106
|
await bot.delete_sticker_from_set(i.file_id)
|
120
107
|
except TelegramError as e:
|
121
|
-
self.cb_msg(
|
108
|
+
self.cb_msg(
|
109
|
+
f"Cannot delete sticker {i.file_id} from {pack_short_name} due to {e}"
|
110
|
+
)
|
122
111
|
else:
|
123
|
-
self.cb_msg(f
|
112
|
+
self.cb_msg(f"Not deleting existing pack {pack_short_name}")
|
124
113
|
|
125
114
|
for src in stickers:
|
126
|
-
self.cb_msg(f
|
115
|
+
self.cb_msg(f"Verifying {src} for uploading to telegram")
|
127
116
|
|
128
117
|
src_full_name = os.path.split(src)[-1]
|
129
118
|
src_name = os.path.splitext(src_full_name)[0]
|
@@ -132,109 +121,160 @@ class UploadTelegram(UploadBase):
|
|
132
121
|
emoji = emoji_dict.get(src_name, None)
|
133
122
|
if emoji:
|
134
123
|
if len(emoji) > 20:
|
135
|
-
self.cb_msg(
|
124
|
+
self.cb_msg(
|
125
|
+
f"Warning: {len(emoji)} emoji for file {src_full_name}, exceeding limit of 20, keep first 20 only..."
|
126
|
+
)
|
136
127
|
emoji_list = [*emoji][:20]
|
137
128
|
else:
|
138
|
-
self.cb_msg(
|
129
|
+
self.cb_msg(
|
130
|
+
f"Warning: Cannot find emoji for file {src_full_name}, skip uploading this file..."
|
131
|
+
)
|
139
132
|
continue
|
140
133
|
|
141
|
-
if ext ==
|
134
|
+
if ext == ".tgs":
|
142
135
|
spec_choice = self.tgs_spec
|
143
136
|
cover_spec_choice = self.tgs_cover_spec
|
144
|
-
sticker_format =
|
145
|
-
elif ext ==
|
137
|
+
sticker_format = "animated"
|
138
|
+
elif ext == ".webm":
|
146
139
|
spec_choice = self.webm_spec
|
147
140
|
cover_spec_choice = self.webm_cover_spec
|
148
|
-
sticker_format =
|
141
|
+
sticker_format = "video"
|
149
142
|
else:
|
150
|
-
ext =
|
143
|
+
ext = ".png"
|
151
144
|
spec_choice = self.png_spec
|
152
145
|
cover_spec_choice = self.png_cover_spec
|
153
|
-
sticker_format =
|
146
|
+
sticker_format = "static"
|
154
147
|
|
155
148
|
if FormatVerify.check_file(src, spec=spec_choice):
|
156
|
-
with open(src,
|
149
|
+
with open(src, "rb") as f:
|
157
150
|
sticker_bytes = f.read()
|
158
151
|
else:
|
159
|
-
_, _, sticker_bytes, _ = StickerConvert(
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
)
|
152
|
+
_, _, sticker_bytes, _ = StickerConvert(
|
153
|
+
src, f"bytes{ext}", self.opt_comp_merged, self.cb_msg
|
154
|
+
).convert()
|
155
|
+
|
156
|
+
sticker = InputSticker(sticker=sticker_bytes, emoji_list=emoji_list)
|
165
157
|
|
166
158
|
try:
|
167
159
|
if pack_exists == False:
|
168
160
|
await bot.create_new_sticker_set(
|
169
|
-
user_id=self.opt_cred
|
161
|
+
user_id=self.opt_cred.telegram_userid,
|
170
162
|
name=pack_short_name,
|
171
163
|
title=pack_title,
|
172
164
|
stickers=[sticker],
|
173
|
-
sticker_format=sticker_format
|
165
|
+
sticker_format=sticker_format,
|
166
|
+
)
|
174
167
|
pack_exists = True
|
175
168
|
else:
|
176
169
|
await bot.add_sticker_to_set(
|
177
|
-
user_id=self.opt_cred
|
170
|
+
user_id=self.opt_cred.telegram_userid,
|
178
171
|
name=pack_short_name,
|
179
|
-
sticker=sticker
|
172
|
+
sticker=sticker,
|
173
|
+
)
|
180
174
|
except TelegramError as e:
|
181
|
-
self.cb_msg(
|
175
|
+
self.cb_msg(
|
176
|
+
f"Cannot upload sticker {src} in {pack_short_name} due to {e}"
|
177
|
+
)
|
182
178
|
continue
|
183
179
|
|
184
|
-
self.cb_msg(f
|
185
|
-
|
180
|
+
self.cb_msg(f"Uploaded {src}")
|
181
|
+
|
186
182
|
cover_path = MetadataHandler.get_cover(self.in_dir)
|
187
183
|
if cover_path:
|
188
184
|
if FormatVerify.check_file(cover_path, spec=cover_spec_choice):
|
189
|
-
with open(cover_path,
|
185
|
+
with open(cover_path, "rb") as f:
|
190
186
|
thumbnail_bytes = f.read()
|
191
187
|
else:
|
192
|
-
_, _, thumbnail_bytes, _ = StickerConvert(
|
188
|
+
_, _, thumbnail_bytes, _ = StickerConvert(
|
189
|
+
cover_path,
|
190
|
+
f"bytes{ext}",
|
191
|
+
self.opt_comp_cover_merged,
|
192
|
+
self.cb_msg,
|
193
|
+
).convert()
|
193
194
|
|
194
195
|
try:
|
195
196
|
await bot.set_sticker_set_thumbnail(
|
196
197
|
name=pack_short_name,
|
197
|
-
user_id=self.opt_cred
|
198
|
-
thumbnail=thumbnail_bytes
|
198
|
+
user_id=self.opt_cred.telegram_userid,
|
199
|
+
thumbnail=thumbnail_bytes,
|
199
200
|
)
|
200
201
|
except TelegramError as e:
|
201
|
-
self.cb_msg(
|
202
|
-
|
203
|
-
|
202
|
+
self.cb_msg(
|
203
|
+
f"Cannot upload cover (thumbnail) for {pack_short_name} due to {e}"
|
204
|
+
)
|
205
|
+
|
206
|
+
result = f"https://t.me/addstickers/{pack_short_name}"
|
204
207
|
return result
|
205
208
|
|
206
209
|
def upload_stickers_telegram(self) -> list[str]:
|
207
210
|
urls = []
|
208
211
|
|
209
|
-
if not self.opt_cred.
|
210
|
-
self.cb_msg(
|
212
|
+
if not self.opt_cred.telegram_token:
|
213
|
+
self.cb_msg("Token required for uploading to telegram")
|
211
214
|
return urls
|
212
|
-
|
213
|
-
title, author, emoji_dict = MetadataHandler.get_metadata(
|
215
|
+
|
216
|
+
title, author, emoji_dict = MetadataHandler.get_metadata(
|
217
|
+
self.in_dir,
|
218
|
+
title=self.opt_output.title,
|
219
|
+
author=self.opt_output.author,
|
220
|
+
)
|
214
221
|
if title == None:
|
215
|
-
raise TypeError(
|
222
|
+
raise TypeError("title cannot be", title)
|
216
223
|
if emoji_dict == None:
|
217
|
-
msg_block =
|
218
|
-
msg_block += f
|
219
|
-
msg_block +=
|
220
|
-
|
221
|
-
|
224
|
+
msg_block = "emoji.txt is required for uploading signal stickers\n"
|
225
|
+
msg_block += f"emoji.txt generated for you in {self.in_dir}\n"
|
226
|
+
msg_block += (
|
227
|
+
f'Default emoji is set to {self.opt_comp.default_emoji}.\n'
|
228
|
+
)
|
229
|
+
msg_block += f"Please edit emoji.txt now, then continue"
|
230
|
+
MetadataHandler.generate_emoji_file(
|
231
|
+
dir=self.in_dir, default_emoji=self.opt_comp.default_emoji
|
232
|
+
)
|
222
233
|
|
223
234
|
self.cb_msg_block(msg_block)
|
224
235
|
|
225
|
-
title, author, emoji_dict = MetadataHandler.get_metadata(
|
236
|
+
title, author, emoji_dict = MetadataHandler.get_metadata(
|
237
|
+
self.in_dir,
|
238
|
+
title=self.opt_output.title,
|
239
|
+
author=self.opt_output.author,
|
240
|
+
)
|
226
241
|
|
227
|
-
packs = MetadataHandler.split_sticker_packs(
|
242
|
+
packs = MetadataHandler.split_sticker_packs(
|
243
|
+
self.in_dir,
|
244
|
+
title=title,
|
245
|
+
file_per_anim_pack=50,
|
246
|
+
file_per_image_pack=120,
|
247
|
+
separate_image_anim=not self.fake_vid,
|
248
|
+
)
|
228
249
|
|
229
250
|
for pack_title, stickers in packs.items():
|
230
|
-
self.cb_msg(f
|
251
|
+
self.cb_msg(f"Uploading pack {pack_title}")
|
231
252
|
result = anyio.run(self.upload_pack, pack_title, stickers, emoji_dict)
|
232
253
|
self.cb_msg(result)
|
233
254
|
urls.append(result)
|
234
255
|
|
235
256
|
return urls
|
236
|
-
|
257
|
+
|
237
258
|
@staticmethod
|
238
|
-
def start(
|
239
|
-
|
240
|
-
|
259
|
+
def start(
|
260
|
+
opt_output: OutputOption,
|
261
|
+
opt_comp: CompOption,
|
262
|
+
opt_cred: CredOption,
|
263
|
+
cb_msg=print,
|
264
|
+
cb_msg_block=input,
|
265
|
+
cb_ask_bool=input,
|
266
|
+
cb_bar=None,
|
267
|
+
out_dir: Optional[str] = None,
|
268
|
+
**kwargs,
|
269
|
+
) -> list[str]:
|
270
|
+
exporter = UploadTelegram(
|
271
|
+
opt_output,
|
272
|
+
opt_comp,
|
273
|
+
opt_cred,
|
274
|
+
cb_msg,
|
275
|
+
cb_msg_block,
|
276
|
+
cb_ask_bool,
|
277
|
+
cb_bar,
|
278
|
+
out_dir,
|
279
|
+
)
|
280
|
+
return exporter.upload_stickers_telegram()
|