Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: localeTools.py

Issue 8627097: Moved Chrome extension scripts to buildtools repository (Closed)
Left Patch Set: Created Oct. 19, 2012, 10:42 a.m.
Right Patch Set: Added build.py gettranslations support for Chrome Created Oct. 22, 2012, 11:25 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« build.py ('K') | « localeSyncChrome.py ('k') | packagerChrome.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # coding: utf-8 1 # coding: utf-8
2 2
3 # This Source Code is subject to the terms of the Mozilla Public License 3 # This Source Code is subject to the terms of the Mozilla Public License
4 # version 2.0 (the "License"). You can obtain a copy of the License at 4 # version 2.0 (the "License"). You can obtain a copy of the License at
5 # http://mozilla.org/MPL/2.0/. 5 # http://mozilla.org/MPL/2.0/.
6 6
7 import re, os, sys, codecs, json, urllib, urllib2 7 import re, os, sys, codecs, json, urllib, urllib2
8 from StringIO import StringIO 8 from StringIO import StringIO
9 from ConfigParser import SafeConfigParser 9 from ConfigParser import SafeConfigParser
10 from zipfile import ZipFile 10 from zipfile import ZipFile
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 data = json.load(fileHandle) 235 data = json.load(fileHandle)
236 fileHandle.close() 236 fileHandle.close()
237 237
238 # Remove synced keys, these don't need to be translated 238 # Remove synced keys, these don't need to be translated
239 if metadata.has_section('locale_sync'): 239 if metadata.has_section('locale_sync'):
240 for file, stringIDs in metadata.items('locale_sync'): 240 for file, stringIDs in metadata.items('locale_sync'):
241 for stringID in re.split(r'\s+', stringIDs): 241 for stringID in re.split(r'\s+', stringIDs):
242 if file == 'remove': 242 if file == 'remove':
243 key = stringID 243 key = stringID
244 else: 244 else:
245 key = re.sub(r'\..*', '', file) + '_' + re.sub(r'\W', '_', stringID) 245 key = re.sub(r'\..*', '', file) + '_' + re.sub(r'\W', '_', stringID)
Felix Dahlke 2013/01/10 16:36:20 We have pretty much the same line in localeSyncChr
Wladimir Palant 2013/01/16 14:20:15 Yes, the idea is to make locale syncing part of th
246 if key in data: 246 if key in data:
247 del data[key] 247 del data[key]
248 248
249 for key, value in data.iteritems(): 249 for key, value in data.iteritems():
250 if isMaster: 250 if isMaster:
251 # Make sure the key name is listed in the description 251 # Make sure the key name is listed in the description
252 if "description" in value: 252 if "description" in value:
253 value["description"] = "%s: %s" % (key, value["description"]) 253 value["description"] = "%s: %s" % (key, value["description"])
254 else: 254 else:
255 value["description"] = key 255 value["description"] = key
256 else: 256 else:
257 # Delete description from translations 257 # Delete description from translations
258 if "description" in value: 258 if "description" in value:
259 del value["description"] 259 del value["description"]
260 260
261 return json.dumps(data, ensure_ascii=False, sort_keys=True, indent=2) 261 return json.dumps(data, ensure_ascii=False, sort_keys=True, indent=2)
262 262
263 def postprocessChromeLocale(path, data):
264 parsed = json.loads(data)
265
266 # Delete description from translations
267 for key, value in parsed.iteritems():
268 if "description" in value:
269 del value["description"]
270
271 file = codecs.open(path, 'wb', encoding='utf-8')
272 json.dump(parsed, file, ensure_ascii=False, sort_keys=True, indent=2, separato rs=(',', ': '))
273 file.close()
274
263 def setupTranslations(type, locales, projectName, key): 275 def setupTranslations(type, locales, projectName, key):
264 # Copy locales list, we don't want to change the parameter 276 # Copy locales list, we don't want to change the parameter
265 locales = set(locales) 277 locales = set(locales)
266 278
267 # Fill up with locales that we don't have but the browser supports 279 # Fill up with locales that we don't have but the browser supports
268 if type == 'chrome': 280 if type == 'chrome':
269 for locale in chromeLocales: 281 for locale in chromeLocales:
270 locales.add(locale) 282 locales.add(locale)
271 else: 283 else:
272 firefoxLocales = urllib2.urlopen('http://www.mozilla.org/en-US/firefox/all.h tml').read() 284 firefoxLocales = urllib2.urlopen('http://www.mozilla.org/en-US/firefox/all.h tml').read()
(...skipping 17 matching lines...) Expand all
290 print 'Warning, following locales aren\'t allowed by server: ' + ', '.join(l ocales - allowed) 302 print 'Warning, following locales aren\'t allowed by server: ' + ', '.join(l ocales - allowed)
291 303
292 locales = list(locales & allowed) 304 locales = list(locales & allowed)
293 locales.sort() 305 locales.sort()
294 params = urllib.urlencode([('languages[]', locale) for locale in locales]) 306 params = urllib.urlencode([('languages[]', locale) for locale in locales])
295 result = urllib2.urlopen('http://api.crowdin.net/api/project/%s/edit-project?k ey=%s&%s' % (projectName, key, params)).read() 307 result = urllib2.urlopen('http://api.crowdin.net/api/project/%s/edit-project?k ey=%s&%s' % (projectName, key, params)).read()
296 if result.find('<success') < 0: 308 if result.find('<success') < 0:
297 raise Exception('Server indicated that the operation was not successful\n' + result) 309 raise Exception('Server indicated that the operation was not successful\n' + result)
298 310
299 def postFiles(files, url): 311 def postFiles(files, url):
300 boundary = '----------ThIs_Is_tHe_bouNdaRY_$' 312 boundary = '----------ThIs_Is_tHe_bouNdaRY_$'
Felix Dahlke 2013/01/10 16:36:20 Would it make sense to generate this randomly?
Wladimir Palant 2013/01/16 14:20:15 I'm not sure where this boundary string originates
301 body = '' 313 body = ''
302 for file, data in files: 314 for file, data in files:
303 body += '--%s\r\n' % boundary 315 body += '--%s\r\n' % boundary
304 body += 'Content-Disposition: form-data; name="files[%s]"; filename="%s"\r\n ' % (file, file) 316 body += 'Content-Disposition: form-data; name="files[%s]"; filename="%s"\r\n ' % (file, file)
305 body += 'Content-Type: application/octet-stream\r\n' 317 body += 'Content-Type: application/octet-stream\r\n'
306 body += 'Content-Transfer-Encoding: binary\r\n' 318 body += 'Content-Transfer-Encoding: binary\r\n'
307 body += '\r\n' + data + '\r\n' 319 body += '\r\n' + data + '\r\n'
308 body += '--%s--\r\n' % boundary 320 body += '--%s--\r\n' % boundary
309 321
310 body = body.encode('utf-8') 322 body = body.encode('utf-8')
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 newName = file 370 newName = file
359 else: 371 else:
360 data = toJSON(path) 372 data = toJSON(path)
361 newName = file + '.json' 373 newName = file + '.json'
362 374
363 if data: 375 if data:
364 files.append((newName, data)) 376 files.append((newName, data))
365 if len(files): 377 if len(files):
366 postFiles(files, 'http://api.crowdin.net/api/project/%s/upload-translation?k ey=%s&language=%s' % (projectName, key, mapLocale(type, locale))) 378 postFiles(files, 'http://api.crowdin.net/api/project/%s/upload-translation?k ey=%s&language=%s' % (projectName, key, mapLocale(type, locale)))
367 379
368 def getTranslations(localesDir, defaultLocale, projectName, key): 380 def getTranslations(type, localesDir, defaultLocale, projectName, key):
369 result = urllib2.urlopen('http://api.crowdin.net/api/project/%s/export?key=%s' % (projectName, key)).read() 381 result = urllib2.urlopen('http://api.crowdin.net/api/project/%s/export?key=%s' % (projectName, key)).read()
370 if result.find('<success') < 0: 382 if result.find('<success') < 0:
371 raise Exception('Server indicated that the operation was not successful\n' + result) 383 raise Exception('Server indicated that the operation was not successful\n' + result)
372 384
373 result = urllib2.urlopen('http://api.crowdin.net/api/project/%s/download/all.z ip?key=%s' % (projectName, key)).read() 385 result = urllib2.urlopen('http://api.crowdin.net/api/project/%s/download/all.z ip?key=%s' % (projectName, key)).read()
374 zip = ZipFile(StringIO(result)) 386 zip = ZipFile(StringIO(result))
375 dirs = {} 387 dirs = {}
376 for info in zip.infolist(): 388 for info in zip.infolist():
377 if not info.filename.endswith('.dtd.json') and not info.filename.endswith('. properties.json'): 389 if not info.filename.endswith('.json'):
378 continue 390 continue
379 391
380 dir, file = os.path.split(info.filename) 392 dir, file = os.path.split(info.filename)
381 origFile = re.sub(r'\.json$', '', file)
382 if not re.match(r'^[\w\-]+$', dir) or dir == defaultLocale: 393 if not re.match(r'^[\w\-]+$', dir) or dir == defaultLocale:
383 continue 394 continue
384 395 if type == 'chrome':
385 for key, value in langMappingGecko.iteritems(): 396 origFile = file
397 else:
398 origFile = re.sub(r'\.json$', '', file)
399 if not origFile.endswith('.dtd') and not origFile.endswith('.properties'):
400 continue
401
402 mapping = langMappingChrome if type == 'chrome' else langMappingGecko
403 for key, value in mapping.iteritems():
386 if value == dir: 404 if value == dir:
387 dir = key 405 dir = key
406 if type == 'chrome':
407 dir = dir.replace('-', '_')
408
409 data = zip.open(info.filename).read()
410 if data == '[]':
411 continue
388 412
389 if not dir in dirs: 413 if not dir in dirs:
390 dirs[dir] = set() 414 dirs[dir] = set()
391 dirs[dir].add(origFile) 415 dirs[dir].add(origFile)
392 416
393 data = zip.open(info.filename).read() 417 path = os.path.join(localesDir, dir, origFile)
394 fromJSON(os.path.join(localesDir, dir, origFile), data) 418 if not os.path.exists(os.path.dirname(path)):
419 os.makedirs(os.path.dirname(path))
420 if type == 'chrome':
421 postprocessChromeLocale(path, data)
422 else:
423 fromJSON(path, data)
395 424
396 # Remove any extra files 425 # Remove any extra files
397 for dir, files in dirs.iteritems(): 426 for dir, files in dirs.iteritems():
398 baseDir = os.path.join(localesDir, dir) 427 baseDir = os.path.join(localesDir, dir)
399 if not os.path.exists(baseDir): 428 if not os.path.exists(baseDir):
400 continue 429 continue
401 for file in os.listdir(baseDir): 430 for file in os.listdir(baseDir):
402 path = os.path.join(baseDir, file) 431 path = os.path.join(baseDir, file)
403 if os.path.isfile(path) and (file.endswith('.properties') or file.endswith ('.dtd')) and not file in files: 432 if os.path.isfile(path) and (file.endswith('.json') or file.endswith('.pro perties') or file.endswith('.dtd')) and not file in files:
404 os.remove(path) 433 os.remove(path)
LEFTRIGHT

Powered by Google App Engine
This is Rietveld