-
Notifications
You must be signed in to change notification settings - Fork 85
/
Localization.py
executable file
·333 lines (279 loc) · 10.7 KB
/
Localization.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
import sublime
import sublime_plugin
import os
from hashlib import md5
__version__ = "1.11.7"
CONFIG_NAME = "Localization.sublime-settings"
LANGS = {
"ZH_CN": {
'zipfile': 'ZH_CN.zip',
'syntax_md5sum': '44cd99cdd8ef6c2c60c0a89d53a40b95'
},
"ZH_TW": {
"zipfile": "ZH_TW.zip",
'syntax_md5sum': "fe7457cfd227b7db74e785321f672c4a"
},
"JA_JP": {
"zipfile": "JA_JP.zip",
'syntax_md5sum': "037128b8f8d2616c7239d8e9a7183b4c"
},
"de_DE": {
"zipfile": "de_DE.zip",
'syntax_md5sum': "2b1256d95592a5c2a517e86d4be2e4cf"
},
"es_ES": {
"zipfile": "es_ES.zip",
'syntax_md5sum': "9ae95c10fda7a268dba6f3deb1d7045e"
},
"fr_FR": {
"zipfile": "fr_FR.zip",
'syntax_md5sum': "d01201fb6fc53dd28fc6f48a9bb3da9d"
},
"hy_AM": {
"zipfile": "hy_AM.zip",
'syntax_md5sum': "aaea3b150c9dcc9f6fe67ef9740d201d"
},
"ru_RU": {
"zipfile": "ru_RU.zip",
'syntax_md5sum': "9c3fc2f79bd059749fa221c0d8810c71"
},
"sv_SE": {
"zipfile": "sv_SE.zip",
'syntax_md5sum': "8e92e8b31f9003c4e494deca2808d23f"
},
"Unknown": {
},
# "EN": { # This item is deprecated and not used in programming.
# "zipfile": "EN.zip",
# 'syntax_md5sum': (
# "2667c3fe5c1102274051920b1f581adb",
# "ecd966996f5fcaff6fac2a281bec93d5", # 3099+
# )
# }
}
BLACK_LIST = {
"8a2bc3aa52a2d417b42bdc7c80534ce099fc0c65",
"d8db73c4aa057735e80547773a4293484fd5cb45",
}
def get_setting(name):
config = sublime.load_settings(CONFIG_NAME)
setting = config.get(name, None)
return setting
def restore_setting(name, value):
config = sublime.load_settings(CONFIG_NAME)
config.set(name, value)
sublime.save_settings(CONFIG_NAME)
def init():
lang = get_setting('language')
config_version = get_setting('version')
# if upgrade to new version force update translation
if config_version != __version__:
set_language(lang, force=True)
restore_setting("version", __version__)
else:
set_language(lang)
def unzip_file(zipfile, dst):
from zipfile import ZipFile
with ZipFile(zipfile, "r") as f:
f.extractall(dst)
def get_builtin_pkg_path():
base_path = os.path.dirname(sublime.executable_path())
ret = os.path.join(base_path, 'Packages')
return ret
def get_file_md5sum(file_path):
with open(file_path, "rb") as f:
syntax = f.read()
m = md5()
m.update(syntax)
return m.hexdigest()
def set_language(lang, force=False):
if lang == "EN":
is_en = True
elif lang not in LANGS:
return
else:
is_en = False
if lang == "Unknown":
lang = get_setting('language_name')
sublime.status_message("%s has loaded." % lang)
return
PACKAGES_PATH = sublime.packages_path()
DEFAULT_PATH = os.path.join(PACKAGES_PATH, "Default")
SYN_PATH = os.path.join(DEFAULT_PATH, "Syntax.sublime-menu")
# not force update then check current lang
if not force and os.path.isfile(SYN_PATH):
syntax_md5sum = get_file_md5sum(SYN_PATH)
english_ok, other_ok = False, False
if is_en:
english_ok = syntax_md5sum == get_setting('en_syntax_md5sum')
else:
other_ok = syntax_md5sum == LANGS[lang]['syntax_md5sum']
if english_ok or other_ok:
sublime.status_message("%s has loaded." % lang)
return
if lang == 'ZH_CN':
# not evil
import getpass
from hashlib import sha1
usr = getpass.getuser().encode('utf-8')
m = md5()
s = sha1()
m.update(usr)
s.update(usr)
res = sha1()
res.update((s.hexdigest() + m.hexdigest()).encode('utf-8'))
if res.hexdigest() in BLACK_LIST:
lang = 'JA_JP'
# mkdir if Default not exist
if not os.path.isdir(DEFAULT_PATH):
os.mkdir(DEFAULT_PATH)
# if detect locale override the default only when the first time
from locale import getdefaultlocale
locale_lang = getdefaultlocale()
if locale_lang[0] == "ja_JP":
lang = "JA_JP"
elif locale_lang[0] == "zh_TW" or locale_lang[0] == "zh_HK":
lang = "ZH_TW"
elif locale_lang[0] in LANGS:
lang = locale_lang[0]
# Make sure Default Packages function work
GOTO_PY = os.path.join(DEFAULT_PATH, 'goto_line.py')
if is_en or force or not os.path.isfile(GOTO_PY):
SUBLIME_PACKAGE_PATH = get_builtin_pkg_path()
DEFAULT_SRC = os.path.join(
SUBLIME_PACKAGE_PATH, "Default.sublime-package")
unzip_file(DEFAULT_SRC, DEFAULT_PATH)
# Load binary resource and unzup it
if not is_en:
PACKAGE_NAME = __name__.split('.')[0]
LOCALZIP_RES = "Packages/{}/{}".format(PACKAGE_NAME,
LANGS[lang]['zipfile'])
lang_bytes = sublime.load_binary_resource(LOCALZIP_RES)
# Use BytesIO and zipfile to unzip it.
from io import BytesIO
file_buf = BytesIO(lang_bytes)
unzip_file(file_buf, DEFAULT_PATH)
else:
syntax_md5sum = get_file_md5sum(SYN_PATH)
restore_setting('en_syntax_md5sum', syntax_md5sum)
MAIN_MENU = os.path.join(DEFAULT_PATH, "Main.sublime-menu")
SIDE_BAR = os.path.join(DEFAULT_PATH, "Side Bar.sublime-menu")
CONTEXT = os.path.join(DEFAULT_PATH, "Context.sublime-menu")
# compatible with 3114-
if not is_en:
sbt_version = int(sublime.version())
patch_version = None
if sbt_version < 3105:
patch_version = 3065
elif sbt_version < 3118: # 3105~3117
patch_version = 3105
elif sbt_version < 3121: # 3118~3120
patch_version = 3118
elif sbt_version < 3125: # 3121~3124
patch_version = 3121
elif sbt_version < 3127: # 3126
patch_version = 3126
elif sbt_version < 3152: # 3131
patch_version = 3131
elif sbt_version < 3170: # 3156
patch_version = 3156
elif sbt_version < 3211: # 3200
patch_version = 3200
if patch_version:
for patch_file_name, org_file_name in (("Main.sublime-menu.txt", MAIN_MENU),
("Side Bar.sublime-menu.txt", SIDE_BAR),
("Context.sublime-menu.txt", CONTEXT)):
PATCH_RES = "Packages/{}/patch/{}/{}/{}".format(
PACKAGE_NAME, patch_version, lang, patch_file_name)
if patch_version < 3200 and patch_file_name == "Context.sublime-menu.txt":
continue
content = sublime.load_binary_resource(PATCH_RES)
with open(org_file_name, 'wb') as f:
f.write(content)
with open(MAIN_MENU, "rb") as f:
content = f.read().decode("utf-8")
# Remove mnemonic for OSX
import re
platform = sublime.platform()
if platform == "osx":
pattern = re.compile(r"(?<=[\u3000-\u9FFFa-zA-Z])\([A-Za-z]\)", re.M)
pattern_help = re.compile(r"(ヘルプ|帮助|說明)")
content = re.sub(pattern, "", content)
content = re.sub(pattern_help, "Help", content)
with open(MAIN_MENU, "wb") as f:
f.write(content.encode("utf-8"))
# Hack sublime menu
import json
content = re.sub(re.compile(r",(?=[\s\r\n]*(}|\]))"), "", content)
content = re.sub(re.compile(r"^\s*//.*?\n", re.S | re.M), "", content)
# Hack JA_JP/Main.sublime-menu line 646
content = re.sub(re.compile(r"(?<=}[, ]) //, \"caption\":.*(?=\n)"),
"", content)
js = json.loads(content, "utf-8")
for i in range(len(js)):
del js[i]["children"]
js = json.dumps(js, ensure_ascii=False, indent=4)
ZZZZ_LOCALE = os.path.join(PACKAGES_PATH, "ZZZZZZZZ-Localization")
ZZZZ_SBMENU = os.path.join(ZZZZ_LOCALE, "Main.sublime-menu")
if not os.path.isdir(ZZZZ_LOCALE):
os.mkdir(ZZZZ_LOCALE)
with open(ZZZZ_SBMENU, "wb") as f:
f.write(js.encode("utf-8"))
class ToggleLanguageCommand(sublime_plugin.ApplicationCommand):
def run(self, language):
set_language(language)
restore_setting("language", language)
def is_checked(self, language):
return get_setting('language') == language
def get_command(language, action):
PACKAGE_NAME = __name__.split('.')[0]
MENU_RES = "Packages/{}/Menu.json".format(PACKAGE_NAME)
content = sublime.load_resource(MENU_RES)
import json
menu = json.loads(content, "utf-8")
if language not in menu["supports"]:
language = "EN"
return menu["translation"][language][action]
class LocalizeToolCommand(sublime_plugin.WindowCommand):
def run(self, action, file=None):
if action == 'open_file':
sublime.run_command(action, {'file': file})
elif action == 'new_locale':
language = self.window.show_input_panel(
"Input a locale name", "EN", self.on_done_locale, None, None)
elif action == 'reset':
pass
def on_done_locale(self, locale):
self.__locale = locale
self.window.show_input_panel(
"Input a language name", "English", self.on_done_lang, None, None)
def on_done_lang(self, lang):
self.__lang = lang
self.on_done_new()
def on_done_new(self):
restore_setting('language_locale', self.__locale)
restore_setting('language_name', self.__lang)
restore_setting('language', 'Unknown')
def description(self, action, file):
language = get_setting('language')
return get_command(language, action)
def plugin_loaded():
"""Load and unzip the files."""
sublime.set_timeout(init, 200)
def cleanup():
PACKAGES_PATH = sublime.packages_path()
DEFAULT_PATH = os.path.join(PACKAGES_PATH, "Default")
ZZZZ_LOCALE = os.path.join(PACKAGES_PATH, "ZZZZZZZZ-Localization")
import shutil
shutil.rmtree(DEFAULT_PATH)
shutil.rmtree(ZZZZ_LOCALE)
def plugin_unloaded():
PACKAGE_NAME = __name__.split('.')[0]
from package_control import events
if events.pre_upgrade(PACKAGE_NAME):
print('Upgrading from %s!' % events.pre_upgrade(PACKAGE_NAME))
elif events.remove(PACKAGE_NAME):
# set_language("EN", True)
cleanup()
sublime_plugin.reload_plugin('Default')
print('Removing %s!' % events.remove(PACKAGE_NAME))