sticker-convert 2.13.3.0__py3-none-any.whl → 2.17.0.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 (93) hide show
  1. sticker_convert/__main__.py +24 -27
  2. sticker_convert/auth/__init__.py +0 -0
  3. sticker_convert/auth/auth_base.py +19 -0
  4. sticker_convert/{utils/auth/get_discord_auth.py → auth/auth_discord.py} +149 -118
  5. sticker_convert/{utils/auth/get_kakao_auth.py → auth/auth_kakao_android_login.py} +331 -330
  6. sticker_convert/auth/auth_kakao_desktop_login.py +327 -0
  7. sticker_convert/{utils/auth/get_kakao_desktop_auth.py → auth/auth_kakao_desktop_memdump.py} +281 -263
  8. sticker_convert/{utils/auth/get_line_auth.py → auth/auth_line.py} +98 -80
  9. sticker_convert/{utils/auth/get_signal_auth.py → auth/auth_signal.py} +139 -135
  10. sticker_convert/auth/auth_telethon.py +161 -0
  11. sticker_convert/{utils/auth/get_viber_auth.py → auth/auth_viber.py} +250 -235
  12. sticker_convert/{utils/auth → auth}/telegram_api.py +736 -675
  13. sticker_convert/cli.py +623 -608
  14. sticker_convert/converter.py +1093 -1084
  15. sticker_convert/definitions.py +4 -0
  16. sticker_convert/downloaders/download_band.py +111 -110
  17. sticker_convert/downloaders/download_base.py +171 -166
  18. sticker_convert/downloaders/download_discord.py +92 -91
  19. sticker_convert/downloaders/download_kakao.py +417 -404
  20. sticker_convert/downloaders/download_line.py +484 -475
  21. sticker_convert/downloaders/download_ogq.py +80 -79
  22. sticker_convert/downloaders/download_signal.py +108 -105
  23. sticker_convert/downloaders/download_telegram.py +56 -55
  24. sticker_convert/downloaders/download_viber.py +121 -120
  25. sticker_convert/gui.py +788 -873
  26. sticker_convert/gui_components/frames/comp_frame.py +180 -166
  27. sticker_convert/gui_components/frames/config_frame.py +156 -113
  28. sticker_convert/gui_components/frames/control_frame.py +32 -30
  29. sticker_convert/gui_components/frames/cred_frame.py +232 -233
  30. sticker_convert/gui_components/frames/input_frame.py +139 -137
  31. sticker_convert/gui_components/frames/output_frame.py +112 -110
  32. sticker_convert/gui_components/frames/right_clicker.py +25 -23
  33. sticker_convert/gui_components/windows/advanced_compression_window.py +757 -757
  34. sticker_convert/gui_components/windows/base_window.py +7 -2
  35. sticker_convert/gui_components/windows/discord_get_auth_window.py +79 -82
  36. sticker_convert/gui_components/windows/kakao_get_auth_window.py +511 -321
  37. sticker_convert/gui_components/windows/line_get_auth_window.py +94 -102
  38. sticker_convert/gui_components/windows/signal_get_auth_window.py +84 -89
  39. sticker_convert/gui_components/windows/viber_get_auth_window.py +168 -168
  40. sticker_convert/ios-message-stickers-template/.github/FUNDING.yml +3 -3
  41. sticker_convert/ios-message-stickers-template/README.md +10 -10
  42. sticker_convert/ios-message-stickers-template/stickers/Info.plist +43 -43
  43. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Info.plist +31 -31
  44. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Contents.json +6 -6
  45. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Contents.json +20 -20
  46. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 1.sticker/Contents.json +9 -9
  47. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 2.sticker/Contents.json +9 -9
  48. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 3.sticker/Contents.json +9 -9
  49. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Contents.json +91 -91
  50. sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.pbxproj +364 -364
  51. sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -7
  52. sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -8
  53. sticker_convert/ios-message-stickers-template/stickers.xcodeproj/xcuserdata/niklaspeterson.xcuserdatad/xcschemes/xcschememanagement.plist +14 -14
  54. sticker_convert/job.py +166 -130
  55. sticker_convert/job_option.py +1 -0
  56. sticker_convert/locales/en_US/LC_MESSAGES/base.mo +0 -0
  57. sticker_convert/locales/ja_JP/LC_MESSAGES/base.mo +0 -0
  58. sticker_convert/locales/zh_CN/LC_MESSAGES/base.mo +0 -0
  59. sticker_convert/locales/zh_TW/LC_MESSAGES/base.mo +0 -0
  60. sticker_convert/py.typed +0 -0
  61. sticker_convert/resources/NotoColorEmoji.ttf +0 -0
  62. sticker_convert/resources/help.ja_JP.json +88 -0
  63. sticker_convert/resources/help.json +10 -7
  64. sticker_convert/resources/help.zh_CN.json +88 -0
  65. sticker_convert/resources/help.zh_TW.json +88 -0
  66. sticker_convert/resources/input.ja_JP.json +74 -0
  67. sticker_convert/resources/input.json +121 -121
  68. sticker_convert/resources/input.zh_CN.json +74 -0
  69. sticker_convert/resources/input.zh_TW.json +74 -0
  70. sticker_convert/resources/output.ja_JP.json +38 -0
  71. sticker_convert/resources/output.zh_CN.json +38 -0
  72. sticker_convert/resources/output.zh_TW.json +38 -0
  73. sticker_convert/uploaders/compress_wastickers.py +186 -177
  74. sticker_convert/uploaders/upload_base.py +44 -35
  75. sticker_convert/uploaders/upload_signal.py +218 -203
  76. sticker_convert/uploaders/upload_telegram.py +353 -338
  77. sticker_convert/uploaders/upload_viber.py +178 -169
  78. sticker_convert/uploaders/xcode_imessage.py +295 -286
  79. sticker_convert/utils/callback.py +238 -6
  80. sticker_convert/utils/emoji.py +16 -4
  81. sticker_convert/utils/files/json_resources_loader.py +24 -19
  82. sticker_convert/utils/files/metadata_handler.py +3 -3
  83. sticker_convert/utils/translate.py +108 -0
  84. sticker_convert/utils/url_detect.py +40 -37
  85. sticker_convert/version.py +1 -1
  86. {sticker_convert-2.13.3.0.dist-info → sticker_convert-2.17.0.0.dist-info}/METADATA +89 -74
  87. {sticker_convert-2.13.3.0.dist-info → sticker_convert-2.17.0.0.dist-info}/RECORD +91 -74
  88. sticker_convert/utils/auth/telethon_setup.py +0 -97
  89. sticker_convert/utils/singletons.py +0 -18
  90. {sticker_convert-2.13.3.0.dist-info → sticker_convert-2.17.0.0.dist-info}/WHEEL +0 -0
  91. {sticker_convert-2.13.3.0.dist-info → sticker_convert-2.17.0.0.dist-info}/entry_points.txt +0 -0
  92. {sticker_convert-2.13.3.0.dist-info → sticker_convert-2.17.0.0.dist-info}/licenses/LICENSE +0 -0
  93. {sticker_convert-2.13.3.0.dist-info → sticker_convert-2.17.0.0.dist-info}/top_level.txt +0 -0
@@ -1,235 +1,250 @@
1
- #!/usr/bin/env python3
2
- import importlib.util
3
- import os
4
- import platform
5
- import shutil
6
- import subprocess
7
- import time
8
- from functools import partial
9
- from getpass import getpass
10
- from pathlib import Path
11
- from typing import Callable, List, Optional, Tuple, cast
12
-
13
- from sticker_convert.utils.process import check_admin, find_pid_by_name, get_mem, killall
14
-
15
- MSG_NO_BIN = """Viber Desktop not detected.
16
- Download and install Viber Desktop,
17
- then login to Viber Desktop and try again."""
18
- MSG_NO_AUTH = """Viber Desktop installed,
19
- but viber_auth not found.
20
- Please login to Viber Desktop and try again."""
21
- MSG_SIP_ENABLED = """You need to disable SIP:
22
- 1. Restart computer in Recovery mode
23
- 2. Launch Terminal from the Utilities menu
24
- 3. Run the command `csrutil disable`
25
- 4. Restart your computer"""
26
- MSG_LAUNCH_FAIL = "Failed to launch Viber"
27
- MSG_PERMISSION_ERROR = "Failed to read Viber process memory"
28
-
29
-
30
- class GetViberAuth:
31
- def __init__(self, cb_ask_str: Callable[..., str] = input) -> None:
32
- self.cb_ask_str = cb_ask_str
33
-
34
- def relaunch_viber(self, viber_bin_path: str) -> Optional[int]:
35
- killed = killall("viber")
36
- if killed:
37
- time.sleep(5)
38
-
39
- if platform.system() == "Darwin":
40
- cmd = ["open", "-n", viber_bin_path]
41
- else:
42
- cmd = [viber_bin_path]
43
- subprocess.Popen(cmd)
44
- time.sleep(10)
45
-
46
- return find_pid_by_name("viber")
47
-
48
- def get_auth_by_pme(
49
- self, viber_bin_path: str, relaunch: bool = True
50
- ) -> Tuple[Optional[str], str]:
51
- from PyMemoryEditor import OpenProcess # type: ignore
52
-
53
- member_id = None
54
- m_token = None
55
- m_ts = None
56
-
57
- if relaunch:
58
- viber_pid = self.relaunch_viber(viber_bin_path)
59
- else:
60
- viber_pid = find_pid_by_name("viber")
61
- if viber_pid is None:
62
- return None, MSG_LAUNCH_FAIL
63
-
64
- try:
65
- with OpenProcess(pid=int(viber_pid)) as process:
66
- for address in process.search_by_value(str, 18, "X-Viber-Auth-Mid: "): # type: ignore
67
- member_id_addr = cast(int, address) + 18
68
- member_id_bytes = process.read_process_memory(
69
- member_id_addr, bytes, 20
70
- )
71
- member_id_term = member_id_bytes.find(b"\x0d\x0a")
72
- if member_id_term == -1:
73
- continue
74
- member_id = member_id_bytes[:member_id_term].decode(
75
- encoding="ascii"
76
- )
77
- break
78
- if member_id is None:
79
- return None, MSG_NO_AUTH
80
-
81
- for address in process.search_by_value(str, 20, "X-Viber-Auth-Token: "): # type: ignore
82
- m_token_addr = cast(int, address) + 20
83
- m_token = process.read_process_memory(m_token_addr, str, 64)
84
- break
85
- if m_token is None:
86
- return None, MSG_NO_AUTH
87
-
88
- for address in process.search_by_value( # type: ignore
89
- str, 24, "X-Viber-Auth-Timestamp: "
90
- ):
91
- m_ts_addr = cast(int, address) + 24
92
- m_ts = process.read_process_memory(m_ts_addr, str, 13)
93
- break
94
- if m_ts is None:
95
- return None, MSG_NO_AUTH
96
- except PermissionError:
97
- return None, MSG_PERMISSION_ERROR
98
-
99
- viber_auth = f"member_id:{member_id};m_token:{m_token};m_ts:{m_ts}"
100
- msg = "Got viber_auth successfully:\n"
101
- msg += f"{viber_auth=}\n"
102
-
103
- return viber_auth, msg
104
-
105
- def get_auth_by_dump(
106
- self, viber_bin_path: str, relaunch: bool = True
107
- ) -> Tuple[Optional[str], str]:
108
- member_id = None
109
- m_token = None
110
- m_ts = None
111
-
112
- if platform.system() == "Darwin":
113
- csrutil_status = subprocess.run(
114
- ["csrutil", "status"], capture_output=True, text=True
115
- ).stdout
116
-
117
- if "enabled" in csrutil_status:
118
- return None, MSG_SIP_ENABLED
119
-
120
- if relaunch:
121
- viber_pid = self.relaunch_viber(viber_bin_path)
122
- else:
123
- viber_pid = find_pid_by_name("viber")
124
- if viber_pid is None:
125
- return None, MSG_LAUNCH_FAIL
126
-
127
- if self.cb_ask_str == input:
128
- pw_func = getpass
129
- else:
130
- pw_func = partial(
131
- self.cb_ask_str, initialvalue="", cli_show_initialvalue=False
132
- )
133
- s = get_mem(viber_pid, pw_func)
134
-
135
- if s is None:
136
- return None, "Failed to dump memory"
137
-
138
- member_id_addr = s.find(b"X-Viber-Auth-Mid: ")
139
- m_token_addr = s.find(b"X-Viber-Auth-Token: ")
140
- m_ts_addr = s.find(b"X-Viber-Auth-Timestamp: ")
141
-
142
- if member_id_addr == -1 or m_token_addr == -1 or m_ts_addr == -1:
143
- return None, MSG_NO_AUTH
144
-
145
- member_id_addr += 18
146
- m_token_addr += 20
147
- m_ts_addr += 24
148
-
149
- member_id_bytes = s[member_id_addr : member_id_addr + 20]
150
- member_id_term = member_id_bytes.find(b"\x0d\x0a")
151
- if member_id_term == -1:
152
- return None, MSG_NO_AUTH
153
- member_id = member_id_bytes[:member_id_term].decode(encoding="ascii")
154
-
155
- m_token = s[m_token_addr : m_token_addr + 64].decode(encoding="ascii")
156
- m_ts = s[m_ts_addr : m_ts_addr + 13].decode(encoding="ascii")
157
-
158
- viber_auth = f"member_id:{member_id};m_token:{m_token};m_ts:{m_ts}"
159
- msg = "Got viber_auth successfully:\n"
160
- msg += f"{viber_auth=}\n"
161
-
162
- return viber_auth, msg
163
-
164
- def get_viber_desktop(self) -> Optional[str]:
165
- if platform.system() == "Windows":
166
- viber_bin_path = os.path.expandvars("%localappdata%/Viber/Viber.exe")
167
- elif platform.system() == "Darwin":
168
- viber_bin_path = "/Applications/Viber.app"
169
- else:
170
- if os.path.isfile("/opt/viber/Viber"):
171
- viber_bin_path = "/opt/viber/Viber"
172
- else:
173
- viber_which = shutil.which("Viber")
174
- if viber_which is None:
175
- viber_which = shutil.which("viber")
176
- if viber_which is None:
177
- viber_which = shutil.which("viber.AppImage")
178
- if viber_which is None:
179
- viber_bin_path = "viber"
180
- else:
181
- viber_bin_path = viber_which
182
-
183
- if Path(viber_bin_path).is_file() or Path(viber_bin_path).is_dir():
184
- return viber_bin_path
185
-
186
- return None
187
-
188
- def get_cred(
189
- self,
190
- viber_bin_path: Optional[str] = None,
191
- ) -> Tuple[Optional[str], str]:
192
- if not viber_bin_path:
193
- viber_bin_path = self.get_viber_desktop()
194
-
195
- if not viber_bin_path:
196
- return None, MSG_NO_BIN
197
-
198
- # get_auth_by_dump()
199
- # + Fast
200
- # - Requires admin
201
-
202
- # get_auth_by_pme()
203
- # + No admin (If have permission to read process)
204
- # - Slow
205
- # - Cannot run on macOS
206
-
207
- # If admin, prefer get_auth_by_dump() over get_auth_by_pme(), vice versa
208
- methods: List[Callable[[str, bool], Tuple[Optional[str], str]]] = []
209
- relaunch = True
210
- viber_auth = None
211
- msg = ""
212
-
213
- pme_present = importlib.util.find_spec("PyMemoryEditor") is not None
214
- if platform.system() == "Darwin":
215
- methods.append(self.get_auth_by_dump)
216
- elif platform.system() == "Windows":
217
- methods.append(self.get_auth_by_dump)
218
- if pme_present:
219
- methods.append(self.get_auth_by_pme)
220
- else:
221
- if not os.path.isfile("/.dockerenv"):
222
- methods.append(self.get_auth_by_dump)
223
- if pme_present:
224
- methods.append(self.get_auth_by_pme)
225
- if check_admin() is False:
226
- methods.reverse()
227
-
228
- for method in methods:
229
- viber_auth, msg = method(viber_bin_path, relaunch)
230
- relaunch = False
231
- if viber_auth is not None:
232
- break
233
-
234
- killall("viber")
235
- return viber_auth, msg
1
+ #!/usr/bin/env python3
2
+ import importlib.util
3
+ import os
4
+ import platform
5
+ import shutil
6
+ import subprocess
7
+ import time
8
+ from pathlib import Path
9
+ from typing import Any, Callable, List, Optional, Tuple, cast
10
+
11
+ from sticker_convert.auth.auth_base import AuthBase
12
+ from sticker_convert.utils.process import check_admin, find_pid_by_name, get_mem, killall
13
+ from sticker_convert.utils.translate import I
14
+
15
+
16
+ class AuthViber(AuthBase):
17
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
18
+ self.MSG_NO_BIN = I(
19
+ "Viber Desktop not detected.\n"
20
+ "Download and install Viber Desktop,\n"
21
+ "then login to Viber Desktop and try again."
22
+ )
23
+ self.MSG_NO_AUTH = I(
24
+ "Viber Desktop installed,\n"
25
+ "but viber_auth not found.\n"
26
+ "Please login to Viber Desktop and try again."
27
+ )
28
+ self.MSG_SIP_ENABLED = I(
29
+ "You need to disable SIP:\n"
30
+ "1. Restart computer in Recovery mode\n"
31
+ "2. Launch Terminal from the Utilities menu\n"
32
+ "3. Run the command `csrutil disable`\n"
33
+ "4. Restart your computer"
34
+ )
35
+ self.MSG_LAUNCH_FAIL = I("Failed to launch Viber")
36
+ self.MSG_PERMISSION_ERROR = I("Failed to read Viber process memory")
37
+
38
+ super().__init__(*args, **kwargs)
39
+
40
+ def relaunch_viber(self, viber_bin_path: str) -> Optional[int]:
41
+ killed = killall("viber")
42
+ if killed:
43
+ time.sleep(5)
44
+
45
+ if platform.system() == "Darwin":
46
+ cmd = ["open", "-n", viber_bin_path]
47
+ else:
48
+ cmd = [viber_bin_path]
49
+ subprocess.Popen(cmd)
50
+ time.sleep(10)
51
+
52
+ return find_pid_by_name("viber")
53
+
54
+ def get_auth_by_pme(
55
+ self, viber_bin_path: str, relaunch: bool = True
56
+ ) -> Tuple[Optional[str], str]:
57
+ from PyMemoryEditor import OpenProcess # type: ignore
58
+
59
+ member_id = None
60
+ m_token = None
61
+ m_ts = None
62
+
63
+ if relaunch:
64
+ viber_pid = self.relaunch_viber(viber_bin_path)
65
+ else:
66
+ viber_pid = find_pid_by_name("viber")
67
+ if viber_pid is None:
68
+ return None, self.MSG_LAUNCH_FAIL
69
+
70
+ try:
71
+ with OpenProcess(pid=int(viber_pid)) as process:
72
+ for address in process.search_by_value(str, 18, "X-Viber-Auth-Mid: "): # type: ignore
73
+ member_id_addr = cast(int, address) + 18
74
+ member_id_bytes = process.read_process_memory(
75
+ member_id_addr, bytes, 20
76
+ )
77
+ member_id_term = member_id_bytes.find(b"\x0d\x0a")
78
+ if member_id_term == -1:
79
+ continue
80
+ member_id = member_id_bytes[:member_id_term].decode(
81
+ encoding="ascii"
82
+ )
83
+ break
84
+ if member_id is None:
85
+ return None, self.MSG_NO_AUTH
86
+
87
+ for address in process.search_by_value(str, 20, "X-Viber-Auth-Token: "): # type: ignore
88
+ m_token_addr = cast(int, address) + 20
89
+ m_token = process.read_process_memory(m_token_addr, str, 64)
90
+ break
91
+ if m_token is None:
92
+ return None, self.MSG_NO_AUTH
93
+
94
+ for address in process.search_by_value( # type: ignore
95
+ str, 24, "X-Viber-Auth-Timestamp: "
96
+ ):
97
+ m_ts_addr = cast(int, address) + 24
98
+ m_ts = process.read_process_memory(m_ts_addr, str, 13)
99
+ break
100
+ if m_ts is None:
101
+ return None, self.MSG_NO_AUTH
102
+ except PermissionError:
103
+ return None, self.MSG_PERMISSION_ERROR
104
+
105
+ viber_auth = f"member_id:{member_id};m_token:{m_token};m_ts:{m_ts}"
106
+ msg = I("Got viber_auth successfully:\n")
107
+ msg += f"{viber_auth=}\n"
108
+
109
+ return viber_auth, msg
110
+
111
+ def get_auth_by_dump(
112
+ self, viber_bin_path: str, relaunch: bool = True
113
+ ) -> Tuple[Optional[str], str]:
114
+ member_id = None
115
+ m_token = None
116
+ m_ts = None
117
+
118
+ if platform.system() == "Darwin":
119
+ csrutil_status = subprocess.run(
120
+ ["csrutil", "status"], capture_output=True, text=True
121
+ ).stdout
122
+
123
+ if "enabled" in csrutil_status:
124
+ return None, self.MSG_SIP_ENABLED
125
+
126
+ if relaunch:
127
+ viber_pid = self.relaunch_viber(viber_bin_path)
128
+ else:
129
+ viber_pid = find_pid_by_name("viber")
130
+ if viber_pid is None:
131
+ return None, self.MSG_LAUNCH_FAIL
132
+
133
+ def pw_func(msg: str) -> str:
134
+ return self.cb.put(
135
+ (
136
+ "ask_str",
137
+ None,
138
+ {
139
+ "message": msg,
140
+ "password": True,
141
+ },
142
+ )
143
+ )
144
+
145
+ s = get_mem(viber_pid, pw_func)
146
+
147
+ if s is None:
148
+ return None, I("Failed to dump memory")
149
+
150
+ member_id_addr = s.find(b"X-Viber-Auth-Mid: ")
151
+ m_token_addr = s.find(b"X-Viber-Auth-Token: ")
152
+ m_ts_addr = s.find(b"X-Viber-Auth-Timestamp: ")
153
+
154
+ if member_id_addr == -1 or m_token_addr == -1 or m_ts_addr == -1:
155
+ return None, self.MSG_NO_AUTH
156
+
157
+ member_id_addr += 18
158
+ m_token_addr += 20
159
+ m_ts_addr += 24
160
+
161
+ member_id_bytes = s[member_id_addr : member_id_addr + 20]
162
+ member_id_term = member_id_bytes.find(b"\x0d\x0a")
163
+ if member_id_term == -1:
164
+ return None, self.MSG_NO_AUTH
165
+ member_id = member_id_bytes[:member_id_term].decode(encoding="ascii")
166
+
167
+ m_token = s[m_token_addr : m_token_addr + 64].decode(encoding="ascii")
168
+ m_ts = s[m_ts_addr : m_ts_addr + 13].decode(encoding="ascii")
169
+
170
+ viber_auth = f"member_id:{member_id};m_token:{m_token};m_ts:{m_ts}"
171
+ msg = I("Got viber_auth successfully:\n")
172
+ msg += f"{viber_auth=}\n"
173
+
174
+ return viber_auth, msg
175
+
176
+ def get_viber_desktop(self) -> Optional[str]:
177
+ if platform.system() == "Windows":
178
+ viber_bin_path = os.path.expandvars("%localappdata%/Viber/Viber.exe")
179
+ elif platform.system() == "Darwin":
180
+ viber_bin_path = "/Applications/Viber.app"
181
+ else:
182
+ if os.path.isfile("/opt/viber/Viber"):
183
+ viber_bin_path = "/opt/viber/Viber"
184
+ else:
185
+ viber_which = shutil.which("Viber")
186
+ if viber_which is None:
187
+ viber_which = shutil.which("viber")
188
+ if viber_which is None:
189
+ viber_which = shutil.which("viber.AppImage")
190
+ if viber_which is None:
191
+ viber_bin_path = "viber"
192
+ else:
193
+ viber_bin_path = viber_which
194
+
195
+ if Path(viber_bin_path).is_file() or Path(viber_bin_path).is_dir():
196
+ return viber_bin_path
197
+
198
+ return None
199
+
200
+ def get_cred(
201
+ self,
202
+ viber_bin_path: Optional[str] = None,
203
+ ) -> Tuple[Optional[str], str]:
204
+ msg = I("Getting Viber credentials...\n(This may take a minute)")
205
+ self.cb.put(("msg_dynamic", (msg,), None))
206
+ if not viber_bin_path:
207
+ viber_bin_path = self.get_viber_desktop()
208
+
209
+ if not viber_bin_path:
210
+ return None, self.MSG_NO_BIN
211
+
212
+ # get_auth_by_dump()
213
+ # + Fast
214
+ # - Requires admin
215
+
216
+ # get_auth_by_pme()
217
+ # + No admin (If have permission to read process)
218
+ # - Slow
219
+ # - Cannot run on macOS
220
+
221
+ # If admin, prefer get_auth_by_dump() over get_auth_by_pme(), vice versa
222
+ methods: List[Callable[[str, bool], Tuple[Optional[str], str]]] = []
223
+ relaunch = True
224
+ viber_auth = None
225
+ msg = ""
226
+
227
+ pme_present = importlib.util.find_spec("PyMemoryEditor") is not None
228
+ if platform.system() == "Darwin":
229
+ methods.append(self.get_auth_by_dump)
230
+ elif platform.system() == "Windows":
231
+ methods.append(self.get_auth_by_dump)
232
+ if pme_present:
233
+ methods.append(self.get_auth_by_pme)
234
+ else:
235
+ if not os.path.isfile("/.dockerenv"):
236
+ methods.append(self.get_auth_by_dump)
237
+ if pme_present:
238
+ methods.append(self.get_auth_by_pme)
239
+ if check_admin() is False:
240
+ methods.reverse()
241
+
242
+ for method in methods:
243
+ viber_auth, msg = method(viber_bin_path, relaunch)
244
+ relaunch = False
245
+ if viber_auth is not None:
246
+ break
247
+
248
+ killall("viber")
249
+ self.cb.put(("msg_dynamic", (None,), None))
250
+ return viber_auth, msg