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
@@ -6,70 +6,115 @@ import anyio
|
|
6
6
|
from telegram import Bot
|
7
7
|
from telegram.error import TelegramError
|
8
8
|
|
9
|
-
from .download_base import DownloadBase
|
10
|
-
from ..utils.metadata_handler import MetadataHandler
|
9
|
+
from .download_base import DownloadBase # type: ignore
|
10
|
+
from ..utils.files.metadata_handler import MetadataHandler # type: ignore
|
11
|
+
from ..job_option import CredOption # type: ignore
|
12
|
+
|
11
13
|
|
12
14
|
class DownloadTelegram(DownloadBase):
|
13
15
|
def __init__(self, *args, **kwargs):
|
14
16
|
super(DownloadTelegram, self).__init__(*args, **kwargs)
|
15
|
-
|
17
|
+
|
16
18
|
def download_stickers_telegram(self) -> bool:
|
17
|
-
self.token = self.opt_cred.
|
19
|
+
self.token = self.opt_cred.telegram_token
|
18
20
|
if self.token == None:
|
19
|
-
self.cb_msg(
|
21
|
+
self.cb_msg("Download failed: Token required for downloading from telegram")
|
20
22
|
return False
|
21
|
-
|
22
|
-
if not (
|
23
|
-
self.cb_msg(
|
23
|
+
|
24
|
+
if not ("telegram.me" in self.url or "t.me" in self.url):
|
25
|
+
self.cb_msg("Download failed: Unrecognized URL format")
|
24
26
|
return False
|
25
27
|
|
26
28
|
self.title = ""
|
27
29
|
try:
|
28
|
-
self.title = self.url.split("/addstickers/")[1].split(
|
30
|
+
self.title = self.url.split("/addstickers/")[1].split("?")[0]
|
29
31
|
except IndexError:
|
30
|
-
self.title = self.url.split("eu/stickers/")[1].split(
|
31
|
-
|
32
|
+
self.title = self.url.split("eu/stickers/")[1].split("?")[0]
|
33
|
+
|
32
34
|
return anyio.run(self.save_stickers)
|
33
35
|
|
34
36
|
async def save_stickers(self) -> bool:
|
35
37
|
bot = Bot(self.token)
|
36
38
|
async with bot:
|
37
39
|
try:
|
38
|
-
sticker_set = await bot.get_sticker_set(
|
40
|
+
sticker_set = await bot.get_sticker_set(
|
41
|
+
self.title,
|
42
|
+
read_timeout=30,
|
43
|
+
write_timeout=30,
|
44
|
+
connect_timeout=30,
|
45
|
+
pool_timeout=30,
|
46
|
+
)
|
39
47
|
except TelegramError as e:
|
40
|
-
self.cb_msg(
|
48
|
+
self.cb_msg(
|
49
|
+
f"Failed to download telegram sticker set {self.title} due to: {e}"
|
50
|
+
)
|
41
51
|
return False
|
42
52
|
|
43
53
|
if self.cb_bar:
|
44
|
-
self.cb_bar(
|
54
|
+
self.cb_bar(
|
55
|
+
set_progress_mode="determinate", steps=len(sticker_set.stickers)
|
56
|
+
)
|
45
57
|
|
46
58
|
emoji_dict = {}
|
47
59
|
num = 0
|
48
60
|
for i in sticker_set.stickers:
|
49
|
-
sticker = await i.get_file(
|
61
|
+
sticker = await i.get_file(
|
62
|
+
read_timeout=30,
|
63
|
+
write_timeout=30,
|
64
|
+
connect_timeout=30,
|
65
|
+
pool_timeout=30,
|
66
|
+
)
|
50
67
|
ext = os.path.splitext(sticker.file_path)[-1]
|
51
68
|
f_id = str(num).zfill(3)
|
52
69
|
f_name = f_id + ext
|
53
70
|
f_path = os.path.join(self.out_dir, f_name)
|
54
|
-
await sticker.download_to_drive(
|
71
|
+
await sticker.download_to_drive(
|
72
|
+
custom_path=f_path,
|
73
|
+
read_timeout=30,
|
74
|
+
write_timeout=30,
|
75
|
+
connect_timeout=30,
|
76
|
+
pool_timeout=30,
|
77
|
+
)
|
55
78
|
emoji_dict[f_id] = i.emoji
|
56
|
-
self.cb_msg(f
|
79
|
+
self.cb_msg(f"Downloaded {f_name}")
|
57
80
|
if self.cb_bar:
|
58
81
|
self.cb_bar(update_bar=True)
|
59
82
|
num += 1
|
60
|
-
|
83
|
+
|
61
84
|
if sticker_set.thumbnail:
|
62
|
-
cover = await sticker_set.thumbnail.get_file(
|
85
|
+
cover = await sticker_set.thumbnail.get_file(
|
86
|
+
read_timeout=30,
|
87
|
+
write_timeout=30,
|
88
|
+
connect_timeout=30,
|
89
|
+
pool_timeout=30,
|
90
|
+
)
|
63
91
|
cover_ext = os.path.splitext(cover.file_path)[-1]
|
64
|
-
cover_name =
|
92
|
+
cover_name = "cover" + cover_ext
|
65
93
|
cover_path = os.path.join(self.out_dir, cover_name)
|
66
|
-
await cover.download_to_drive(
|
67
|
-
|
94
|
+
await cover.download_to_drive(
|
95
|
+
custom_path=cover_path,
|
96
|
+
read_timeout=30,
|
97
|
+
write_timeout=30,
|
98
|
+
connect_timeout=30,
|
99
|
+
pool_timeout=30,
|
100
|
+
)
|
101
|
+
self.cb_msg(f"Downloaded {cover_name}")
|
68
102
|
|
69
|
-
MetadataHandler.set_metadata(
|
103
|
+
MetadataHandler.set_metadata(
|
104
|
+
self.out_dir, title=self.title, emoji_dict=emoji_dict
|
105
|
+
)
|
70
106
|
return True
|
71
107
|
|
72
108
|
@staticmethod
|
73
|
-
def start(
|
74
|
-
|
75
|
-
|
109
|
+
def start(
|
110
|
+
url: str,
|
111
|
+
out_dir: str,
|
112
|
+
opt_cred: Optional[CredOption] = None,
|
113
|
+
cb_msg=print,
|
114
|
+
cb_msg_block=input,
|
115
|
+
cb_bar=None,
|
116
|
+
) -> bool:
|
117
|
+
downloader = DownloadTelegram(
|
118
|
+
url, out_dir, opt_cred, cb_msg, cb_msg_block, cb_bar
|
119
|
+
)
|
120
|
+
return downloader.download_stickers_telegram()
|
sticker_convert/gui.py
CHANGED
@@ -16,21 +16,22 @@ from PIL import ImageFont
|
|
16
16
|
from ttkbootstrap import Window, StringVar, BooleanVar, IntVar # type: ignore
|
17
17
|
from ttkbootstrap.dialogs import Messagebox, Querybox # type: ignore
|
18
18
|
|
19
|
-
from .
|
20
|
-
from .
|
21
|
-
from .utils.
|
22
|
-
from .utils.
|
19
|
+
from .job import Job # type: ignore
|
20
|
+
from .job_option import InputOption, CompOption, OutputOption, CredOption # type: ignore
|
21
|
+
from .utils.files.json_manager import JsonManager # type: ignore
|
22
|
+
from .utils.files.dir_utils import DirUtils # type: ignore
|
23
|
+
from .utils.files.metadata_handler import MetadataHandler # type: ignore
|
23
24
|
from .utils.url_detect import UrlDetect # type: ignore
|
24
|
-
from .
|
25
|
+
from .gui_components.gui_utils import GUIUtils # type: ignore
|
25
26
|
from .__init__ import __version__ # type: ignore
|
26
27
|
|
27
|
-
from .
|
28
|
-
from .
|
29
|
-
from .
|
30
|
-
from .
|
31
|
-
from .
|
32
|
-
from .
|
33
|
-
from .
|
28
|
+
from .gui_components.frames.input_frame import InputFrame # type: ignore
|
29
|
+
from .gui_components.frames.comp_frame import CompFrame # type: ignore
|
30
|
+
from .gui_components.frames.cred_frame import CredFrame # type: ignore
|
31
|
+
from .gui_components.frames.output_frame import OutputFrame # type: ignore
|
32
|
+
from .gui_components.frames.config_frame import ConfigFrame # type: ignore
|
33
|
+
from .gui_components.frames.progress_frame import ProgressFrame # type: ignore
|
34
|
+
from .gui_components.frames.control_frame import ControlFrame # type: ignore
|
34
35
|
|
35
36
|
class GUI(Window):
|
36
37
|
def __init__(self):
|
@@ -73,7 +74,7 @@ class GUI(Window):
|
|
73
74
|
self.mainloop()
|
74
75
|
|
75
76
|
def quit(self):
|
76
|
-
if self.
|
77
|
+
if self.job:
|
77
78
|
response = self.cb_ask_bool('Job is running, really quit?')
|
78
79
|
if response == False:
|
79
80
|
return
|
@@ -86,7 +87,7 @@ class GUI(Window):
|
|
86
87
|
else:
|
87
88
|
self.delete_creds()
|
88
89
|
|
89
|
-
if self.
|
90
|
+
if self.job:
|
90
91
|
self.cancel_job()
|
91
92
|
self.destroy()
|
92
93
|
|
@@ -157,7 +158,7 @@ class GUI(Window):
|
|
157
158
|
self.response_dict_lock = Lock()
|
158
159
|
self.response_dict = {}
|
159
160
|
self.action_queue = Queue()
|
160
|
-
self.
|
161
|
+
self.job = None
|
161
162
|
|
162
163
|
def init_frames(self):
|
163
164
|
self.input_frame = InputFrame(self, self.scrollable_frame, borderwidth=1, text='Input')
|
@@ -179,13 +180,14 @@ class GUI(Window):
|
|
179
180
|
|
180
181
|
def warn_tkinter_bug(self):
|
181
182
|
if (platform.system() == 'Darwin' and
|
182
|
-
platform.mac_ver().split('.')[0] == '14' and
|
183
|
+
platform.mac_ver()[0].split('.')[0] == '14' and
|
183
184
|
sys.version_info[0] == 3 and
|
184
|
-
sys.version_info[1] == 11
|
185
|
+
sys.version_info[1] == 11 and
|
186
|
+
sys.version_info[2] <= 6):
|
185
187
|
msg = 'NOTICE: If buttons are not responsive, try to press '
|
186
188
|
msg += 'on title bar or move mouse cursor away from window for a while.'
|
187
189
|
self.cb_msg(msg)
|
188
|
-
msg = '(This is due to a bug in tkinter specific to macOS 14
|
190
|
+
msg = '(This is due to a bug in tkinter specific to macOS 14 python <=3.11.6)'
|
189
191
|
self.cb_msg(msg)
|
190
192
|
msg = '(https://github.com/python/cpython/issues/110218)'
|
191
193
|
self.cb_msg(msg)
|
@@ -201,13 +203,13 @@ class GUI(Window):
|
|
201
203
|
Messagebox.show_error(message='Warning: json(s) under "resources" directory cannot be found', title='sticker-convert')
|
202
204
|
sys.exit()
|
203
205
|
|
204
|
-
self.settings_path = os.path.join(
|
206
|
+
self.settings_path = os.path.join(DirUtils.get_config_dir(), 'config.json')
|
205
207
|
if os.path.isfile(self.settings_path):
|
206
208
|
self.settings = JsonManager.load_json(self.settings_path)
|
207
209
|
else:
|
208
210
|
self.settings = {}
|
209
211
|
|
210
|
-
self.creds_path = os.path.join(
|
212
|
+
self.creds_path = os.path.join(DirUtils.get_config_dir(), 'creds.json')
|
211
213
|
if os.path.isfile(self.creds_path):
|
212
214
|
self.creds = JsonManager.load_json(self.creds_path)
|
213
215
|
else:
|
@@ -216,54 +218,14 @@ class GUI(Window):
|
|
216
218
|
def save_config(self):
|
217
219
|
# Only update comp_custom if custom preset is selected
|
218
220
|
if self.comp_preset_var.get() == 'custom':
|
219
|
-
comp_custom =
|
220
|
-
|
221
|
-
|
222
|
-
'vid': self.vid_size_max_var.get() if not self.size_disable_var.get() else None
|
223
|
-
},
|
224
|
-
'format': {
|
225
|
-
'img': self.img_format_var.get(),
|
226
|
-
'vid': self.vid_format_var.get()
|
227
|
-
},
|
228
|
-
'fps': {
|
229
|
-
'min': self.fps_min_var.get() if not self.fps_disable_var.get() else None,
|
230
|
-
'max': self.fps_max_var.get() if not self.fps_disable_var.get() else None
|
231
|
-
},
|
232
|
-
'res': {
|
233
|
-
'w': {
|
234
|
-
'min': self.res_w_min_var.get() if not self.res_w_disable_var.get() else None,
|
235
|
-
'max': self.res_w_max_var.get() if not self.res_w_disable_var.get() else None
|
236
|
-
},
|
237
|
-
'h': {
|
238
|
-
'min': self.res_h_min_var.get() if not self.res_h_disable_var.get() else None,
|
239
|
-
'max': self.res_h_max_var.get() if not self.res_h_disable_var.get() else None
|
240
|
-
}
|
241
|
-
},
|
242
|
-
'quality': {
|
243
|
-
'min': self.quality_min_var.get() if not self.quality_disable_var.get() else None,
|
244
|
-
'max': self.quality_max_var.get() if not self.quality_disable_var.get() else None
|
245
|
-
},
|
246
|
-
'color': {
|
247
|
-
'min': self.color_min_var.get() if not self.color_disable_var.get() else None,
|
248
|
-
'max': self.color_max_var.get() if not self.color_disable_var.get() else None
|
249
|
-
},
|
250
|
-
'duration': {
|
251
|
-
'min': self.duration_min_var.get() if not self.duration_disable_var.get() else None,
|
252
|
-
'max': self.duration_max_var.get() if not self.duration_disable_var.get() else None
|
253
|
-
},
|
254
|
-
'steps': self.steps_var.get(),
|
255
|
-
'fake_vid': self.fake_vid_var.get(),
|
256
|
-
'default_emoji': self.default_emoji_var.get(),
|
257
|
-
}
|
221
|
+
comp_custom = self.get_opt_comp()
|
222
|
+
del comp_custom['preset']
|
223
|
+
del comp_custom['no_compress']
|
258
224
|
else:
|
259
225
|
comp_custom = self.compression_presets.get('custom')
|
260
226
|
|
261
227
|
self.settings = {
|
262
|
-
'input':
|
263
|
-
'option': self.get_input_name(),
|
264
|
-
'url': self.input_address_var.get(),
|
265
|
-
'dir': self.input_setdir_var.get()
|
266
|
-
},
|
228
|
+
'input': self.get_opt_input(),
|
267
229
|
'comp': {
|
268
230
|
'no_compress': self.no_compress_var.get(),
|
269
231
|
'preset': self.comp_preset_var.get(),
|
@@ -271,12 +233,7 @@ class GUI(Window):
|
|
271
233
|
'processes': self.processes_var.get()
|
272
234
|
},
|
273
235
|
'comp_custom': comp_custom,
|
274
|
-
'output':
|
275
|
-
'option': self.get_output_name(),
|
276
|
-
'dir': self.output_setdir_var.get(),
|
277
|
-
'title': self.title_var.get(),
|
278
|
-
'author': self.author_var.get()
|
279
|
-
},
|
236
|
+
'output': self.get_opt_output(),
|
280
237
|
'creds': {
|
281
238
|
'save_cred': self.settings_save_cred_var.get()
|
282
239
|
}
|
@@ -285,26 +242,7 @@ class GUI(Window):
|
|
285
242
|
JsonManager.save_json(self.settings_path, self.settings)
|
286
243
|
|
287
244
|
def save_creds(self):
|
288
|
-
self.creds =
|
289
|
-
'signal': {
|
290
|
-
'uuid': self.signal_uuid_var.get(),
|
291
|
-
'password': self.signal_password_var.get()
|
292
|
-
},
|
293
|
-
'telegram': {
|
294
|
-
'token': self.telegram_token_var.get(),
|
295
|
-
'userid': self.telegram_userid_var.get()
|
296
|
-
},
|
297
|
-
'kakao': {
|
298
|
-
'auth_token': self.kakao_auth_token_var.get(),
|
299
|
-
'username': self.kakao_username_var.get(),
|
300
|
-
'password': self.kakao_password_var.get(),
|
301
|
-
'country_code': self.kakao_country_code_var.get(),
|
302
|
-
'phone_number': self.kakao_phone_number_var.get()
|
303
|
-
},
|
304
|
-
'line': {
|
305
|
-
'cookies': self.line_cookies_var.get()
|
306
|
-
}
|
307
|
-
}
|
245
|
+
self.creds = self.get_opt_cred()
|
308
246
|
|
309
247
|
JsonManager.save_json(self.creds_path, self.creds)
|
310
248
|
|
@@ -317,38 +255,34 @@ class GUI(Window):
|
|
317
255
|
os.remove(self.settings_path)
|
318
256
|
|
319
257
|
def apply_config(self):
|
258
|
+
# Input
|
320
259
|
self.default_input_mode = self.settings.get('input', {}).get('option', 'auto')
|
321
260
|
self.input_address_var.set(self.settings.get('input', {}).get('url', ''))
|
322
|
-
|
323
|
-
default_stickers_input_dir = os.path.join(CurrDir.get_curr_dir(), 'stickers_input')
|
261
|
+
default_stickers_input_dir = os.path.join(DirUtils.get_curr_dir(), 'stickers_input')
|
324
262
|
self.input_setdir_var.set(self.settings.get('input', {}).get('dir', default_stickers_input_dir))
|
325
263
|
if not os.path.isdir(self.input_setdir_var.get()):
|
326
264
|
self.input_setdir_var.set(default_stickers_input_dir)
|
265
|
+
self.input_option_display_var.set(self.input_presets[self.default_input_mode]['full_name'])
|
266
|
+
self.input_option_true_var.set(self.input_presets[self.default_input_mode]['full_name'])
|
327
267
|
|
268
|
+
# Compression
|
328
269
|
self.no_compress_var.set(self.settings.get('comp', {}).get('no_compress', False))
|
329
|
-
|
330
270
|
default_comp_preset = list(self.compression_presets.keys())[0]
|
331
271
|
self.comp_preset_var.set(self.settings.get('comp', {}).get('preset', default_comp_preset))
|
332
|
-
|
272
|
+
if self.settings.get('comp_custom'):
|
273
|
+
self.compression_presets['custom'] = self.settings.get('comp_custom')
|
333
274
|
self.cache_dir_var.set(self.settings.get('comp', {}).get('cache_dir', ''))
|
334
275
|
self.processes_var.set(self.settings.get('comp', {}).get('processes', math.ceil(cpu_count() / 2)))
|
335
276
|
self.default_output_mode = self.settings.get('output', {}).get('option', 'signal')
|
336
277
|
|
337
|
-
|
278
|
+
# Output
|
279
|
+
default_stickers_output_dir = os.path.join(DirUtils.get_curr_dir(), 'stickers_output')
|
338
280
|
self.output_setdir_var.set(self.settings.get('output', {}).get('dir', default_stickers_output_dir))
|
339
281
|
if not os.path.isdir(self.output_setdir_var.get()):
|
340
282
|
self.output_setdir_var.set(default_stickers_output_dir)
|
341
|
-
|
342
283
|
self.title_var.set(self.settings.get('output', {}).get('title', ''))
|
343
284
|
self.author_var.set(self.settings.get('output', {}).get('author', ''))
|
344
285
|
self.settings_save_cred_var.set(self.settings.get('creds', {}).get('save_cred', True))
|
345
|
-
|
346
|
-
if self.settings.get('comp_custom'):
|
347
|
-
self.compression_presets['custom'] = self.settings.get('comp_custom')
|
348
|
-
|
349
|
-
self.input_option_display_var.set(self.input_presets[self.default_input_mode]['full_name'])
|
350
|
-
self.input_option_true_var.set(self.input_presets[self.default_input_mode]['full_name'])
|
351
|
-
|
352
286
|
self.output_option_display_var.set(self.output_presets[self.default_output_mode]['full_name'])
|
353
287
|
self.output_option_true_var.set(self.output_presets[self.default_output_mode]['full_name'])
|
354
288
|
|
@@ -392,31 +326,24 @@ class GUI(Window):
|
|
392
326
|
|
393
327
|
def start_job(self):
|
394
328
|
Thread(target=self.start_process, daemon=True).start()
|
395
|
-
|
396
|
-
def start_process(self):
|
397
|
-
self.save_config()
|
398
|
-
if self.settings_save_cred_var.get() == True:
|
399
|
-
self.save_creds()
|
400
|
-
else:
|
401
|
-
self.delete_creds()
|
402
|
-
|
403
|
-
self.control_frame.start_btn.config(text='Cancel', bootstyle='danger')
|
404
|
-
self.set_inputs('disabled')
|
405
329
|
|
406
|
-
|
330
|
+
def get_opt_input(self) -> dict:
|
331
|
+
return {
|
407
332
|
'option': self.get_input_name(),
|
408
333
|
'url': self.input_address_var.get(),
|
409
334
|
'dir': self.input_setdir_var.get()
|
410
335
|
}
|
411
|
-
|
412
|
-
|
336
|
+
|
337
|
+
def get_opt_output(self) -> dict:
|
338
|
+
return {
|
413
339
|
'option': self.get_output_name(),
|
414
340
|
'dir': self.output_setdir_var.get(),
|
415
341
|
'title': self.title_var.get(),
|
416
342
|
'author': self.author_var.get()
|
417
343
|
}
|
418
|
-
|
419
|
-
|
344
|
+
|
345
|
+
def get_opt_comp(self) -> dict:
|
346
|
+
return {
|
420
347
|
'preset': self.get_preset(),
|
421
348
|
'size_max': {
|
422
349
|
'img': self.img_size_max_var.get() if not self.size_disable_var.get() else None,
|
@@ -459,8 +386,9 @@ class GUI(Window):
|
|
459
386
|
'no_compress': self.no_compress_var.get(),
|
460
387
|
'processes': self.processes_var.get()
|
461
388
|
}
|
462
|
-
|
463
|
-
|
389
|
+
|
390
|
+
def get_opt_cred(self) -> dict:
|
391
|
+
return {
|
464
392
|
'signal': {
|
465
393
|
'uuid': self.signal_uuid_var.get(),
|
466
394
|
'password': self.signal_password_var.get()
|
@@ -480,16 +408,30 @@ class GUI(Window):
|
|
480
408
|
'cookies': self.line_cookies_var.get()
|
481
409
|
}
|
482
410
|
}
|
411
|
+
|
412
|
+
def start_process(self):
|
413
|
+
self.save_config()
|
414
|
+
if self.settings_save_cred_var.get() == True:
|
415
|
+
self.save_creds()
|
416
|
+
else:
|
417
|
+
self.delete_creds()
|
418
|
+
|
419
|
+
self.control_frame.start_btn.config(text='Cancel', bootstyle='danger')
|
420
|
+
self.set_inputs('disabled')
|
421
|
+
|
422
|
+
opt_input = InputOption(self.get_opt_input())
|
423
|
+
opt_output = OutputOption(self.get_opt_output())
|
424
|
+
opt_comp = CompOption(self.get_opt_comp())
|
425
|
+
opt_cred = CredOption(self.get_opt_cred())
|
483
426
|
|
484
|
-
self.
|
427
|
+
self.job = Job(
|
485
428
|
opt_input, opt_comp, opt_output, opt_cred,
|
486
|
-
self.input_presets, self.output_presets,
|
487
429
|
self.cb_msg, self.cb_msg_block, self.cb_bar, self.cb_ask_bool
|
488
430
|
)
|
489
431
|
|
490
|
-
status = self.
|
432
|
+
status = self.job.start()
|
491
433
|
|
492
|
-
self.
|
434
|
+
self.job = None
|
493
435
|
|
494
436
|
if status == 1:
|
495
437
|
self.cb_msg(msg='An error occured during this run.')
|
@@ -505,10 +447,10 @@ class GUI(Window):
|
|
505
447
|
|
506
448
|
def cancel_job(self):
|
507
449
|
self.cb_msg(msg='Cancelling job...')
|
508
|
-
self.
|
509
|
-
while not self.
|
510
|
-
self.
|
511
|
-
for process in self.
|
450
|
+
self.job.is_cancel_job.value = 1
|
451
|
+
while not self.job.jobs_queue.empty():
|
452
|
+
self.job.jobs_queue.get()
|
453
|
+
for process in self.job.processes:
|
512
454
|
process.terminate()
|
513
455
|
process.join()
|
514
456
|
|
@@ -559,7 +501,11 @@ class GUI(Window):
|
|
559
501
|
response = self.get_response_from_id(response_id)
|
560
502
|
return response
|
561
503
|
|
562
|
-
def cb_ask_str(self,
|
504
|
+
def cb_ask_str(self,
|
505
|
+
question: str,
|
506
|
+
initialvalue: Optional[str] = None,
|
507
|
+
cli_show_initialvalue: bool = True,
|
508
|
+
parent: Optional[object] = None) -> str:
|
563
509
|
return self.exec_in_main(partial(Querybox.get_string, question, title='sticker-convert', initialvalue=initialvalue, parent=parent))
|
564
510
|
|
565
511
|
def cb_ask_bool(self, question, parent=None) -> bool:
|
@@ -573,7 +519,10 @@ class GUI(Window):
|
|
573
519
|
with self.msg_lock:
|
574
520
|
self.progress_frame.update_message_box(*args, **kwargs)
|
575
521
|
|
576
|
-
def cb_msg_block(self,
|
522
|
+
def cb_msg_block(self,
|
523
|
+
message: Optional[str] = None,
|
524
|
+
parent: Optional[object] = None,
|
525
|
+
*args, **kwargs):
|
577
526
|
if message == None and len(args) > 0:
|
578
527
|
message = ' '.join(str(i) for i in args)
|
579
528
|
self.exec_in_main(partial(Messagebox.show_info, message, title='sticker-convert', parent=parent))
|
@@ -3,10 +3,9 @@ from ttkbootstrap import LabelFrame, OptionMenu, Button, Entry, Label, Checkbutt
|
|
3
3
|
from typing import TYPE_CHECKING
|
4
4
|
|
5
5
|
if TYPE_CHECKING:
|
6
|
-
from
|
7
|
-
from ..
|
6
|
+
from ...gui import GUI # type: ignore
|
7
|
+
from ..windows.advanced_compression_window import AdvancedCompressionWindow # type: ignore
|
8
8
|
from .right_clicker import RightClicker # type: ignore
|
9
|
-
from ..__init__ import __version__ # type: ignore
|
10
9
|
|
11
10
|
class CompFrame(LabelFrame):
|
12
11
|
def __init__(self, gui: "GUI", *args, **kwargs):
|
@@ -7,9 +7,8 @@ from ttkbootstrap import LabelFrame, Button, Label, Checkbutton # type: ignore
|
|
7
7
|
|
8
8
|
if TYPE_CHECKING:
|
9
9
|
from ..gui import GUI # type: ignore
|
10
|
-
from
|
11
|
-
from
|
12
|
-
from ..__init__ import __version__ # type: ignore
|
10
|
+
from ...utils.files.dir_utils import DirUtils # type: ignore
|
11
|
+
from ...utils.files.run_bin import RunBin # type: ignore
|
13
12
|
|
14
13
|
class ConfigFrame(LabelFrame):
|
15
14
|
def __init__(self, gui: "GUI", *args, **kwargs):
|
@@ -62,7 +61,7 @@ class ConfigFrame(LabelFrame):
|
|
62
61
|
self.gui.cb_msg_block('Restored to default config.')
|
63
62
|
|
64
63
|
def cb_open_config_directory(self, *args, **kwargs):
|
65
|
-
config_dir =
|
64
|
+
config_dir = DirUtils.get_config_dir()
|
66
65
|
self.gui.cb_msg(msg=f'Config is located at {config_dir}')
|
67
66
|
if platform.system() == 'Windows':
|
68
67
|
os.startfile(config_dir)
|
@@ -4,7 +4,7 @@ from typing import TYPE_CHECKING
|
|
4
4
|
from ttkbootstrap import Frame, Button # type: ignore
|
5
5
|
|
6
6
|
if TYPE_CHECKING:
|
7
|
-
from
|
7
|
+
from ...gui import GUI # type: ignore
|
8
8
|
|
9
9
|
class ControlFrame(Frame):
|
10
10
|
def __init__(self, gui: "GUI", *args, **kwargs):
|
@@ -16,7 +16,7 @@ class ControlFrame(Frame):
|
|
16
16
|
self.start_btn.pack(expand=True, fill='x')
|
17
17
|
|
18
18
|
def cb_start_btn(self, *args, **kwargs):
|
19
|
-
if self.gui.
|
19
|
+
if self.gui.job:
|
20
20
|
response = self.gui.cb_ask_bool('Cancel job?')
|
21
21
|
if response == True:
|
22
22
|
self.gui.cancel_job()
|
@@ -5,10 +5,10 @@ from typing import TYPE_CHECKING
|
|
5
5
|
from ttkbootstrap import LabelFrame, Button, Entry, Label # type: ignore
|
6
6
|
|
7
7
|
if TYPE_CHECKING:
|
8
|
-
from
|
9
|
-
from ..
|
10
|
-
from ..
|
11
|
-
from ..
|
8
|
+
from ...gui import GUI # type: ignore
|
9
|
+
from ..windows.signal_get_auth_window import SignalGetAuthWindow # type: ignore
|
10
|
+
from ..windows.line_get_auth_window import LineGetAuthWindow # type: ignore
|
11
|
+
from ..windows.kakao_get_auth_window import KakaoGetAuthWindow # type: ignore
|
12
12
|
from .right_clicker import RightClicker # type: ignore
|
13
13
|
|
14
14
|
class CredFrame(LabelFrame):
|
@@ -6,9 +6,9 @@ from tkinter import filedialog
|
|
6
6
|
from ttkbootstrap import LabelFrame, OptionMenu, Button, Entry, Label # type: ignore
|
7
7
|
|
8
8
|
if TYPE_CHECKING:
|
9
|
-
from
|
10
|
-
from
|
11
|
-
from
|
9
|
+
from ...gui import GUI # type: ignore
|
10
|
+
from ...utils.url_detect import UrlDetect # type: ignore
|
11
|
+
from ...utils.files.dir_utils import DirUtils # type: ignore
|
12
12
|
from .right_clicker import RightClicker # type: ignore
|
13
13
|
|
14
14
|
class InputFrame(LabelFrame):
|
@@ -50,7 +50,7 @@ class InputFrame(LabelFrame):
|
|
50
50
|
def cb_set_indir(self, *args):
|
51
51
|
orig_input_dir = self.gui.input_setdir_var.get()
|
52
52
|
if not os.path.isdir(orig_input_dir):
|
53
|
-
orig_input_dir =
|
53
|
+
orig_input_dir = DirUtils.get_curr_dir()
|
54
54
|
input_dir = filedialog.askdirectory(initialdir=orig_input_dir)
|
55
55
|
if input_dir:
|
56
56
|
self.gui.input_setdir_var.set(input_dir)
|
@@ -6,8 +6,8 @@ from tkinter import filedialog
|
|
6
6
|
from ttkbootstrap import LabelFrame, OptionMenu, Button, Entry, Label # type: ignore
|
7
7
|
|
8
8
|
if TYPE_CHECKING:
|
9
|
-
from
|
10
|
-
from
|
9
|
+
from ...gui import GUI # type: ignore
|
10
|
+
from ...utils.files.dir_utils import DirUtils # type: ignore
|
11
11
|
from .right_clicker import RightClicker # type: ignore
|
12
12
|
|
13
13
|
class OutputFrame(LabelFrame):
|
@@ -48,7 +48,7 @@ class OutputFrame(LabelFrame):
|
|
48
48
|
def cb_set_outdir(self, *args):
|
49
49
|
orig_output_dir = self.gui.output_setdir_var.get()
|
50
50
|
if not os.path.isdir(orig_output_dir):
|
51
|
-
orig_output_dir =
|
51
|
+
orig_output_dir = DirUtils.get_curr_dir()
|
52
52
|
output_dir = filedialog.askdirectory(initialdir=orig_output_dir)
|
53
53
|
if output_dir:
|
54
54
|
self.gui.output_setdir_var.set(output_dir)
|
@@ -6,7 +6,7 @@ from ttkbootstrap.scrolled import ScrolledText # type: ignore
|
|
6
6
|
from tqdm import tqdm
|
7
7
|
|
8
8
|
if TYPE_CHECKING:
|
9
|
-
from
|
9
|
+
from ...gui import GUI # type: ignore
|
10
10
|
from .right_clicker import RightClicker # type: ignore
|
11
11
|
|
12
12
|
class ProgressFrame(LabelFrame):
|