| OLD | NEW | 
|    1 # This Source Code Form is subject to the terms of the Mozilla Public |    1 # This Source Code Form is subject to the terms of the Mozilla Public | 
|    2 # License, v. 2.0. If a copy of the MPL was not distributed with this |    2 # License, v. 2.0. If a copy of the MPL was not distributed with this | 
|    3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. |    3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. | 
|    4  |    4  | 
|    5 import errno |    5 import errno | 
|    6 import io |    6 import io | 
|    7 import json |    7 import json | 
|    8 import os |    8 import os | 
|    9 import re |    9 import re | 
|   10 from StringIO import StringIO |   10 from StringIO import StringIO | 
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  183         ).encode('utf-8') |  183         ).encode('utf-8') | 
|  184  |  184  | 
|  185  |  185  | 
|  186 def toJson(data): |  186 def toJson(data): | 
|  187     return json.dumps( |  187     return json.dumps( | 
|  188         data, ensure_ascii=False, sort_keys=True, |  188         data, ensure_ascii=False, sort_keys=True, | 
|  189         indent=2, separators=(',', ': ') |  189         indent=2, separators=(',', ': ') | 
|  190     ).encode('utf-8') + '\n' |  190     ).encode('utf-8') + '\n' | 
|  191  |  191  | 
|  192  |  192  | 
|  193 def importGeckoLocales(params, files): |  193 def import_string_webext(data, key, source): | 
 |  194     """Sets data[key] to the desired {'message':value}, adds all additional | 
 |  195     info from the source dict. | 
 |  196     """ | 
 |  197     value = source['message'] | 
 |  198  | 
 |  199     data[key] = {'messages': value} | 
 |  200     for k, v in source.items(): | 
 |  201         data[key].setdefault(k, v) | 
 |  202  | 
 |  203  | 
 |  204 def import_string_gecko(data, key, value): | 
 |  205     """Only sets {'message': value} in data-dictionary, after stripping | 
 |  206     undesired gecko-style access keys. | 
 |  207     """ | 
 |  208  | 
 |  209     # Remove access keys from possible gecko-style | 
 |  210     # translations | 
 |  211     match = re.search(r'^(.*?)\s*\(&.\)$', value) | 
 |  212     if match: | 
 |  213         value = match.group(1) | 
 |  214     else: | 
 |  215         index = value.find('&') | 
 |  216         if index >= 0: | 
 |  217             value = value[0:index] + value[index + 1:] | 
 |  218  | 
 |  219     data[key] = {'message': value} | 
 |  220  | 
 |  221  | 
 |  222 def import_locales(params, files): | 
|  194     import localeTools |  223     import localeTools | 
|  195  |  224  | 
|  196     # FIXME: localeTools doesn't use real Chrome locales, it uses dash as |  225     # FIXME: localeTools doesn't use real Chrome locales, it uses dash as | 
|  197     # separator instead. |  226     # separator instead. | 
|  198     convert_locale_code = lambda code: code.replace('-', '_') |  227     convert_locale_code = lambda code: code.replace('-', '_') | 
|  199  |  228  | 
|  200     # We need to map Chrome locales to Gecko locales. Start by mapping Chrome |  229     # We need to map Chrome locales to Gecko locales. Start by mapping Chrome | 
|  201     # locales to themselves, merely with the dash as separator. |  230     # locales to themselves, merely with the dash as separator. | 
|  202     locale_mapping = {convert_locale_code(l): l for l in localeTools.chromeLocal
     es} |  231     locale_mapping = {convert_locale_code(l): l for l in localeTools.chromeLocal
     es} | 
|  203  |  232  | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|  220             fileName, keys = item |  249             fileName, keys = item | 
|  221             parts = map(lambda n: source if n == '*' else n, fileName.split('/')
     ) |  250             parts = map(lambda n: source if n == '*' else n, fileName.split('/')
     ) | 
|  222             sourceFile = os.path.join(os.path.dirname(item.source), *parts) |  251             sourceFile = os.path.join(os.path.dirname(item.source), *parts) | 
|  223             incompleteMarker = os.path.join(os.path.dirname(sourceFile), '.incom
     plete') |  252             incompleteMarker = os.path.join(os.path.dirname(sourceFile), '.incom
     plete') | 
|  224             if not os.path.exists(sourceFile) or os.path.exists(incompleteMarker
     ): |  253             if not os.path.exists(sourceFile) or os.path.exists(incompleteMarker
     ): | 
|  225                 continue |  254                 continue | 
|  226  |  255  | 
|  227             data = json.loads(files[targetFile].decode('utf-8')) |  256             data = json.loads(files[targetFile].decode('utf-8')) | 
|  228  |  257  | 
|  229             try: |  258             try: | 
 |  259                 # The WebExtensions (.json) and Gecko format provide | 
 |  260                 # translations differently and/or provide additional | 
 |  261                 # information like e.g. "placeholders". We want to adhere to | 
 |  262                 # that and preserve the addtional info. | 
 |  263  | 
|  230                 if sourceFile.endswith('.json'): |  264                 if sourceFile.endswith('.json'): | 
|  231                     with io.open(sourceFile, 'r', encoding='utf-8') as handle: |  265                     with io.open(sourceFile, 'r', encoding='utf-8') as handle: | 
|  232                         sourceData = {k: v['message'] for k, v in json.load(hand
     le).iteritems()} |  266                         sourceData = json.load(handle) | 
 |  267  | 
 |  268                     import_string = import_string_webext | 
|  233                 else: |  269                 else: | 
|  234                     sourceData = localeTools.readFile(sourceFile) |  270                     sourceData = localeTools.readFile(sourceFile) | 
|  235  |  271  | 
 |  272                     import_string = import_string_gecko | 
 |  273  | 
|  236                 # Resolve wildcard imports |  274                 # Resolve wildcard imports | 
|  237                 if keys == '*' or keys == '=*': |  275                 if keys == '*' or keys == '=*': | 
|  238                     importList = sourceData.keys() |  276                     importList = sourceData.keys() | 
|  239                     importList = filter(lambda k: not k.startswith('_'), importL
     ist) |  277                     importList = filter(lambda k: not k.startswith('_'), importL
     ist) | 
|  240                     if keys == '=*': |  278                     if keys == '=*': | 
|  241                         importList = map(lambda k: '=' + k, importList) |  279                         importList = map(lambda k: '=' + k, importList) | 
|  242                     keys = ' '.join(importList) |  280                     keys = ' '.join(importList) | 
|  243  |  281  | 
|  244                 for stringID in keys.split(): |  282                 for stringID in keys.split(): | 
|  245                     noMangling = False |  283                     noMangling = False | 
|  246                     if stringID.startswith('='): |  284                     if stringID.startswith('='): | 
|  247                         stringID = stringID[1:] |  285                         stringID = stringID[1:] | 
|  248                         noMangling = True |  286                         noMangling = True | 
|  249  |  287  | 
|  250                     if stringID in sourceData: |  288                     if stringID in sourceData: | 
|  251                         if noMangling: |  289                         if noMangling: | 
|  252                             key = re.sub(r'\W', '_', stringID) |  290                             key = re.sub(r'\W', '_', stringID) | 
|  253                         else: |  291                         else: | 
|  254                             key = re.sub(r'\..*', '', parts[-1]) + '_' + re.sub(
     r'\W', '_', stringID) |  292                             key = re.sub(r'\..*', '', parts[-1]) + '_' + re.sub(
     r'\W', '_', stringID) | 
|  255                         if key in data: |  293                         if key in data: | 
|  256                             print 'Warning: locale string %s defined multiple ti
     mes' % key |  294                             print 'Warning: locale string %s defined multiple ti
     mes' % key | 
|  257  |  295  | 
|  258                         # Remove access keys |  296                         import_string(data, key, sourceData[stringID]) | 
|  259                         value = sourceData[stringID] |  | 
|  260                         match = re.search(r'^(.*?)\s*\(&.\)$', value) |  | 
|  261                         if match: |  | 
|  262                             value = match.group(1) |  | 
|  263                         else: |  | 
|  264                             index = value.find('&') |  | 
|  265                             if index >= 0: |  | 
|  266                                 value = value[0:index] + value[index + 1:] |  | 
|  267                         data[key] = {'message': value} |  | 
|  268             except Exception as e: |  297             except Exception as e: | 
|  269                 print 'Warning: error importing locale data from %s: %s' % (sour
     ceFile, e) |  298                 print 'Warning: error importing locale data from %s: %s' % (sour
     ceFile, e) | 
|  270  |  299  | 
|  271             files[targetFile] = toJson(data) |  300             files[targetFile] = toJson(data) | 
|  272  |  301  | 
|  273  |  302  | 
|  274 def truncate(text, length_limit): |  303 def truncate(text, length_limit): | 
|  275     if len(text) <= length_limit: |  304     if len(text) <= length_limit: | 
|  276         return text |  305         return text | 
|  277     return text[:length_limit - 1].rstrip() + u'\u2026' |  306     return text[:length_limit - 1].rstrip() + u'\u2026' | 
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  373     if metadata.has_section('convert_js'): |  402     if metadata.has_section('convert_js'): | 
|  374         convertJS(params, files) |  403         convertJS(params, files) | 
|  375  |  404  | 
|  376     if metadata.has_section('preprocess'): |  405     if metadata.has_section('preprocess'): | 
|  377         files.preprocess( |  406         files.preprocess( | 
|  378             [f for f, _ in metadata.items('preprocess')], |  407             [f for f, _ in metadata.items('preprocess')], | 
|  379             {'needsExt': True} |  408             {'needsExt': True} | 
|  380         ) |  409         ) | 
|  381  |  410  | 
|  382     if metadata.has_section('import_locales'): |  411     if metadata.has_section('import_locales'): | 
|  383         importGeckoLocales(params, files) |  412         import_locales(params, files) | 
|  384  |  413  | 
|  385     files['manifest.json'] = createManifest(params, files) |  414     files['manifest.json'] = createManifest(params, files) | 
|  386     if type == 'chrome': |  415     if type == 'chrome': | 
|  387         fixTranslationsForCWS(files) |  416         fixTranslationsForCWS(files) | 
|  388  |  417  | 
|  389     if devenv: |  418     if devenv: | 
|  390         import buildtools |  419         import buildtools | 
|  391         import random |  420         import random | 
|  392         files.read(os.path.join(buildtools.__path__[0], 'chromeDevenvPoller__.js
     '), relpath='devenvPoller__.js') |  421         files.read(os.path.join(buildtools.__path__[0], 'chromeDevenvPoller__.js
     '), relpath='devenvPoller__.js') | 
|  393         files['devenvVersion__'] = str(random.random()) |  422         files['devenvVersion__'] = str(random.random()) | 
|  394  |  423  | 
|  395         if metadata.has_option('general', 'testScripts'): |  424         if metadata.has_option('general', 'testScripts'): | 
|  396             files['qunit/index.html'] = createScriptPage( |  425             files['qunit/index.html'] = createScriptPage( | 
|  397                 params, 'testIndex.html.tmpl', ('general', 'testScripts') |  426                 params, 'testIndex.html.tmpl', ('general', 'testScripts') | 
|  398             ) |  427             ) | 
|  399  |  428  | 
|  400     zipdata = files.zipToString() |  429     zipdata = files.zipToString() | 
|  401     signature = None |  430     signature = None | 
|  402     pubkey = None |  431     pubkey = None | 
|  403     if keyFile != None: |  432     if keyFile != None: | 
|  404         signature = signBinary(zipdata, keyFile) |  433         signature = signBinary(zipdata, keyFile) | 
|  405         pubkey = getPublicKey(keyFile) |  434         pubkey = getPublicKey(keyFile) | 
|  406     writePackage(outFile, pubkey, signature, zipdata) |  435     writePackage(outFile, pubkey, signature, zipdata) | 
| OLD | NEW |