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.
Files changed (57) hide show
  1. sticker_convert/__init__.py +1 -1
  2. sticker_convert/__main__.py +7 -4
  3. sticker_convert/cli.py +42 -32
  4. sticker_convert/converter.py +432 -0
  5. sticker_convert/downloaders/download_base.py +40 -16
  6. sticker_convert/downloaders/download_kakao.py +103 -136
  7. sticker_convert/downloaders/download_line.py +30 -12
  8. sticker_convert/downloaders/download_signal.py +48 -32
  9. sticker_convert/downloaders/download_telegram.py +71 -26
  10. sticker_convert/gui.py +79 -130
  11. sticker_convert/{gui_frames → gui_components/frames}/comp_frame.py +2 -3
  12. sticker_convert/{gui_frames → gui_components/frames}/config_frame.py +3 -4
  13. sticker_convert/{gui_frames → gui_components/frames}/control_frame.py +2 -2
  14. sticker_convert/{gui_frames → gui_components/frames}/cred_frame.py +4 -4
  15. sticker_convert/{gui_frames → gui_components/frames}/input_frame.py +4 -4
  16. sticker_convert/{gui_frames → gui_components/frames}/output_frame.py +3 -3
  17. sticker_convert/{gui_frames → gui_components/frames}/progress_frame.py +1 -1
  18. sticker_convert/{utils → gui_components}/gui_utils.py +38 -21
  19. sticker_convert/{gui_windows → gui_components/windows}/advanced_compression_window.py +3 -2
  20. sticker_convert/{gui_windows → gui_components/windows}/base_window.py +3 -2
  21. sticker_convert/{gui_windows → gui_components/windows}/kakao_get_auth_window.py +3 -3
  22. sticker_convert/{gui_windows → gui_components/windows}/line_get_auth_window.py +2 -2
  23. sticker_convert/{gui_windows → gui_components/windows}/signal_get_auth_window.py +2 -2
  24. sticker_convert/{flow.py → job.py} +91 -102
  25. sticker_convert/job_option.py +301 -0
  26. sticker_convert/resources/compression.json +1 -1
  27. sticker_convert/uploaders/compress_wastickers.py +95 -74
  28. sticker_convert/uploaders/upload_base.py +16 -4
  29. sticker_convert/uploaders/upload_signal.py +100 -62
  30. sticker_convert/uploaders/upload_telegram.py +168 -128
  31. sticker_convert/uploaders/xcode_imessage.py +202 -132
  32. sticker_convert/{auth → utils/auth}/get_kakao_auth.py +7 -5
  33. sticker_convert/{auth → utils/auth}/get_line_auth.py +6 -5
  34. sticker_convert/{auth → utils/auth}/get_signal_auth.py +1 -1
  35. sticker_convert/utils/fake_cb_msg.py +5 -2
  36. sticker_convert/utils/{cache_store.py → files/cache_store.py} +7 -3
  37. sticker_convert/utils/files/dir_utils.py +64 -0
  38. sticker_convert/utils/{json_manager.py → files/json_manager.py} +5 -4
  39. sticker_convert/utils/files/metadata_handler.py +226 -0
  40. sticker_convert/utils/files/run_bin.py +58 -0
  41. sticker_convert/utils/{apple_png_normalize.py → media/apple_png_normalize.py} +23 -20
  42. sticker_convert/utils/{codec_info.py → media/codec_info.py} +41 -35
  43. sticker_convert/utils/media/decrypt_kakao.py +68 -0
  44. sticker_convert/utils/media/format_verify.py +184 -0
  45. sticker_convert/utils/url_detect.py +16 -14
  46. {sticker_convert-2.1.5.dist-info → sticker_convert-2.1.7.dist-info}/METADATA +11 -11
  47. {sticker_convert-2.1.5.dist-info → sticker_convert-2.1.7.dist-info}/RECORD +52 -50
  48. {sticker_convert-2.1.5.dist-info → sticker_convert-2.1.7.dist-info}/WHEEL +1 -1
  49. sticker_convert/utils/converter.py +0 -399
  50. sticker_convert/utils/curr_dir.py +0 -70
  51. sticker_convert/utils/format_verify.py +0 -188
  52. sticker_convert/utils/metadata_handler.py +0 -190
  53. sticker_convert/utils/run_bin.py +0 -46
  54. /sticker_convert/{gui_frames → gui_components/frames}/right_clicker.py +0 -0
  55. {sticker_convert-2.1.5.dist-info → sticker_convert-2.1.7.dist-info}/LICENSE +0 -0
  56. {sticker_convert-2.1.5.dist-info → sticker_convert-2.1.7.dist-info}/entry_points.txt +0 -0
  57. {sticker_convert-2.1.5.dist-info → sticker_convert-2.1.7.dist-info}/top_level.txt +0 -0
@@ -7,38 +7,47 @@ import plistlib
7
7
  from typing import Optional
8
8
  import zipfile
9
9
 
10
- from mergedeep import merge # type: ignore
10
+ from .upload_base import UploadBase # type: ignore
11
+ from ..converter import StickerConvert # type: ignore
12
+ from ..utils.media.format_verify import FormatVerify # type: ignore
13
+ from ..utils.media.codec_info import CodecInfo # type: ignore
14
+ from ..utils.files.metadata_handler import MetadataHandler # type: ignore
15
+ from ..job_option import CompOption, OutputOption, CredOption # type: ignore
11
16
 
12
- from .upload_base import UploadBase # type: ignore
13
- from ..utils.converter import StickerConvert # type: ignore
14
- from ..utils.format_verify import FormatVerify # type: ignore
15
- from ..utils.metadata_handler import MetadataHandler # type: ignore
16
- from ..utils.codec_info import CodecInfo # type: ignore
17
17
 
18
18
  class XcodeImessageIconset:
19
+ iconset = {}
20
+
19
21
  def __init__(self):
20
- self.iconset = {}
22
+ if self.iconset != {}:
23
+ return
21
24
 
22
- if os.path.isdir('ios-message-stickers-template'):
23
- with open('ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Contents.json') as f:
25
+ if os.path.isdir("ios-message-stickers-template"):
26
+ with open(
27
+ "ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Contents.json"
28
+ ) as f:
24
29
  dict = json.load(f)
25
- elif os.path.isfile('ios-message-stickers-template.zip'):
26
- with zipfile.ZipFile('ios-message-stickers-template.zip', 'r') as f:
27
- dict = json.loads(f.read('stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Contents.json').decode())
30
+ elif os.path.isfile("ios-message-stickers-template.zip"):
31
+ with zipfile.ZipFile("ios-message-stickers-template.zip", "r") as f:
32
+ dict = json.loads(
33
+ f.read(
34
+ "stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Contents.json"
35
+ ).decode()
36
+ )
28
37
  else:
29
- raise FileNotFoundError('ios-message-stickers-template not found')
30
-
31
- for i in dict['images']:
32
- filename = i['filename']
33
- size = i['size']
34
- size_w = int(size.split('x')[0])
35
- size_h = int(size.split('x')[1])
36
- scale = int(i['scale'].replace('x', ''))
38
+ raise FileNotFoundError("ios-message-stickers-template not found")
39
+
40
+ for i in dict["images"]:
41
+ filename = i["filename"]
42
+ size = i["size"]
43
+ size_w = int(size.split("x")[0])
44
+ size_h = int(size.split("x")[1])
45
+ scale = int(i["scale"].replace("x", ""))
37
46
  size_w_scaled = size_w * scale
38
47
  size_h_scaled = size_h * scale
39
48
 
40
49
  self.iconset[filename] = (size_w_scaled, size_h_scaled)
41
-
50
+
42
51
  # self.iconset = {
43
52
  # 'App-Store-1024x1024pt.png': (1024, 1024),
44
53
  # 'iPad-Settings-29pt@2x.png': (58, 58),
@@ -56,51 +65,38 @@ class XcodeImessageIconset:
56
65
  # }
57
66
 
58
67
 
59
-
60
68
  class XcodeImessage(UploadBase):
61
69
  def __init__(self, *args, **kwargs):
62
70
  super(XcodeImessage, self).__init__(*args, **kwargs)
63
71
  self.iconset = XcodeImessageIconset().iconset
64
72
 
65
- base_spec = {
66
- "size_max": {
67
- "img": 500000,
68
- "vid": 500000
69
- },
70
- 'res': {
71
- 'w': {
72
- 'min': 300,
73
- 'max': 300
74
- },
75
- 'h': {
76
- 'min': 300,
77
- 'max': 300
78
- }
79
- },
80
- 'format': ('.png', '.apng', '.gif', '.jpeg', 'jpg'),
81
- 'square': True
82
- }
73
+ base_spec = CompOption({
74
+ "size_max": {"img": 500000, "vid": 500000},
75
+ "res": 300,
76
+ "format": [".png", ".apng", ".gif", ".jpeg", "jpg"],
77
+ "square": True,
78
+ })
83
79
 
84
80
  self.small_spec = copy.deepcopy(base_spec)
85
81
 
86
82
  self.medium_spec = copy.deepcopy(base_spec)
87
- self.medium_spec['res']['w']['min'] = 408
88
- self.medium_spec['res']['w']['max'] = 408
89
- self.medium_spec['res']['h']['min'] = 408
90
- self.medium_spec['res']['h']['max'] = 408
83
+ self.medium_spec.res = 408
91
84
 
92
85
  self.large_spec = copy.deepcopy(base_spec)
93
- self.large_spec['res']['w']['min'] = 618
94
- self.large_spec['res']['w']['max'] = 618
95
- self.large_spec['res']['h']['min'] = 618
96
- self.large_spec['res']['h']['max'] = 618
97
-
86
+ self.large_spec.res = 618
87
+
98
88
  def create_imessage_xcode(self) -> list[str]:
99
89
  urls = []
100
- title, author, emoji_dict = MetadataHandler.get_metadata(self.in_dir, title=self.opt_output.get('title'), author=self.opt_output.get('author'))
101
- author = author.replace(' ', '_')
102
- title = title.replace(' ', '_')
103
- packs = MetadataHandler.split_sticker_packs(self.in_dir, title=title, file_per_pack=100, separate_image_anim=False)
90
+ title, author, emoji_dict = MetadataHandler.get_metadata(
91
+ self.in_dir,
92
+ title=self.opt_output.title,
93
+ author=self.opt_output.author,
94
+ )
95
+ author = author.replace(" ", "_")
96
+ title = title.replace(" ", "_")
97
+ packs = MetadataHandler.split_sticker_packs(
98
+ self.in_dir, title=title, file_per_pack=100, separate_image_anim=False
99
+ )
104
100
 
105
101
  res_choice = None
106
102
 
@@ -108,7 +104,7 @@ class XcodeImessage(UploadBase):
108
104
  pack_title = FormatVerify.sanitize_filename(pack_title)
109
105
 
110
106
  for src in stickers:
111
- self.cb_msg(f'Verifying {src} for creating Xcode iMessage sticker pack')
107
+ self.cb_msg(f"Verifying {src} for creating Xcode iMessage sticker pack")
112
108
 
113
109
  src_path = os.path.join(self.in_dir, src)
114
110
  dst_path = os.path.join(self.out_dir, src)
@@ -116,7 +112,7 @@ class XcodeImessage(UploadBase):
116
112
  if res_choice == None:
117
113
  res_choice, _ = CodecInfo.get_file_res(src_path)
118
114
  res_choice = res_choice if res_choice != None else 300
119
-
115
+
120
116
  if res_choice == 618:
121
117
  spec_choice = self.large_spec
122
118
  elif res_choice == 408:
@@ -124,14 +120,17 @@ class XcodeImessage(UploadBase):
124
120
  else:
125
121
  # res_choice == 300
126
122
  spec_choice = self.small_spec
127
-
128
- opt_comp_merged = merge({}, self.opt_comp, spec_choice)
123
+
124
+ opt_comp_merged = copy.deepcopy(self.opt_comp)
125
+ opt_comp_merged.merge(spec_choice)
129
126
 
130
127
  if FormatVerify.check_file(src, spec=spec_choice):
131
128
  if src_path != dst_path:
132
129
  shutil.copy(src_path, dst_path)
133
130
  else:
134
- StickerConvert(src_path, dst_path, opt_comp_merged, self.cb_msg).convert()
131
+ StickerConvert(
132
+ src_path, dst_path, opt_comp_merged, self.cb_msg
133
+ ).convert()
135
134
 
136
135
  self.add_metadata(author, pack_title)
137
136
  self.create_xcode_proj(author, pack_title)
@@ -139,11 +138,18 @@ class XcodeImessage(UploadBase):
139
138
  result = os.path.join(self.out_dir, pack_title)
140
139
  self.cb_msg(result)
141
140
  urls.append(result)
142
-
141
+
143
142
  return urls
144
143
 
145
144
  def add_metadata(self, author: str, title: str):
146
- first_image_path = os.path.join(self.in_dir, [i for i in sorted(os.listdir(self.in_dir)) if os.path.isfile(os.path.join(self.in_dir, i)) and i.endswith('.png')][0])
145
+ first_image_path = os.path.join(
146
+ self.in_dir,
147
+ [
148
+ i
149
+ for i in sorted(os.listdir(self.in_dir))
150
+ if os.path.isfile(os.path.join(self.in_dir, i)) and i.endswith(".png")
151
+ ][0],
152
+ )
147
153
  cover_path = MetadataHandler.get_cover(self.in_dir)
148
154
  if cover_path:
149
155
  icon_source = cover_path
@@ -151,70 +157,106 @@ class XcodeImessage(UploadBase):
151
157
  icon_source = first_image_path
152
158
 
153
159
  for icon, res in self.iconset.items():
154
- spec_cover = {
160
+ spec_cover = CompOption({
155
161
  "res": {
156
- "w": {
157
- "min": res[0],
158
- "max": res[0]
159
- },
160
- "h": {
161
- "min": res[1],
162
- "max": res[1]
163
- }
162
+ "w": res[0],
163
+ "h": res[1]
164
164
  }
165
- }
165
+ })
166
166
 
167
167
  icon_old_path = os.path.join(self.in_dir, icon)
168
168
  icon_new_path = os.path.join(self.out_dir, icon)
169
- if icon in os.listdir(self.in_dir) and not FormatVerify.check_file(icon_old_path, spec=spec_cover):
170
- StickerConvert(icon_old_path, icon_new_path, spec_cover, self.cb_msg).convert()
169
+ if icon in os.listdir(self.in_dir) and not FormatVerify.check_file(
170
+ icon_old_path, spec=spec_cover
171
+ ):
172
+ StickerConvert(
173
+ icon_old_path, icon_new_path, spec_cover, self.cb_msg
174
+ ).convert()
171
175
  else:
172
- StickerConvert(icon_source, icon_new_path, spec_cover, self.cb_msg).convert()
173
-
176
+ StickerConvert(
177
+ icon_source, icon_new_path, spec_cover, self.cb_msg
178
+ ).convert()
179
+
174
180
  MetadataHandler.set_metadata(self.out_dir, author=author, title=title)
175
181
 
176
182
  def create_xcode_proj(self, author: str, title: str):
177
183
  pack_path = os.path.join(self.out_dir, title)
178
- if os.path.isfile('ios-message-stickers-template.zip'):
179
- with zipfile.ZipFile('ios-message-stickers-template.zip', 'r') as f:
184
+ if os.path.isfile("ios-message-stickers-template.zip"):
185
+ with zipfile.ZipFile("ios-message-stickers-template.zip", "r") as f:
180
186
  f.extractall(pack_path)
181
- elif os.path.isdir('ios-message-stickers-template'):
182
- shutil.copytree('ios-message-stickers-template', pack_path)
187
+ elif os.path.isdir("ios-message-stickers-template"):
188
+ shutil.copytree("ios-message-stickers-template", pack_path)
183
189
  else:
184
- self.cb_msg('Failed to create Xcode project: ios-message-stickers-template not found')
185
-
186
- os.remove(os.path.join(pack_path, 'README.md'))
187
- shutil.rmtree(os.path.join(pack_path, 'stickers.xcodeproj/project.xcworkspace'), ignore_errors=True)
188
- shutil.rmtree(os.path.join(pack_path, 'stickers.xcodeproj/xcuserdata'), ignore_errors=True)
189
-
190
- with open(os.path.join(pack_path, 'stickers.xcodeproj/project.pbxproj'), encoding='utf-8') as f:
190
+ self.cb_msg(
191
+ "Failed to create Xcode project: ios-message-stickers-template not found"
192
+ )
193
+
194
+ os.remove(os.path.join(pack_path, "README.md"))
195
+ shutil.rmtree(
196
+ os.path.join(pack_path, "stickers.xcodeproj/project.xcworkspace"),
197
+ ignore_errors=True,
198
+ )
199
+ shutil.rmtree(
200
+ os.path.join(pack_path, "stickers.xcodeproj/xcuserdata"), ignore_errors=True
201
+ )
202
+
203
+ with open(
204
+ os.path.join(pack_path, "stickers.xcodeproj/project.pbxproj"),
205
+ encoding="utf-8",
206
+ ) as f:
191
207
  pbxproj_data = f.read()
192
-
193
- pbxproj_data = pbxproj_data.replace('stickers StickerPackExtension', f'{title} StickerPackExtension')
194
- pbxproj_data = pbxproj_data.replace('stickers.app', f'{title}.app')
195
- pbxproj_data = pbxproj_data.replace('/* stickers */', f'/* {title} */')
196
- pbxproj_data = pbxproj_data.replace('name = stickers', f'name = {title}')
197
- pbxproj_data = pbxproj_data.replace('productName = stickers', f'productName = {title}')
198
- pbxproj_data = pbxproj_data.replace('/* Build configuration list for PBXProject "stickers" */', f'/* Build configuration list for PBXProject "{title}" */')
199
- pbxproj_data = pbxproj_data.replace('/* Build configuration list for PBXNativeTarget "stickers StickerPackExtension" */', f'/* Build configuration list for PBXNativeTarget "{title} StickerPackExtension" */')
200
- pbxproj_data = pbxproj_data.replace('/* Build configuration list for PBXNativeTarget "stickers" */', f'/* Build configuration list for PBXNativeTarget "{title}" */')
201
- pbxproj_data = pbxproj_data.replace('com.niklaspeterson', f'com.{author}')
202
- pbxproj_data = pbxproj_data.replace('stickers/Info.plist', f'{title}/Info.plist')
203
-
204
- with open(os.path.join(pack_path, 'stickers.xcodeproj/project.pbxproj'), 'w+', encoding='utf-8') as f:
208
+
209
+ pbxproj_data = pbxproj_data.replace(
210
+ "stickers StickerPackExtension", f"{title} StickerPackExtension"
211
+ )
212
+ pbxproj_data = pbxproj_data.replace("stickers.app", f"{title}.app")
213
+ pbxproj_data = pbxproj_data.replace("/* stickers */", f"/* {title} */")
214
+ pbxproj_data = pbxproj_data.replace("name = stickers", f"name = {title}")
215
+ pbxproj_data = pbxproj_data.replace(
216
+ "productName = stickers", f"productName = {title}"
217
+ )
218
+ pbxproj_data = pbxproj_data.replace(
219
+ '/* Build configuration list for PBXProject "stickers" */',
220
+ f'/* Build configuration list for PBXProject "{title}" */',
221
+ )
222
+ pbxproj_data = pbxproj_data.replace(
223
+ '/* Build configuration list for PBXNativeTarget "stickers StickerPackExtension" */',
224
+ f'/* Build configuration list for PBXNativeTarget "{title} StickerPackExtension" */',
225
+ )
226
+ pbxproj_data = pbxproj_data.replace(
227
+ '/* Build configuration list for PBXNativeTarget "stickers" */',
228
+ f'/* Build configuration list for PBXNativeTarget "{title}" */',
229
+ )
230
+ pbxproj_data = pbxproj_data.replace("com.niklaspeterson", f"com.{author}")
231
+ pbxproj_data = pbxproj_data.replace(
232
+ "stickers/Info.plist", f"{title}/Info.plist"
233
+ )
234
+
235
+ with open(
236
+ os.path.join(pack_path, "stickers.xcodeproj/project.pbxproj"),
237
+ "w+",
238
+ encoding="utf-8",
239
+ ) as f:
205
240
  f.write(pbxproj_data)
206
-
241
+
207
242
  # packname StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack
208
- stickers_path = os.path.join(pack_path, 'stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack')
209
-
243
+ stickers_path = os.path.join(
244
+ pack_path,
245
+ "stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack",
246
+ )
247
+
210
248
  for i in os.listdir(stickers_path):
211
- if i.endswith('.sticker'):
249
+ if i.endswith(".sticker"):
212
250
  shutil.rmtree(os.path.join(stickers_path, i))
213
-
251
+
214
252
  stickers_lst = []
215
253
  for i in sorted(os.listdir(self.in_dir)):
216
- if CodecInfo.get_file_ext(i) == '.png' and os.path.splitext(i)[0] != 'cover' and i not in self.iconset:
217
- sticker_dir = f'{os.path.splitext(i)[0]}.sticker' # 0.sticker
254
+ if (
255
+ CodecInfo.get_file_ext(i) == ".png"
256
+ and os.path.splitext(i)[0] != "cover"
257
+ and i not in self.iconset
258
+ ):
259
+ sticker_dir = f"{os.path.splitext(i)[0]}.sticker" # 0.sticker
218
260
  stickers_lst.append(sticker_dir)
219
261
  # packname StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/0.sticker
220
262
  sticker_path = os.path.join(stickers_path, sticker_dir)
@@ -223,56 +265,84 @@ class XcodeImessage(UploadBase):
223
265
  shutil.copy(os.path.join(self.in_dir, i), os.path.join(sticker_path, i))
224
266
 
225
267
  json_content = {
226
- 'info': {
227
- 'author': 'xcode',
228
- 'version': 1,
268
+ "info": {
269
+ "author": "xcode",
270
+ "version": 1,
229
271
  },
230
- 'properties': {
231
- 'filename': i
232
- }
272
+ "properties": {"filename": i},
233
273
  }
234
274
 
235
275
  # packname StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/0.sticker/Contents.json
236
- with open(os.path.join(sticker_path, 'Contents.json'), 'w+') as f:
276
+ with open(os.path.join(sticker_path, "Contents.json"), "w+") as f:
237
277
  json.dump(json_content, f, indent=2)
238
-
278
+
239
279
  # packname StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Contents.json
240
- with open(os.path.join(stickers_path, 'Contents.json')) as f:
280
+ with open(os.path.join(stickers_path, "Contents.json")) as f:
241
281
  json_content = json.load(f)
242
-
243
- json_content['stickers'] = []
282
+
283
+ json_content["stickers"] = []
244
284
  for i in stickers_lst:
245
- json_content['stickers'].append({'filename': i}) # type: ignore[attr-defined]
246
-
247
- with open(os.path.join(stickers_path, 'Contents.json'), 'w+') as f:
285
+ json_content["stickers"].append({"filename": i}) # type: ignore[attr-defined]
286
+
287
+ with open(os.path.join(stickers_path, "Contents.json"), "w+") as f:
248
288
  json.dump(json_content, f, indent=2)
249
289
 
250
290
  # packname StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset
251
- iconset_path = os.path.join(pack_path, 'stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset')
291
+ iconset_path = os.path.join(
292
+ pack_path,
293
+ "stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset",
294
+ )
252
295
 
253
296
  for i in os.listdir(iconset_path):
254
- if os.path.splitext(i)[1] == '.png':
297
+ if os.path.splitext(i)[1] == ".png":
255
298
  os.remove(os.path.join(iconset_path, i))
256
299
 
257
300
  icons_lst = []
258
301
  for i in self.iconset:
259
302
  shutil.copy(os.path.join(self.in_dir, i), os.path.join(iconset_path, i))
260
303
  icons_lst.append(i)
261
-
304
+
262
305
  # packname/Info.plist
263
- plist_path = os.path.join(pack_path, 'stickers/Info.plist')
264
- with open(plist_path, 'rb') as f:
306
+ plist_path = os.path.join(pack_path, "stickers/Info.plist")
307
+ with open(plist_path, "rb") as f:
265
308
  plist_dict = plistlib.load(f)
266
- plist_dict['CFBundleDisplayName'] = title
309
+ plist_dict["CFBundleDisplayName"] = title
267
310
 
268
- with open(plist_path, 'wb+') as f:
311
+ with open(plist_path, "wb+") as f:
269
312
  plistlib.dump(plist_dict, f)
270
313
 
271
- os.rename(os.path.join(pack_path, 'stickers'), os.path.join(pack_path, f'{title}'))
272
- os.rename(os.path.join(pack_path, 'stickers StickerPackExtension'), os.path.join(pack_path, f'{title} StickerPackExtension'))
273
- os.rename(os.path.join(pack_path, 'stickers.xcodeproj'), os.path.join(pack_path, f'{title}.xcodeproj'))
274
-
314
+ os.rename(
315
+ os.path.join(pack_path, "stickers"), os.path.join(pack_path, f"{title}")
316
+ )
317
+ os.rename(
318
+ os.path.join(pack_path, "stickers StickerPackExtension"),
319
+ os.path.join(pack_path, f"{title} StickerPackExtension"),
320
+ )
321
+ os.rename(
322
+ os.path.join(pack_path, "stickers.xcodeproj"),
323
+ os.path.join(pack_path, f"{title}.xcodeproj"),
324
+ )
325
+
275
326
  @staticmethod
276
- def start(opt_output: dict, opt_comp: dict, opt_cred: dict, cb_msg=print, cb_msg_block=input, cb_ask_bool=input, cb_bar=None, out_dir: Optional[str] = None, **kwargs) -> list[str]:
277
- exporter = XcodeImessage(opt_output, opt_comp, opt_cred, cb_msg, cb_msg_block, cb_ask_bool, cb_bar, out_dir)
327
+ def start(
328
+ opt_output: OutputOption,
329
+ opt_comp: CompOption,
330
+ opt_cred: CredOption,
331
+ cb_msg=print,
332
+ cb_msg_block=input,
333
+ cb_ask_bool=input,
334
+ cb_bar=None,
335
+ out_dir: Optional[str] = None,
336
+ **kwargs,
337
+ ) -> list[str]:
338
+ exporter = XcodeImessage(
339
+ opt_output,
340
+ opt_comp,
341
+ opt_cred,
342
+ cb_msg,
343
+ cb_msg_block,
344
+ cb_ask_bool,
345
+ cb_bar,
346
+ out_dir,
347
+ )
278
348
  return exporter.create_imessage_xcode()
@@ -6,12 +6,14 @@ import json
6
6
  from urllib.parse import urlparse, parse_qs
7
7
  from typing import Optional
8
8
 
9
+ from ...job_option import CredOption
10
+
9
11
  class GetKakaoAuth:
10
- def __init__(self, opt_cred: dict, cb_msg=print, cb_msg_block=input, cb_ask_str=input):
11
- self.username = opt_cred['kakao']['username']
12
- self.password = opt_cred['kakao']['password']
13
- self.country_code = opt_cred['kakao']['country_code']
14
- self.phone_number = opt_cred['kakao']['phone_number']
12
+ def __init__(self, opt_cred: CredOption, cb_msg=print, cb_msg_block=input, cb_ask_str=input):
13
+ self.username = opt_cred.kakao_username
14
+ self.password = opt_cred.kakao_password
15
+ self.country_code = opt_cred.kakao_country_code
16
+ self.phone_number = opt_cred.kakao_phone_number
15
17
 
16
18
  self.cb_msg = cb_msg
17
19
  self.cb_msg_block = cb_msg_block
@@ -2,18 +2,19 @@
2
2
  import json
3
3
  from typing import Optional
4
4
 
5
- import browser_cookie3 # type: ignore
5
+ import rookiepy # type: ignore
6
6
  import requests
7
7
 
8
8
  class GetLineAuth:
9
9
  def get_cred(self) -> Optional[str]:
10
- cookies_jar = browser_cookie3.load(domain_name='store.line.me')
10
+ cookies_rookie = [c for c in rookiepy.load() if c.domain == 'store.line.me']
11
+ cookies_dict = rookiepy.to_dict(cookies_rookie)
12
+ cookies_jar = rookiepy.to_cookiejar(cookies_rookie)
11
13
 
12
14
  if not GetLineAuth.validate_cookies(cookies_jar):
13
15
  return None
14
-
15
- cookies_dict = requests.utils.dict_from_cookiejar(cookies_jar)
16
- cookies_list = ['%s=%s' % (name, value) for (name, value) in cookies_dict.items()]
16
+
17
+ cookies_list = ['%s=%s' % (i['name'], i['value']) for i in cookies_dict]
17
18
  cookies = ';'.join(cookies_list)
18
19
 
19
20
  return cookies
@@ -15,7 +15,7 @@ from selenium import webdriver
15
15
  from selenium.webdriver.chrome.service import Service
16
16
  from selenium.common.exceptions import JavascriptException
17
17
 
18
- from ..utils.run_bin import RunBin # type: ignore
18
+ from ..files.run_bin import RunBin # type: ignore
19
19
 
20
20
  # https://stackoverflow.com/a/17197027
21
21
  def strings(filename: str, min: int = 4) -> Generator[str, None, None]:
@@ -1,8 +1,11 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
+
3
4
  class FakeCbMsg:
4
- def __init__(self, msg_protocol = print):
5
+ def __init__(self, msg_protocol=print, silent=False):
5
6
  self.msg_protocol = msg_protocol
7
+ self.silent = silent
6
8
 
7
9
  def put(self, msg: str):
8
- self.msg_protocol(msg) # type: ignore[operator]
10
+ if not self.silent:
11
+ self.msg_protocol(msg) # type: ignore[operator]
@@ -3,14 +3,17 @@ import os
3
3
  import platform
4
4
  import shutil
5
5
  from uuid import uuid4
6
- if platform.system() == 'Linux':
7
- import memory_tempfile # type: ignore
6
+
7
+ if platform.system() == "Linux":
8
+ import memory_tempfile # type: ignore
9
+
8
10
  tempfile = memory_tempfile.MemoryTempfile(fallback=True)
9
11
  else:
10
12
  import tempfile
11
13
  import contextlib
12
14
  from typing import Optional
13
15
 
16
+
14
17
  @contextlib.contextmanager
15
18
  def debug_cache_dir(path: str):
16
19
  path_random = os.path.join(path, str(uuid4()))
@@ -20,10 +23,11 @@ def debug_cache_dir(path: str):
20
23
  finally:
21
24
  shutil.rmtree(path_random)
22
25
 
26
+
23
27
  class CacheStore:
24
28
  @staticmethod
25
29
  def get_cache_store(path: Optional[str] = None):
26
30
  if path:
27
31
  return debug_cache_dir(path)
28
32
  else:
29
- return tempfile.TemporaryDirectory()
33
+ return tempfile.TemporaryDirectory()
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env python3
2
+ import os
3
+ import sys
4
+ import platform
5
+ from typing import Optional
6
+
7
+
8
+ class DirUtils:
9
+ @staticmethod
10
+ def _get_curr_dir_if_writable() -> Optional[str]:
11
+ appimage_path = os.getenv("APPIMAGE")
12
+ curr_dir = os.getcwd()
13
+
14
+ if (
15
+ curr_dir.startswith("/usr/bin/")
16
+ or curr_dir.startswith("/bin")
17
+ or curr_dir.startswith("/usr/local/bin")
18
+ or curr_dir.startswith("C:\\Program Files")
19
+ or "site-packages" in __file__
20
+ ):
21
+ return None
22
+
23
+ if (
24
+ platform.system() == "Darwin"
25
+ and getattr(sys, "frozen", False)
26
+ and ".app/Contents/MacOS" in curr_dir
27
+ ):
28
+ if curr_dir.startswith("/Applications/"):
29
+ return None
30
+ else:
31
+ curr_dir = os.path.abspath("../../../")
32
+
33
+ if appimage_path:
34
+ curr_dir = os.path.split(appimage_path)[0]
35
+
36
+ if not os.access(curr_dir, os.W_OK):
37
+ return None
38
+
39
+ return curr_dir
40
+
41
+ @staticmethod
42
+ def get_curr_dir() -> str:
43
+ home_dir = os.path.expanduser("~")
44
+ if os.path.isdir(os.path.join(home_dir, "Desktop")):
45
+ fallback_dir = os.path.join(home_dir, "Desktop")
46
+ else:
47
+ fallback_dir = home_dir
48
+
49
+ if (curr_dir := DirUtils._get_curr_dir_if_writable()) != None:
50
+ return curr_dir
51
+ else:
52
+ return fallback_dir
53
+
54
+ @staticmethod
55
+ def get_config_dir() -> str:
56
+ if platform.system() == "Windows":
57
+ fallback_dir = os.path.expandvars("%APPDATA%\\sticker-convert")
58
+ else:
59
+ fallback_dir = os.path.expanduser("~/.config/sticker-convert")
60
+
61
+ if (config_dir := DirUtils._get_curr_dir_if_writable()) != None:
62
+ return config_dir
63
+ else:
64
+ return fallback_dir
@@ -3,17 +3,18 @@ import os
3
3
  import json
4
4
  from typing import Optional
5
5
 
6
+
6
7
  class JsonManager:
7
8
  @staticmethod
8
9
  def load_json(path: str) -> Optional[dict]:
9
10
  if not os.path.isfile(path):
10
11
  return None
11
12
  else:
12
- with open(path, encoding='utf-8') as f:
13
+ with open(path, encoding="utf-8") as f:
13
14
  data = json.load(f)
14
15
  return data
15
-
16
+
16
17
  @staticmethod
17
18
  def save_json(path: str, data: dict):
18
- with open(path, 'w+', encoding='utf-8') as f:
19
- json.dump(data, f, indent=4)
19
+ with open(path, "w+", encoding="utf-8") as f:
20
+ json.dump(data, f, indent=4)