sticker-convert 2.8.1__py3-none-any.whl → 2.8.3__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
sticker_convert/cli.py CHANGED
@@ -119,6 +119,7 @@ class CLI:
119
119
  "duration_max",
120
120
  "vid_size_max",
121
121
  "img_size_max",
122
+ "padding_percent",
122
123
  )
123
124
  flags_comp_float = ("fps_power", "res_power", "quality_power", "color_power")
124
125
  flags_comp_str = (
@@ -372,6 +373,9 @@ class CLI:
372
373
  bg_color=self.compression_presets[preset]["bg_color"]
373
374
  if args.bg_color is None
374
375
  else args.bg_color,
376
+ padding_percent=self.compression_presets[preset]["padding_percent"]
377
+ if args.padding_percent is None
378
+ else args.padding_percent,
375
379
  steps=self.compression_presets[preset]["steps"]
376
380
  if args.steps is None
377
381
  else args.steps,
@@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional, Tuple, Uni
9
9
  import numpy as np
10
10
  from PIL import Image
11
11
  from PIL import __version__ as PillowVersion
12
+ from PIL import features
12
13
 
13
14
  from sticker_convert.job_option import CompOption
14
15
  from sticker_convert.utils.callback import CallbackProtocol, CallbackReturn
@@ -32,6 +33,17 @@ MSG_FAIL_COMP = (
32
33
  "[F] Failed Compression {} -> {}, "
33
34
  "cannot get below limit {} with lowest quality under current settings (Best size: {})"
34
35
  )
36
+ MSG_PYWEBP_DUPFRAME = (
37
+ "[W] {} contains duplicated frame.\n"
38
+ " System WebP>=0.5.0 was not found, hence Pillow cannot be used\n"
39
+ " for creating animated webp. Using pywebp instead, which is known to\n"
40
+ " collapse same frames into single frame, causing problem with animation timing."
41
+ )
42
+ MSG_WEBP_PIL_DUPFRAME = (
43
+ "[W] {} contains duplicated frame.\n"
44
+ " Using Pillow to create animated webp to avoid same frames collapse\n"
45
+ " into single frame, but this is slower."
46
+ )
35
47
 
36
48
  YUV_RGB_MATRIX = np.array(
37
49
  [
@@ -41,6 +53,10 @@ YUV_RGB_MATRIX = np.array(
41
53
  ]
42
54
  )
43
55
 
56
+ # Whether animated WebP is supported
57
+ # See https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#saving-sequences
58
+ PIL_WEBP_ANIM = cast(bool, features.check("webp_anim")) # type: ignore
59
+
44
60
 
45
61
  def get_step_value(
46
62
  max_step: Optional[int],
@@ -179,6 +195,8 @@ class StickerConvert:
179
195
  self.result_step: Optional[int] = None
180
196
 
181
197
  self.apngasm = None
198
+ self.msg_pywebp_dupframe_displayed = False
199
+ self.msg_webp_pil_dupframe_displayed = False
182
200
 
183
201
  @staticmethod
184
202
  def convert(
@@ -394,7 +412,7 @@ class StickerConvert:
394
412
  with open(self.out_f, "wb+") as f:
395
413
  f.write(data)
396
414
 
397
- if result_step:
415
+ if result_step is not None:
398
416
  msg = MSG_DONE_COMP.format(
399
417
  self.in_f_name, self.out_f_name, self.result_size, result_step
400
418
  )
@@ -597,12 +615,13 @@ class StickerConvert:
597
615
  if self.res_h is None:
598
616
  self.res_h = height
599
617
 
618
+ scaling = 1 - (self.opt_comp.padding_percent / 100)
600
619
  if width > height:
601
- width_new = self.res_w
602
- height_new = height * self.res_w // width
620
+ width_new = int(self.res_w * scaling)
621
+ height_new = int(height * self.res_w // width * scaling)
603
622
  else:
604
- height_new = self.res_h
605
- width_new = width * self.res_h // height
623
+ height_new = int(self.res_h * scaling)
624
+ width_new = int(width * self.res_h // height * scaling)
606
625
 
607
626
  with im.resize((width_new, height_new), resample=resample) as im_resized:
608
627
  with Image.new(
@@ -677,14 +696,51 @@ class StickerConvert:
677
696
  self._frames_export_apng()
678
697
  else:
679
698
  self._frames_export_png()
680
- elif self.out_f.suffix == ".webp" and is_animated:
699
+ elif self.out_f.suffix == ".webp":
681
700
  self._frames_export_webp()
682
701
  elif self.out_f.suffix == ".gif":
683
- self._frames_export_gif()
702
+ self._frames_export_pil_anim()
684
703
  elif self.out_f.suffix in (".webm", ".mp4", ".mkv") or is_animated:
685
704
  self._frames_export_pyav()
686
705
  else:
687
706
  self._frames_export_pil()
707
+
708
+ def _check_dup(self) -> bool:
709
+ if len(self.frames_processed) == 1:
710
+ return False
711
+
712
+ prev_frame = self.frames_processed[0]
713
+ for frame in self.frames_processed[1:]:
714
+ if np.array_equal(frame, prev_frame):
715
+ return True
716
+ prev_frame = frame
717
+
718
+ return False
719
+
720
+ def _frames_export_webp(self) -> None:
721
+ has_dup_frames = self._check_dup()
722
+ if self.fps:
723
+ # It was noted that pywebp would collapse all frames.
724
+ # aed005b attempted to fix this by creating webp with
725
+ # variable frame duration. However, the webp created would
726
+ # not be accepted by WhatsApp.
727
+ # Therefore, we are preferring Pillow over pywebp.
728
+ if has_dup_frames:
729
+ if PIL_WEBP_ANIM:
730
+ # Warn that using Pillow is slower
731
+ if not self.msg_webp_pil_dupframe_displayed:
732
+ self.cb.put(MSG_WEBP_PIL_DUPFRAME.format(self.in_f_name))
733
+ self.msg_webp_pil_dupframe_displayed = True
734
+ self._frames_export_pil_anim()
735
+ else:
736
+ if not self.msg_pywebp_dupframe_displayed:
737
+ self.cb.put(MSG_PYWEBP_DUPFRAME.format(self.in_f_name))
738
+ self.msg_pywebp_dupframe_displayed = True
739
+ self._frames_export_pywebp()
740
+ else:
741
+ self._frames_export_pywebp()
742
+ else:
743
+ self._frames_export_pil()
688
744
 
689
745
  def _frames_export_pil(self) -> None:
690
746
  with Image.fromarray(self.frames_processed[0]) as im: # type: ignore
@@ -709,7 +765,7 @@ class StickerConvert:
709
765
  codec = "apng"
710
766
  pixel_format = "rgba"
711
767
  options["plays"] = "0"
712
- elif self.out_f.suffix in (".webp", ".webm", ".mkv"):
768
+ elif self.out_f.suffix in (".webm", ".mkv"):
713
769
  codec = "libvpx-vp9"
714
770
  pixel_format = "yuva420p"
715
771
  options["loop"] = "0"
@@ -733,7 +789,7 @@ class StickerConvert:
733
789
  output.mux(out_stream.encode(av_frame))
734
790
  output.mux(out_stream.encode())
735
791
 
736
- def _frames_export_gif(self) -> None:
792
+ def _frames_export_pil_anim(self) -> None:
737
793
  extra_kwargs: Dict[str, Any] = {}
738
794
 
739
795
  # disposal=2 on gif cause flicker in image with transparency
@@ -744,25 +800,34 @@ class StickerConvert:
744
800
  else:
745
801
  extra_kwargs["optimize"] = True
746
802
 
747
- # GIF can only have one alpha color
748
- # Change lowest alpha to alpha=0
749
- # Only keep alpha=0 and alpha=255, nothing in between
750
- frames_processed = np.array(self.frames_processed)
751
- alpha = frames_processed[:, :, :, 3]
752
- alpha_min = np.min(alpha) # type: ignore
753
- if alpha_min < 255:
754
- alpha[alpha > alpha_min] = 255
755
- alpha[alpha == alpha_min] = 0
756
-
757
- if 0 in alpha:
758
- extra_kwargs["transparency"] = 0
759
- extra_kwargs["disposal"] = 2
760
- im_out = [self.quantize(Image.fromarray(i)) for i in frames_processed] # type: ignore
803
+ if self.out_f.suffix == ".gif":
804
+ # GIF can only have one alpha color
805
+ # Change lowest alpha to alpha=0
806
+ # Only keep alpha=0 and alpha=255, nothing in between
807
+ frames_processed = np.array(self.frames_processed)
808
+ alpha = frames_processed[:, :, :, 3]
809
+ alpha_min = np.min(alpha) # type: ignore
810
+ if alpha_min < 255:
811
+ alpha[alpha > alpha_min] = 255
812
+ alpha[alpha == alpha_min] = 0
813
+
814
+ if 0 in alpha:
815
+ extra_kwargs["transparency"] = 0
816
+ extra_kwargs["disposal"] = 2
817
+ im_out = [self.quantize(Image.fromarray(i)) for i in frames_processed] # type: ignore
818
+ else:
819
+ im_out = [
820
+ self.quantize(Image.fromarray(i).convert("RGB")).convert("RGB") # type: ignore
821
+ for i in frames_processed
822
+ ]
823
+ extra_kwargs["format"] = "GIF"
824
+ elif self.out_f.suffix == ".webp":
825
+ im_out = [Image.fromarray(i) for i in self.frames_processed] # type: ignore
826
+ extra_kwargs["format"] = "WebP"
827
+ extra_kwargs["minimize_size"] = True
828
+ extra_kwargs["method"] = 6
761
829
  else:
762
- im_out = [
763
- self.quantize(Image.fromarray(i).convert("RGB")).convert("RGB") # type: ignore
764
- for i in frames_processed
765
- ]
830
+ raise RuntimeError(f"Invalid format {self.out_f.suffix}")
766
831
 
767
832
  if self.fps:
768
833
  extra_kwargs["save_all"] = True
@@ -772,12 +837,11 @@ class StickerConvert:
772
837
 
773
838
  im_out[0].save(
774
839
  self.tmp_f,
775
- format="GIF",
776
840
  quality=self.quality,
777
841
  **extra_kwargs,
778
842
  )
779
843
 
780
- def _frames_export_webp(self) -> None:
844
+ def _frames_export_pywebp(self) -> None:
781
845
  import webp # type: ignore
782
846
 
783
847
  assert self.fps
@@ -785,25 +849,10 @@ class StickerConvert:
785
849
  config = webp.WebPConfig.new(quality=self.quality) # type: ignore
786
850
  enc = webp.WebPAnimEncoder.new(self.res_w, self.res_h) # type: ignore
787
851
  timestamp_ms = 0
788
- timestamp_inc = int(1000 / self.fps)
789
-
790
- pic = webp.WebPPicture.from_numpy(self.frames_processed[0]) # type: ignore
791
- enc.encode_frame(pic, 0, config=config) # type: ignore
792
-
793
- frame_num = 1
794
- frame_num_prev = 1
795
- frame_total = len(self.frames_processed)
796
- while frame_num < frame_total - 1:
797
- while frame_num < frame_total - 1 and np.array_equal(
798
- self.frames_processed[frame_num_prev],
799
- self.frames_processed[frame_num],
800
- ):
801
- timestamp_ms += timestamp_inc
802
- frame_num += 1
803
- pic = webp.WebPPicture.from_numpy(self.frames_processed[frame_num]) # type: ignore
852
+ for frame in self.frames_processed:
853
+ pic = webp.WebPPicture.from_numpy(frame) # type: ignore
804
854
  enc.encode_frame(pic, timestamp_ms, config=config) # type: ignore
805
- frame_num_prev = frame_num
806
-
855
+ timestamp_ms += int(1000 / self.fps)
807
856
  anim_data = enc.assemble(timestamp_ms) # type: ignore
808
857
  self.tmp_f.write(anim_data.buffer()) # type: ignore
809
858
 
@@ -42,7 +42,7 @@ class DownloadTelegram(DownloadBase):
42
42
  application = ( # type: ignore
43
43
  ApplicationBuilder()
44
44
  .token(self.token)
45
- .rate_limiter(AIORateLimiter())
45
+ .rate_limiter(AIORateLimiter(max_retries=3))
46
46
  .connect_timeout(timeout)
47
47
  .pool_timeout(timeout)
48
48
  .read_timeout(timeout)
sticker_convert/gui.py CHANGED
@@ -125,6 +125,7 @@ class GUI(Window):
125
125
  self.duration_min_var = IntVar(self)
126
126
  self.duration_max_var = IntVar(self)
127
127
  self.duration_disable_var = BooleanVar()
128
+ self.padding_percent_var = IntVar(self)
128
129
  self.img_size_max_var = IntVar(self)
129
130
  self.vid_size_max_var = IntVar(self)
130
131
  self.size_disable_var = BooleanVar()
@@ -519,6 +520,7 @@ class GUI(Window):
519
520
  if not self.duration_disable_var.get()
520
521
  else None,
521
522
  bg_color=self.bg_color_var.get(),
523
+ padding_percent=self.padding_percent_var.get(),
522
524
  steps=self.steps_var.get(),
523
525
  fake_vid=self.fake_vid_var.get(),
524
526
  scale_filter=self.scale_filter_var.get(),
@@ -642,10 +644,10 @@ class GUI(Window):
642
644
 
643
645
  def cb_bar(
644
646
  self,
645
- *args: Any,
646
647
  set_progress_mode: Optional[str] = None,
647
648
  steps: int = 0,
648
649
  update_bar: int = 0,
650
+ *args: Any,
649
651
  **kwargs: Any,
650
652
  ) -> None:
651
653
  self.progress_frame.update_progress_bar(
@@ -227,6 +227,16 @@ class AdvancedCompressionWindow(BaseWindow):
227
227
  )
228
228
  self.color_power_entry.bind("<Button-3><ButtonRelease-3>", RightClicker)
229
229
 
230
+ self.padding_percent_help_btn = self.add_help_btn(
231
+ self.gui.help["comp"]["padding_percent"]
232
+ )
233
+ self.padding_percent_lbl1 = Label(self.frame_advcomp, text="Padding")
234
+ self.padding_percent_lbl2 = Label(self.frame_advcomp, text="0-100%")
235
+ self.padding_percent_entry = Entry(
236
+ self.frame_advcomp, textvariable=self.gui.padding_percent_var, width=8
237
+ )
238
+ self.padding_percent_entry.bind("<Button-3><ButtonRelease-3>", RightClicker)
239
+
230
240
  self.fake_vid_help_btn = self.add_help_btn(self.gui.help["comp"]["fake_vid"])
231
241
  self.fake_vid_lbl = Label(
232
242
  self.frame_advcomp, text="Convert (faking) image to video"
@@ -297,113 +307,119 @@ class AdvancedCompressionWindow(BaseWindow):
297
307
  self.ph_im = ImageTk.PhotoImage(self.im)
298
308
  self.default_emoji_dsp = Label(self.frame_advcomp, image=self.ph_im)
299
309
 
300
- self.fps_help_btn.grid(column=0, row=2, sticky="w", padx=3, pady=3)
301
- self.fps_lbl.grid(column=1, row=2, sticky="w", padx=3, pady=3)
302
- self.fps_min_lbl.grid(column=2, row=2, sticky="w", padx=3, pady=3)
303
- self.fps_min_entry.grid(column=3, row=2, sticky="nes", padx=3, pady=3)
304
- self.fps_max_lbl.grid(column=4, row=2, sticky="w", padx=3, pady=3)
305
- self.fps_max_entry.grid(column=5, row=2, sticky="nes", padx=3, pady=3)
306
- self.fps_disable_cbox.grid(column=6, row=2, sticky="nes", padx=3, pady=3)
307
-
308
- self.res_w_help_btn.grid(column=0, row=3, sticky="w", padx=3, pady=3)
309
- self.res_w_lbl.grid(column=1, row=3, sticky="w", padx=3, pady=3)
310
- self.res_w_min_lbl.grid(column=2, row=3, sticky="w", padx=3, pady=3)
311
- self.res_w_min_entry.grid(column=3, row=3, sticky="nes", padx=3, pady=3)
312
- self.res_w_max_lbl.grid(column=4, row=3, sticky="w", padx=3, pady=3)
313
- self.res_w_max_entry.grid(column=5, row=3, sticky="nes", padx=3, pady=3)
314
- self.res_w_disable_cbox.grid(column=6, row=3, sticky="nes", padx=3, pady=3)
315
-
316
- self.res_h_help_btn.grid(column=0, row=4, sticky="w", padx=3, pady=3)
317
- self.res_h_lbl.grid(column=1, row=4, sticky="w", padx=3, pady=3)
318
- self.res_h_min_lbl.grid(column=2, row=4, sticky="w", padx=3, pady=3)
319
- self.res_h_min_entry.grid(column=3, row=4, sticky="nes", padx=3, pady=3)
320
- self.res_h_max_lbl.grid(column=4, row=4, sticky="w", padx=3, pady=3)
321
- self.res_h_max_entry.grid(column=5, row=4, sticky="nes", padx=3, pady=3)
322
- self.res_h_disable_cbox.grid(column=6, row=4, sticky="nes", padx=3, pady=3)
323
-
324
- self.quality_help_btn.grid(column=0, row=5, sticky="w", padx=3, pady=3)
325
- self.quality_lbl.grid(column=1, row=5, sticky="w", padx=3, pady=3)
326
- self.quality_min_lbl.grid(column=2, row=5, sticky="w", padx=3, pady=3)
327
- self.quality_min_entry.grid(column=3, row=5, sticky="nes", padx=3, pady=3)
328
- self.quality_max_lbl.grid(column=4, row=5, sticky="w", padx=3, pady=3)
329
- self.quality_max_entry.grid(column=5, row=5, sticky="nes", padx=3, pady=3)
330
- self.quality_disable_cbox.grid(column=6, row=5, sticky="nes", padx=3, pady=3)
331
-
332
- self.color_help_btn.grid(column=0, row=6, sticky="w", padx=3, pady=3)
333
- self.color_lbl.grid(column=1, row=6, sticky="w", padx=3, pady=3)
334
- self.color_min_lbl.grid(column=2, row=6, sticky="w", padx=3, pady=3)
335
- self.color_min_entry.grid(column=3, row=6, sticky="nes", padx=3, pady=3)
336
- self.color_max_lbl.grid(column=4, row=6, sticky="w", padx=3, pady=3)
337
- self.color_max_entry.grid(column=5, row=6, sticky="nes", padx=3, pady=3)
338
- self.color_disable_cbox.grid(column=6, row=6, sticky="nes", padx=3, pady=3)
339
-
340
- self.duration_help_btn.grid(column=0, row=7, sticky="w", padx=3, pady=3)
341
- self.duration_lbl.grid(column=1, row=7, sticky="w", padx=3, pady=3)
342
- self.duration_min_lbl.grid(column=2, row=7, sticky="w", padx=3, pady=3)
343
- self.duration_min_entry.grid(column=3, row=7, sticky="nes", padx=3, pady=3)
344
- self.duration_max_lbl.grid(column=4, row=7, sticky="w", padx=3, pady=3)
345
- self.duration_max_entry.grid(column=5, row=7, sticky="nes", padx=3, pady=3)
346
- self.duration_disable_cbox.grid(column=6, row=7, sticky="nes", padx=3, pady=3)
347
-
348
- self.size_help_btn.grid(column=0, row=8, sticky="w", padx=3, pady=3)
349
- self.size_lbl.grid(column=1, row=8, sticky="w", padx=3, pady=3)
350
- self.img_size_max_lbl.grid(column=2, row=8, sticky="w", padx=3, pady=3)
351
- self.img_size_max_entry.grid(column=3, row=8, sticky="nes", padx=3, pady=3)
352
- self.vid_size_max_lbl.grid(column=4, row=8, sticky="w", padx=3, pady=3)
353
- self.vid_size_max_entry.grid(column=5, row=8, sticky="nes", padx=3, pady=3)
354
- self.size_disable_cbox.grid(column=6, row=8, sticky="nes", padx=3, pady=3)
355
-
356
- self.format_help_btn.grid(column=0, row=9, sticky="w", padx=3, pady=3)
357
- self.format_lbl.grid(column=1, row=9, sticky="w", padx=3, pady=3)
358
- self.img_format_lbl.grid(column=2, row=9, sticky="w", padx=3, pady=3)
359
- self.img_format_entry.grid(column=3, row=9, sticky="nes", padx=3, pady=3)
360
- self.vid_format_lbl.grid(column=4, row=9, sticky="w", padx=3, pady=3)
361
- self.vid_format_entry.grid(column=5, row=9, sticky="nes", padx=3, pady=3)
362
-
363
- self.power_help_btn1.grid(column=0, row=10, sticky="w", padx=3, pady=3)
364
- self.power_lbl1.grid(column=1, row=10, sticky="w", padx=3, pady=3)
365
- self.fps_power_lbl.grid(column=2, row=10, sticky="w", padx=3, pady=3)
366
- self.fps_power_entry.grid(column=3, row=10, sticky="w", padx=3, pady=3)
367
- self.res_power_lbl.grid(column=4, row=10, sticky="w", padx=3, pady=3)
368
- self.res_power_entry.grid(column=5, row=10, sticky="w", padx=3, pady=3)
369
-
370
- self.power_help_btn2.grid(column=0, row=11, sticky="w", padx=3, pady=3)
371
- self.power_lbl2.grid(column=1, row=11, sticky="w", padx=3, pady=3)
372
- self.quality_power_lbl.grid(column=2, row=11, sticky="w", padx=3, pady=3)
373
- self.quality_power_entry.grid(column=3, row=11, sticky="w", padx=3, pady=3)
374
- self.color_power_lbl.grid(column=4, row=11, sticky="w", padx=3, pady=3)
375
- self.color_power_entry.grid(column=5, row=11, sticky="w", padx=3, pady=3)
376
-
377
- self.fake_vid_help_btn.grid(column=0, row=12, sticky="w", padx=3, pady=3)
378
- self.fake_vid_lbl.grid(column=1, row=12, sticky="w", padx=3, pady=3)
379
- self.fake_vid_cbox.grid(column=6, row=12, sticky="nes", padx=3, pady=3)
380
-
381
- self.bg_color_help_btn.grid(column=0, row=13, sticky="w", padx=3, pady=3)
382
- self.bg_color_lbl.grid(column=1, row=13, sticky="w", padx=3, pady=3)
383
- self.bg_color_entry.grid(column=5, row=13, sticky="w", padx=3, pady=3)
384
- self.bg_color_btn.grid(column=6, row=13, sticky="nes", padx=3, pady=3)
385
-
386
- self.scale_filter_help_btn.grid(column=0, row=14, sticky="w", padx=3, pady=3)
387
- self.scale_filter_lbl.grid(column=1, row=14, sticky="w", padx=3, pady=3)
310
+ r = 0
311
+ self.fps_help_btn.grid(column=0, row=r, sticky="w", padx=3, pady=3)
312
+ self.fps_lbl.grid(column=1, row=r, sticky="w", padx=3, pady=3)
313
+ self.fps_min_lbl.grid(column=2, row=r, sticky="w", padx=3, pady=3)
314
+ self.fps_min_entry.grid(column=3, row=r, sticky="nes", padx=3, pady=3)
315
+ self.fps_max_lbl.grid(column=4, row=r, sticky="w", padx=3, pady=3)
316
+ self.fps_max_entry.grid(column=5, row=r, sticky="nes", padx=3, pady=3)
317
+ self.fps_disable_cbox.grid(column=6, row=r, sticky="nes", padx=3, pady=3)
318
+ r += 1
319
+ self.res_w_help_btn.grid(column=0, row=r, sticky="w", padx=3, pady=3)
320
+ self.res_w_lbl.grid(column=1, row=r, sticky="w", padx=3, pady=3)
321
+ self.res_w_min_lbl.grid(column=2, row=r, sticky="w", padx=3, pady=3)
322
+ self.res_w_min_entry.grid(column=3, row=r, sticky="nes", padx=3, pady=3)
323
+ self.res_w_max_lbl.grid(column=4, row=r, sticky="w", padx=3, pady=3)
324
+ self.res_w_max_entry.grid(column=5, row=r, sticky="nes", padx=3, pady=3)
325
+ self.res_w_disable_cbox.grid(column=6, row=r, sticky="nes", padx=3, pady=3)
326
+ r += 1
327
+ self.res_h_help_btn.grid(column=0, row=r, sticky="w", padx=3, pady=3)
328
+ self.res_h_lbl.grid(column=1, row=r, sticky="w", padx=3, pady=3)
329
+ self.res_h_min_lbl.grid(column=2, row=r, sticky="w", padx=3, pady=3)
330
+ self.res_h_min_entry.grid(column=3, row=r, sticky="nes", padx=3, pady=3)
331
+ self.res_h_max_lbl.grid(column=4, row=r, sticky="w", padx=3, pady=3)
332
+ self.res_h_max_entry.grid(column=5, row=r, sticky="nes", padx=3, pady=3)
333
+ self.res_h_disable_cbox.grid(column=6, row=r, sticky="nes", padx=3, pady=3)
334
+ r += 1
335
+ self.quality_help_btn.grid(column=0, row=r, sticky="w", padx=3, pady=3)
336
+ self.quality_lbl.grid(column=1, row=r, sticky="w", padx=3, pady=3)
337
+ self.quality_min_lbl.grid(column=2, row=r, sticky="w", padx=3, pady=3)
338
+ self.quality_min_entry.grid(column=3, row=r, sticky="nes", padx=3, pady=3)
339
+ self.quality_max_lbl.grid(column=4, row=r, sticky="w", padx=3, pady=3)
340
+ self.quality_max_entry.grid(column=5, row=r, sticky="nes", padx=3, pady=3)
341
+ self.quality_disable_cbox.grid(column=6, row=r, sticky="nes", padx=3, pady=3)
342
+ r += 1
343
+ self.color_help_btn.grid(column=0, row=r, sticky="w", padx=3, pady=3)
344
+ self.color_lbl.grid(column=1, row=r, sticky="w", padx=3, pady=3)
345
+ self.color_min_lbl.grid(column=2, row=r, sticky="w", padx=3, pady=3)
346
+ self.color_min_entry.grid(column=3, row=r, sticky="nes", padx=3, pady=3)
347
+ self.color_max_lbl.grid(column=4, row=r, sticky="w", padx=3, pady=3)
348
+ self.color_max_entry.grid(column=5, row=r, sticky="nes", padx=3, pady=3)
349
+ self.color_disable_cbox.grid(column=6, row=r, sticky="nes", padx=3, pady=3)
350
+ r += 1
351
+ self.duration_help_btn.grid(column=0, row=r, sticky="w", padx=3, pady=3)
352
+ self.duration_lbl.grid(column=1, row=r, sticky="w", padx=3, pady=3)
353
+ self.duration_min_lbl.grid(column=2, row=r, sticky="w", padx=3, pady=3)
354
+ self.duration_min_entry.grid(column=3, row=r, sticky="nes", padx=3, pady=3)
355
+ self.duration_max_lbl.grid(column=4, row=r, sticky="w", padx=3, pady=3)
356
+ self.duration_max_entry.grid(column=5, row=r, sticky="nes", padx=3, pady=3)
357
+ self.duration_disable_cbox.grid(column=6, row=r, sticky="nes", padx=3, pady=3)
358
+ r += 1
359
+ self.size_help_btn.grid(column=0, row=r, sticky="w", padx=3, pady=3)
360
+ self.size_lbl.grid(column=1, row=r, sticky="w", padx=3, pady=3)
361
+ self.img_size_max_lbl.grid(column=2, row=r, sticky="w", padx=3, pady=3)
362
+ self.img_size_max_entry.grid(column=3, row=r, sticky="nes", padx=3, pady=3)
363
+ self.vid_size_max_lbl.grid(column=4, row=r, sticky="w", padx=3, pady=3)
364
+ self.vid_size_max_entry.grid(column=5, row=r, sticky="nes", padx=3, pady=3)
365
+ self.size_disable_cbox.grid(column=6, row=r, sticky="nes", padx=3, pady=3)
366
+ r += 1
367
+ self.format_help_btn.grid(column=0, row=r, sticky="w", padx=3, pady=3)
368
+ self.format_lbl.grid(column=1, row=r, sticky="w", padx=3, pady=3)
369
+ self.img_format_lbl.grid(column=2, row=r, sticky="w", padx=3, pady=3)
370
+ self.img_format_entry.grid(column=3, row=r, sticky="nes", padx=3, pady=3)
371
+ self.vid_format_lbl.grid(column=4, row=r, sticky="w", padx=3, pady=3)
372
+ self.vid_format_entry.grid(column=5, row=r, sticky="nes", padx=3, pady=3)
373
+ r += 1
374
+ self.power_help_btn1.grid(column=0, row=r, sticky="w", padx=3, pady=3)
375
+ self.power_lbl1.grid(column=1, row=r, sticky="w", padx=3, pady=3)
376
+ self.fps_power_lbl.grid(column=2, row=r, sticky="w", padx=3, pady=3)
377
+ self.fps_power_entry.grid(column=3, row=r, sticky="w", padx=3, pady=3)
378
+ self.res_power_lbl.grid(column=4, row=r, sticky="w", padx=3, pady=3)
379
+ self.res_power_entry.grid(column=5, row=r, sticky="w", padx=3, pady=3)
380
+ r += 1
381
+ self.power_help_btn2.grid(column=0, row=r, sticky="w", padx=3, pady=3)
382
+ self.power_lbl2.grid(column=1, row=r, sticky="w", padx=3, pady=3)
383
+ self.quality_power_lbl.grid(column=2, row=r, sticky="w", padx=3, pady=3)
384
+ self.quality_power_entry.grid(column=3, row=r, sticky="w", padx=3, pady=3)
385
+ self.color_power_lbl.grid(column=4, row=r, sticky="w", padx=3, pady=3)
386
+ self.color_power_entry.grid(column=5, row=r, sticky="w", padx=3, pady=3)
387
+ r += 1
388
+ self.padding_percent_help_btn.grid(column=0, row=r, sticky="w", padx=3, pady=3)
389
+ self.padding_percent_lbl1.grid(column=1, row=r, sticky="w", padx=3, pady=3)
390
+ self.padding_percent_lbl2.grid(column=2, row=r, sticky="w", padx=3, pady=3)
391
+ self.padding_percent_entry.grid(column=3, row=r, sticky="w", padx=3, pady=3)
392
+ r += 1
393
+ self.fake_vid_help_btn.grid(column=0, row=r, sticky="w", padx=3, pady=3)
394
+ self.fake_vid_lbl.grid(column=1, row=r, sticky="w", padx=3, pady=3)
395
+ self.fake_vid_cbox.grid(column=6, row=r, sticky="nes", padx=3, pady=3)
396
+ r += 1
397
+ self.bg_color_help_btn.grid(column=0, row=r, sticky="w", padx=3, pady=3)
398
+ self.bg_color_lbl.grid(column=1, row=r, sticky="w", padx=3, pady=3)
399
+ self.bg_color_entry.grid(column=5, row=r, sticky="w", padx=3, pady=3)
400
+ self.bg_color_btn.grid(column=6, row=r, sticky="nes", padx=3, pady=3)
401
+ r += 1
402
+ self.scale_filter_help_btn.grid(column=0, row=r, sticky="w", padx=3, pady=3)
403
+ self.scale_filter_lbl.grid(column=1, row=r, sticky="w", padx=3, pady=3)
388
404
  self.scale_filter_opt.grid(
389
- column=2, row=14, columnspan=4, sticky="nes", padx=3, pady=3
405
+ column=2, row=r, columnspan=4, sticky="nes", padx=3, pady=3
390
406
  )
391
-
392
- self.quantize_method_help_btn.grid(column=0, row=15, sticky="w", padx=3, pady=3)
393
- self.quantize_method_lbl.grid(column=1, row=15, sticky="w", padx=3, pady=3)
407
+ r += 1
408
+ self.quantize_method_help_btn.grid(column=0, row=r, sticky="w", padx=3, pady=3)
409
+ self.quantize_method_lbl.grid(column=1, row=r, sticky="w", padx=3, pady=3)
394
410
  self.quantize_method_opt.grid(
395
- column=2, row=15, columnspan=4, sticky="nes", padx=3, pady=3
411
+ column=2, row=r, columnspan=4, sticky="nes", padx=3, pady=3
396
412
  )
397
-
398
- self.cache_dir_help_btn.grid(column=0, row=16, sticky="w", padx=3, pady=3)
399
- self.cache_dir_lbl.grid(column=1, row=16, sticky="w", padx=3, pady=3)
413
+ r += 1
414
+ self.cache_dir_help_btn.grid(column=0, row=r, sticky="w", padx=3, pady=3)
415
+ self.cache_dir_lbl.grid(column=1, row=r, sticky="w", padx=3, pady=3)
400
416
  self.cache_dir_entry.grid(
401
- column=2, row=16, columnspan=4, sticky="nes", padx=3, pady=3
417
+ column=2, row=r, columnspan=4, sticky="nes", padx=3, pady=3
402
418
  )
403
-
404
- self.default_emoji_help_btn.grid(column=0, row=17, sticky="w", padx=3, pady=3)
405
- self.default_emoji_lbl.grid(column=1, row=17, sticky="w", padx=3, pady=3)
406
- self.default_emoji_dsp.grid(column=6, row=17, sticky="nes", padx=3, pady=3)
419
+ r += 1
420
+ self.default_emoji_help_btn.grid(column=0, row=r, sticky="w", padx=3, pady=3)
421
+ self.default_emoji_lbl.grid(column=1, row=r, sticky="w", padx=3, pady=3)
422
+ self.default_emoji_dsp.grid(column=6, row=r, sticky="nes", padx=3, pady=3)
407
423
 
408
424
  # https://stackoverflow.com/questions/43731784/tkinter-canvas-scrollbar-with-grid
409
425
  # Create a frame for the canvas with non-zero row&column weights
sticker_convert/job.py CHANGED
@@ -172,8 +172,6 @@ class Executor:
172
172
  except KeyboardInterrupt:
173
173
  pass
174
174
 
175
- if self.cb_thread_instance:
176
- self.cb_thread_instance.join()
177
175
  self.processes.clear()
178
176
 
179
177
  def kill_workers(self, *_: Any, **__: Any) -> None:
@@ -182,14 +180,14 @@ class Executor:
182
180
  for process in self.processes:
183
181
  process.terminate()
184
182
 
185
- self.cleanup(killed=True)
183
+ self.cb_msg("Job cancelled.")
184
+ self.cleanup()
186
185
 
187
- def cleanup(self, killed: bool = False) -> None:
188
- if killed:
189
- self.cb_msg("Job cancelled.")
186
+ def cleanup(self) -> None:
190
187
  self.cb_bar("clear")
191
- # self.cb_queue.put(None)
192
- self.manager.shutdown()
188
+ self.cb_queue.put(None)
189
+ if self.cb_thread_instance:
190
+ self.cb_thread_instance.join()
193
191
 
194
192
 
195
193
  class Job:
@@ -602,6 +600,9 @@ class Job:
602
600
  in_fs.append(i)
603
601
 
604
602
  in_fs_count = len(in_fs)
603
+ if in_fs_count == 0:
604
+ self.executor.cb("No files to compress")
605
+ return True
605
606
 
606
607
  self.executor.cb(msg)
607
608
  self.executor.cb(
@@ -69,6 +69,8 @@ class CompOption(BaseOption):
69
69
 
70
70
  bg_color: Optional[str] = None
71
71
 
72
+ padding_percent: int = 0
73
+
72
74
  steps: int = 1
73
75
  fake_vid: Optional[bool] = None
74
76
  quantize_method: Optional[str] = None
@@ -104,6 +106,7 @@ class CompOption(BaseOption):
104
106
  "duration": {"min": self.duration_min, "max": self.duration_max},
105
107
  "steps": self.steps,
106
108
  "bg_color": self.bg_color,
109
+ "padding_percent": self.padding_percent,
107
110
  "fake_vid": self.fake_vid,
108
111
  "quantize_method": self.quantize_method,
109
112
  "scale_filter": self.scale_filter,
@@ -38,6 +38,7 @@
38
38
  "min": 0,
39
39
  "max": 10000
40
40
  },
41
+ "padding_percent": 0,
41
42
  "bg_color": "",
42
43
  "steps": 16,
43
44
  "fake_vid": false,
@@ -84,6 +85,7 @@
84
85
  "min": 0,
85
86
  "max": 3000
86
87
  },
88
+ "padding_percent": 0,
87
89
  "bg_color": "",
88
90
  "steps": 16,
89
91
  "fake_vid": false,
@@ -130,6 +132,7 @@
130
132
  "min": 0,
131
133
  "max": 3000
132
134
  },
135
+ "padding_percent": 0,
133
136
  "bg_color": "",
134
137
  "steps": 16,
135
138
  "fake_vid": false,
@@ -176,6 +179,7 @@
176
179
  "min": 0,
177
180
  "max": 3000
178
181
  },
182
+ "padding_percent": 0,
179
183
  "bg_color": "",
180
184
  "steps": 16,
181
185
  "fake_vid": false,
@@ -222,6 +226,7 @@
222
226
  "min": 8,
223
227
  "max": 10000
224
228
  },
229
+ "padding_percent": 0,
225
230
  "bg_color": "",
226
231
  "steps": 16,
227
232
  "fake_vid": true,
@@ -268,6 +273,7 @@
268
273
  "min": 83,
269
274
  "max": 4000
270
275
  },
276
+ "padding_percent": 0,
271
277
  "bg_color": "",
272
278
  "steps": 16,
273
279
  "fake_vid": false,
@@ -314,6 +320,7 @@
314
320
  "min": 0,
315
321
  "max": 5000
316
322
  },
323
+ "padding_percent": 0,
317
324
  "bg_color": "",
318
325
  "steps": 16,
319
326
  "fake_vid": false,
@@ -360,6 +367,7 @@
360
367
  "min": 0,
361
368
  "max": 2000
362
369
  },
370
+ "padding_percent": 0,
363
371
  "bg_color": "",
364
372
  "steps": 16,
365
373
  "fake_vid": false,
@@ -406,6 +414,7 @@
406
414
  "min": 0,
407
415
  "max": 2000
408
416
  },
417
+ "padding_percent": 0,
409
418
  "bg_color": "",
410
419
  "steps": 16,
411
420
  "fake_vid": false,
@@ -452,6 +461,7 @@
452
461
  "min": 0,
453
462
  "max": 2000
454
463
  },
464
+ "padding_percent": 0,
455
465
  "bg_color": "",
456
466
  "steps": 16,
457
467
  "fake_vid": false,
@@ -498,6 +508,7 @@
498
508
  "min": 0,
499
509
  "max": 10000
500
510
  },
511
+ "padding_percent": 0,
501
512
  "bg_color": "",
502
513
  "steps": 16,
503
514
  "fake_vid": false,
@@ -39,6 +39,7 @@
39
39
  "duration": "Change playback speed if outside of duration limit.\nDuration set in miliseconds.\n0 will disable limit.",
40
40
  "duration_min": "Set minimum output duration in miliseconds.",
41
41
  "duration_max": "Set maximum output duration in miliseconds.",
42
+ "padding_percent": "Set percentage of space used as padding.",
42
43
  "bg_color": "Set custom background color.\nExample: 00ff00 for green.\nIf this is not set, background color would be auto set to black if image is bright, or white if image is dark.\nNote: The color should not be visible if output format supports transparency.",
43
44
  "size": "Set maximum file size in bytes for video and image.",
44
45
  "vid_size_max": "Set maximum file size limit for animated stickers.",
@@ -79,7 +79,7 @@ class CompressWastickers(UploadBase):
79
79
  else:
80
80
  ext = ".png"
81
81
 
82
- dst = Path(tempdir, str(num) + ext)
82
+ dst = Path(tempdir, f"sticker_{num+1}{ext}")
83
83
 
84
84
  if FormatVerify.check_file(
85
85
  src, spec=self.webp_spec
@@ -114,7 +114,7 @@ class CompressWastickers(UploadBase):
114
114
  opt_comp_merged.merge(self.spec_cover)
115
115
 
116
116
  cover_path_old = MetadataHandler.get_cover(self.opt_output.dir)
117
- cover_path_new = Path(pack_dir, "100.png")
117
+ cover_path_new = Path(pack_dir, "tray.png")
118
118
  if cover_path_old:
119
119
  if FormatVerify.check_file(cover_path_old, spec=self.spec_cover):
120
120
  shutil.copy(cover_path_old, cover_path_new)
@@ -142,7 +142,7 @@ class CompressWastickers(UploadBase):
142
142
  self.cb_return,
143
143
  )
144
144
 
145
- MetadataHandler.set_metadata(pack_dir, author=author, title=title)
145
+ MetadataHandler.set_metadata(pack_dir, author=author, title=title, newline=True)
146
146
 
147
147
  @staticmethod
148
148
  def start(
@@ -78,7 +78,7 @@ class UploadTelegram(UploadBase):
78
78
  application = ( # type: ignore
79
79
  ApplicationBuilder()
80
80
  .token(self.opt_cred.telegram_token.strip())
81
- .rate_limiter(AIORateLimiter())
81
+ .rate_limiter(AIORateLimiter(max_retries=3))
82
82
  .connect_timeout(timeout)
83
83
  .pool_timeout(timeout)
84
84
  .read_timeout(timeout)
@@ -133,16 +133,21 @@ class MetadataHandler:
133
133
  title: Optional[str] = None,
134
134
  author: Optional[str] = None,
135
135
  emoji_dict: Optional[Dict[str, str]] = None,
136
+ newline: bool = False,
136
137
  ) -> None:
137
138
  title_path = Path(directory, "title.txt")
138
139
  if title is not None:
139
140
  with open(title_path, "w+", encoding="utf-8") as f:
140
141
  f.write(title)
142
+ if newline:
143
+ f.write("\n")
141
144
 
142
145
  author_path = Path(directory, "author.txt")
143
146
  if author is not None:
144
147
  with open(author_path, "w+", encoding="utf-8") as f:
145
148
  f.write(author)
149
+ if newline:
150
+ f.write("\n")
146
151
 
147
152
  emoji_path = Path(directory, "emoji.txt")
148
153
  if emoji_dict is not None:
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
- __version__ = "2.8.1"
3
+ __version__ = "2.8.3"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sticker-convert
3
- Version: 2.8.1
3
+ Version: 2.8.3
4
4
  Summary: Convert (animated) stickers to/from WhatsApp, Telegram, Signal, Line, Kakao, iMessage. Written in Python.
5
5
  Author-email: laggykiller <chaudominic2@gmail.com>
6
6
  Maintainer-email: laggykiller <chaudominic2@gmail.com>
@@ -483,23 +483,24 @@ usage: sticker-convert.py [-h] [--version] [--no-confirm] [--custom-presets CUST
483
483
  [--preset {auto,signal,telegram,telegram_emoji,whatsapp,line,kakao,imessage_small,imessage_medium,imessage_large,custom}]
484
484
  [--steps STEPS] [--processes PROCESSES] [--fps-min FPS_MIN] [--fps-max FPS_MAX]
485
485
  [--fps-power FPS_POWER] [--res-min RES_MIN] [--res-max RES_MAX] [--res-w-min RES_W_MIN]
486
- [--res-w-max RES_W_MAX] [--res-h-min RES_H_MIN] [--res-h-max RES_H_MAX] [--res-power RES_POWER]
487
- [--quality-min QUALITY_MIN] [--quality-max QUALITY_MAX] [--quality-power QUALITY_POWER]
488
- [--color-min COLOR_MIN] [--color-max COLOR_MAX] [--color-power COLOR_POWER]
489
- [--duration-min DURATION_MIN] [--duration-max DURATION_MAX] [--bg-color BG_COLOR]
490
- [--vid-size-max VID_SIZE_MAX] [--img-size-max IMG_SIZE_MAX] [--vid-format VID_FORMAT]
491
- [--img-format IMG_FORMAT] [--fake-vid] [--scale-filter SCALE_FILTER]
492
- [--quantize-method QUANTIZE_METHOD] [--cache-dir CACHE_DIR] [--default-emoji DEFAULT_EMOJI]
493
- [--signal-uuid SIGNAL_UUID] [--signal-password SIGNAL_PASSWORD] [--signal-get-auth]
494
- [--signal-data-dir SIGNAL_DATA_DIR] [--telegram-token TELEGRAM_TOKEN]
495
- [--telegram-userid TELEGRAM_USERID] [--kakao-auth-token KAKAO_AUTH_TOKEN] [--kakao-get-auth]
496
- [--kakao-username KAKAO_USERNAME] [--kakao-password KAKAO_PASSWORD]
497
- [--kakao-country-code KAKAO_COUNTRY_CODE] [--kakao-phone-number KAKAO_PHONE_NUMBER] [--line-get-auth]
498
- [--line-cookies LINE_COOKIES] [--save-cred SAVE_CRED]
486
+ [--res-w-max RES_W_MAX] [--res-h-min RES_H_MIN] [--res-h-max RES_H_MAX]
487
+ [--res-power RES_POWER] [--quality-min QUALITY_MIN] [--quality-max QUALITY_MAX]
488
+ [--quality-power QUALITY_POWER] [--color-min COLOR_MIN] [--color-max COLOR_MAX]
489
+ [--color-power COLOR_POWER] [--duration-min DURATION_MIN] [--duration-max DURATION_MAX]
490
+ [--padding-percent PADDING_PERCENT] [--bg-color BG_COLOR] [--vid-size-max VID_SIZE_MAX]
491
+ [--img-size-max IMG_SIZE_MAX] [--vid-format VID_FORMAT] [--img-format IMG_FORMAT]
492
+ [--fake-vid] [--scale-filter SCALE_FILTER] [--quantize-method QUANTIZE_METHOD]
493
+ [--cache-dir CACHE_DIR] [--default-emoji DEFAULT_EMOJI] [--signal-uuid SIGNAL_UUID]
494
+ [--signal-password SIGNAL_PASSWORD] [--signal-get-auth] [--signal-data-dir SIGNAL_DATA_DIR]
495
+ [--telegram-token TELEGRAM_TOKEN] [--telegram-userid TELEGRAM_USERID]
496
+ [--kakao-auth-token KAKAO_AUTH_TOKEN] [--kakao-get-auth] [--kakao-username KAKAO_USERNAME]
497
+ [--kakao-password KAKAO_PASSWORD] [--kakao-country-code KAKAO_COUNTRY_CODE]
498
+ [--kakao-phone-number KAKAO_PHONE_NUMBER] [--line-get-auth] [--line-cookies LINE_COOKIES]
499
+ [--save-cred SAVE_CRED]
499
500
 
500
501
  CLI for stickers-convert
501
502
 
502
- optional arguments:
503
+ options:
503
504
  -h, --help show this help message and exit
504
505
  --version show program's version number and exit
505
506
  --no-confirm Do not ask any questions.
@@ -585,6 +586,8 @@ Compression options:
585
586
  Set minimum output duration in miliseconds.
586
587
  --duration-max DURATION_MAX
587
588
  Set maximum output duration in miliseconds.
589
+ --padding-percent PADDING_PERCENT
590
+ Set percentage of space used as padding.
588
591
  --bg-color BG_COLOR Set custom background color.
589
592
  Example: 00ff00 for green.
590
593
  If this is not set, background color would be auto set to black if image is bright, or white if image is dark.
@@ -1,18 +1,18 @@
1
1
  sticker_convert/__init__.py,sha256=iQnv6UOOA69c3soAn7ZOnAIubTIQSUxtq1Uhh8xRWvU,102
2
2
  sticker_convert/__main__.py,sha256=6RJauR-SCSSTT3TU7FFB6B6PVwsCxO2xZXtmZ3jc2Is,463
3
- sticker_convert/cli.py,sha256=kyfhvMoHq42uLZsYYLrr6b30xsNE93GVZlbGYPFjC2I,18385
4
- sticker_convert/converter.py,sha256=VRAvSBtsr9XTJHd2iOydZ3xpAb7OZ9tBedYNYMGfnjA,34950
3
+ sticker_convert/cli.py,sha256=KMl8G25rTpSko46SC-WdI5YDBykyluQL13PYpZW_O8M,18579
4
+ sticker_convert/converter.py,sha256=CwhOuH8Os5zU_cLKmK0IKLAurA_-9-4E0cccQNHLp8Y,37357
5
5
  sticker_convert/definitions.py,sha256=ZhP2ALCEud-w9ZZD4c3TDG9eHGPZyaAL7zPUsJAbjtE,2073
6
- sticker_convert/gui.py,sha256=TqdgFbHBRYgcXWWrsfxLUJ8Zu9WeE11vYyZMX6nalik,30599
7
- sticker_convert/job.py,sha256=Qky9gMtaHg4BmgDn6I_K1gvmYNlfR-ydp9-H95X963M,25592
8
- sticker_convert/job_option.py,sha256=1YVhyTfu2cWz3qpAKbdIM11jbL0CJz0ksOYAeg8v6dc,7649
9
- sticker_convert/version.py,sha256=C5EXaFbWRR6BU63HDiiI9CxdR6UJMMuL7gTZEPmmC0U,46
6
+ sticker_convert/gui.py,sha256=TRPGwMhSMPHnZppHmw2OWHKTJtGoeLpGWD0eRYi4_yk,30707
7
+ sticker_convert/job.py,sha256=dBo98c5dIbg5ZUY8CEE1XQOSoBuf5VOZc-8pmq0Y1Js,25608
8
+ sticker_convert/job_option.py,sha256=JHAFCxp7-dDwD-1PbpYLAFRF3OoJu8cj_BjOm5r8Gp8,7732
9
+ sticker_convert/version.py,sha256=s6EC7_A6bcTAEEXvg8UKbvmODYWmAfNLeSy3bqzdqAY,46
10
10
  sticker_convert/downloaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  sticker_convert/downloaders/download_base.py,sha256=CcrgZiBOYJbYcDGCPDHp-ECGXSpfmGtQCzS7KRbBl1E,2726
12
12
  sticker_convert/downloaders/download_kakao.py,sha256=UFp7EpMea62fIePY5DfhH4jThAwdeazfoC5iW1g4dAo,8516
13
13
  sticker_convert/downloaders/download_line.py,sha256=9WzOWujTbZdAqBi52k21OUEfRmcV1loCaJiDmg6dklw,17853
14
14
  sticker_convert/downloaders/download_signal.py,sha256=A-paX51kRvXIs6tY9aXv77_DJhBPcTfqZ8ib31yk5ks,3160
15
- sticker_convert/downloaders/download_telegram.py,sha256=JETwy2gSOP2f5DjI636l4uW8Ix8_jzZ6aVzgTpavqC4,4601
15
+ sticker_convert/downloaders/download_telegram.py,sha256=jufMqc78aXOPDr7fQf9ykkNyhQ7KVCp4gRBxs09NgMo,4614
16
16
  sticker_convert/gui_components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  sticker_convert/gui_components/gui_utils.py,sha256=okho2cA1Scem_m6rPiYifreFzpFrM21-yUkiAv64EUI,3431
18
18
  sticker_convert/gui_components/frames/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -25,7 +25,7 @@ sticker_convert/gui_components/frames/output_frame.py,sha256=n2WLk22h61DoZli8WbF
25
25
  sticker_convert/gui_components/frames/progress_frame.py,sha256=LWUZg_iL7iiNTfu7N5Ct_pklZdghxihENi7DP9YozOE,4915
26
26
  sticker_convert/gui_components/frames/right_clicker.py,sha256=dGIvSzEChrkguR80pzUemBNJ39uzJjVJQKeDNUoW3Gk,721
27
27
  sticker_convert/gui_components/windows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
- sticker_convert/gui_components/windows/advanced_compression_window.py,sha256=I3I3seZ5xLTEIsJt3A4t4vsF9ZFY3DmxJVo_yD4HSfA,30639
28
+ sticker_convert/gui_components/windows/advanced_compression_window.py,sha256=leHynwQ4lVEyL4KJ0ySWW2PRPpWRbRV52cghvnb2qCM,31688
29
29
  sticker_convert/gui_components/windows/base_window.py,sha256=xBE1peGMPvWsdrFej0CJUVhmQ57GJGvz-cX03nIIhkE,1108
30
30
  sticker_convert/gui_components/windows/kakao_get_auth_window.py,sha256=AvXB2Q8pAPkKILHTvlLGV9jfBcvskCA4arko4nvBTdo,7115
31
31
  sticker_convert/gui_components/windows/line_get_auth_window.py,sha256=S4ES_lk2-GDvPokZtYALnUc5zW1VbS4WulNqO9K1aSs,3375
@@ -66,16 +66,16 @@ sticker_convert/resources/NotoColorEmoji.ttf,sha256=LurIVaCIA8bSCfjrdO1feYr0bhKL
66
66
  sticker_convert/resources/appicon.icns,sha256=FB2DVTOQcFfQNZ9RcyG3z9c9k7eOiI1qw0IJhXMRFg4,5404
67
67
  sticker_convert/resources/appicon.ico,sha256=-ldugcl2Yq2pBRTktnhGKWInpKyWzRjCiPvMr3XPTlc,38078
68
68
  sticker_convert/resources/appicon.png,sha256=6XBEQz7PnerqS43aRkwpWolFG4WvKMuQ-st1ly-_JPg,5265
69
- sticker_convert/resources/compression.json,sha256=vwn6wLsfsPnNnpjhJHRvzozBI4F_kkb9-eBR8IlyYLo,10833
69
+ sticker_convert/resources/compression.json,sha256=gWD7339773learbiFMGpTzNJVCVj8tS6ELi7yR7yKl8,11163
70
70
  sticker_convert/resources/emoji.json,sha256=sXSuKusyG1L2Stuf9BL5ZqfzOIOdeAeE3RXcrXAsLdY,413367
71
- sticker_convert/resources/help.json,sha256=TUZi_70uVmgImApBUtKieDGEMtu8syVjE0ah8sKEcbk,6470
71
+ sticker_convert/resources/help.json,sha256=7VKc4Oxw6e4zv2IIeYRQ5e_aa88UlsgIHSBm9Tf-V70,6541
72
72
  sticker_convert/resources/input.json,sha256=sRz8qWaLh2KTjjlPIxz2UfynVn2Bn0olywbb8-qT_Hc,2251
73
73
  sticker_convert/resources/output.json,sha256=QYP2gqDvEaAm5I9bH4NReaB1XMLboevv69u-V8YdZUs,1373
74
74
  sticker_convert/uploaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
- sticker_convert/uploaders/compress_wastickers.py,sha256=xNua2pDPD-7Q2Fx9WLo1IlncVs3jVPMN-pxXTswjk8g,5997
75
+ sticker_convert/uploaders/compress_wastickers.py,sha256=SMPf1_ir30ZKO2ChHspDFuyaufx0XeVBVLOlHmawEdY,6021
76
76
  sticker_convert/uploaders/upload_base.py,sha256=uQupPn6r4zrlAzpKzzX7CgvZb69ATyrwPKahWOQj0ds,1203
77
77
  sticker_convert/uploaders/upload_signal.py,sha256=vFMvQ4TwDNliPuQ7ecXHzTT-qrTwPAORbSxZ7Nk9VM4,6541
78
- sticker_convert/uploaders/upload_telegram.py,sha256=Q4dy6Esdatf5WZwffRLnTIsP9zJv_GDlujIRTH46tH4,14621
78
+ sticker_convert/uploaders/upload_telegram.py,sha256=KXQskywHjiVWLDz6qjzJhZk14PNRD3vQ-HNORNa1vNI,14634
79
79
  sticker_convert/uploaders/xcode_imessage.py,sha256=1gvOljf6kYsq_11tYhnF19Yf4oGY5y34te2DWBRMwf0,11254
80
80
  sticker_convert/utils/callback.py,sha256=_w_dZ3DZTA9m4TjEg6NH_VOa5Dl2YHXdXAlwx_tBdoY,6061
81
81
  sticker_convert/utils/url_detect.py,sha256=Cw3SzHj0xQTgCY8KvXbgFGRn_VhDJuZvH0mWsiQOg5s,769
@@ -85,16 +85,16 @@ sticker_convert/utils/auth/get_signal_auth.py,sha256=6Sx-lMuyBHeX1RpjAWI8u03qnRu
85
85
  sticker_convert/utils/files/cache_store.py,sha256=etfe614OAhAyrnM5fGeESKq6R88YLNqkqkxSzEmZ0V0,1047
86
86
  sticker_convert/utils/files/json_manager.py,sha256=Vr6pZJdLMkrJJWN99210aduVHb0ILyf0SSTaw4TZqgc,541
87
87
  sticker_convert/utils/files/json_resources_loader.py,sha256=flZFixUXRTrOAhvRQpuSQgmJ69yXL94sxukcowLT1JQ,1049
88
- sticker_convert/utils/files/metadata_handler.py,sha256=TJpQ-7KdnqQh09hwR6xB_scRLhbJ6D3zgORy3dkf858,9933
88
+ sticker_convert/utils/files/metadata_handler.py,sha256=5ED1UVoAaObgAXe4NZ8sXfsNX7JQvGIqgfCQCjpXRjc,10088
89
89
  sticker_convert/utils/files/run_bin.py,sha256=QalA9je6liHxiOtxsjsFsIkc2t59quhcJCVpP1X3p50,1743
90
90
  sticker_convert/utils/files/sanitize_filename.py,sha256=HBklPGsHRJjFQUIC5rYTQsUrsuTtezZXIEA8CPhLP8A,2156
91
91
  sticker_convert/utils/media/apple_png_normalize.py,sha256=LbrQhc7LlYX4I9ek4XJsZE4l0MygBA1jB-PFiYLEkzk,3657
92
92
  sticker_convert/utils/media/codec_info.py,sha256=SJSFvQzXHnGkj7MH9xJ5xiC4cqiOjFKckFKE_FICdT4,15562
93
93
  sticker_convert/utils/media/decrypt_kakao.py,sha256=4wq9ZDRnFkx1WmFZnyEogBofiLGsWQM_X69HlA36578,1947
94
94
  sticker_convert/utils/media/format_verify.py,sha256=Xf94jyqk_6M9IlFGMy0wYIgQKn_yg00nD4XW0CgAbew,5732
95
- sticker_convert-2.8.1.dist-info/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
96
- sticker_convert-2.8.1.dist-info/METADATA,sha256=BrT7dQzYs0b7LwI4wA7vEEMrLANAx-qwRVpJsQivKg4,49132
97
- sticker_convert-2.8.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
98
- sticker_convert-2.8.1.dist-info/entry_points.txt,sha256=MNJ7XyC--ugxi5jS1nzjDLGnxCyLuaGdsVLnJhDHCqs,66
99
- sticker_convert-2.8.1.dist-info/top_level.txt,sha256=r9vfnB0l1ZnH5pTH5RvkobnK3Ow9m0RsncaOMAtiAtk,16
100
- sticker_convert-2.8.1.dist-info/RECORD,,
95
+ sticker_convert-2.8.3.dist-info/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
96
+ sticker_convert-2.8.3.dist-info/METADATA,sha256=1Z_8zjVrd5RMAilj-dAEVVGBtbYzkchvTDgzeWsfCTA,49284
97
+ sticker_convert-2.8.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
98
+ sticker_convert-2.8.3.dist-info/entry_points.txt,sha256=MNJ7XyC--ugxi5jS1nzjDLGnxCyLuaGdsVLnJhDHCqs,66
99
+ sticker_convert-2.8.3.dist-info/top_level.txt,sha256=r9vfnB0l1ZnH5pTH5RvkobnK3Ow9m0RsncaOMAtiAtk,16
100
+ sticker_convert-2.8.3.dist-info/RECORD,,