sticker-convert 2.13.0__py3-none-any.whl → 2.13.2.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.
Files changed (28) hide show
  1. sticker_convert/cli.py +3 -0
  2. sticker_convert/converter.py +1 -1
  3. sticker_convert/downloaders/download_line.py +8 -4
  4. sticker_convert/downloaders/download_ogq.py +79 -0
  5. sticker_convert/gui_components/windows/advanced_compression_window.py +1 -1
  6. sticker_convert/gui_components/windows/kakao_get_auth_window.py +25 -4
  7. sticker_convert/gui_components/windows/viber_get_auth_window.py +15 -0
  8. sticker_convert/job.py +4 -0
  9. sticker_convert/resources/compression.json +47 -0
  10. sticker_convert/resources/help.json +1 -1
  11. sticker_convert/resources/input.json +10 -0
  12. sticker_convert/utils/auth/get_discord_auth.py +1 -1
  13. sticker_convert/utils/auth/get_kakao_desktop_auth.py +36 -41
  14. sticker_convert/utils/auth/get_viber_auth.py +2 -4
  15. sticker_convert/utils/auth/telegram_api.py +3 -1
  16. sticker_convert/utils/auth/telethon_setup.py +18 -7
  17. sticker_convert/utils/chrome_remotedebug.py +9 -23
  18. sticker_convert/utils/chromiums/linux.py +52 -0
  19. sticker_convert/utils/chromiums/osx.py +68 -0
  20. sticker_convert/utils/chromiums/windows.py +45 -0
  21. sticker_convert/utils/process.py +152 -108
  22. sticker_convert/version.py +1 -1
  23. {sticker_convert-2.13.0.dist-info → sticker_convert-2.13.2.0.dist-info}/METADATA +20 -13
  24. {sticker_convert-2.13.0.dist-info → sticker_convert-2.13.2.0.dist-info}/RECORD +28 -24
  25. {sticker_convert-2.13.0.dist-info → sticker_convert-2.13.2.0.dist-info}/WHEEL +1 -1
  26. {sticker_convert-2.13.0.dist-info → sticker_convert-2.13.2.0.dist-info}/entry_points.txt +0 -0
  27. {sticker_convert-2.13.0.dist-info → sticker_convert-2.13.2.0.dist-info}/licenses/LICENSE +0 -0
  28. {sticker_convert-2.13.0.dist-info → sticker_convert-2.13.2.0.dist-info}/top_level.txt +0 -0
sticker_convert/cli.py CHANGED
@@ -233,6 +233,7 @@ class CLI:
233
233
  "telegram_telethon": args.download_telegram_telethon,
234
234
  "kakao": args.download_kakao,
235
235
  "band": args.download_band,
236
+ "ogq": args.download_ogq,
236
237
  "viber": args.download_viber,
237
238
  "discord": args.download_discord,
238
239
  "discord_emoji": args.download_discord_emoji,
@@ -551,6 +552,8 @@ class CLI:
551
552
  opt_cred.telethon_api_hash = telethon_api_hash
552
553
 
553
554
  self.cb.msg("Telethon setup successful")
555
+ else:
556
+ self.cb.msg("Telethon setup failed")
554
557
 
555
558
  if args.line_get_auth:
556
559
  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:
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env python3
2
+ from __future__ import annotations
3
+
4
+ from pathlib import Path
5
+ from typing import Any, List, Optional, Tuple
6
+ from urllib import parse
7
+
8
+ import requests
9
+ from bs4 import BeautifulSoup
10
+
11
+ from sticker_convert.downloaders.download_base import DownloadBase
12
+ from sticker_convert.job_option import CredOption, InputOption
13
+ from sticker_convert.utils.callback import CallbackProtocol, CallbackReturn
14
+ from sticker_convert.utils.files.metadata_handler import MetadataHandler
15
+
16
+ # Reference: https://github.com/star-39/moe-sticker-bot/issues/49
17
+
18
+
19
+ class DownloadOgq(DownloadBase):
20
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
21
+ super().__init__(*args, **kwargs)
22
+ self.headers = {"User-Agent": "Mozilla/5.0"}
23
+
24
+ def download_stickers_ogq(self) -> Tuple[int, int]:
25
+ url_parse = parse.urlparse(self.url)
26
+ if (
27
+ url_parse.netloc != "ogqmarket.naver.com"
28
+ or url_parse.path.startswith("/artworks/sticker/detail") is False
29
+ ):
30
+ self.cb.put(f"Invalid url: {self.url}")
31
+ artwork_id = {
32
+ i.split("=")[0]: i.split("=")[1] for i in url_parse.query.split("&")
33
+ }["artworkId"]
34
+
35
+ html = requests.get(self.url, headers=self.headers).text
36
+ soup = BeautifulSoup(html, "html.parser")
37
+
38
+ author_tag = soup.select_one("div.info div.nickname span") # type: ignore
39
+ author = author_tag.text.strip() if author_tag else "OGQ"
40
+ title_tag = soup.select_one("div.header div div.title p") # type: ignore
41
+ title = title_tag.text.strip() if title_tag else artwork_id
42
+
43
+ seen: List[str] = []
44
+ imgs: List[str] = []
45
+ targets: List[Tuple[str, Path]] = []
46
+ n = 0
47
+ for img in soup.find_all("img", alt="sticker-detail-image-prevew"):
48
+ src = img.get("src")
49
+ if not src:
50
+ continue
51
+ src = src.split("?")[0]
52
+ if src in seen:
53
+ continue
54
+ seen.append(src)
55
+ imgs.append(src)
56
+ sticker_url = f"{src}?type=ma480_480"
57
+ sticker_url_parse = parse.urlparse(sticker_url)
58
+ ext = sticker_url_parse.path.split(".")[-1]
59
+ if sticker_url_parse.path.split("/")[-1].startswith("original_"):
60
+ path = self.out_dir / f"{n}.{ext}"
61
+ else:
62
+ path = self.out_dir / f"cover.{ext}"
63
+ targets.append((sticker_url, path))
64
+ n += 1
65
+
66
+ results = self.download_multiple_files(targets)
67
+ MetadataHandler.set_metadata(self.out_dir, title=title, author=author)
68
+
69
+ return len(results.values()), len(targets)
70
+
71
+ @staticmethod
72
+ def start(
73
+ opt_input: InputOption,
74
+ opt_cred: Optional[CredOption],
75
+ cb: CallbackProtocol,
76
+ cb_return: CallbackReturn,
77
+ ) -> Tuple[int, int]:
78
+ downloader = DownloadOgq(opt_input, opt_cred, cb, cb_return)
79
+ return downloader.download_stickers_ogq()
@@ -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(
sticker_convert/job.py CHANGED
@@ -16,6 +16,7 @@ from sticker_convert.downloaders.download_band import DownloadBand
16
16
  from sticker_convert.downloaders.download_discord import DownloadDiscord
17
17
  from sticker_convert.downloaders.download_kakao import DownloadKakao
18
18
  from sticker_convert.downloaders.download_line import DownloadLine
19
+ from sticker_convert.downloaders.download_ogq import DownloadOgq
19
20
  from sticker_convert.downloaders.download_signal import DownloadSignal
20
21
  from sticker_convert.downloaders.download_telegram import DownloadTelegram
21
22
  from sticker_convert.downloaders.download_viber import DownloadViber
@@ -570,6 +571,9 @@ class Job:
570
571
  if self.opt_input.option == "band":
571
572
  downloaders.append(DownloadBand.start)
572
573
 
574
+ if self.opt_input.option == "ogq":
575
+ downloaders.append(DownloadOgq.start)
576
+
573
577
  if self.opt_input.option == "viber":
574
578
  downloaders.append(DownloadViber.start)
575
579
 
@@ -375,6 +375,53 @@
375
375
  "quantize_method": "imagequant",
376
376
  "default_emoji": "😀"
377
377
  },
378
+ "ogq": {
379
+ "size_max": {
380
+ "img": 0,
381
+ "vid": 0
382
+ },
383
+ "format": {
384
+ "img": ".png",
385
+ "vid": ".gif"
386
+ },
387
+ "fps": {
388
+ "min": 1,
389
+ "max": 30,
390
+ "power": -0.5
391
+ },
392
+ "res": {
393
+ "w": {
394
+ "min": 480,
395
+ "max": 480
396
+ },
397
+ "h": {
398
+ "min": 480,
399
+ "max": 480
400
+ },
401
+ "power": 3
402
+ },
403
+ "quality": {
404
+ "min": 10,
405
+ "max": 95,
406
+ "power": 5
407
+ },
408
+ "color": {
409
+ "min": 32,
410
+ "max": 257,
411
+ "power": 3
412
+ },
413
+ "duration": {
414
+ "min": 83,
415
+ "max": 4000
416
+ },
417
+ "padding_percent": 0,
418
+ "bg_color": "",
419
+ "steps": 16,
420
+ "fake_vid": false,
421
+ "scale_filter": "bicubic",
422
+ "quantize_method": "imagequant",
423
+ "default_emoji": "😀"
424
+ },
378
425
  "viber": {
379
426
  "size_max": {
380
427
  "img": 0,
@@ -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.",
@@ -69,6 +69,16 @@
69
69
  "author": false
70
70
  }
71
71
  },
72
+ "ogq": {
73
+ "full_name": "Download from OGQ",
74
+ "help": "Download OGQ stickers from a URL / ID as input",
75
+ "example": "Example: https://ogqmarket.naver.com/artworks/sticker/detail?artworkId=xxxxx",
76
+ "address_lbls": "URL address",
77
+ "metadata_provides": {
78
+ "title": true,
79
+ "author": false
80
+ }
81
+ },
72
82
  "viber": {
73
83
  "full_name": "Download from Viber",
74
84
  "help": "Download viber stickers from a URL as input",
@@ -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