sticker-convert 2.13.0__py3-none-any.whl → 2.13.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
sticker_convert/cli.py CHANGED
@@ -551,6 +551,8 @@ class CLI:
551
551
  opt_cred.telethon_api_hash = telethon_api_hash
552
552
 
553
553
  self.cb.msg("Telethon setup successful")
554
+ else:
555
+ self.cb.msg("Telethon setup failed")
554
556
 
555
557
  if args.line_get_auth:
556
558
  get_line_auth = GetLineAuth()
@@ -441,7 +441,7 @@ class StickerConvert:
441
441
  if self.opt_comp.chromium_path:
442
442
  chrome_path = self.opt_comp.chromium_path
443
443
  else:
444
- chrome_path = CRD.get_chrome_path()
444
+ chrome_path = CRD.get_chromium_path()
445
445
  args = [
446
446
  "--headless",
447
447
  "--kiosk",
@@ -77,7 +77,7 @@ class MetadataLine:
77
77
  @staticmethod
78
78
  def get_metadata_sticon(
79
79
  pack_id: str, region: str
80
- ) -> Optional[Tuple[str, str, List[Dict[str, Any]], str, bool]]:
80
+ ) -> Optional[Tuple[str, str, List[Dict[str, Any]], str, bool, bool]]:
81
81
  pack_meta_r = requests.get(
82
82
  f"https://stickershop.line-scdn.net/sticonshop/v1/{pack_id}/sticon/iphone/meta.json"
83
83
  )
@@ -114,14 +114,15 @@ class MetadataLine:
114
114
  files = pack_meta["orders"]
115
115
 
116
116
  resource_type = pack_meta.get("sticonResourceType")
117
+ has_animation = True if resource_type == "ANIMATION" else False
117
118
  has_sound = False
118
119
 
119
- return title, author, files, resource_type, has_sound
120
+ return title, author, files, resource_type, has_animation, has_sound
120
121
 
121
122
  @staticmethod
122
123
  def get_metadata_stickers(
123
124
  pack_id: str, region: str
124
- ) -> Optional[Tuple[str, str, List[Dict[str, Any]], str, bool]]:
125
+ ) -> Optional[Tuple[str, str, List[Dict[str, Any]], str, bool, bool]]:
125
126
  pack_meta_r = requests.get(
126
127
  f"https://stickershop.line-scdn.net/stickershop/v1/product/{pack_id}/android/productInfo.meta"
127
128
  )
@@ -153,9 +154,10 @@ class MetadataLine:
153
154
  files = pack_meta["stickers"]
154
155
 
155
156
  resource_type = pack_meta.get("stickerResourceType")
157
+ has_animation = pack_meta.get("hasAnimation")
156
158
  has_sound = pack_meta.get("hasSound")
157
159
 
158
- return title, author, files, resource_type, has_sound
160
+ return title, author, files, resource_type, has_animation, has_sound
159
161
 
160
162
 
161
163
  class DownloadLine(DownloadBase):
@@ -207,6 +209,7 @@ class DownloadLine(DownloadBase):
207
209
  if (
208
210
  self.resource_type in ("ANIMATION", "ANIMATION_SOUND", "POPUP")
209
211
  or self.has_sound is True
212
+ or self.has_animation is True
210
213
  ):
211
214
  pack_url = f"https://stickershop.line-scdn.net/stickershop/v1/product/{self.pack_id}/iphone/stickerpack@2x.zip"
212
215
  elif self.resource_type == "PER_STICKER_TEXT":
@@ -419,6 +422,7 @@ class DownloadLine(DownloadBase):
419
422
  self.author,
420
423
  self.pack_files,
421
424
  self.resource_type,
425
+ self.has_animation,
422
426
  self.has_sound,
423
427
  ) = metadata
424
428
  else:
@@ -609,7 +609,7 @@ class AdvancedCompressionWindow(BaseWindow):
609
609
  )[1]
610
610
  if color:
611
611
  self.gui.bg_color_var.set(color.replace("#", "") + "00")
612
- self.lift()
612
+ self.lift() # type: ignore
613
613
  self.attributes("-topmost", True) # type: ignore
614
614
  self.attributes("-topmost", False) # type: ignore
615
615
 
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env python3
2
+ import platform
2
3
  from functools import partial
3
4
  from threading import Thread
4
5
  from typing import Any, Optional
@@ -51,6 +52,20 @@ class KakaoGetAuthWindow(BaseWindow):
51
52
  justify="left",
52
53
  anchor="w",
53
54
  )
55
+ if platform.system() != "Darwin":
56
+ self.explanation1_4_lbl = Label(
57
+ self.frame_from_desktop,
58
+ text="Note: This will download ProcDump and read memory of KakaoTalk Desktop",
59
+ justify="left",
60
+ anchor="w",
61
+ )
62
+ else:
63
+ self.explanation1_4_lbl = Label(
64
+ self.frame_from_desktop,
65
+ text="Note: This will read memory of KakaoTalk Desktop",
66
+ justify="left",
67
+ anchor="w",
68
+ )
54
69
  self.kakao_bin_path_lbl = Label(
55
70
  self.frame_from_desktop,
56
71
  text="Kakao app path (Optional):",
@@ -85,10 +100,13 @@ class KakaoGetAuthWindow(BaseWindow):
85
100
  self.explanation1_3_lbl.grid(
86
101
  column=0, row=2, columnspan=2, sticky="w", padx=3, pady=3
87
102
  )
88
- self.kakao_bin_path_lbl.grid(column=0, row=3, sticky="w", padx=3, pady=3)
89
- self.kakao_bin_path_entry.grid(column=1, row=3, sticky="w", padx=3, pady=3)
90
- self.launch_desktop_btn.grid(column=0, row=4, columnspan=2, padx=3, pady=3)
91
- self.get_auth_desktop_btn.grid(column=0, row=5, columnspan=2, padx=3, pady=3)
103
+ self.explanation1_4_lbl.grid(
104
+ column=0, row=3, columnspan=2, sticky="w", padx=3, pady=3
105
+ )
106
+ self.kakao_bin_path_lbl.grid(column=0, row=4, sticky="w", padx=3, pady=3)
107
+ self.kakao_bin_path_entry.grid(column=1, row=4, sticky="w", padx=3, pady=3)
108
+ self.launch_desktop_btn.grid(column=0, row=5, columnspan=2, padx=3, pady=3)
109
+ self.get_auth_desktop_btn.grid(column=0, row=6, columnspan=2, padx=3, pady=3)
92
110
 
93
111
  # Method 2 frame
94
112
  self.explanation2_1_lbl = Label(
@@ -277,6 +295,8 @@ class KakaoGetAuthWindow(BaseWindow):
277
295
 
278
296
  def cb_from_desktop_thread(self, *_: Any) -> None:
279
297
  self.gui.save_creds()
298
+ self.gui.cb_msg("Getting auth_token, this may take a minute...")
299
+ self.gui.cb_bar("indeterminate")
280
300
  m = GetKakaoDesktopAuth(
281
301
  cb_ask_str=self.cb_ask_str_kakao,
282
302
  )
@@ -298,3 +318,4 @@ class KakaoGetAuthWindow(BaseWindow):
298
318
  self.gui.highlight_fields()
299
319
 
300
320
  self.cb_msg_block_kakao(msg)
321
+ self.gui.cb_bar("clear")
@@ -59,10 +59,25 @@ class ViberGetAuthWindow(BaseWindow):
59
59
  justify="left",
60
60
  anchor="w",
61
61
  )
62
+ if platform.system() != "Darwin":
63
+ self.explanation_lbl3 = Label(
64
+ self.frame_info,
65
+ text="Note: This will download ProcDump and read memory of Viber Desktop",
66
+ justify="left",
67
+ anchor="w",
68
+ )
69
+ else:
70
+ self.explanation_lbl3 = Label(
71
+ self.frame_info,
72
+ text="Note: This will read memory of Viber Desktop",
73
+ justify="left",
74
+ anchor="w",
75
+ )
62
76
 
63
77
  self.explanation_lbl0.grid(column=0, row=0, sticky="w", padx=3, pady=3)
64
78
  self.explanation_lbl1.grid(column=0, row=1, sticky="w", padx=3, pady=3)
65
79
  self.explanation_lbl2.grid(column=0, row=2, sticky="w", padx=3, pady=3)
80
+ self.explanation_lbl3.grid(column=0, row=3, sticky="w", padx=3, pady=3)
66
81
 
67
82
  # Start button frame
68
83
  self.launch_btn = Button(
@@ -64,7 +64,7 @@
64
64
  "telethon_setup": "Setup Telethon",
65
65
  "kakao_auth_token": "Set Kakao auth_token. Required for downloading animated stickers from https://e.kakao.com/t/xxxxx",
66
66
  "kakao_get_auth": "Generate Kakao auth_token by simulating login. Kakao username, password, country code and phone number are also required.",
67
- "kakao_get_auth_desktop": "Get Kakao auth_token from Kakao Desktop application.\n(Only working on Windows.)",
67
+ "kakao_get_auth_desktop": "Get Kakao auth_token from Kakao Desktop application.",
68
68
  "kakao_bin_path": "Set Kakao Desktop application path for launching and getting auth_token.\nUseful for portable installation.",
69
69
  "kakao_username": "Set Kakao username, which is email or phone number used for signing up Kakao account\nExample: +447700900142\nRequired for generating Kakao auth_token.",
70
70
  "kakao_password": "Set Kakao password (Password of Kakao account).\nRequired for generating Kakao auth_token.",
@@ -72,7 +72,7 @@ class GetDiscordAuth:
72
72
  if chrome_path is not None:
73
73
  using_discord_app = True
74
74
  else:
75
- chrome_path = CRD.get_chrome_path()
75
+ chrome_path = CRD.get_chromium_path()
76
76
  if chrome_path is None:
77
77
  return (
78
78
  None,
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env python3
2
- import importlib.util
3
2
  import os
4
3
  import platform
5
4
  import re
@@ -8,9 +7,9 @@ import time
8
7
  from functools import partial
9
8
  from getpass import getpass
10
9
  from pathlib import Path
11
- from typing import Callable, List, Optional, Tuple, cast
10
+ from typing import Callable, Optional, Tuple, Union, cast
12
11
 
13
- from sticker_convert.utils.process import check_admin, find_pid_by_name, get_mem, killall
12
+ from sticker_convert.utils.process import find_pid_by_name, get_mem, killall
14
13
 
15
14
  MSG_NO_BIN = """Kakao Desktop not detected.
16
15
  Download and install Kakao Desktop,
@@ -97,13 +96,20 @@ class GetKakaoDesktopAuth:
97
96
  self, kakao_bin_path: str, relaunch: bool = True
98
97
  ) -> Tuple[Optional[str], str]:
99
98
  auth_token = None
100
-
101
- if relaunch:
102
- kakao_pid = self.relaunch_kakao(kakao_bin_path)
99
+ kakao_pid: Union[str, int, None]
100
+ if platform.system() == "Windows":
101
+ is_wine = False
102
+ if relaunch:
103
+ kakao_pid = self.relaunch_kakao(kakao_bin_path)
104
+ else:
105
+ kakao_pid = find_pid_by_name("kakaotalk")
106
+ if kakao_pid is None:
107
+ return None, MSG_LAUNCH_FAIL
103
108
  else:
104
- kakao_pid = find_pid_by_name("kakaotalk")
105
- if kakao_pid is None:
106
- return None, MSG_LAUNCH_FAIL
109
+ is_wine = True
110
+ kakao_pid = "KakaoTalk.exe"
111
+ if relaunch and self.relaunch_kakao(kakao_bin_path) is None:
112
+ return None, MSG_LAUNCH_FAIL
107
113
 
108
114
  if self.cb_ask_str == input:
109
115
  pw_func = getpass
@@ -111,10 +117,10 @@ class GetKakaoDesktopAuth:
111
117
  pw_func = partial(
112
118
  self.cb_ask_str, initialvalue="", cli_show_initialvalue=False
113
119
  )
114
- s, msg = get_mem(kakao_pid, pw_func)
120
+ s = get_mem(kakao_pid, pw_func, is_wine)
115
121
 
116
122
  if s is None:
117
- return None, msg
123
+ return None, "Failed to dump memory"
118
124
 
119
125
  auth_token = None
120
126
  for i in re.finditer(b"authorization: ", s):
@@ -140,6 +146,13 @@ class GetKakaoDesktopAuth:
140
146
  return auth_token, msg
141
147
 
142
148
  def get_auth_darwin(self, kakao_bin_path: str) -> Tuple[Optional[str], str]:
149
+ csrutil_status = subprocess.run(
150
+ ["csrutil", "status"], capture_output=True, text=True
151
+ ).stdout
152
+
153
+ if "enabled" in csrutil_status:
154
+ return None, MSG_SIP_ENABLED
155
+
143
156
  killall("kakaotalk")
144
157
 
145
158
  subprocess.run(
@@ -205,9 +218,10 @@ class GetKakaoDesktopAuth:
205
218
  elif platform.system() == "Darwin":
206
219
  kakao_bin_path = "/Applications/KakaoTalk.app"
207
220
  else:
208
- kakao_bin_path = os.path.expanduser(
209
- "~/.wine/drive_c/Program Files (x86)/Kakao/KakaoTalk/KakaoTalk.exe"
210
- )
221
+ wineprefix = os.environ.get("WINEPREFIX")
222
+ if not (wineprefix and Path(wineprefix).exists()):
223
+ wineprefix = os.path.expanduser("~/.wine")
224
+ kakao_bin_path = f"{wineprefix}/drive_c/Program Files (x86)/Kakao/KakaoTalk/KakaoTalk.exe"
211
225
 
212
226
  if Path(kakao_bin_path).exists():
213
227
  return kakao_bin_path
@@ -220,7 +234,7 @@ class GetKakaoDesktopAuth:
220
234
  ) -> Tuple[Optional[str], str]:
221
235
  # get_auth_by_dump()
222
236
  # + Fast
223
- # - Requires admin
237
+ # - Requires downloading procdump, or builtin method that needs admin
224
238
 
225
239
  # get_auth_by_pme()
226
240
  # + No admin (If have permission to read process)
@@ -233,32 +247,13 @@ class GetKakaoDesktopAuth:
233
247
  if not kakao_bin_path:
234
248
  return None, MSG_NO_BIN
235
249
 
236
- if platform.system() != "Darwin":
237
- # If admin, prefer get_auth_by_dump() over get_auth_by_pme(), vice versa
238
- methods: List[Callable[[str, bool], Tuple[Optional[str], str]]] = []
239
- relaunch = True
240
- kakao_auth = None
241
- msg = ""
242
-
243
- pme_present = importlib.util.find_spec("PyMemoryEditor") is not None
244
- methods.append(self.get_auth_by_dump)
245
- if pme_present:
246
- methods.append(self.get_auth_by_pme)
247
- if check_admin() is False:
248
- methods.reverse()
249
-
250
- for method in methods:
251
- kakao_auth, msg = method(kakao_bin_path, relaunch)
252
- relaunch = False
253
- if kakao_auth is not None:
254
- break
255
- else:
256
- csrutil_status = subprocess.run(
257
- ["csrutil", "status"], capture_output=True, text=True
258
- ).stdout
259
-
260
- if "enabled" in csrutil_status:
261
- return None, MSG_SIP_ENABLED
250
+ if platform.system() == "Windows":
251
+ kakao_auth, msg = self.get_auth_by_dump(kakao_bin_path)
252
+ if kakao_auth is None:
253
+ kakao_auth, msg = self.get_auth_by_pme(kakao_bin_path, False)
254
+ elif platform.system() == "Darwin":
262
255
  kakao_auth, msg = self.get_auth_darwin(kakao_bin_path)
256
+ else:
257
+ kakao_auth, msg = self.get_auth_by_dump(kakao_bin_path)
263
258
 
264
259
  return kakao_auth, msg
@@ -130,10 +130,10 @@ class GetViberAuth:
130
130
  pw_func = partial(
131
131
  self.cb_ask_str, initialvalue="", cli_show_initialvalue=False
132
132
  )
133
- s, msg = get_mem(viber_pid, pw_func)
133
+ s = get_mem(viber_pid, pw_func)
134
134
 
135
135
  if s is None:
136
- return None, msg
136
+ return None, "Failed to dump memory"
137
137
 
138
138
  member_id_addr = s.find(b"X-Viber-Auth-Mid: ")
139
139
  m_token_addr = s.find(b"X-Viber-Auth-Token: ")
@@ -217,8 +217,6 @@ class GetViberAuth:
217
217
  methods.append(self.get_auth_by_dump)
218
218
  if pme_present:
219
219
  methods.append(self.get_auth_by_pme)
220
- if check_admin() is False:
221
- methods.reverse()
222
220
  else:
223
221
  if not os.path.isfile("/.dockerenv"):
224
222
  methods.append(self.get_auth_by_dump)
@@ -342,10 +342,12 @@ class TelethonAPI(TelegramAPI):
342
342
  self.cb = cb
343
343
  self.cb_return = cb_return
344
344
 
345
- success, self.client, _, _ = await TelethonSetup(
345
+ success, client, _, _ = await TelethonSetup(
346
346
  self.opt_cred, self.cb_ask_str
347
347
  ).start_async()
348
348
 
349
+ if success is True and client is not None:
350
+ self.client = client
349
351
  return success
350
352
 
351
353
  async def exit(self) -> None:
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- from typing import Callable, Tuple
2
+ from typing import Callable, Optional, Tuple
3
3
 
4
4
  import anyio
5
5
  from telethon import TelegramClient # type: ignore
@@ -58,28 +58,39 @@ class TelethonSetup:
58
58
  def guide(self) -> None:
59
59
  self.cb_ask_str(GUIDE_MSG)
60
60
 
61
- def get_api_info(self) -> None:
61
+ def get_api_info(self) -> bool:
62
62
  api_id_ask = "Enter api_id: "
63
63
  wrong_hint = ""
64
+
64
65
  while True:
65
66
  telethon_api_id = self.cb_ask_str(wrong_hint + api_id_ask)
66
- if telethon_api_id.isnumeric():
67
+ if telethon_api_id == "":
68
+ return False
69
+ elif telethon_api_id.isnumeric():
67
70
  self.opt_cred.telethon_api_id = int(telethon_api_id)
68
71
  break
69
72
  else:
70
73
  wrong_hint = "Error: api_id should be numeric\n"
74
+
71
75
  self.opt_cred.telethon_api_hash = self.cb_ask_str("Enter api_hash: ")
76
+ if self.opt_cred.telethon_api_hash == "":
77
+ return False
78
+ return True
72
79
 
73
80
  def signin(self) -> Tuple[bool, TelegramClient, int, str]:
74
81
  return anyio.run(self.signin_async)
75
82
 
76
- def start(self) -> Tuple[bool, TelegramClient, int, str]:
83
+ def start(self) -> Tuple[bool, Optional[TelegramClient], int, str]:
84
+ cred_valid = False
77
85
  if self.opt_cred.telethon_api_id == 0 or self.opt_cred.telethon_api_hash == "":
78
86
  self.guide()
79
- self.get_api_info()
80
- return self.signin()
87
+ cred_valid = self.get_api_info()
88
+ if cred_valid:
89
+ return self.signin()
90
+ else:
91
+ return False, None, 0, ""
81
92
 
82
- async def start_async(self) -> Tuple[bool, TelegramClient, int, str]:
93
+ async def start_async(self) -> Tuple[bool, Optional[TelegramClient], int, str]:
83
94
  if self.opt_cred.telethon_api_id == 0 or self.opt_cred.telethon_api_hash == "":
84
95
  self.guide()
85
96
  self.get_api_info()
@@ -9,7 +9,7 @@ import signal
9
9
  import socket
10
10
  import subprocess
11
11
  import time
12
- from typing import Any, Dict, List, Optional, Tuple, Union, cast
12
+ from typing import Any, Dict, List, Optional, Union, cast
13
13
 
14
14
  import requests
15
15
  import websocket
@@ -83,28 +83,14 @@ class CRD:
83
83
  self.chrome_proc = subprocess.Popen(launch_cmd)
84
84
 
85
85
  @staticmethod
86
- def get_chrome_path() -> Optional[str]:
87
- import logging
88
-
89
- import browsers # type: ignore
90
-
91
- # browsers module would turn on info logging
92
- logger = logging.getLogger()
93
- logger.setLevel(logging.CRITICAL)
94
-
95
- bs: List[Tuple[int, str]] = []
96
- for b in browsers.browsers():
97
- browser_type = b["browser_type"]
98
- path = b["path"]
99
- try:
100
- rank = BROWSER_PREF.index(browser_type)
101
- except ValueError:
102
- continue
103
- bs.append((rank, path))
104
- if len(bs) == 0:
105
- return None
106
- bs = sorted(bs, key=lambda x: x[0])
107
- return bs[0][1]
86
+ def get_chromium_path() -> Optional[str]:
87
+ if platform.system() == "Windows":
88
+ from sticker_convert.utils.chromiums.windows import get_chromium_path
89
+ elif platform.system() == "Darwin":
90
+ from sticker_convert.utils.chromiums.osx import get_chromium_path
91
+ else:
92
+ from sticker_convert.utils.chromiums.linux import get_chromium_path
93
+ return get_chromium_path()
108
94
 
109
95
  def connect(self, target_id: int = 0) -> None:
110
96
  self.cmd_id = 1
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env python3
2
+ import configparser
3
+ import os
4
+ import re
5
+ from typing import Optional
6
+
7
+ # Adopted from https://github.com/roniemartinez/browsers/blob/master/browsers/linux.py
8
+
9
+ LINUX_DESKTOP_ENTRY_LIST = (
10
+ ("chrome", ("google-chrome",)),
11
+ ("chromium", ("chromium", "chromium_chromium")),
12
+ ("brave", ("brave-browser", "brave_brave")),
13
+ ("brave-beta", ("brave-browser-beta",)),
14
+ ("brave-nightly", ("brave-browser-nightly",)),
15
+ ("msedge", ("microsoft-edge",)),
16
+ ("opera", ("opera_opera",)),
17
+ ("opera-beta", ("opera-beta_opera-beta",)),
18
+ ("opera-developer", ("opera-developer_opera-developer",)),
19
+ ("vivaldi", ("vivaldi_vivaldi-stable",)),
20
+ )
21
+
22
+ # $XDG_DATA_HOME and $XDG_DATA_DIRS are not always set
23
+ XDG_DATA_LOCATIONS = (
24
+ "~/.local/share/applications",
25
+ "/usr/share/applications",
26
+ "/var/lib/snapd/desktop/applications",
27
+ )
28
+
29
+ VERSION_PATTERN = re.compile(
30
+ r"\b(\S+\.\S+)\b"
31
+ ) # simple pattern assuming all version strings have a dot on them
32
+
33
+
34
+ def get_chromium_path() -> Optional[str]:
35
+ for _, desktop_entries in LINUX_DESKTOP_ENTRY_LIST:
36
+ for application_dir in XDG_DATA_LOCATIONS:
37
+ for desktop_entry in desktop_entries:
38
+ path = os.path.join(application_dir, f"{desktop_entry}.desktop")
39
+
40
+ if not os.path.isfile(path):
41
+ continue
42
+
43
+ config = configparser.ConfigParser(interpolation=None)
44
+ config.read(path, encoding="utf-8")
45
+ executable_path = config.get("Desktop Entry", "Exec")
46
+
47
+ if executable_path.lower().endswith(" %u"):
48
+ executable_path = executable_path[:-3].strip()
49
+
50
+ return executable_path
51
+
52
+ return None
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env python3
2
+ import glob
3
+ import os
4
+ import plistlib
5
+ import subprocess
6
+ from typing import Optional
7
+
8
+ # Adopted from https://github.com/roniemartinez/browsers/blob/master/browsers/osx.py
9
+
10
+ OSX_CHROMIUMS_BUNDLE_LIST = (
11
+ # browser name, bundle ID, version string
12
+ ("chrome", "com.google.Chrome", "CFBundleShortVersionString"),
13
+ ("chrome-beta", "com.google.Chrome.beta", "CFBundleShortVersionString"),
14
+ ("chrome-canary", "com.google.Chrome.canary", "CFBundleShortVersionString"),
15
+ ("chrome-dev", "com.google.Chrome.dev", "CFBundleShortVersionString"),
16
+ ("chrome-test", "com.google.chrome.for.testing", "CFBundleShortVersionString"),
17
+ ("chromium", "org.chromium.Chromium", "CFBundleShortVersionString"),
18
+ ("msedge", "com.microsoft.edgemac", "CFBundleShortVersionString"),
19
+ ("msedge-beta", "com.microsoft.edgemac.Beta", "CFBundleShortVersionString"),
20
+ ("msedge-dev", "com.microsoft.edgemac.Dev", "CFBundleShortVersionString"),
21
+ ("msedge-canary", "com.microsoft.edgemac.Canary", "CFBundleShortVersionString"),
22
+ ("brave", "com.brave.Browser", "CFBundleVersion"),
23
+ ("brave-beta", "com.brave.Browser.beta", "CFBundleVersion"),
24
+ ("brave-dev", "com.brave.Browser.dev", "CFBundleVersion"),
25
+ ("brave-nightly", "com.brave.Browser.nightly", "CFBundleVersion"),
26
+ ("opera", "com.operasoftware.Opera", "CFBundleVersion"),
27
+ ("opera-beta", "com.operasoftware.OperaNext", "CFBundleVersion"),
28
+ ("opera-developer", "com.operasoftware.OperaDeveloper", "CFBundleVersion"),
29
+ ("opera-gx", "com.operasoftware.OperaGX", "CFBundleVersion"),
30
+ ("opera-neon", "com.opera.Neon", "CFBundleShortVersionString"),
31
+ ("duckduckgo", "com.duckduckgo.macos.browser", "CFBundleShortVersionString"),
32
+ ("epic", "com.hiddenreflex.Epic", "CFBundleShortVersionString"),
33
+ ("vivaldi", "com.vivaldi.Vivaldi", "CFBundleShortVersionString"),
34
+ ("yandex", "ru.yandex.desktop.yandex-browser", "CFBundleShortVersionString"),
35
+ )
36
+
37
+ OSX_CHROMIUMS_BUNDLE_DICT = {item[1]: item for item in OSX_CHROMIUMS_BUNDLE_LIST}
38
+
39
+
40
+ def get_chromium_path() -> Optional[str]:
41
+ for _, bundle_id, _ in OSX_CHROMIUMS_BUNDLE_LIST:
42
+ app_dirs = subprocess.getoutput(
43
+ f'mdfind "kMDItemCFBundleIdentifier == {bundle_id}"'
44
+ ).splitlines()
45
+ for app_dir in app_dirs:
46
+ plist_path = os.path.join(app_dir, "Contents/Info.plist")
47
+
48
+ with open(plist_path, "rb") as f:
49
+ plist = plistlib.load(f)
50
+ executable_name = plist["CFBundleExecutable"]
51
+ executable = os.path.join(app_dir, "Contents/MacOS", executable_name)
52
+ return executable
53
+
54
+ # Naively iterate /Applications folder in case the above check fails
55
+ for plist_path in glob.glob("/Applications/*.app/Contents/Info.plist"):
56
+ with open(plist_path, "rb") as f:
57
+ plist = plistlib.load(f)
58
+ bundle_id = plist.get("CFBundleIdentifier")
59
+ if bundle_id not in OSX_CHROMIUMS_BUNDLE_DICT:
60
+ continue
61
+
62
+ app_dir = os.path.dirname(os.path.dirname(plist_path))
63
+ executable_name = plist["CFBundleExecutable"]
64
+ executable = os.path.join(app_dir, "Contents/MacOS", executable_name)
65
+
66
+ return executable
67
+
68
+ return None
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env python3
2
+ import os
3
+ from typing import Optional
4
+
5
+ # Not adopting approach of reading registry like https://github.com/roniemartinez/browsers
6
+ # As trigger antivirus
7
+
8
+ PF32 = os.environ.get("PROGRAMW6432")
9
+ PF64 = os.environ.get("PROGRAMFILES")
10
+ LAD = os.environ.get("LOCALAPPDATA")
11
+
12
+ WINDOWS_CHROMIUMS_PATHS = (
13
+ f"{PF64}\\Google\\Chrome\\Application\\chrome.exe", # chromium
14
+ f"{PF32}\\Google\\Chrome\\Application\\chrome.exe", # chromium
15
+ f"{LAD}\\Google\\Chrome SxS\\Application\\chrome.exe", # chromium-canary
16
+ f"{PF64}\\Opera\\opera.exe", # opera
17
+ f"{PF32}\\Opera\\opera.exe", # opera
18
+ f"{LAD}\\Programs\\Opera\\opera.exe", # opera
19
+ f"{LAD}\\Programs\\Opera\\launcher.exe", # opera
20
+ f"{LAD}\\Programs\\Opera Beta\\opera.exe", # opera-beta
21
+ f"{LAD}\\Programs\\Opera Beta\\launcher.exe", # opera-beta
22
+ f"{LAD}\\Programs\\Opera Developer\\opera.exe", # opera-developer
23
+ f"{LAD}\\Programs\\Opera Developer\\launcher.exe", # opera-developer
24
+ f"{PF64}\\Microsoft\\Edge\\Application\\msedge.exe", # msedge
25
+ f"{PF32}\\Microsoft\\Edge\\Application\\msedge.exe", # msedge
26
+ f"{PF64}\\Microsoft\\Edge Beta\\Application\\msedge.exe", # msedge-beta
27
+ f"{PF32}\\Microsoft\\Edge Beta\\Application\\msedge.exe", # msedge-beta
28
+ f"{PF64}\\Microsoft\\Edge Dev\\Application\\msedge.exe", # msedge-dev
29
+ f"{PF32}\\Microsoft\\Edge Dev\\Application\\msedge.exe", # msedge-dev
30
+ f"{LAD}\\Microsoft\\Edge SxS\\Application\\msedge.exe", # msedge-canary
31
+ f"{PF64}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe", # brave
32
+ f"{PF32}\\BraveSoftware\\Brave-Browser\\Application\\brave.exe", # brave
33
+ f"{PF64}\\BraveSoftware\\Brave-Browser-Beta\\Application\\brave.exe", # brave-beta
34
+ f"{PF32}\\BraveSoftware\\Brave-Browser-Beta\\Application\\brave.exe", # brave-beta
35
+ f"{PF64}\\BraveSoftware\\Brave-Browser-Nightly\\Application\\brave.exe", # brave-nightly
36
+ f"{PF32}\\BraveSoftware\\Brave-Browser-Nightly\\Application\\brave.exe", # brave-nightly
37
+ )
38
+
39
+
40
+ def get_chromium_path() -> Optional[str]:
41
+ for path in WINDOWS_CHROMIUMS_PATHS:
42
+ if os.path.exists(path):
43
+ return path
44
+
45
+ return None
@@ -5,17 +5,20 @@ import shutil
5
5
  import subprocess
6
6
  import time
7
7
  from getpass import getpass
8
- from typing import Callable, Optional, Tuple
8
+ from io import BytesIO
9
+ from typing import Callable, Optional, Union
10
+ from zipfile import ZipFile
9
11
 
10
12
  import psutil
13
+ import requests
11
14
 
12
- from sticker_convert.definitions import ROOT_DIR
15
+ from sticker_convert.definitions import CONFIG_DIR, ROOT_DIR
13
16
 
14
17
 
15
18
  def killall(name: str) -> bool:
16
19
  result = False
17
20
 
18
- for proc in psutil.process_iter():
21
+ for proc in psutil.process_iter(): # type: ignore
19
22
  if name in proc.name().lower():
20
23
  proc.kill()
21
24
  result = True
@@ -24,7 +27,7 @@ def killall(name: str) -> bool:
24
27
 
25
28
 
26
29
  def find_pid_by_name(name: str) -> Optional[int]:
27
- for proc in psutil.process_iter():
30
+ for proc in psutil.process_iter(): # type: ignore
28
31
  if name in proc.name().lower():
29
32
  return proc.pid
30
33
 
@@ -65,123 +68,164 @@ elif platform.system() == "Linux":
65
68
  return True if "may run the following commands" in s else False
66
69
 
67
70
 
68
- def get_mem(
69
- pid: int, pw_func: Optional[Callable[..., str]] = None
70
- ) -> Tuple[Optional[bytes], str]:
71
- return b"", ""
72
-
73
-
74
- if platform.system() == "Windows":
75
-
76
- def get_mem(
77
- pid: int, pw_func: Optional[Callable[..., str]] = None
78
- ) -> Tuple[Optional[bytes], str]:
79
- from pathlib import WindowsPath
80
-
81
- memdump_ps_path = str(WindowsPath(ROOT_DIR / "resources/memdump_windows.ps1"))
82
- arglist = f'-NoProfile -ExecutionPolicy Bypass -File "{memdump_ps_path}" {pid}'
83
- dump_fpath = os.path.expandvars(f"%temp%/memdump.bin.{pid}")
84
-
85
- cmd = [
86
- "powershell",
87
- "-NoProfile",
88
- "-ExecutionPolicy",
89
- "Bypass",
90
- "-Command",
91
- f"Start-Process -Verb RunAs powershell -ArgumentList '{arglist}'",
92
- ]
93
-
94
- subprocess.run(cmd, capture_output=True, text=True)
95
-
96
- while True:
97
- try:
98
- with open(dump_fpath, "rb") as f:
99
- s = f.read()
100
- if len(s) != 0:
101
- break
102
- time.sleep(1)
103
- except (FileNotFoundError, PermissionError):
104
- pass
105
-
106
- while True:
107
- try:
108
- os.remove(dump_fpath)
71
+ def _get_mem_win_procdump(
72
+ pid: Union[str, int],
73
+ pw_func: Optional[Callable[..., str]] = None,
74
+ is_wine: bool = False,
75
+ ) -> Optional[bytes]:
76
+ procdump_dir = CONFIG_DIR / "ProcDump"
77
+ procdump_bin = procdump_dir / "procdump.exe"
78
+ if procdump_bin.is_file() is False:
79
+ r = requests.get("https://download.sysinternals.com/files/Procdump.zip")
80
+ if r.ok is False:
81
+ return None
82
+ with ZipFile(BytesIO(r.content)) as zf:
83
+ zf.extractall(procdump_dir)
84
+
85
+ if procdump_bin.is_file() is False:
86
+ return None
87
+
88
+ if is_wine:
89
+ cmd = ["wine"]
90
+ dump_fpath = f"/tmp/memdump.{pid}.dmp"
91
+ else:
92
+ cmd = []
93
+ dump_fpath = os.path.expandvars(f"%temp%/memdump.{pid}.dmp")
94
+ cmd += [str(procdump_bin), "-accepteula", "-ma", str(pid), dump_fpath]
95
+
96
+ subprocess.run(cmd)
97
+
98
+ with open(dump_fpath, "rb") as f:
99
+ s = f.read()
100
+ os.remove(dump_fpath)
101
+
102
+ return s
103
+
104
+
105
+ def _get_mem_win_builtin(
106
+ pid: Union[str, int], pw_func: Optional[Callable[..., str]] = None
107
+ ) -> Optional[bytes]:
108
+ from pathlib import WindowsPath
109
+
110
+ memdump_ps_path = str(WindowsPath(ROOT_DIR / "resources/memdump_windows.ps1"))
111
+ arglist = f'-NoProfile -ExecutionPolicy Bypass -File "{memdump_ps_path}" {pid}'
112
+ dump_fpath = os.path.expandvars(f"%temp%/memdump.{pid}.dmp")
113
+
114
+ cmd = [
115
+ "powershell",
116
+ "-NoProfile",
117
+ "-ExecutionPolicy",
118
+ "Bypass",
119
+ "-Command",
120
+ f"Start-Process -Verb RunAs powershell -ArgumentList '{arglist}'",
121
+ ]
122
+
123
+ subprocess.run(cmd, capture_output=True, text=True)
124
+
125
+ while True:
126
+ try:
127
+ with open(dump_fpath, "rb") as f:
128
+ s = f.read()
129
+ if len(s) != 0:
109
130
  break
110
- except PermissionError:
111
- pass
112
-
113
- return s, ""
131
+ time.sleep(1)
132
+ except (FileNotFoundError, PermissionError):
133
+ pass
114
134
 
115
- elif platform.system() == "Darwin":
135
+ while True:
136
+ try:
137
+ os.remove(dump_fpath)
138
+ break
139
+ except PermissionError:
140
+ pass
116
141
 
117
- def get_mem(
118
- pid: int, pw_func: Optional[Callable[..., str]] = None
119
- ) -> Tuple[Optional[bytes], str]:
120
- subprocess.run(
142
+ return s
143
+
144
+
145
+ def _get_mem_darwin(
146
+ pid: Union[str, int], pw_func: Optional[Callable[..., str]] = None
147
+ ) -> Optional[bytes]:
148
+ subprocess.run(
149
+ [
150
+ "lldb",
151
+ "--attach-pid",
152
+ str(pid),
153
+ "-o",
154
+ f"process save-core /tmp/memdump.{pid}.dmp",
155
+ "-o",
156
+ "quit",
157
+ ],
158
+ stdout=subprocess.DEVNULL,
159
+ stderr=subprocess.DEVNULL,
160
+ )
161
+
162
+ with open(f"/tmp/memdump.{pid}.dmp", "rb") as f:
163
+ s = f.read()
164
+
165
+ os.remove(f"/tmp/memdump.{pid}.dmp")
166
+
167
+ return s
168
+
169
+
170
+ def _get_mem_linux(
171
+ pid: Union[str, int], pw_func: Optional[Callable[..., str]] = None
172
+ ) -> Optional[bytes]:
173
+ memdump_sh_path = (ROOT_DIR / "resources/memdump_linux.sh").as_posix()
174
+
175
+ s = subprocess.run(
176
+ [
177
+ memdump_sh_path,
178
+ str(pid),
179
+ ],
180
+ capture_output=True,
181
+ ).stdout
182
+
183
+ if len(s) > 1000:
184
+ pass
185
+ elif shutil.which("pkexec") and os.getenv("DISPLAY"):
186
+ s = subprocess.run(
121
187
  [
122
- "lldb",
123
- "--attach-pid",
188
+ "pkexec",
189
+ memdump_sh_path,
124
190
  str(pid),
125
- "-o",
126
- f"process save-core /tmp/memdump.{pid}.dmp",
127
- "-o",
128
- "quit",
129
191
  ],
130
- stdout=subprocess.DEVNULL,
131
- stderr=subprocess.DEVNULL,
192
+ capture_output=True,
193
+ ).stdout
194
+ else:
195
+ prompt = "Enter sudo password: "
196
+ if pw_func:
197
+ sudo_password = pw_func(prompt)
198
+ else:
199
+ sudo_password = getpass(prompt)
200
+ sudo_password_pipe = subprocess.Popen(
201
+ ("echo", sudo_password), stdout=subprocess.PIPE
132
202
  )
133
-
134
- with open(f"/tmp/memdump.{pid}.dmp", "rb") as f:
135
- s = f.read()
136
-
137
- os.remove(f"/tmp/memdump.{pid}.dmp")
138
-
139
- return s, ""
140
-
141
- else:
142
-
143
- def get_mem(
144
- pid: int, pw_func: Optional[Callable[..., str]] = None
145
- ) -> Tuple[Optional[bytes], str]:
146
- memdump_sh_path = (ROOT_DIR / "resources/memdump_linux.sh").as_posix()
147
-
148
203
  s = subprocess.run(
149
204
  [
205
+ "sudo",
206
+ "-S",
150
207
  memdump_sh_path,
151
208
  str(pid),
152
209
  ],
153
210
  capture_output=True,
211
+ stdin=sudo_password_pipe.stdout,
154
212
  ).stdout
155
213
 
156
- if len(s) > 1000:
157
- pass
158
- elif shutil.which("pkexec") and os.getenv("DISPLAY"):
159
- s = subprocess.run(
160
- [
161
- "pkexec",
162
- memdump_sh_path,
163
- str(pid),
164
- ],
165
- capture_output=True,
166
- ).stdout
214
+ return s
215
+
216
+
217
+ def get_mem(
218
+ pid: Union[str, int],
219
+ pw_func: Optional[Callable[..., str]] = None,
220
+ is_wine: bool = False,
221
+ ) -> Optional[bytes]:
222
+ if is_wine or platform.system() == "Windows":
223
+ dump = _get_mem_win_procdump(pid, pw_func, is_wine)
224
+ if dump is not None or is_wine:
225
+ return dump
167
226
  else:
168
- prompt = "Enter sudo password: "
169
- if pw_func:
170
- sudo_password = pw_func(prompt)
171
- else:
172
- sudo_password = getpass(prompt)
173
- sudo_password_pipe = subprocess.Popen(
174
- ("echo", sudo_password), stdout=subprocess.PIPE
175
- )
176
- s = subprocess.run(
177
- [
178
- "sudo",
179
- "-S",
180
- memdump_sh_path,
181
- str(pid),
182
- ],
183
- capture_output=True,
184
- stdin=sudo_password_pipe.stdout,
185
- ).stdout
186
-
187
- return s, ""
227
+ return _get_mem_win_builtin(pid, pw_func)
228
+ elif platform.system() == "Darwin":
229
+ return _get_mem_darwin(pid, pw_func)
230
+ else:
231
+ return _get_mem_linux(pid, pw_func)
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
- __version__ = "2.13.0"
3
+ __version__ = "2.13.1.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sticker-convert
3
- Version: 2.13.0
3
+ Version: 2.13.1.0
4
4
  Summary: Convert (animated) stickers to/from WhatsApp, Telegram, Signal, Line, Kakao, Viber, Discord, iMessage. Written in Python.
5
5
  Author-email: laggykiller <chaudominic2@gmail.com>
6
6
  Maintainer-email: laggykiller <chaudominic2@gmail.com>
@@ -367,7 +367,7 @@ Requires-Dist: aiolimiter~=1.2.1
367
367
  Requires-Dist: anyio~=4.9.0
368
368
  Requires-Dist: apngasm_python~=1.3.2
369
369
  Requires-Dist: av>=13.1.0
370
- Requires-Dist: beautifulsoup4~=4.13.3
370
+ Requires-Dist: beautifulsoup4~=4.13.4
371
371
  Requires-Dist: cryptg~=0.5.0.post0
372
372
  Requires-Dist: rookiepy~=0.5.6
373
373
  Requires-Dist: httpx~=0.28.1
@@ -376,16 +376,15 @@ Requires-Dist: memory-tempfile~=2.2.3
376
376
  Requires-Dist: mergedeep~=1.3.4
377
377
  Requires-Dist: numpy>=1.22.4
378
378
  Requires-Dist: Pillow~=11.2.1
379
- Requires-Dist: pybrowsers~=0.8.0
380
379
  Requires-Dist: pyoxipng~=9.1.0
381
- Requires-Dist: python-telegram-bot~=22.0
380
+ Requires-Dist: python-telegram-bot~=22.1
382
381
  Requires-Dist: psutil~=7.0.0
383
382
  Requires-Dist: PyMemoryEditor~=1.5.22
384
383
  Requires-Dist: requests~=2.32.3
385
384
  Requires-Dist: rlottie_python~=1.3.7
386
385
  Requires-Dist: signalstickers-client-fork-laggykiller~=3.3.0.post2
387
386
  Requires-Dist: socksio~=1.0.0
388
- Requires-Dist: telethon~=1.39.0
387
+ Requires-Dist: telethon~=1.40.0
389
388
  Requires-Dist: tqdm~=4.67.1
390
389
  Requires-Dist: ttkbootstrap-fork-laggykiller~=1.5.1
391
390
  Requires-Dist: websocket_client~=1.8.0
@@ -402,7 +401,7 @@ Dynamic: license-file
402
401
 
403
402
  ## Downloads
404
403
  - [Pre-compiled releases](https://github.com/laggykiller/sticker-convert/releases) for Windows, MacOS and Linux (As AppImage).
405
- - Windows: Unzip the downloaded file and run `sticker-convert.exe`
404
+ - Windows: Unzip the downloaded file and run `sticker-convert.exe`, or download msi file for installation
406
405
  - MacOS: Unzip the downloaded file, hold control and open `hold_control_and_click_open_me.command` for the first time, then `sticker-convert.app` in the future
407
406
  - Linux:
408
407
  - AppImage: `chmod +x` the downloaded AppImage and run it
@@ -686,7 +685,6 @@ Credentials options:
686
685
  --kakao-get-auth Generate Kakao auth_token by simulating login. Kakao username, password, country code and phone number are also required.
687
686
  --kakao-get-auth-desktop
688
687
  Get Kakao auth_token from Kakao Desktop application.
689
- (Only working on Windows.)
690
688
  --kakao-bin-path KAKAO_BIN_PATH
691
689
  Set Kakao Desktop application path for launching and getting auth_token.
692
690
  Useful for portable installation.
@@ -889,8 +887,10 @@ See [docs/TODO.md](docs/TODO.md)
889
887
  - Information about Line stickers: https://github.com/doubleplusc/Line-sticker-downloader
890
888
  - Information about Kakao animated stickers: https://gist.github.com/chitacan/9802668
891
889
  - Downloading and decrypting Kakao animated stickers: https://github.com/blluv/KakaoTalkEmoticonDownloader
890
+ - Finding browser executable paths: https://github.com/roniemartinez/browsers
892
891
  - Application icon taken from [Icons8](https://icons8.com/)
893
892
  - Banner generated from [GitHub Socialify](https://socialify.git.ci/)
893
+ - Free code signing on Windows provided by [SignPath.io](https://about.signpath.io/), certificate by [SignPath Foundation](https://signpath.org/)
894
894
 
895
895
  ## DISCLAIMER
896
896
  - The author of this repo is NOT affiliated with Signal, Telegram, WhatsApp, Line, Kakao, Naver Band, Viber, Discord, iMessage or Sticker Maker.
@@ -1,18 +1,18 @@
1
1
  sticker_convert/__init__.py,sha256=iQnv6UOOA69c3soAn7ZOnAIubTIQSUxtq1Uhh8xRWvU,102
2
2
  sticker_convert/__main__.py,sha256=elDCMvU27letiYs8jPUpxaCq5puURnvcDuqGsAAb6_w,592
3
- sticker_convert/cli.py,sha256=2mTp9h9I3sIBpEftfZvPr0vfjaqdvuHD5yFngLi5MwY,22473
4
- sticker_convert/converter.py,sha256=BWg42NaRRDxXxo74L5Rh0l2BDkpe2Bh948Trypeg2vA,39758
3
+ sticker_convert/cli.py,sha256=JdfZe4-GGFoa8vkNaUwCtwzmypCfMNaPZuhzHpmLBpM,22544
4
+ sticker_convert/converter.py,sha256=6_FGXW-S6t2xs56fid49z2FaEc1VFtJ-jJOA-SUKSH8,39760
5
5
  sticker_convert/definitions.py,sha256=BqROmOvqIqw8ANaqZXIxJAXGD0HgjAvCfFouQ4SaWHc,2254
6
6
  sticker_convert/gui.py,sha256=bd8rMgFaXrn41y6aOHNlD6gPBDleDmiHMsGMZNfz1jk,34239
7
7
  sticker_convert/job.py,sha256=FJiaJEcfMr8GnNfPC3SDcpTs7ytoiAZk6cxUbzsw9IE,28257
8
8
  sticker_convert/job_option.py,sha256=yI_uKWJEAul2XTC6pucz9PfW0iNwwOr0aVC-PAHkMA4,8109
9
- sticker_convert/version.py,sha256=bJKod-cGHYLxNjnXLfxixQN8STyD8kVf2ApImRquwfM,47
9
+ sticker_convert/version.py,sha256=IqHvkpNtjDMGeiZS1r9gF2cyof0NHldraqS5R5rrq10,49
10
10
  sticker_convert/downloaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  sticker_convert/downloaders/download_band.py,sha256=JPjwwdxbMXPBM9TXF76wT9mtoDCLssYnrm1iS2C6uVM,3629
12
12
  sticker_convert/downloaders/download_base.py,sha256=MI5pCT_tkfoaFlrD1oNynDj1Rv1CK0APuNVElTEAEis,5110
13
13
  sticker_convert/downloaders/download_discord.py,sha256=6AFpLAYL2hRvVcsqUtzDUC31U66U02ZcnKXDnZRi2jk,3496
14
14
  sticker_convert/downloaders/download_kakao.py,sha256=lRmpEcYjHizIRM0uFBDvjMqNEpur0VmOTKAmiir9eB0,15181
15
- sticker_convert/downloaders/download_line.py,sha256=c-hTzEarGQP0b-pnPl29NuSKcaZWUeRo_94YpJzz72M,17911
15
+ sticker_convert/downloaders/download_line.py,sha256=751-g6BH0ITwNlYNsZuBxyB92Q8f3o6Qv9VHmHDoLps,18161
16
16
  sticker_convert/downloaders/download_signal.py,sha256=3wv-BLd4qggly4AdtwV8f3vUpCVZ-8GnoPLoWngY3Pk,3728
17
17
  sticker_convert/downloaders/download_telegram.py,sha256=iGmOcVjU2Ai19t1lyDY2JhQIc--O5XMyNCGXZAA4DVY,2028
18
18
  sticker_convert/downloaders/download_viber.py,sha256=SFnyaVEd_33J1KvRhcHDJqnLKGsbLMeA2NomVHm2ulM,4226
@@ -28,13 +28,13 @@ sticker_convert/gui_components/frames/output_frame.py,sha256=n2WLk22h61DoZli8WbF
28
28
  sticker_convert/gui_components/frames/progress_frame.py,sha256=LWUZg_iL7iiNTfu7N5Ct_pklZdghxihENi7DP9YozOE,4915
29
29
  sticker_convert/gui_components/frames/right_clicker.py,sha256=dGIvSzEChrkguR80pzUemBNJ39uzJjVJQKeDNUoW3Gk,721
30
30
  sticker_convert/gui_components/windows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
- sticker_convert/gui_components/windows/advanced_compression_window.py,sha256=djJNyPodBmNhW0vHvdg6xAd7LYkVm9UINMHrRXVmr_k,32718
31
+ sticker_convert/gui_components/windows/advanced_compression_window.py,sha256=il1ZenzjZuL94MFOTR3vfCCTlZ7BIZfsVmC16CLLwI4,32734
32
32
  sticker_convert/gui_components/windows/base_window.py,sha256=xBE1peGMPvWsdrFej0CJUVhmQ57GJGvz-cX03nIIhkE,1108
33
33
  sticker_convert/gui_components/windows/discord_get_auth_window.py,sha256=a9ptBqtpZslQJ87-ZPotcT6gigouIHWAFijfkWv2rZQ,2786
34
- sticker_convert/gui_components/windows/kakao_get_auth_window.py,sha256=1nawn_D4wkziW_lROjUJlmVtITAuGt_4uruGMcEr7Oo,11128
34
+ sticker_convert/gui_components/windows/kakao_get_auth_window.py,sha256=9YfzuKQE6bjfqFxkpCa4XxMnw2T1UPPI_A6Z8E75J_M,11953
35
35
  sticker_convert/gui_components/windows/line_get_auth_window.py,sha256=S4ES_lk2-GDvPokZtYALnUc5zW1VbS4WulNqO9K1aSs,3375
36
36
  sticker_convert/gui_components/windows/signal_get_auth_window.py,sha256=d9vWMfrD0s-qI-TmB0796LRvDW64Jh2wmA1mZcRubUw,3126
37
- sticker_convert/gui_components/windows/viber_get_auth_window.py,sha256=8EGNohkBZjmTJ_0Rt4XP0zVd1eLraqukNoE84E9d5CA,5191
37
+ sticker_convert/gui_components/windows/viber_get_auth_window.py,sha256=DI-RayYAfk6ig7NlGy97ulYgZZs77S8CEDIUJdtGDwI,5787
38
38
  sticker_convert/ios-message-stickers-template/.gitignore,sha256=4uuTph_9eHfqXHUavLOmGOji6aIHOif2bUEU_hCBn4Y,9
39
39
  sticker_convert/ios-message-stickers-template/README.md,sha256=oN0FvJkCWWjSZ3PMrCvY3T1zCsdkZYFgGHAoFh0Kmt8,467
40
40
  sticker_convert/ios-message-stickers-template/.github/FUNDING.yml,sha256=3LlmdSAGDsBA2o_C1iBYTNLwkABnyZuN0zxgPPyd-f8,70
@@ -73,7 +73,7 @@ sticker_convert/resources/appicon.ico,sha256=-ldugcl2Yq2pBRTktnhGKWInpKyWzRjCiPv
73
73
  sticker_convert/resources/appicon.png,sha256=6XBEQz7PnerqS43aRkwpWolFG4WvKMuQ-st1ly-_JPg,5265
74
74
  sticker_convert/resources/compression.json,sha256=wEgtjcDyLEYup53s-SCGu2Wc3UdReWeSj9POWn5PXkk,15184
75
75
  sticker_convert/resources/emoji.json,sha256=q9DRFdVJfm7feZW7ZM6Xa5P1QsMvrn0PbBVU9jKcJKI,422720
76
- sticker_convert/resources/help.json,sha256=IDJhDD5plY8_Ze5gnM6rMs6H1-urWo94sEHeGzO5QeU,7364
76
+ sticker_convert/resources/help.json,sha256=28m5oMhybN3yg7EhmjBlPJq1HtHYa0joG355Ie1Zn10,7336
77
77
  sticker_convert/resources/input.json,sha256=vLP8pVo4Mfh-yLRjy5j1x4SMR1dQC9xCRzQ6RWN_t2E,4213
78
78
  sticker_convert/resources/memdump_linux.sh,sha256=SFKXiE0ztZyGvpFYPOrdQ0wmY3ndgJuqfiofC7BQon0,625
79
79
  sticker_convert/resources/memdump_windows.ps1,sha256=CfyNSSEW3HJOkTu-mKrP3qh5aprN-1VCBfj-R1fELA0,302
@@ -86,19 +86,22 @@ sticker_convert/uploaders/upload_telegram.py,sha256=WlUyLJlW83XZz6RhA76jHMXA6TNU
86
86
  sticker_convert/uploaders/upload_viber.py,sha256=_vOK0UgP7V7ZeFG6pR3sVf3A744Q6J19qzO-2hDvt5w,6583
87
87
  sticker_convert/uploaders/xcode_imessage.py,sha256=iTTT8gDYOTNkKqXeSWUBuWfxu7xeE418t2Z1YQFR5L0,11365
88
88
  sticker_convert/utils/callback.py,sha256=spYUGlklOs1yPZAxoqwOWgR1sdimpfM8a27if3TaVYk,6155
89
- sticker_convert/utils/chrome_remotedebug.py,sha256=p8D85NDlLiS7Vj2wLLZX7TN6hENe2p5PxVDoeOr_mTE,6902
89
+ sticker_convert/utils/chrome_remotedebug.py,sha256=moFj-Uz_bBy4-wXFET80sdwkzNC4PW8LMwwrU8yKOg8,6642
90
90
  sticker_convert/utils/emoji.py,sha256=AqB26JY-PkYzNwPLReSnqLiQKe-bR9UXnLclAbgubJ8,367
91
- sticker_convert/utils/process.py,sha256=EAQZ9WpiKmkvToIv8G1HNY4V7m0jXyyePTmeP2XOZzE,4688
91
+ sticker_convert/utils/process.py,sha256=y_W-D9zkxAEfPvYJZTKxNtNHxmuK0NldpDXu-OdGR1M,5704
92
92
  sticker_convert/utils/singletons.py,sha256=SiV374FxU68DpysGoj_ytU1ErINkeOBbP4s9QTcexeY,357
93
93
  sticker_convert/utils/url_detect.py,sha256=_wmI28hUyngq8TVz1bw7YM90qPLd3bIynawVlbr_lcI,939
94
- sticker_convert/utils/auth/get_discord_auth.py,sha256=6qh1BuN-GieSXqJu9WbthLsflrYIGaEgKHGrQoPbO1M,4281
94
+ sticker_convert/utils/auth/get_discord_auth.py,sha256=8H9Z0c7pl6JjzkP8lo0-lCFnBAT5Eql-LYc6M92FY_k,4283
95
95
  sticker_convert/utils/auth/get_kakao_auth.py,sha256=Wok5sp0GGBgTwwlfYB7lVq82ndBAOGTcqsWEaWAXFNE,10760
96
- sticker_convert/utils/auth/get_kakao_desktop_auth.py,sha256=0qxy1MfLFFDhSaEzWYT3H1GGOUBWDrmRPoonCIt1nuE,8613
96
+ sticker_convert/utils/auth/get_kakao_desktop_auth.py,sha256=a-P0sXXjZRnGwqcdgGZc_idnAvUXYx0EMCKpUXOuqJo,8659
97
97
  sticker_convert/utils/auth/get_line_auth.py,sha256=8l8ha2vQmk3rHGvDE7PkcxQXbH3oe62LKbI3qVUtvqc,2196
98
98
  sticker_convert/utils/auth/get_signal_auth.py,sha256=I6od2aj8yl1eLV8S2TtNQEPM77DC7FpkRKex0pXY2II,4580
99
- sticker_convert/utils/auth/get_viber_auth.py,sha256=redKrHbCCBWHhOqAQOBIOWQpLM3R7Kr86ArTh7OWI4g,8181
100
- sticker_convert/utils/auth/telegram_api.py,sha256=hX9fT0Pp8yMxcKSXLe9Mvy12mQ_rWj-KTyamABI8YWA,24232
101
- sticker_convert/utils/auth/telethon_setup.py,sha256=vBgRPBU_jXI8sHpYEofvO84F-dObY0TCfFzhHyw3OLI,2994
99
+ sticker_convert/utils/auth/get_viber_auth.py,sha256=aQiv1JI2RKiPVoo_JjbjcWwsUr2OK2FXMsFLPb3TtGU,8123
100
+ sticker_convert/utils/auth/telegram_api.py,sha256=MAWNFA6Ttn-aO1g_waeIZkc4AMUH_Atds2x8-jhhQIU,24311
101
+ sticker_convert/utils/auth/telethon_setup.py,sha256=7VtsSM3n8qrN_VXV8hBaNSmApxgIPCa84Z08fRr43eQ,3309
102
+ sticker_convert/utils/chromiums/linux.py,sha256=voWOxQVNy2icGDQfnZEa-2Nwrv-Qmuvt0v1L65hKnY8,1719
103
+ sticker_convert/utils/chromiums/osx.py,sha256=ET6_uWZDbPCIN-GihMmjNcva0-WAyn0fA2-SzNn5wcU,3255
104
+ sticker_convert/utils/chromiums/windows.py,sha256=wOyEQIQNV3_Nb2m44aFJh6QJj16cDpNmD1NxnVNlkrk,2188
102
105
  sticker_convert/utils/files/cache_store.py,sha256=etfe614OAhAyrnM5fGeESKq6R88YLNqkqkxSzEmZ0V0,1047
103
106
  sticker_convert/utils/files/json_manager.py,sha256=Vr6pZJdLMkrJJWN99210aduVHb0ILyf0SSTaw4TZqgc,541
104
107
  sticker_convert/utils/files/json_resources_loader.py,sha256=flZFixUXRTrOAhvRQpuSQgmJ69yXL94sxukcowLT1JQ,1049
@@ -109,9 +112,9 @@ sticker_convert/utils/media/apple_png_normalize.py,sha256=LbrQhc7LlYX4I9ek4XJsZE
109
112
  sticker_convert/utils/media/codec_info.py,sha256=HwA6eVh7cLhOlUoR_K9d_wyBRJ_ocGtB3GAyne_iZAU,16483
110
113
  sticker_convert/utils/media/decrypt_kakao.py,sha256=4wq9ZDRnFkx1WmFZnyEogBofiLGsWQM_X69HlA36578,1947
111
114
  sticker_convert/utils/media/format_verify.py,sha256=oM32P186tWe9YxvBQRPr8D3FEmBN3b2rEe_2S_MwxyQ,6236
112
- sticker_convert-2.13.0.dist-info/licenses/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
113
- sticker_convert-2.13.0.dist-info/METADATA,sha256=P6ZK34jRKvYmFd_2zm-8KAdjewwSJnoSaDN2yy3SR0Q,54352
114
- sticker_convert-2.13.0.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
115
- sticker_convert-2.13.0.dist-info/entry_points.txt,sha256=MNJ7XyC--ugxi5jS1nzjDLGnxCyLuaGdsVLnJhDHCqs,66
116
- sticker_convert-2.13.0.dist-info/top_level.txt,sha256=r9vfnB0l1ZnH5pTH5RvkobnK3Ow9m0RsncaOMAtiAtk,16
117
- sticker_convert-2.13.0.dist-info/RECORD,,
115
+ sticker_convert-2.13.1.0.dist-info/licenses/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
116
+ sticker_convert-2.13.1.0.dist-info/METADATA,sha256=HS8RD0rAFH3H34wZn7ilCqeVEa0p8L0QOYik4EB_dIY,54533
117
+ sticker_convert-2.13.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
118
+ sticker_convert-2.13.1.0.dist-info/entry_points.txt,sha256=MNJ7XyC--ugxi5jS1nzjDLGnxCyLuaGdsVLnJhDHCqs,66
119
+ sticker_convert-2.13.1.0.dist-info/top_level.txt,sha256=r9vfnB0l1ZnH5pTH5RvkobnK3Ow9m0RsncaOMAtiAtk,16
120
+ sticker_convert-2.13.1.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (79.0.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5