sticker-convert 2.7.2__py3-none-any.whl → 2.7.4__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.
Files changed (56) hide show
  1. sticker_convert/__init__.py +1 -0
  2. sticker_convert/__main__.py +3 -1
  3. sticker_convert/cli.py +20 -24
  4. sticker_convert/converter.py +108 -119
  5. sticker_convert/definitions.py +8 -12
  6. sticker_convert/downloaders/download_base.py +14 -31
  7. sticker_convert/downloaders/download_kakao.py +25 -39
  8. sticker_convert/downloaders/download_line.py +24 -33
  9. sticker_convert/downloaders/download_signal.py +7 -16
  10. sticker_convert/downloaders/download_telegram.py +6 -15
  11. sticker_convert/gui.py +53 -61
  12. sticker_convert/gui_components/frames/comp_frame.py +11 -20
  13. sticker_convert/gui_components/frames/config_frame.py +9 -9
  14. sticker_convert/gui_components/frames/control_frame.py +3 -3
  15. sticker_convert/gui_components/frames/cred_frame.py +12 -18
  16. sticker_convert/gui_components/frames/input_frame.py +9 -15
  17. sticker_convert/gui_components/frames/output_frame.py +9 -15
  18. sticker_convert/gui_components/frames/progress_frame.py +8 -8
  19. sticker_convert/gui_components/frames/right_clicker.py +2 -2
  20. sticker_convert/gui_components/gui_utils.py +6 -8
  21. sticker_convert/gui_components/windows/advanced_compression_window.py +23 -32
  22. sticker_convert/gui_components/windows/base_window.py +6 -6
  23. sticker_convert/gui_components/windows/kakao_get_auth_window.py +5 -11
  24. sticker_convert/gui_components/windows/line_get_auth_window.py +5 -5
  25. sticker_convert/gui_components/windows/signal_get_auth_window.py +6 -6
  26. sticker_convert/job.py +84 -90
  27. sticker_convert/job_option.py +36 -32
  28. sticker_convert/resources/emoji.json +334 -70
  29. sticker_convert/resources/help.json +1 -1
  30. sticker_convert/uploaders/compress_wastickers.py +19 -30
  31. sticker_convert/uploaders/upload_base.py +19 -13
  32. sticker_convert/uploaders/upload_signal.py +20 -33
  33. sticker_convert/uploaders/upload_telegram.py +21 -28
  34. sticker_convert/uploaders/xcode_imessage.py +30 -95
  35. sticker_convert/utils/auth/get_kakao_auth.py +7 -8
  36. sticker_convert/utils/auth/get_line_auth.py +5 -6
  37. sticker_convert/utils/auth/get_signal_auth.py +7 -7
  38. sticker_convert/utils/callback.py +31 -23
  39. sticker_convert/utils/files/cache_store.py +6 -8
  40. sticker_convert/utils/files/json_manager.py +6 -7
  41. sticker_convert/utils/files/json_resources_loader.py +12 -0
  42. sticker_convert/utils/files/metadata_handler.py +93 -84
  43. sticker_convert/utils/files/run_bin.py +11 -10
  44. sticker_convert/utils/files/sanitize_filename.py +30 -28
  45. sticker_convert/utils/media/apple_png_normalize.py +3 -2
  46. sticker_convert/utils/media/codec_info.py +41 -44
  47. sticker_convert/utils/media/decrypt_kakao.py +7 -7
  48. sticker_convert/utils/media/format_verify.py +14 -14
  49. sticker_convert/utils/url_detect.py +4 -5
  50. sticker_convert/version.py +2 -1
  51. {sticker_convert-2.7.2.dist-info → sticker_convert-2.7.4.dist-info}/METADATA +19 -17
  52. {sticker_convert-2.7.2.dist-info → sticker_convert-2.7.4.dist-info}/RECORD +56 -55
  53. {sticker_convert-2.7.2.dist-info → sticker_convert-2.7.4.dist-info}/WHEEL +1 -1
  54. {sticker_convert-2.7.2.dist-info → sticker_convert-2.7.4.dist-info}/LICENSE +0 -0
  55. {sticker_convert-2.7.2.dist-info → sticker_convert-2.7.4.dist-info}/entry_points.txt +0 -0
  56. {sticker_convert-2.7.2.dist-info → sticker_convert-2.7.4.dist-info}/top_level.txt +0 -0
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env python3
2
2
  from queue import Queue
3
- from typing import Optional, Union
3
+ from typing import Union
4
4
 
5
5
  from sticker_convert.job_option import CompOption, CredOption, OutputOption
6
- from sticker_convert.utils.callback import Callback, CallbackReturn
6
+ from sticker_convert.utils.callback import Callback, CallbackReturn, CbQueueItemType
7
7
 
8
8
 
9
9
  class UploadBase:
@@ -12,18 +12,9 @@ class UploadBase:
12
12
  opt_output: OutputOption,
13
13
  opt_comp: CompOption,
14
14
  opt_cred: CredOption,
15
- cb: Union[
16
- Queue[
17
- Union[
18
- tuple[str, Optional[tuple[str]], Optional[dict[str, str]]],
19
- str,
20
- None,
21
- ]
22
- ],
23
- Callback,
24
- ],
15
+ cb: "Union[Queue[CbQueueItemType], Callback]",
25
16
  cb_return: CallbackReturn,
26
- ):
17
+ ) -> None:
27
18
  if not cb:
28
19
  cb = Callback(silent=True)
29
20
  cb_return = CallbackReturn()
@@ -33,3 +24,18 @@ class UploadBase:
33
24
  self.opt_cred = opt_cred
34
25
  self.cb = cb
35
26
  self.cb_return = cb_return
27
+
28
+ self.base_spec = CompOption(
29
+ fps_power=self.opt_comp.fps_power,
30
+ res_power=self.opt_comp.res_power,
31
+ quality_min=self.opt_comp.quality_min,
32
+ quality_max=self.opt_comp.quality_max,
33
+ quality_power=self.opt_comp.quality_power,
34
+ color_min=self.opt_comp.color_min,
35
+ color_max=self.opt_comp.color_max,
36
+ color_power=self.opt_comp.color_power,
37
+ quantize_method=self.opt_comp.quantize_method,
38
+ scale_filter=self.opt_comp.scale_filter,
39
+ steps=self.opt_comp.steps,
40
+ cache_dir=self.opt_comp.cache_dir,
41
+ )
@@ -2,47 +2,43 @@
2
2
  import copy
3
3
  from pathlib import Path
4
4
  from queue import Queue
5
- from typing import Any, Optional, Union
5
+ from typing import Any, Dict, List, Union
6
6
 
7
7
  import anyio
8
8
  from signalstickers_client import StickersClient # type: ignore
9
9
  from signalstickers_client.errors import SignalException # type: ignore
10
- from signalstickers_client.models import ( # type: ignore
11
- LocalStickerPack,
12
- Sticker,
13
- )
10
+ from signalstickers_client.models import LocalStickerPack, Sticker # type: ignore
14
11
 
15
12
  from sticker_convert.converter import StickerConvert
16
13
  from sticker_convert.job_option import CompOption, CredOption, OutputOption
17
14
  from sticker_convert.uploaders.upload_base import UploadBase
18
- from sticker_convert.utils.callback import Callback, CallbackReturn
15
+ from sticker_convert.utils.callback import Callback, CallbackReturn, CbQueueItemType
19
16
  from sticker_convert.utils.files.metadata_handler import MetadataHandler
20
17
  from sticker_convert.utils.media.codec_info import CodecInfo
21
18
  from sticker_convert.utils.media.format_verify import FormatVerify
22
19
 
23
20
 
24
21
  class UploadSignal(UploadBase):
25
- def __init__(self, *args: Any, **kwargs: Any):
26
- super(UploadSignal, self).__init__(*args, **kwargs)
22
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
23
+ super().__init__(*args, **kwargs)
27
24
 
28
- base_spec = CompOption()
29
- base_spec.set_size_max(300000)
30
- base_spec.set_res_max(512)
31
- base_spec.duration_max = 3000
32
- base_spec.square = True
25
+ self.base_spec.set_size_max(300000)
26
+ self.base_spec.set_res_max(512)
27
+ self.base_spec.duration_max = 3000
28
+ self.base_spec.square = True
33
29
 
34
- self.png_spec = copy.deepcopy(base_spec)
30
+ self.png_spec = copy.deepcopy(self.base_spec)
35
31
  self.png_spec.set_format((".apng",))
36
32
 
37
- self.webp_spec = copy.deepcopy(base_spec)
33
+ self.webp_spec = copy.deepcopy(self.base_spec)
38
34
  self.webp_spec.format_img = (".webp",)
39
35
  self.webp_spec.animated = False
40
36
 
41
37
  self.opt_comp_merged = copy.deepcopy(self.opt_comp)
42
- self.opt_comp_merged.merge(base_spec)
38
+ self.opt_comp_merged.merge(self.base_spec)
43
39
 
44
40
  @staticmethod
45
- async def upload_pack(pack: LocalStickerPack, uuid: str, password: str):
41
+ async def upload_pack(pack: LocalStickerPack, uuid: str, password: str) -> str:
46
42
  async with StickersClient(uuid, password) as client:
47
43
  pack_id, pack_key = await client.upload_pack(pack) # type: ignore
48
44
 
@@ -52,8 +48,8 @@ class UploadSignal(UploadBase):
52
48
  return result
53
49
 
54
50
  def add_stickers_to_pack(
55
- self, pack: LocalStickerPack, stickers: list[Path], emoji_dict: dict[str, str]
56
- ):
51
+ self, pack: LocalStickerPack, stickers: List[Path], emoji_dict: Dict[str, str]
52
+ ) -> None:
57
53
  for src in stickers:
58
54
  self.cb.put(f"Verifying {src} for uploading to signal")
59
55
 
@@ -96,8 +92,8 @@ class UploadSignal(UploadBase):
96
92
 
97
93
  pack._addsticker(sticker) # type: ignore
98
94
 
99
- def upload_stickers_signal(self) -> list[str]:
100
- urls: list[str] = []
95
+ def upload_stickers_signal(self) -> List[str]:
96
+ urls: List[str] = []
101
97
 
102
98
  if not self.opt_cred.signal_uuid:
103
99
  self.cb.put("uuid required for uploading to Signal")
@@ -121,7 +117,7 @@ class UploadSignal(UploadBase):
121
117
  msg_block += f"Default emoji is set to {self.opt_comp.default_emoji}.\n"
122
118
  msg_block += "Please edit emoji.txt now, then continue"
123
119
  MetadataHandler.generate_emoji_file(
124
- dir=self.opt_output.dir, default_emoji=self.opt_comp.default_emoji
120
+ directory=self.opt_output.dir, default_emoji=self.opt_comp.default_emoji
125
121
  )
126
122
 
127
123
  self.cb.put(("msg_block", (msg_block,), None))
@@ -171,17 +167,8 @@ class UploadSignal(UploadBase):
171
167
  opt_output: OutputOption,
172
168
  opt_comp: CompOption,
173
169
  opt_cred: CredOption,
174
- cb: Union[
175
- Queue[
176
- Union[
177
- tuple[str, Optional[tuple[str]], Optional[dict[str, str]]],
178
- str,
179
- None,
180
- ]
181
- ],
182
- Callback,
183
- ],
170
+ cb: "Union[Queue[CbQueueItemType], Callback]",
184
171
  cb_return: CallbackReturn,
185
- ) -> list[str]:
172
+ ) -> List[str]:
186
173
  exporter = UploadSignal(opt_output, opt_comp, opt_cred, cb, cb_return)
187
174
  return exporter.upload_stickers_signal()
@@ -3,7 +3,7 @@ import copy
3
3
  import re
4
4
  from pathlib import Path
5
5
  from queue import Queue
6
- from typing import Any, Optional, Union, cast
6
+ from typing import Any, Dict, List, Union, cast
7
7
 
8
8
  import anyio
9
9
  from telegram import Bot, InputSticker, Sticker
@@ -12,38 +12,39 @@ from telegram.error import TelegramError
12
12
  from sticker_convert.converter import StickerConvert
13
13
  from sticker_convert.job_option import CompOption, CredOption, OutputOption
14
14
  from sticker_convert.uploaders.upload_base import UploadBase
15
- from sticker_convert.utils.callback import Callback, CallbackReturn
15
+ from sticker_convert.utils.callback import Callback, CallbackReturn, CbQueueItemType
16
16
  from sticker_convert.utils.files.metadata_handler import MetadataHandler
17
17
  from sticker_convert.utils.media.format_verify import FormatVerify
18
18
 
19
19
 
20
20
  class UploadTelegram(UploadBase):
21
- def __init__(self, *args: Any, **kwargs: Any):
22
- super(UploadTelegram, self).__init__(*args, **kwargs)
21
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
22
+ super().__init__(*args, **kwargs)
23
23
 
24
- base_spec = CompOption(
25
- size_max_img=512000, size_max_vid=256000, square=True, duration_max=3000
26
- )
27
- base_spec.set_res(512)
24
+ self.base_spec.size_max_img = 512000
25
+ self.base_spec.size_max_vid = 256000
26
+ self.base_spec.square = True
27
+ self.base_spec.duration_max = 3000
28
+ self.base_spec.set_res(512)
28
29
 
29
- self.png_spec = copy.deepcopy(base_spec)
30
+ self.png_spec = copy.deepcopy(self.base_spec)
30
31
  self.png_spec.set_format((".png",))
31
32
  self.png_spec.animated = False
32
33
 
33
- self.tgs_spec = copy.deepcopy(base_spec)
34
+ self.tgs_spec = copy.deepcopy(self.base_spec)
34
35
  self.tgs_spec.set_format((".tgs",))
35
36
  self.tgs_spec.fps_min = 60
36
37
  self.tgs_spec.fps_max = 60
37
38
  self.tgs_spec.size_max_img = 64000
38
39
  self.tgs_spec.size_max_vid = 64000
39
40
 
40
- self.webm_spec = copy.deepcopy(base_spec)
41
+ self.webm_spec = copy.deepcopy(self.base_spec)
41
42
  self.webm_spec.set_format((".webm",))
42
43
  self.webm_spec.fps_max = 30
43
44
  self.webm_spec.animated = None if self.opt_comp.fake_vid else True
44
45
 
45
46
  self.opt_comp_merged = copy.deepcopy(self.opt_comp)
46
- self.opt_comp_merged.merge(base_spec)
47
+ self.opt_comp_merged.merge(self.base_spec)
47
48
 
48
49
  base_cover_spec = CompOption(
49
50
  size_max_img=128000, size_max_vid=32000, square=True, duration_max=3000
@@ -65,10 +66,10 @@ class UploadTelegram(UploadBase):
65
66
  self.webm_cover_spec.animated = True
66
67
 
67
68
  self.opt_comp_cover_merged = copy.deepcopy(self.opt_comp)
68
- self.opt_comp_cover_merged.merge(base_spec)
69
+ self.opt_comp_cover_merged.merge(self.base_spec)
69
70
 
70
71
  async def upload_pack(
71
- self, pack_title: str, stickers: list[Path], emoji_dict: dict[str, str]
72
+ self, pack_title: str, stickers: List[Path], emoji_dict: Dict[str, str]
72
73
  ) -> str:
73
74
  assert self.opt_cred.telegram_token
74
75
  bot = Bot(self.opt_cred.telegram_token.strip())
@@ -208,6 +209,7 @@ class UploadTelegram(UploadBase):
208
209
  Path(f"bytes{ext}"), # type: ignore
209
210
  self.opt_comp_cover_merged,
210
211
  self.cb,
212
+ self.cb_return,
211
213
  )
212
214
 
213
215
  try:
@@ -227,8 +229,8 @@ class UploadTelegram(UploadBase):
227
229
  result = f"https://t.me/addstickers/{pack_short_name}"
228
230
  return result
229
231
 
230
- def upload_stickers_telegram(self) -> list[str]:
231
- urls: list[str] = []
232
+ def upload_stickers_telegram(self) -> List[str]:
233
+ urls: List[str] = []
232
234
 
233
235
  if not (self.opt_cred.telegram_token and self.opt_cred.telegram_userid):
234
236
  self.cb.put("Token and userid required for uploading to telegram")
@@ -247,7 +249,7 @@ class UploadTelegram(UploadBase):
247
249
  msg_block += f"Default emoji is set to {self.opt_comp.default_emoji}.\n"
248
250
  msg_block += "Please edit emoji.txt now, then continue"
249
251
  MetadataHandler.generate_emoji_file(
250
- dir=self.opt_output.dir, default_emoji=self.opt_comp.default_emoji
252
+ directory=self.opt_output.dir, default_emoji=self.opt_comp.default_emoji
251
253
  )
252
254
 
253
255
  self.cb.put(("msg_block", (msg_block,), None))
@@ -281,18 +283,9 @@ class UploadTelegram(UploadBase):
281
283
  opt_output: OutputOption,
282
284
  opt_comp: CompOption,
283
285
  opt_cred: CredOption,
284
- cb: Union[
285
- Queue[
286
- Union[
287
- tuple[str, Optional[tuple[str]], Optional[dict[str, str]]],
288
- str,
289
- None,
290
- ]
291
- ],
292
- Callback,
293
- ],
286
+ cb: "Union[Queue[CbQueueItemType], Callback]",
294
287
  cb_return: CallbackReturn,
295
- ) -> list[str]:
288
+ ) -> List[str]:
296
289
  exporter = UploadTelegram(
297
290
  opt_output,
298
291
  opt_comp,
@@ -7,93 +7,37 @@ import shutil
7
7
  import zipfile
8
8
  from pathlib import Path
9
9
  from queue import Queue
10
- from typing import Any, Optional, Union
10
+ from typing import Any, Dict, List, Union
11
11
 
12
12
  from sticker_convert.converter import StickerConvert
13
13
  from sticker_convert.definitions import ROOT_DIR
14
14
  from sticker_convert.job_option import CompOption, CredOption, OutputOption
15
15
  from sticker_convert.uploaders.upload_base import UploadBase
16
- from sticker_convert.utils.callback import Callback, CallbackReturn
17
- from sticker_convert.utils.files.metadata_handler import MetadataHandler
16
+ from sticker_convert.utils.callback import Callback, CallbackReturn, CbQueueItemType
17
+ from sticker_convert.utils.files.metadata_handler import XCODE_IMESSAGE_ICONSET, MetadataHandler
18
18
  from sticker_convert.utils.files.sanitize_filename import sanitize_filename
19
19
  from sticker_convert.utils.media.codec_info import CodecInfo
20
20
  from sticker_convert.utils.media.format_verify import FormatVerify
21
21
 
22
22
 
23
- class XcodeImessageIconset:
24
- iconset: dict[str, tuple[int, int]] = {}
25
-
26
- def __init__(self):
27
- if self.iconset != {}:
28
- return
29
-
30
- if (ROOT_DIR / "ios-message-stickers-template").is_dir():
31
- with open(
32
- ROOT_DIR
33
- / "ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Contents.json"
34
- ) as f:
35
- dict = json.load(f)
36
- elif (ROOT_DIR / "ios-message-stickers-template.zip").is_file():
37
- with zipfile.ZipFile(
38
- (ROOT_DIR / "ios-message-stickers-template.zip"), "r"
39
- ) as f:
40
- dict = json.loads(
41
- f.read(
42
- "stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Contents.json"
43
- ).decode()
44
- )
45
- else:
46
- raise FileNotFoundError("ios-message-stickers-template not found")
47
-
48
- for i in dict["images"]:
49
- filename = i["filename"]
50
- size = i["size"]
51
- size_w = int(size.split("x")[0])
52
- size_h = int(size.split("x")[1])
53
- scale = int(i["scale"].replace("x", ""))
54
- size_w_scaled = size_w * scale
55
- size_h_scaled = size_h * scale
56
-
57
- self.iconset[filename] = (size_w_scaled, size_h_scaled)
58
-
59
- # self.iconset = {
60
- # 'App-Store-1024x1024pt.png': (1024, 1024),
61
- # 'iPad-Settings-29pt@2x.png': (58, 58),
62
- # 'iPhone-settings-29pt@2x.png': (58, 58),
63
- # 'iPhone-settings-29pt@3x.png': (87, 87),
64
- # 'Messages27x20pt@2x.png': (54, 40),
65
- # 'Messages27x20pt@3x.png': (81, 60),
66
- # 'Messages32x24pt@2x.png': (64, 48),
67
- # 'Messages32x24pt@3x.png': (96, 72),
68
- # 'Messages-App-Store-1024x768pt.png': (1024, 768),
69
- # 'Messages-iPad-67x50pt@2x.png': (134, 100),
70
- # 'Messages-iPad-Pro-74x55pt@2x.png': (148, 110),
71
- # 'Messages-iPhone-60x45pt@2x.png': (120, 90),
72
- # 'Messages-iPhone-60x45pt@3x.png': (180, 135)
73
- # }
74
-
75
-
76
23
  class XcodeImessage(UploadBase):
77
- def __init__(self, *args: Any, **kwargs: Any):
78
- super(XcodeImessage, self).__init__(*args, **kwargs)
79
- self.iconset = XcodeImessageIconset().iconset
80
-
81
- base_spec = CompOption()
82
- base_spec.set_size_max(500000)
83
- base_spec.set_res(300)
84
- base_spec.set_format(("png", ".apng", ".gif", ".jpeg", "jpg"))
85
- base_spec.square = True
24
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
25
+ super().__init__(*args, **kwargs)
26
+ self.base_spec.set_size_max(500000)
27
+ self.base_spec.set_res(300)
28
+ self.base_spec.set_format(("png", ".apng", ".gif", ".jpeg", "jpg"))
29
+ self.base_spec.square = True
86
30
 
87
- self.small_spec = copy.deepcopy(base_spec)
31
+ self.small_spec = copy.deepcopy(self.base_spec)
88
32
 
89
- self.medium_spec = copy.deepcopy(base_spec)
33
+ self.medium_spec = copy.deepcopy(self.base_spec)
90
34
  self.medium_spec.set_res(408)
91
35
 
92
- self.large_spec = copy.deepcopy(base_spec)
36
+ self.large_spec = copy.deepcopy(self.base_spec)
93
37
  self.large_spec.set_res(618)
94
38
 
95
- def create_imessage_xcode(self) -> list[str]:
96
- urls: list[str] = []
39
+ def create_imessage_xcode(self) -> List[str]:
40
+ urls: List[str] = []
97
41
  title, author, _ = MetadataHandler.get_metadata(
98
42
  self.opt_output.dir,
99
43
  title=self.opt_output.title,
@@ -155,7 +99,7 @@ class XcodeImessage(UploadBase):
155
99
 
156
100
  return urls
157
101
 
158
- def add_metadata(self, author: str, title: str):
102
+ def add_metadata(self, author: str, title: str) -> None:
159
103
  first_image_path = Path(
160
104
  self.opt_output.dir,
161
105
  [
@@ -170,16 +114,16 @@ class XcodeImessage(UploadBase):
170
114
  else:
171
115
  icon_source = first_image_path
172
116
 
173
- for icon, res in self.iconset.items():
117
+ for icon, res in XCODE_IMESSAGE_ICONSET.items():
174
118
  spec_cover = CompOption()
175
119
  spec_cover.set_res_w(res[0])
176
120
  spec_cover.set_res_h(res[1])
177
121
  spec_cover.set_fps(0)
178
122
 
179
123
  icon_path = self.opt_output.dir / icon
180
- if Path(icon) in [
181
- i for i in self.opt_output.dir.iterdir()
182
- ] and not FormatVerify.check_file(icon_path, spec=spec_cover):
124
+ if Path(icon) in list(
125
+ self.opt_output.dir.iterdir()
126
+ ) and not FormatVerify.check_file(icon_path, spec=spec_cover):
183
127
  StickerConvert.convert(
184
128
  icon_path, icon_path, spec_cover, self.cb, self.cb_return
185
129
  )
@@ -190,7 +134,7 @@ class XcodeImessage(UploadBase):
190
134
 
191
135
  MetadataHandler.set_metadata(self.opt_output.dir, author=author, title=title)
192
136
 
193
- def create_xcode_proj(self, author: str, title: str):
137
+ def create_xcode_proj(self, author: str, title: str) -> None:
194
138
  pack_path = self.opt_output.dir / title
195
139
  if (ROOT_DIR / "ios-message-stickers-template.zip").is_file():
196
140
  with zipfile.ZipFile(
@@ -260,12 +204,12 @@ class XcodeImessage(UploadBase):
260
204
  if i.suffix == ".sticker":
261
205
  shutil.rmtree(stickers_path / i)
262
206
 
263
- stickers_lst: list[str] = []
207
+ stickers_lst: List[str] = []
264
208
  for i in sorted(self.opt_output.dir.iterdir()):
265
209
  if (
266
210
  CodecInfo.get_file_ext(i) == ".png"
267
211
  and i.stem != "cover"
268
- and i.name not in self.iconset
212
+ and i.name not in XCODE_IMESSAGE_ICONSET
269
213
  ):
270
214
  sticker_dir = f"{i.stem}.sticker" # 0.sticker
271
215
  stickers_lst.append(sticker_dir)
@@ -284,18 +228,18 @@ class XcodeImessage(UploadBase):
284
228
  }
285
229
 
286
230
  # packname StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/0.sticker/Contents.json
287
- with open(sticker_path / "Contents.json", "w+") as f:
231
+ with open(sticker_path / "Contents.json", "w+", encoding="utf-8") as f:
288
232
  json.dump(sticker_json_content, f, indent=2)
289
233
 
290
234
  # packname StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Contents.json
291
- with open(stickers_path / "Contents.json") as f:
292
- stickerpack_json_content: dict[str, list[dict[str, str]]] = json.load(f)
235
+ with open(stickers_path / "Contents.json", encoding="utf-8") as f:
236
+ stickerpack_json_content: Dict[str, List[Dict[str, str]]] = json.load(f)
293
237
 
294
238
  stickerpack_json_content["stickers"] = []
295
239
  for sticker in stickers_lst:
296
240
  stickerpack_json_content["stickers"].append({"filename": sticker})
297
241
 
298
- with open(stickers_path / "Contents.json", "w+") as f:
242
+ with open(stickers_path / "Contents.json", "w+", encoding="utf-8") as f:
299
243
  json.dump(stickerpack_json_content, f, indent=2)
300
244
 
301
245
  # packname StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset
@@ -308,8 +252,8 @@ class XcodeImessage(UploadBase):
308
252
  if Path(iconfile_name).suffix == ".png":
309
253
  os.remove(iconset_path / iconfile_name)
310
254
 
311
- icons_lst: list[str] = []
312
- for icon in self.iconset:
255
+ icons_lst: List[str] = []
256
+ for icon in XCODE_IMESSAGE_ICONSET:
313
257
  shutil.copy(self.opt_output.dir / icon, iconset_path / icon)
314
258
  icons_lst.append(icon)
315
259
 
@@ -335,17 +279,8 @@ class XcodeImessage(UploadBase):
335
279
  opt_output: OutputOption,
336
280
  opt_comp: CompOption,
337
281
  opt_cred: CredOption,
338
- cb: Union[
339
- Queue[
340
- Union[
341
- tuple[str, Optional[tuple[str]], Optional[dict[str, str]]],
342
- str,
343
- None,
344
- ]
345
- ],
346
- Callback,
347
- ],
282
+ cb: "Union[Queue[CbQueueItemType], Callback]",
348
283
  cb_return: CallbackReturn,
349
- ) -> list[str]:
284
+ ) -> List[str]:
350
285
  exporter = XcodeImessage(opt_output, opt_comp, opt_cred, cb, cb_return)
351
286
  return exporter.create_imessage_xcode()
@@ -2,7 +2,7 @@
2
2
  import json
3
3
  import secrets
4
4
  import uuid
5
- from typing import Any, Callable, Optional
5
+ from typing import Any, Callable, Dict, Optional
6
6
  from urllib.parse import parse_qs, urlparse
7
7
 
8
8
  import requests
@@ -17,7 +17,7 @@ class GetKakaoAuth:
17
17
  cb_msg: Callable[..., None] = print,
18
18
  cb_msg_block: Callable[..., Any] = input,
19
19
  cb_ask_str: Callable[..., str] = input,
20
- ):
20
+ ) -> None:
21
21
  self.username = opt_cred.kakao_username
22
22
  self.password = opt_cred.kakao_password
23
23
  self.country_code = opt_cred.kakao_country_code
@@ -92,7 +92,7 @@ class GetKakaoAuth:
92
92
  def enter_phone(self) -> bool:
93
93
  self.cb_msg("Submitting phone number")
94
94
 
95
- json_data: dict[str, Any] = {
95
+ json_data: Dict[str, Any] = {
96
96
  "countryCode": self.country_code,
97
97
  "countryIso": self.country_iso,
98
98
  "phoneNumber": self.phone_number,
@@ -117,13 +117,12 @@ class GetKakaoAuth:
117
117
 
118
118
  if self.verify_method == "passcode":
119
119
  return self.verify_receive_sms()
120
- elif self.verify_method == "mo-send":
120
+ if self.verify_method == "mo-send":
121
121
  dest_number = response_json["viewData"]["moNumber"]
122
122
  msg = response_json["viewData"]["moMessage"]
123
123
  return self.verify_send_sms(dest_number, msg)
124
- else:
125
- self.cb_msg_block(f"Unknown verification method: {response.text}")
126
- return False
124
+ self.cb_msg_block(f"Unknown verification method: {response.text}")
125
+ return False
127
126
 
128
127
  def verify_send_sms(self, dest_number: str, msg: str) -> bool:
129
128
  self.cb_msg("Verification by sending SMS")
@@ -210,7 +209,7 @@ class GetKakaoAuth:
210
209
  "Connection": "close",
211
210
  }
212
211
 
213
- json_data: dict[str, str] = {
212
+ json_data: Dict[str, str] = {
214
213
  "decision": "continue",
215
214
  "lang": self.app_language,
216
215
  "sessionToken": session_token,
@@ -2,15 +2,15 @@
2
2
  import json
3
3
  import platform
4
4
  from http.cookiejar import CookieJar
5
- from typing import Any, Callable, Optional, Union
5
+ from typing import Any, Callable, Dict, List, Optional, Union
6
6
 
7
7
  import requests
8
- import rookiepy
8
+ import rookiepy # type: ignore
9
9
 
10
10
 
11
11
  class GetLineAuth:
12
12
  def get_cred(self) -> Optional[str]:
13
- browsers: list[Callable[..., Any]] = [
13
+ browsers: List[Callable[..., Any]] = [
14
14
  rookiepy.load, # type: ignore # Supposed to load from any browser, but may fail
15
15
  rookiepy.firefox, # type: ignore
16
16
  rookiepy.libre_wolf, # type: ignore
@@ -59,7 +59,7 @@ class GetLineAuth:
59
59
  return cookies
60
60
 
61
61
  @staticmethod
62
- def validate_cookies(cookies: Union[CookieJar, dict[str, str]]) -> bool:
62
+ def validate_cookies(cookies: Union[CookieJar, Dict[str, str]]) -> bool:
63
63
  headers = {
64
64
  "x-requested-with": "XMLHttpRequest",
65
65
  }
@@ -77,5 +77,4 @@ class GetLineAuth:
77
77
 
78
78
  if response_dict["errorMessage"]:
79
79
  return False
80
- else:
81
- return True
80
+ return True
@@ -4,13 +4,13 @@ import os
4
4
  import platform
5
5
  import shutil
6
6
  from pathlib import Path
7
- from typing import Optional
7
+ from typing import Optional, Tuple
8
8
 
9
9
  from sqlcipher3 import dbapi2 as sqlite3
10
10
 
11
11
 
12
12
  class GetSignalAuth:
13
- def get_signal_desktop(self) -> tuple[Optional[str], Optional[str]]:
13
+ def get_signal_desktop(self) -> Tuple[Optional[str], Optional[str]]:
14
14
  if platform.system() == "Windows":
15
15
  signal_bin_path_prod = os.path.expandvars(
16
16
  "%localappdata%/Programs/signal-desktop/Signal.exe"
@@ -45,16 +45,16 @@ class GetSignalAuth:
45
45
 
46
46
  if Path(signal_bin_path_prod).is_file():
47
47
  return signal_bin_path_prod, signal_user_data_dir_prod
48
- elif Path(signal_bin_path_beta).is_file():
48
+ if Path(signal_bin_path_beta).is_file():
49
49
  return signal_bin_path_beta, signal_user_data_dir_beta
50
- else:
51
- return None, None
50
+
51
+ return None, None
52
52
 
53
53
  def get_cred(
54
54
  self,
55
55
  signal_bin_path: Optional[str] = None,
56
56
  signal_user_data_dir: Optional[str] = None,
57
- ) -> tuple[Optional[str], Optional[str], str]:
57
+ ) -> Tuple[Optional[str], Optional[str], str]:
58
58
  if not (signal_bin_path and signal_user_data_dir):
59
59
  signal_bin_path, signal_user_data_dir = self.get_signal_desktop()
60
60
 
@@ -76,7 +76,7 @@ class GetSignalAuth:
76
76
  msg += f"{signal_user_data_dir=}\n"
77
77
  return None, None, msg
78
78
 
79
- with open(signal_config) as f:
79
+ with open(signal_config, encoding="utf-8") as f:
80
80
  config = json.load(f)
81
81
  key = config.get("key")
82
82
  db_key = f"x'{key}'"