sticker-convert 2.8.12__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.
- sticker_convert/__main__.py +24 -24
- sticker_convert/auth/__init__.py +0 -0
- sticker_convert/auth/auth_base.py +19 -0
- sticker_convert/auth/auth_discord.py +149 -0
- sticker_convert/{utils/auth/get_kakao_auth.py → auth/auth_kakao_android_login.py} +331 -300
- sticker_convert/auth/auth_kakao_desktop_login.py +327 -0
- sticker_convert/auth/auth_kakao_desktop_memdump.py +281 -0
- sticker_convert/{utils/auth/get_line_auth.py → auth/auth_line.py} +98 -80
- sticker_convert/auth/auth_signal.py +139 -0
- sticker_convert/auth/auth_telethon.py +161 -0
- sticker_convert/auth/auth_viber.py +250 -0
- sticker_convert/auth/telegram_api.py +736 -0
- sticker_convert/cli.py +623 -509
- sticker_convert/converter.py +1093 -962
- sticker_convert/definitions.py +11 -0
- sticker_convert/downloaders/download_band.py +111 -0
- sticker_convert/downloaders/download_base.py +171 -130
- sticker_convert/downloaders/download_discord.py +92 -0
- sticker_convert/downloaders/download_kakao.py +417 -255
- sticker_convert/downloaders/download_line.py +484 -472
- sticker_convert/downloaders/download_ogq.py +80 -0
- sticker_convert/downloaders/download_signal.py +108 -92
- sticker_convert/downloaders/download_telegram.py +56 -130
- sticker_convert/downloaders/download_viber.py +121 -95
- sticker_convert/gui.py +788 -795
- sticker_convert/gui_components/frames/comp_frame.py +180 -165
- sticker_convert/gui_components/frames/config_frame.py +156 -113
- sticker_convert/gui_components/frames/control_frame.py +32 -30
- sticker_convert/gui_components/frames/cred_frame.py +232 -162
- sticker_convert/gui_components/frames/input_frame.py +139 -137
- sticker_convert/gui_components/frames/output_frame.py +112 -110
- sticker_convert/gui_components/frames/right_clicker.py +25 -23
- sticker_convert/gui_components/windows/advanced_compression_window.py +757 -715
- sticker_convert/gui_components/windows/base_window.py +7 -2
- sticker_convert/gui_components/windows/discord_get_auth_window.py +79 -0
- sticker_convert/gui_components/windows/kakao_get_auth_window.py +511 -186
- sticker_convert/gui_components/windows/line_get_auth_window.py +94 -102
- sticker_convert/gui_components/windows/signal_get_auth_window.py +84 -135
- sticker_convert/gui_components/windows/viber_get_auth_window.py +168 -0
- sticker_convert/ios-message-stickers-template/.github/FUNDING.yml +3 -3
- sticker_convert/ios-message-stickers-template/.gitignore +0 -0
- sticker_convert/ios-message-stickers-template/README.md +10 -10
- sticker_convert/ios-message-stickers-template/stickers/Info.plist +43 -43
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Info.plist +31 -31
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Contents.json +6 -6
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Contents.json +20 -20
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 1.sticker/Contents.json +9 -9
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 1.sticker/Sticker 1.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 2.sticker/Contents.json +9 -9
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 2.sticker/Sticker 2.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 3.sticker/Contents.json +9 -9
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 3.sticker/Sticker 3.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/App-Store-1024x1024pt.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Contents.json +91 -91
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-App-Store-1024x768pt.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-iPad-67x50pt@2x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-iPad-Pro-74x55pt@2x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-iPhone-60x45pt@2x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-iPhone-60x45pt@3x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages27x20pt@2x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages27x20pt@3x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages32x24pt@2x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages32x24pt@3x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/iPad-Settings-29pt@2x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/iPhone-Settings-29pt@3x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/iPhone-settings-29pt@2x.png +0 -0
- sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.pbxproj +364 -364
- sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -7
- sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -8
- sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.xcworkspace/xcuserdata/niklaspeterson.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- sticker_convert/ios-message-stickers-template/stickers.xcodeproj/xcuserdata/niklaspeterson.xcuserdatad/xcschemes/xcschememanagement.plist +14 -14
- sticker_convert/job.py +279 -179
- sticker_convert/job_option.py +15 -2
- sticker_convert/locales/en_US/LC_MESSAGES/base.mo +0 -0
- sticker_convert/locales/ja_JP/LC_MESSAGES/base.mo +0 -0
- sticker_convert/locales/zh_CN/LC_MESSAGES/base.mo +0 -0
- sticker_convert/locales/zh_TW/LC_MESSAGES/base.mo +0 -0
- sticker_convert/py.typed +0 -0
- sticker_convert/resources/NotoColorEmoji.ttf +0 -0
- sticker_convert/resources/compression.json +220 -16
- sticker_convert/resources/emoji.json +527 -77
- sticker_convert/resources/help.ja_JP.json +88 -0
- sticker_convert/resources/help.json +24 -10
- sticker_convert/resources/help.zh_CN.json +88 -0
- sticker_convert/resources/help.zh_TW.json +88 -0
- sticker_convert/resources/input.ja_JP.json +74 -0
- sticker_convert/resources/input.json +121 -71
- sticker_convert/resources/input.zh_CN.json +74 -0
- sticker_convert/resources/input.zh_TW.json +74 -0
- sticker_convert/resources/memdump_linux.sh +25 -0
- sticker_convert/resources/memdump_windows.ps1 +8 -0
- sticker_convert/resources/output.ja_JP.json +38 -0
- sticker_convert/resources/output.json +24 -0
- sticker_convert/resources/output.zh_CN.json +38 -0
- sticker_convert/resources/output.zh_TW.json +38 -0
- sticker_convert/uploaders/compress_wastickers.py +186 -156
- sticker_convert/uploaders/upload_base.py +44 -35
- sticker_convert/uploaders/upload_signal.py +218 -173
- sticker_convert/uploaders/upload_telegram.py +353 -388
- sticker_convert/uploaders/upload_viber.py +178 -0
- sticker_convert/uploaders/xcode_imessage.py +295 -285
- sticker_convert/utils/callback.py +238 -6
- sticker_convert/utils/chrome_remotedebug.py +219 -0
- sticker_convert/utils/chromiums/linux.py +52 -0
- sticker_convert/utils/chromiums/osx.py +68 -0
- sticker_convert/utils/chromiums/windows.py +45 -0
- sticker_convert/utils/emoji.py +28 -0
- sticker_convert/utils/files/json_resources_loader.py +24 -19
- sticker_convert/utils/files/metadata_handler.py +8 -7
- sticker_convert/utils/files/run_bin.py +1 -1
- sticker_convert/utils/media/codec_info.py +99 -67
- sticker_convert/utils/media/format_verify.py +33 -20
- sticker_convert/utils/process.py +231 -0
- sticker_convert/utils/translate.py +108 -0
- sticker_convert/utils/url_detect.py +40 -33
- sticker_convert/version.py +1 -1
- {sticker_convert-2.8.12.dist-info → sticker_convert-2.17.0.0.dist-info}/METADATA +189 -96
- sticker_convert-2.17.0.0.dist-info/RECORD +138 -0
- {sticker_convert-2.8.12.dist-info → sticker_convert-2.17.0.0.dist-info}/WHEEL +1 -1
- sticker_convert/utils/auth/get_signal_auth.py +0 -129
- sticker_convert-2.8.12.dist-info/RECORD +0 -101
- {sticker_convert-2.8.12.dist-info → sticker_convert-2.17.0.0.dist-info}/entry_points.txt +0 -0
- {sticker_convert-2.8.12.dist-info → sticker_convert-2.17.0.0.dist-info/licenses}/LICENSE +0 -0
- {sticker_convert-2.8.12.dist-info → sticker_convert-2.17.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import os
|
|
3
|
+
import platform
|
|
4
|
+
import shutil
|
|
5
|
+
import subprocess
|
|
6
|
+
import time
|
|
7
|
+
from getpass import getpass
|
|
8
|
+
from io import BytesIO
|
|
9
|
+
from typing import Callable, Optional, Union
|
|
10
|
+
from zipfile import ZipFile
|
|
11
|
+
|
|
12
|
+
import psutil
|
|
13
|
+
import requests
|
|
14
|
+
|
|
15
|
+
from sticker_convert.definitions import CONFIG_DIR, ROOT_DIR
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def killall(name: str) -> bool:
|
|
19
|
+
result = False
|
|
20
|
+
|
|
21
|
+
for proc in psutil.process_iter(): # type: ignore
|
|
22
|
+
if name in proc.name().lower():
|
|
23
|
+
proc.kill()
|
|
24
|
+
result = True
|
|
25
|
+
|
|
26
|
+
return result
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def find_pid_by_name(name: str) -> Optional[int]:
|
|
30
|
+
for proc in psutil.process_iter(): # type: ignore
|
|
31
|
+
if name in proc.name().lower():
|
|
32
|
+
return proc.pid
|
|
33
|
+
|
|
34
|
+
return None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def check_admin() -> bool:
|
|
38
|
+
return True
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
if platform.system() == "Windows":
|
|
42
|
+
|
|
43
|
+
def check_admin() -> bool:
|
|
44
|
+
username = os.getenv("username")
|
|
45
|
+
if username is None:
|
|
46
|
+
return False
|
|
47
|
+
|
|
48
|
+
s = subprocess.run(
|
|
49
|
+
["net", "user", username],
|
|
50
|
+
capture_output=True,
|
|
51
|
+
text=True,
|
|
52
|
+
).stdout
|
|
53
|
+
|
|
54
|
+
return True if "*Administrators" in s else False
|
|
55
|
+
|
|
56
|
+
elif platform.system() == "Linux":
|
|
57
|
+
|
|
58
|
+
def check_admin() -> bool:
|
|
59
|
+
if shutil.which("sudo") is None:
|
|
60
|
+
return True
|
|
61
|
+
|
|
62
|
+
s = subprocess.run(
|
|
63
|
+
["sudo", "-l"],
|
|
64
|
+
capture_output=True,
|
|
65
|
+
text=True,
|
|
66
|
+
).stdout
|
|
67
|
+
|
|
68
|
+
return True if "may run the following commands" in s else False
|
|
69
|
+
|
|
70
|
+
|
|
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:
|
|
130
|
+
break
|
|
131
|
+
time.sleep(1)
|
|
132
|
+
except (FileNotFoundError, PermissionError):
|
|
133
|
+
pass
|
|
134
|
+
|
|
135
|
+
while True:
|
|
136
|
+
try:
|
|
137
|
+
os.remove(dump_fpath)
|
|
138
|
+
break
|
|
139
|
+
except PermissionError:
|
|
140
|
+
pass
|
|
141
|
+
|
|
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(
|
|
187
|
+
[
|
|
188
|
+
"pkexec",
|
|
189
|
+
memdump_sh_path,
|
|
190
|
+
str(pid),
|
|
191
|
+
],
|
|
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
|
|
202
|
+
)
|
|
203
|
+
s = subprocess.run(
|
|
204
|
+
[
|
|
205
|
+
"sudo",
|
|
206
|
+
"-S",
|
|
207
|
+
memdump_sh_path,
|
|
208
|
+
str(pid),
|
|
209
|
+
],
|
|
210
|
+
capture_output=True,
|
|
211
|
+
stdin=sudo_password_pipe.stdout,
|
|
212
|
+
).stdout
|
|
213
|
+
|
|
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
|
|
226
|
+
else:
|
|
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)
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import gettext
|
|
3
|
+
import locale
|
|
4
|
+
import platform
|
|
5
|
+
import sys
|
|
6
|
+
from json import JSONDecodeError
|
|
7
|
+
from multiprocessing import current_process
|
|
8
|
+
from typing import Any, Callable, Dict, cast
|
|
9
|
+
|
|
10
|
+
from sticker_convert.definitions import CONFIG_DIR, ROOT_DIR, RUNTIME_STATE
|
|
11
|
+
from sticker_convert.utils.files.json_manager import JsonManager
|
|
12
|
+
|
|
13
|
+
LANG_DICT = {
|
|
14
|
+
"en_US": ("en_US",),
|
|
15
|
+
"ja_JP": ("ja_jp",),
|
|
16
|
+
"zh_CN": ("zh_chs", "zh_cn", "zh_sg"),
|
|
17
|
+
"zh_TW": ("zh_tw", "zh_hk", "zh_mo", "zh_cht"),
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_default_lang() -> str:
|
|
22
|
+
lang = locale.getlocale()[0]
|
|
23
|
+
winlang = ""
|
|
24
|
+
if platform.system() == "Windows":
|
|
25
|
+
import ctypes
|
|
26
|
+
|
|
27
|
+
windll = ctypes.windll.kernel32 # type: ignore
|
|
28
|
+
winlang_id = cast(int, windll.GetUserDefaultUILanguage()) # type: ignore
|
|
29
|
+
winlang = cast(str, locale.windows_locale[winlang_id]) # type: ignore
|
|
30
|
+
|
|
31
|
+
for k, v in LANG_DICT.items():
|
|
32
|
+
for i in v:
|
|
33
|
+
if (
|
|
34
|
+
lang is not None and lang.lower().startswith(i)
|
|
35
|
+
) or winlang.lower().startswith(i):
|
|
36
|
+
return k
|
|
37
|
+
|
|
38
|
+
return "en_US"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def get_lang() -> str:
|
|
42
|
+
# Priority 1: From --lang CLI flag
|
|
43
|
+
is_lang = False
|
|
44
|
+
lang = None
|
|
45
|
+
for i in sys.argv:
|
|
46
|
+
if is_lang:
|
|
47
|
+
return i
|
|
48
|
+
if i == "--lang":
|
|
49
|
+
is_lang = True
|
|
50
|
+
|
|
51
|
+
# Priority 2: From config
|
|
52
|
+
settings_path = CONFIG_DIR / "config.json"
|
|
53
|
+
if settings_path.is_file():
|
|
54
|
+
try:
|
|
55
|
+
settings: Dict[Any, Any] = JsonManager.load_json(settings_path)
|
|
56
|
+
lang = settings.get("lang")
|
|
57
|
+
if lang:
|
|
58
|
+
if lang in LANG_DICT:
|
|
59
|
+
return lang
|
|
60
|
+
elif lang != "auto":
|
|
61
|
+
return "en_US"
|
|
62
|
+
except JSONDecodeError:
|
|
63
|
+
pass
|
|
64
|
+
|
|
65
|
+
# Priority 3: Default locale
|
|
66
|
+
lang = get_default_lang()
|
|
67
|
+
return lang
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
LANG = RUNTIME_STATE.get("LANG", get_lang())
|
|
71
|
+
RUNTIME_STATE["LANG"] = LANG
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def gettext_dummy(x: str) -> str:
|
|
75
|
+
return x
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def get_translator() -> Callable[[str], str]:
|
|
79
|
+
if RUNTIME_STATE.get("TRANS") is not None:
|
|
80
|
+
return RUNTIME_STATE["TRANS"]
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
trans: Callable[[str], str] = gettext.translation(
|
|
84
|
+
"base", ROOT_DIR / "locales", languages=[RUNTIME_STATE["LANG"]]
|
|
85
|
+
).gettext
|
|
86
|
+
except FileNotFoundError:
|
|
87
|
+
if current_process().name == "MainProcess":
|
|
88
|
+
print(f"Warning: Cannot find locales/{LANG}/LC_MESSAGES/base.mo")
|
|
89
|
+
print(
|
|
90
|
+
"Please generate by running scripts/update-locales.sh in root of repo"
|
|
91
|
+
)
|
|
92
|
+
print("Fallback to using English...")
|
|
93
|
+
trans = gettext_dummy
|
|
94
|
+
RUNTIME_STATE["TRANS"] = trans
|
|
95
|
+
return trans
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def I(x: str) -> str: # noqa: E743
|
|
99
|
+
return get_translator()(x)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
SUPPORTED_LANG = {
|
|
103
|
+
I("Auto"): "auto",
|
|
104
|
+
"English": "en_US",
|
|
105
|
+
"繁體中文": "zh_TW",
|
|
106
|
+
"简体中文": "zh_CN",
|
|
107
|
+
"日本語": "ja_JP",
|
|
108
|
+
}
|
|
@@ -1,33 +1,40 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
import string
|
|
3
|
-
from typing import Optional
|
|
4
|
-
from urllib.parse import urlparse
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class UrlDetect:
|
|
8
|
-
@staticmethod
|
|
9
|
-
def detect(url: str) -> Optional[str]:
|
|
10
|
-
domain = urlparse(url).netloc
|
|
11
|
-
|
|
12
|
-
if domain == "signal.art":
|
|
13
|
-
return "signal"
|
|
14
|
-
|
|
15
|
-
if domain in ("telegram.me", "t.me"):
|
|
16
|
-
return "telegram"
|
|
17
|
-
|
|
18
|
-
if (
|
|
19
|
-
domain in ("store.line.me", "line.me")
|
|
20
|
-
or url.startswith("line://shop/detail/")
|
|
21
|
-
or (len(url) == 24 and all(c in string.hexdigits for c in url))
|
|
22
|
-
):
|
|
23
|
-
return "line"
|
|
24
|
-
|
|
25
|
-
if domain in ("e.kakao.com", "emoticon.kakao.com")
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import string
|
|
3
|
+
from typing import Optional
|
|
4
|
+
from urllib.parse import urlparse
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class UrlDetect:
|
|
8
|
+
@staticmethod
|
|
9
|
+
def detect(url: str) -> Optional[str]:
|
|
10
|
+
domain = urlparse(url).netloc
|
|
11
|
+
|
|
12
|
+
if domain == "signal.art" or url.startswith("sgnl://addstickers/"):
|
|
13
|
+
return "signal"
|
|
14
|
+
|
|
15
|
+
if domain in ("telegram.me", "t.me"):
|
|
16
|
+
return "telegram"
|
|
17
|
+
|
|
18
|
+
if (
|
|
19
|
+
domain in ("store.line.me", "line.me")
|
|
20
|
+
or url.startswith("line://shop/detail/")
|
|
21
|
+
or (len(url) == 24 and all(c in string.hexdigits for c in url))
|
|
22
|
+
):
|
|
23
|
+
return "line"
|
|
24
|
+
|
|
25
|
+
if domain in ("e.kakao.com", "emoticon.kakao.com"):
|
|
26
|
+
return "kakao"
|
|
27
|
+
|
|
28
|
+
if domain == "www.band.us":
|
|
29
|
+
return "band"
|
|
30
|
+
|
|
31
|
+
if domain == "ogqmarket.naver.com":
|
|
32
|
+
return "ogq"
|
|
33
|
+
|
|
34
|
+
if domain == "stickers.viber.com":
|
|
35
|
+
return "viber"
|
|
36
|
+
|
|
37
|
+
if domain == "discord.com":
|
|
38
|
+
return "discord"
|
|
39
|
+
|
|
40
|
+
return None
|
sticker_convert/version.py
CHANGED