def fetch_all_translations(self, obj, source, field): # TODO: get all locales or KEY_LOCALES_FOR_EDITORIAL_CONTENT at least? base_locale = to_language(settings.LANGUAGE_CODE) current_locale = to_language(get_language()) default_locale = obj.default_locale return self._fetch_some_translations( field, {base_locale, current_locale, default_locale})
def fetch_single_translation(self, obj, source, field, requested_language): value = gettext(field) if field else field default_language = to_language(settings.LANGUAGE_CODE) requested_language = to_language(requested_language) if not value or requested_language == default_language or value != field: actual_language = requested_language else: # we've fallen back to the default locale actual_language = default_language return self._format_single_translation_response( value, actual_language, requested_language, )
def get_context_data(self): addon_url = self.addon.get_url_path(add_prefix=False) # We need to display the name in some language that is relevant to the # recipient(s) instead of using the reviewer's. addon.default_locale # should work. if self.addon.name.locale != self.addon.default_locale: lang = to_language(self.addon.default_locale) with translation.override(lang): addon = Addon.unfiltered.get(pk=self.addon.pk) else: addon = self.addon review_url_kw = {'addon_id': self.addon.pk} if (self.version and self.version.channel == amo.RELEASE_CHANNEL_UNLISTED): review_url_kw['channel'] = 'unlisted' dev_ver_url = reverse( 'devhub.addons.versions', args=[self.addon.id]) else: dev_ver_url = self.addon.get_dev_url('versions') return {'name': addon.name, 'number': self.version.version if self.version else '', 'reviewer': self.user.display_name, 'addon_url': absolutify(addon_url), 'dev_versions_url': absolutify(dev_ver_url), 'review_url': absolutify(reverse('reviewers.review', kwargs=review_url_kw, add_prefix=False)), 'comments': self.data.get('comments'), 'SITE_URL': settings.SITE_URL}
def fetch_all_translations(self, obj, source, field): translations = field.__class__.objects.filter( id=field.id, localized_string__isnull=False) return { to_language(trans.locale): unicode(trans) for trans in translations } if translations else None
def get_context_data(self): addon_url = self.addon.get_url_path(add_prefix=False) dev_ver_url = self.addon.get_dev_url('versions') # We need to display the name in some language that is relevant to the # recipient(s) instead of using the reviewer's. addon.default_locale # should work. if self.addon.name.locale != self.addon.default_locale: lang = to_language(self.addon.default_locale) with translation.override(lang): addon = Addon.unfiltered.get(pk=self.addon.pk) else: addon = self.addon return { 'name': addon.name, 'number': self.version.version if self.version else '', 'reviewer': self.user.display_name, 'addon_url': absolutify(addon_url), 'dev_versions_url': absolutify(dev_ver_url), 'review_url': absolutify( reverse('editors.review', args=[self.addon.pk], add_prefix=False)), 'comments': self.data.get('comments'), 'SITE_URL': settings.SITE_URL }
def fetch_all_translations(self, obj, source, field): # this property is set by amo.utils.attach_trans_dict if trans_dict := getattr(obj, 'translations', None): translations = trans_dict.get(field.id, []) return { to_language(locale): value for (locale, value) in translations }
def _fetch_some_translations(self, field, langs): if not field: return {} base_locale = to_language(settings.LANGUAGE_CODE) translations = {} if base_locale in langs: # we get the base_locale for free - it's just the field text translations[base_locale] = str(field) langs = (lang for lang in langs if lang != base_locale) for lang in langs: with override(lang): value = gettext(field) if value not in translations.values(): translations[lang] = value return translations
def fetch_single_translation(self, obj, source, field, requested_language): base_locale = to_language(settings.LANGUAGE_CODE) default_locale = obj.default_locale translations = self._fetch_some_translations( field, {base_locale, requested_language, default_locale}) actual_language = ( requested_language if requested_language in translations else default_locale if default_locale in translations else base_locale) value = translations.get(actual_language) return self._format_single_translation_response( value, actual_language, requested_language, )
def get_context_data(self): addon_url = self.addon.get_url_path(add_prefix=False) dev_ver_url = self.addon.get_dev_url('versions') # We need to display the name in some language that is relevant to the # recipient(s) instead of using the reviewer's. addon.default_locale # should work. if self.addon.name.locale != self.addon.default_locale: lang = to_language(self.addon.default_locale) with translation.override(lang): addon = Addon.unfiltered.get(pk=self.addon.pk) else: addon = self.addon return {'name': addon.name, 'number': self.version.version if self.version else '', 'reviewer': self.user.display_name, 'addon_url': absolutify(addon_url), 'dev_versions_url': absolutify(dev_ver_url), 'review_url': absolutify(reverse('editors.review', args=[self.addon.pk], add_prefix=False)), 'comments': self.data.get('comments'), 'SITE_URL': settings.SITE_URL}
def fetch_all_translations(self, obj, source, field): translations = field.__class__.objects.filter(id=field.id, localized_string__isnull=False) return dict((to_language(trans.locale), unicode(trans)) for trans in translations) if translations else None
def build_webext_dictionary_from_legacy(addon, destination): """Create a webext package of a legacy dictionary `addon`, and put it in `destination` path.""" from olympia.files.utils import SafeZip # Avoid circular import. old_path = addon.current_version.all_files[0].file_path old_zip = SafeZip(old_path) if not old_zip.is_valid: raise ValidationError('Current dictionary xpi is not valid') dictionary_path = '' with zipfile.ZipFile(destination, 'w', zipfile.ZIP_DEFLATED) as new_zip: for obj in old_zip.filelist: splitted = obj.filename.split('/') # Ignore useless directories and files. if splitted[0] in ('META-INF', '__MACOSX', 'chrome', 'chrome.manifest', 'install.rdf'): continue # Also ignore javascript (regardless of where they are, not just at # the root), since dictionaries should not contain any code. if splitted[-1].endswith('.js'): continue # Store the path of the last .dic file we find. It can be inside a # directory. if (splitted[-1].endswith('.dic')): dictionary_path = obj.filename new_zip.writestr(obj.filename, old_zip.read(obj.filename)) # Now that all files we want from the old zip are copied, build and # add manifest.json. if not dictionary_path: # This should not happen... It likely means it's an invalid # dictionary to begin with, or one that has its .dic file in a # chrome/ directory for some reason. Abort! raise ValidationError('Current dictionary xpi has no .dic file') if addon.target_locale: target_language = addon.target_locale else: # Guess target_locale since we don't have one already. Note that # for extra confusion, target_locale is a language, not a locale. target_language = to_language( os.path.splitext(os.path.basename(dictionary_path))[0]) if target_language not in settings.AMO_LANGUAGES: # We couldn't find that language in the list we support. Let's # try with just the prefix. target_language = target_language.split('-')[0] if target_language not in settings.AMO_LANGUAGES: # We tried our best. raise ValidationError(u'Addon has no target_locale and we' u' could not guess one from the xpi') # Dumb version number increment. This will be invalid in some cases, # but some of the dictionaries we have currently already have wild # version numbers anyway. version_number = addon.current_version.version if version_number.endswith('.1-typefix'): version_number = version_number.replace('.1-typefix', '.2webext') else: version_number = '%s.1webext' % version_number manifest = { 'manifest_version': 2, 'name': unicode(addon.name), 'browser_specific_settings': { 'gecko': { 'id': addon.guid, }, }, 'version': version_number, 'dictionaries': { target_language: dictionary_path }, } # Write manifest.json we just build. new_zip.writestr('manifest.json', json.dumps(manifest))
def test_to_language(test_input, expected): assert to_language(test_input) == expected
def check(a, b): eq_(to_language(a), b)
request = self.context.get('request', None) if request and request.method == 'GET' and 'lang' in request.GET: return request.GET['lang'] else: return None def fetch_all_translations(self, obj, source, field): # this property is set by amo.utils.attach_trans_dict if trans_dict := getattr(obj, 'translations', None): translations = trans_dict.get(field.id, []) return {to_language(locale): value for (locale, value) in translations} else: translations = field.__class__.objects.filter( id=field.id, localized_string__isnull=False ) return {to_language(trans.locale): str(trans) for trans in translations} def _format_single_translation_response(self, value, lang, requested_lang): if not value or not lang: return None if lang == requested_lang: return {lang: value} else: return {lang: value, requested_lang: None, '_default': lang} def fetch_single_translation(self, obj, source, field, requested_language): return self._format_single_translation_response( str(field) if field else field, to_language(field.locale), to_language(requested_language), )
def fetch_single_translation(self, obj, source, field, requested_language): return self._format_single_translation_response( str(field) if field else field, to_language(field.locale), to_language(requested_language), )
request = self.context.get('request', None) return is_gate_active(request, 'l10n_flat_input_output') def fetch_all_translations(self, obj, source, field): # this property is set by amo.utils.attach_trans_dict if trans_dict := getattr(obj, 'translations', None): translations = trans_dict.get(field.id, []) return { to_language(locale): value for (locale, value) in translations } else: translations = field.__class__.objects.filter( id=field.id, localized_string__isnull=False) return { to_language(trans.locale): str(trans) for trans in translations } def _format_single_translation_response(self, value, lang, requested_lang): if not value or not lang: return None if lang == requested_lang: return {lang: value} else: return {lang: value, requested_lang: None, '_default': lang} def fetch_single_translation(self, obj, source, field, requested_language): return self._format_single_translation_response( str(field) if field else field, to_language(field.locale),
def extract(addon): """Extract indexable attributes from an add-on.""" attrs = ('id', 'slug', 'created', 'default_locale', 'last_updated', 'weekly_downloads', 'bayesian_rating', 'average_daily_users', 'status', 'type', 'hotness', 'is_disabled', 'is_listed') d = {attr: getattr(addon, attr) for attr in attrs} # Coerce the Translation into a string. d['name_sort'] = unicode(addon.name).lower() translations = addon.translations d['name'] = list(set(string for _, string in translations[addon.name_id])) d['name_translations'] = [ {'lang': to_language(lang), 'string': string} for lang, string in addon.translations[addon.name_id] if string] d['description'] = list(set(string for _, string in translations[addon.description_id])) d['description_translations'] = [ {'lang': to_language(lang), 'string': string} for lang, string in addon.translations[addon.description_id] if string] d['summary'] = list(set(string for _, string in translations[addon.summary_id])) d['authors'] = [a.name for a in addon.listed_authors] d['device'] = getattr(addon, 'device_ids', []) # This is an extra query, not good for perf. d['category'] = getattr(addon, 'category_ids', []) d['tags'] = getattr(addon, 'tag_list', []) d['price'] = getattr(addon, 'price', 0.0) if addon.current_version: d['platforms'] = [p.id for p in addon.current_version.supported_platforms] d['appversion'] = {} for app, appver in addon.compatible_apps.items(): if appver: min_, max_ = appver.min.version_int, appver.max.version_int else: # Fake wide compatibility for search tools and personas. min_, max_ = 0, version_int('9999') d['appversion'][app.id] = dict(min=min_, max=max_) try: d['has_version'] = addon._current_version is not None except ObjectDoesNotExist: d['has_version'] = None d['app'] = [app.id for app in addon.compatible_apps.keys()] if addon.type == amo.ADDON_PERSONA: try: # This would otherwise get attached when by the transformer. d['weekly_downloads'] = addon.persona.popularity # Boost on popularity. d['boost'] = addon.persona.popularity ** .2 d['has_theme_rereview'] = ( addon.persona.rereviewqueuetheme_set.exists()) except Persona.DoesNotExist: # The addon won't have a persona while it's being created. pass else: # Boost by the number of users on a logarithmic scale. The maximum # boost (11,000,000 users for adblock) is about 5x. d['boost'] = addon.average_daily_users ** .2 # Double the boost if the add-on is public. if addon.status == amo.STATUS_PUBLIC and 'boost' in d: d['boost'] = max(d['boost'], 1) * 4 # Indices for each language. languages is a list of locales we want to # index with analyzer if the string's locale matches. for analyzer, languages in amo.SEARCH_ANALYZER_MAP.iteritems(): if (not settings.ES_USE_PLUGINS and analyzer in amo.SEARCH_ANALYZER_PLUGINS): continue d['name_' + analyzer] = list( set(string for locale, string in translations[addon.name_id] if locale.lower() in languages)) d['summary_' + analyzer] = list( set(string for locale, string in translations[addon.summary_id] if locale.lower() in languages)) d['description_' + analyzer] = list( set(string for locale, string in translations[addon.description_id] if locale.lower() in languages)) return d
def fetch_single_translation(self, obj, source, field, requested_language): return ( {to_language(field.locale): six.text_type(field)} if field else None)
def fetch_all_translations(self, obj, source, field): translations = field.__class__.objects.filter( id=field.id, localized_string__isnull=False) return {to_language(trans.locale): six.text_type(trans) for trans in translations} if translations else None
def check(a, b): assert to_language(a) == b
def fetch_single_translation(self, obj, source, field, requested_language): return {to_language(field.locale): str(field)} if field else None
def fetch_single_translation(self, obj, source, field, requested_language): return {to_language(field.locale): unicode(field)} if field else None
def build_webext_dictionary_from_legacy(addon, destination): """Create a webext package of a legacy dictionary `addon`, and put it in `destination` path.""" from olympia.files.utils import SafeZip # Avoid circular import. old_path = addon.current_version.all_files[0].file_path old_zip = SafeZip(old_path) if not old_zip.is_valid: raise ValidationError('Current dictionary xpi is not valid') dictionary_path = '' with zipfile.ZipFile(destination, 'w', zipfile.ZIP_DEFLATED) as new_zip: for obj in old_zip.filelist: splitted = obj.filename.split('/') # Ignore useless directories and files. if splitted[0] in ('META-INF', '__MACOSX', 'chrome', 'chrome.manifest', 'install.rdf'): continue # Also ignore javascript (regardless of where they are, not just at # the root), since dictionaries should not contain any code. if splitted[-1].endswith('.js'): continue # Store the path of the last .dic file we find. It can be inside a # directory. if (splitted[-1].endswith('.dic')): dictionary_path = obj.filename new_zip.writestr(obj.filename, old_zip.read(obj.filename)) # Now that all files we want from the old zip are copied, build and # add manifest.json. if not dictionary_path: # This should not happen... It likely means it's an invalid # dictionary to begin with, or one that has its .dic file in a # chrome/ directory for some reason. Abort! raise ValidationError('Current dictionary xpi has no .dic file') if addon.target_locale: target_language = addon.target_locale else: # Guess target_locale since we don't have one already. Note that # for extra confusion, target_locale is a language, not a locale. target_language = to_language(os.path.splitext( os.path.basename(dictionary_path))[0]) if target_language not in settings.AMO_LANGUAGES: # We couldn't find that language in the list we support. Let's # try with just the prefix. target_language = target_language.split('-')[0] if target_language not in settings.AMO_LANGUAGES: # We tried our best. raise ValidationError(u'Addon has no target_locale and we' u' could not guess one from the xpi') # Dumb version number increment. This will be invalid in some cases, # but some of the dictionaries we have currently already have wild # version numbers anyway. version_number = addon.current_version.version if version_number.endswith('.1-typefix'): version_number = version_number.replace('.1-typefix', '.2webext') else: version_number = '%s.1webext' % version_number manifest = { 'manifest_version': 2, 'name': unicode(addon.name), 'applications': { 'gecko': { 'id': addon.guid, }, }, 'version': version_number, 'dictionaries': {target_language: dictionary_path}, } # Write manifest.json we just build. new_zip.writestr('manifest.json', json.dumps(manifest))
def fetch_all_translations(self, obj, source, field): # skip gettext in the default locale # TODO: iterate through all/subset of locales to actually get all translations? return {to_language(settings.LANGUAGE_CODE): str(field)}