def resolve_i18n_message(message, messages, locale, default_locale=None): """Resolve a translatable string in an add-on. This matches ``__MSG_extensionName__`` like names and returns the correct translation for `locale`. :param locale: The locale to fetch the translation for, If ``None`` (default) ``settings.LANGUAGE_CODE`` is used. :param messages: A dictionary of messages, e.g the return value of `extract_translations`. """ if not message or not isinstance(message, basestring): # Don't even attempt to extract invalid data. # See https://github.com/mozilla/addons-server/issues/3067 # for more details return message match = MSG_RE.match(message) if match is None: return message locale = find_language(locale) if default_locale: default_locale = find_language(default_locale) msgid = match.group('msgid') default = {'message': message} if locale in messages: message = messages[locale].get(msgid, default) elif default_locale in messages: message = messages[default_locale].get(msgid, default) if not isinstance(message, dict): # Fallback for invalid message format, should be caught by # addons-linter in the future but we'll have to handle it. # See https://github.com/mozilla/addons-server/issues/3485 return default['message'] return message['message']
def extract_translations(file_obj): """Extract all translation messages from `file_obj`. :param locale: if not `None` the list will be restricted only to `locale`. """ xpi = get_filepath(file_obj) messages = {} try: with zipfile.ZipFile(xpi, 'r') as source: file_list = source.namelist() # Fetch all locales the add-on supports # see https://developer.chrome.com/extensions/i18n#overview-locales # for more details on the format. locales = { name.split('/')[1] for name in file_list if name.startswith('_locales/') and name.endswith('/messages.json') } for locale in locales: corrected_locale = find_language(locale) # Filter out languages we don't support. if not corrected_locale: continue fname = '_locales/{0}/messages.json'.format(locale) try: data = source.read(fname) messages[corrected_locale] = decode_json(data) except (ValueError, KeyError): # `ValueError` thrown by `decode_json` if the json is # invalid and `KeyError` thrown by `source.read` # usually means the file doesn't exist for some reason, # we fail silently continue except IOError: pass return messages
def extract_translations(file_obj): """Extract all translation messages from `file_obj`. :param locale: if not `None` the list will be restricted only to `locale`. """ xpi = get_filepath(file_obj) messages = {} try: with zipfile.ZipFile(xpi, 'r') as source: file_list = source.namelist() # Fetch all locales the add-on supports # see https://developer.chrome.com/extensions/i18n#overview-locales # for more details on the format. locales = { name.split('/')[1] for name in file_list if name.startswith('_locales/') and name.endswith('/messages.json')} for locale in locales: corrected_locale = find_language(locale) # Filter out languages we don't support. if not corrected_locale: continue fname = '_locales/{0}/messages.json'.format(locale) try: data = source.read(fname) messages[corrected_locale] = decode_json(data) except (ValueError, KeyError): # `ValueError` thrown by `decode_json` if the json is # invalid and `KeyError` thrown by `source.read` # usually means the file doesn't exist for some reason, # we fail silently continue except IOError: pass return messages
def check(a, b): eq_(find_language(a), b)
def test_find_language(test_input, expected): assert find_language(test_input) == expected
def check(a, b): assert find_language(a) == b