def dump_po(project, locale): """Update .po (gettext) files from database.""" locale_paths = get_locale_paths(project, locale) for path in locale_paths: po = polib.pofile(path) date = datetime.datetime(1, 1, 1) newest = Translation() relative_path = get_relative_path(path, locale) resource = Resource.objects.filter(project=project, path=relative_path) entities = Entity.objects.filter(resource=resource, obsolete=False) for entity in entities: entry = po.find(polib.unescape(smart_text(entity.string))) if entry: if not entry.msgid_plural: translation = get_translation(entity=entity, locale=locale) if translation.string != '': entry.msgstr = polib.unescape(translation.string) if translation.date > date: date = translation.date newest = translation if ('fuzzy' in entry.flags and not translation.fuzzy): entry.flags.remove('fuzzy') else: for i in range(0, 6): if i < (locale.nplurals or 1): translation = get_translation( entity=entity, locale=locale, plural_form=i) if translation.string != '': entry.msgstr_plural[unicode(i)] = \ polib.unescape(translation.string) if translation.date > date: date = translation.date newest = translation if ('fuzzy' in entry.flags and not translation.fuzzy): entry.flags.remove('fuzzy') # Remove obsolete plural forms if exist else: if unicode(i) in entry.msgstr_plural: del entry.msgstr_plural[unicode(i)] # Update PO metadata if newest.id: po.metadata['PO-Revision-Date'] = newest.date if newest.user: po.metadata['Last-Translator'] = '%s <%s>' \ % (newest.user.first_name, newest.user.email) po.metadata['Language'] = locale.code po.metadata['X-Generator'] = 'Pontoon' if locale.nplurals: po.metadata['Plural-Forms'] = 'nplurals=%s; plural=%s;' \ % (str(locale.nplurals), locale.plural_rule) po.save() log.debug("File updated: " + path)
def dump_ini(project, locale): """Update .ini files from database.""" path = get_locale_directory(project, locale)["path"] source_path = get_source_paths(path)[0] resource = Resource.objects.get(project=project, path=source_path) entities = Entity.objects.filter(resource=resource, obsolete=False) config = configparser.ConfigParser() with codecs.open(source_path, 'r+', 'utf-8', errors='replace') as f: try: config.read_file(f) if config.has_section(locale.code): for entity in entities: key = entity.key translation = get_translation( entity=entity, locale=locale).string config.set(locale.code, key, translation) # Erase and then write, otherwise content gets appended f.seek(0) f.truncate() config.write(f) log.debug("File updated: " + source_path) else: log.debug("Locale not available in the source file") raise Exception("error") except Exception as e: log.debug("INI configparser: " + str(e))
def dump_lang(project, locale): """Update .lang files from database.""" locale_paths = get_locale_paths(project, locale) for path in locale_paths: relative_path = get_relative_path(path, locale) try: resource = Resource.objects.get( project=project, path=relative_path) except Resource.DoesNotExist as e: log.error('Resource does not exist') continue with codecs.open(path, 'r+', 'utf-8', errors='replace') as lines: content = [] translation = None for line in lines: if translation: # Keep newlines and white spaces in line if present trans_line = line.replace(line.strip(), translation) content.append(trans_line) translation = None continue content.append(line) line = line.strip() if not line: continue if line[0] == ';': original = line[1:].strip() try: entity = Entity.objects.get( resource=resource, string=original) except Entity.DoesNotExist as e: log.error('%s: Entity "%s" does not exist %s' % (path, original, project.name)) continue translation = get_translation( entity=entity, locale=locale).string if translation == '': translation = original elif translation == original: translation += ' {ok}' # Erase file and then write, otherwise content gets appended lines.seek(0) lines.truncate() lines.writelines(content) log.debug("File updated: " + path)
def delete_translation(request, template=None): """Delete given translation.""" log.debug("Delete given translation.") if not request.is_ajax(): log.error("Non-AJAX request") raise Http404 try: t = request.POST['translation'] except MultiValueDictKeyError as e: log.error(str(e)) return HttpResponse("error") log.debug("Translation: " + t) try: translation = Translation.objects.get(pk=t) except Translation.DoesNotExist as e: log.error(str(e)) return HttpResponse("error") # Non-privileged users can only delete own non-approved translations if not request.user.has_perm('base.can_localize'): if translation.user == request.user: if translation.approved is True: log.error( "Non-privileged users cannot delete approved translation") return HttpResponse("error") else: return render(request, '403.html', status=403) entity = translation.entity locale = translation.locale plural_form = translation.plural_form translation.delete() # Mark next translation approved if needed next = get_translation(entity=entity, locale=locale, plural_form=plural_form) if next.pk is not None and request.user.has_perm('base.can_localize'): next.approved = True next.approved_user = request.user next.approved_date = timezone.now() next.save() return HttpResponse(json.dumps({ 'type': 'deleted', 'next': next.id, }), content_type='application/json')
def get_translations_from_other_locales(request, template=None): """Get entity translations for all but specified locale.""" log.debug("Get entity translation for all but specified locale.") if not request.is_ajax(): log.error("Non-AJAX request") raise Http404 try: entity = request.GET['entity'] locale = request.GET['locale'] except MultiValueDictKeyError as e: log.error(str(e)) return HttpResponse("error") log.debug("Entity: " + entity) log.debug("Locale: " + locale) try: entity = Entity.objects.get(pk=entity) except Entity.DoesNotExist as e: log.error(str(e)) return HttpResponse("error") try: locale = Locale.objects.get(code__iexact=locale) except Locale.DoesNotExist as e: log.error(str(e)) return HttpResponse("error") payload = [] locales = entity.resource.project.locales.all().exclude( code__iexact=locale.code) for l in locales: plural_form = None if entity.string_plural == "" else 0 translation = get_translation(entity=entity, locale=l, plural_form=plural_form) if translation.string != '' or translation.pk is not None: payload.append({ "locale": { "code": l.code, "name": l.name }, "translation": translation.string }) if len(payload) == 0: log.debug("Translations do not exist") return HttpResponse("error") else: return HttpResponse(json.dumps(payload, indent=4), content_type='application/json')
def get_translations_from_other_locales(request, template=None): """Get entity translations for all but specified locale.""" log.debug("Get entity translation for all but specified locale.") if not request.is_ajax(): log.error("Non-AJAX request") raise Http404 try: entity = request.GET['entity'] locale = request.GET['locale'] except MultiValueDictKeyError as e: log.error(str(e)) return HttpResponse("error") log.debug("Entity: " + entity) log.debug("Locale: " + locale) try: entity = Entity.objects.get(pk=entity) except Entity.DoesNotExist as e: log.error(str(e)) return HttpResponse("error") try: locale = Locale.objects.get(code__iexact=locale) except Locale.DoesNotExist as e: log.error(str(e)) return HttpResponse("error") payload = [] locales = entity.resource.project.locales.all().exclude( code__iexact=locale.code) for l in locales: plural_form = None if entity.string_plural == "" else 0 translation = get_translation( entity=entity, locale=l, plural_form=plural_form) if translation.string != '' or translation.pk is not None: payload.append({ "locale": { "code": l.code, "name": l.name }, "translation": translation.string }) if len(payload) == 0: log.debug("Translations do not exist") return HttpResponse("error") else: return HttpResponse( json.dumps(payload, indent=4), content_type='application/json')
def delete_translation(request, template=None): """Delete given translation.""" log.debug("Delete given translation.") if not request.is_ajax(): log.error("Non-AJAX request") raise Http404 try: t = request.POST['translation'] except MultiValueDictKeyError as e: log.error(str(e)) return HttpResponse("error") log.debug("Translation: " + t) try: translation = Translation.objects.get(pk=t) except Translation.DoesNotExist as e: log.error(str(e)) return HttpResponse("error") # Non-privileged users can only delete own non-approved translations if not request.user.has_perm('base.can_localize'): if translation.user == request.user: if translation.approved is True: log.error( "Non-privileged users cannot delete approved translation") return HttpResponse("error") else: return render(request, '403.html', status=403) entity = translation.entity locale = translation.locale plural_form = translation.plural_form translation.mark_for_deletion() # Mark next translation approved if needed next = get_translation( entity=entity, locale=locale, plural_form=plural_form) if next.pk is not None and request.user.has_perm('base.can_localize'): next.approved = True next.approved_user = request.user next.approved_date = timezone.now() next.save() return HttpResponse(json.dumps({ 'type': 'deleted', 'next': next.id, }), content_type='application/json')
def delete_translation(request): """Delete given translation.""" try: t = request.POST['translation'] except MultiValueDictKeyError as e: log.error(str(e)) return HttpResponse("error") try: translation = Translation.objects.get(pk=t) except Translation.DoesNotExist as e: log.error(str(e)) return HttpResponse("error") # Non-privileged users can only delete own non-approved translations if not request.user.has_perm('base.can_translate_locale', translation.locale): if translation.user == request.user: if translation.approved is True: log.error( "Non-privileged users cannot delete approved translation") return HttpResponse("error") else: return render(request, '403.html', status=403) entity = translation.entity locale = translation.locale plural_form = translation.plural_form translation.delete() # Mark next translation approved if needed next = get_translation( entity=entity, locale=locale, plural_form=plural_form) if next.pk is not None and request.user.has_perm('base.can_translate_locale', next.locale): next.approved = True next.approved_user = request.user next.approved_date = timezone.now() next.save() return JsonResponse({ 'type': 'deleted', 'next': next.id, })
def translation_memory(request): """Get translations from internal translations.""" try: text = request.GET['text'] locale = request.GET['locale'] pk = request.GET['pk'] except MultiValueDictKeyError as e: log.error(str(e)) return HttpResponse("error") try: locale = Locale.objects.get(code__iexact=locale) except Locale.DoesNotExist as e: log.error(e) return HttpResponse("error") min_quality = 0.7 max_results = 5 length = len(text) min_dist = math.ceil(max(length * min_quality, 2)) max_dist = math.floor(min(length / min_quality, 1000)) # Only check entities with similar length entities = Entity.objects.all().extra( where=["CHAR_LENGTH(string) BETWEEN %s AND %s" % (min_dist, max_dist)]) # Exclude existing entity if pk: entities = entities.exclude(pk=pk) translations = {} for e in entities: source = e.string quality = Levenshtein.ratio(text, source) if quality > min_quality: plural_form = None if e.string_plural == "" else 0 translation = get_translation( entity=e, locale=locale, fuzzy=False, plural_form=plural_form) if translation.string != '' or translation.pk is not None: count = 1 quality = quality * 100 if translation.string in translations: existing = translations[translation.string] count = existing['count'] + 1 # Store data for best match among equal translations only if quality < existing['quality']: quality = existing['quality'] source = existing['source'] translations[translation.string] = { 'source': source, 'quality': quality, 'count': count, } if len(translations) > 0: # Sort by translation count t = sorted(translations.iteritems(), key=itemgetter(1), reverse=True) translations_array = [] for a, b in t[:max_results]: b["target"] = a translations_array.append(b) return HttpResponse(json.dumps({ 'translations': translations_array }), content_type='application/json') else: return HttpResponse("no")
def update_translation(request): """Update entity translation for the specified locale and user.""" try: entity = request.POST['entity'] string = request.POST['translation'] locale = request.POST['locale'] plural_form = request.POST['plural_form'] original = request.POST['original'] ignore_check = request.POST['ignore_check'] except MultiValueDictKeyError as error: log.error(str(error)) return HttpResponse("error") try: e = Entity.objects.get(pk=entity) except Entity.DoesNotExist as error: log.error(str(error)) return HttpResponse("error") try: l = Locale.objects.get(code__iexact=locale) except Locale.DoesNotExist as error: log.error(str(error)) return HttpResponse("error") if plural_form == "-1": plural_form = None user = request.user if not request.user.is_authenticated(): if e.resource.project.pk != 1: log.error("Not authenticated") return HttpResponse("error") else: user = None try: quality_checks = UserProfile.objects.get(user=user).quality_checks except UserProfile.DoesNotExist as error: quality_checks = True ignore = False if ignore_check == 'true' or not quality_checks: ignore = True now = timezone.now() can_translate = ( request.user.has_perm('base.can_translate_locale', l) and not request.user.profile.force_suggestions ) translations = Translation.objects.filter( entity=e, locale=l, plural_form=plural_form) # Newlines are not allowed in .lang files (bug 1190754) if e.resource.format == 'lang' and '\n' in string: return HttpResponse('Newline characters are not allowed.') # Translations exist if len(translations) > 0: # Same translation exists try: t = translations.get(string=string) # If added by privileged user, approve and unfuzzy it if can_translate: # Unless there's nothing to be changed if t.user is not None and t.approved and t.approved_user \ and t.approved_date and not t.fuzzy: return HttpResponse("Same translation already exists.") warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings unapprove(translations) unfuzzy(translations) if t.user is None: t.user = user t.approved = True t.approved_date = timezone.now() t.fuzzy = False if t.approved_user is None: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() return HttpResponse(json.dumps({ 'type': 'updated', 'translation': t.serialize(), }), content_type='application/json') # If added by non-privileged user, unfuzzy it else: if t.fuzzy: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings if t.user is None: t.user = user t.approved = False t.approved_user = None t.approved_date = None t.fuzzy = False if request.user.is_authenticated(): t.save() return HttpResponse(json.dumps({ 'type': 'updated', 'translation': t.serialize(), }), content_type='application/json') return HttpResponse("Same translation already exists.") # Different translation added except: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings if can_translate: unapprove(translations) unfuzzy(translations) t = Translation( entity=e, locale=l, user=user, string=string, plural_form=plural_form, date=now, approved=can_translate) if can_translate: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() active = get_translation( entity=e, locale=l, plural_form=plural_form) return HttpResponse(json.dumps({ 'type': 'added', 'translation': active.serialize(), }), content_type='application/json') # No translations saved yet else: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings t = Translation( entity=e, locale=l, user=user, string=string, plural_form=plural_form, date=now, approved=can_translate) if can_translate: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() return HttpResponse(json.dumps({ 'type': 'saved', 'translation': t.serialize(), }), content_type='application/json')
def update_translation(request): """Update entity translation for the specified locale and user.""" try: entity = request.POST['entity'] string = request.POST['translation'] locale = request.POST['locale'] plural_form = request.POST['plural_form'] original = request.POST['original'] ignore_check = request.POST['ignore_check'] except MultiValueDictKeyError as error: log.error(str(error)) return HttpResponse("error") try: e = Entity.objects.get(pk=entity) except Entity.DoesNotExist as error: log.error(str(error)) return HttpResponse("error") try: l = Locale.objects.get(code__iexact=locale) except Locale.DoesNotExist as error: log.error(str(error)) return HttpResponse("error") if plural_form == "-1": plural_form = None user = request.user if not request.user.is_authenticated(): if e.resource.project.pk != 1: log.error("Not authenticated") return HttpResponse("error") else: user = None try: quality_checks = UserProfile.objects.get(user=user).quality_checks except UserProfile.DoesNotExist as error: quality_checks = True ignore = False if ignore_check == 'true' or not quality_checks: ignore = True now = timezone.now() can_translate = (request.user.has_perm('base.can_translate_locale', l) and not request.user.profile.force_suggestions) translations = Translation.objects.filter(entity=e, locale=l, plural_form=plural_form) # Newlines are not allowed in .lang files (bug 1190754) if e.resource.format == 'lang' and '\n' in string: return HttpResponse('Newline characters are not allowed.') # Translations exist if len(translations) > 0: # Same translation exists try: t = translations.get(string=string) # If added by privileged user, approve and unfuzzy it if can_translate: # Unless there's nothing to be changed if t.user is not None and t.approved and t.approved_user \ and t.approved_date and not t.fuzzy: return HttpResponse("Same translation already exists.") warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings unapprove(translations) unfuzzy(translations) if t.user is None: t.user = user t.approved = True t.approved_date = timezone.now() t.fuzzy = False if t.approved_user is None: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() return JsonResponse({ 'type': 'updated', 'translation': t.serialize(), }) # If added by non-privileged user, unfuzzy it else: if t.fuzzy: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings if t.user is None: t.user = user t.approved = False t.approved_user = None t.approved_date = None t.fuzzy = False if request.user.is_authenticated(): t.save() return JsonResponse({ 'type': 'updated', 'translation': t.serialize(), }) return HttpResponse("Same translation already exists.") # Different translation added except: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings if can_translate: unapprove(translations) unfuzzy(translations) t = Translation(entity=e, locale=l, user=user, string=string, plural_form=plural_form, date=now, approved=can_translate) if can_translate: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() active = get_translation(entity=e, locale=l, plural_form=plural_form) return JsonResponse({ 'type': 'added', 'translation': active.serialize(), }) # No translations saved yet else: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings t = Translation(entity=e, locale=l, user=user, string=string, plural_form=plural_form, date=now, approved=can_translate) if can_translate: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() return JsonResponse({ 'type': 'saved', 'translation': t.serialize(), })
def dump_properties(project, locale): """Update .properties files from database. Generate files from source files, but only ones with translated strings.""" resources = Resource.objects.filter(project=project) entities = Entity.objects.filter(resource__in=resources, obsolete=False) locale_directory_path = get_locale_directory(project, locale)["path"] # Remove all non-hidden files and folders in locale repository items = os.listdir(locale_directory_path) items = [i for i in items if not i[0] == '.'] for item in items: path = os.path.join(locale_directory_path, item) try: shutil.rmtree(path) except OSError: os.remove(path) except Exception as e: log.error(e) parser = silme.format.properties.PropertiesFormatParser source_directory = get_source_directory(project.repository_path) # Get relative paths to translated files only translations = Translation.objects.filter( entity__in=entities, locale=locale) entities_pks = translations.values("entity").distinct() entities_translated = Entity.objects.filter(pk__in=entities_pks) resources_pks = entities_translated.values("resource").distinct() resources_translated = Resource.objects.filter(pk__in=resources_pks) relative_paths = resources_translated.values_list("path").distinct() for relative in relative_paths: path = os.path.join(locale_directory_path, relative[0]) # Create folders and copy files from source basedir = os.path.dirname(path) if not os.path.exists(basedir): os.makedirs(basedir) try: shutil.copy( os.path.join(source_directory['path'], relative[0]), path) # Obsolete files except Exception as e: log.debug(e) continue with codecs.open(path, 'r+', 'utf-8') as f: structure = parser.get_structure(f.read()) resource = resources.filter(path=relative[0]) entities_with_path = entities.filter(resource=resource) for entity in entities_with_path: key = entity.key translation = get_translation(entity=entity, locale=locale) try: if (translation.string != '' or translation.pk is not None): # Modify translated entities structure.modify_entity(key, translation.string) else: # Remove untranslated and following newline pos = structure.entity_pos(key) structure.remove_entity(key) line = structure[pos] if type(line) == unicode and line.startswith('\n'): line = line[len('\n'):] structure[pos] = line if len(line) is 0: structure.remove_element(pos) # Obsolete entities except KeyError as e: pass # Erase file and then write, otherwise content gets appended f.seek(0) f.truncate() content = parser.dump_structure(structure) f.write(content) log.debug("File updated: " + path)
def update_translation(request, template=None): """Update entity translation for the specified locale and user.""" log.debug("Update entity translation for the specified locale and user.") if not request.is_ajax(): log.error("Non-AJAX request") raise Http404 if request.method != 'POST': log.error("Non-POST request") raise Http404 try: entity = request.POST['entity'] string = request.POST['translation'] locale = request.POST['locale'] plural_form = request.POST['plural_form'] original = request.POST['original'] ignore_check = request.POST['ignore_check'] except MultiValueDictKeyError as error: log.error(str(error)) return HttpResponse("error") log.debug("Entity: " + entity) log.debug("Translation: " + string) log.debug("Locale: " + locale) try: e = Entity.objects.get(pk=entity) except Entity.DoesNotExist as error: log.error(str(error)) return HttpResponse("error") try: l = Locale.objects.get(code=locale) except Locale.DoesNotExist as error: log.error(str(error)) return HttpResponse("error") if plural_form == "-1": plural_form = None user = request.user if not request.user.is_authenticated(): if e.resource.project.pk != 1: log.error("Not authenticated") return HttpResponse("error") else: user = None try: quality_checks = UserProfile.objects.get(user=user).quality_checks except UserProfile.DoesNotExist as error: quality_checks = True ignore = False if ignore_check == 'true' or not quality_checks: ignore = True now = datetime.datetime.now() can_localize = request.user.has_perm('base.can_localize') translations = Translation.objects.filter( entity=e, locale=l, plural_form=plural_form) # Translations exist if len(translations) > 0: # Same translation exists try: t = translations.get(string__iexact=string) # If added by privileged user, approve and unfuzzy it if can_localize: # Unless there's nothing to be changed if t.user is not None and t.approved and t.approved_user \ and t.approved_date and not t.fuzzy: return HttpResponse("Same translation already exist.") warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings unapprove(translations) unfuzzy(translations) if t.user is None: t.user = user t.approved = True t.fuzzy = False if t.approved_user is None: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() return HttpResponse(json.dumps({ 'type': 'updated', 'translation': t.serialize(), }), mimetype='application/json') # If added by non-privileged user, unfuzzy it else: if t.fuzzy: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings if t.user is None: t.user = user t.approved = False t.approved_user = None t.approved_date = None t.fuzzy = False if request.user.is_authenticated(): t.save() return HttpResponse(json.dumps({ 'type': 'updated', 'translation': t.serialize(), }), mimetype='application/json') return HttpResponse("Same translation already exist.") # Different translation added except: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings if can_localize: unapprove(translations) unfuzzy(translations) t = Translation( entity=e, locale=l, user=user, string=string, plural_form=plural_form, date=now, approved=can_localize) if can_localize: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() active = get_translation( entity=e, locale=l, plural_form=plural_form) return HttpResponse(json.dumps({ 'type': 'added', 'translation': active.serialize(), }), mimetype='application/json') # No translations saved yet else: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings t = Translation( entity=e, locale=l, user=user, string=string, plural_form=plural_form, date=now, approved=can_localize) if can_localize: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() return HttpResponse(json.dumps({ 'type': 'saved', 'translation': t.serialize(), }), mimetype='application/json')
def update_translation(request, template=None): """Update entity translation for the specified locale and user.""" log.debug("Update entity translation for the specified locale and user.") if not request.is_ajax(): log.error("Non-AJAX request") raise Http404 if request.method != "POST": log.error("Non-POST request") raise Http404 try: entity = request.POST["entity"] string = request.POST["translation"] locale = request.POST["locale"] plural_form = request.POST["plural_form"] original = request.POST["original"] ignore_check = request.POST["ignore_check"] except MultiValueDictKeyError as error: log.error(str(error)) return HttpResponse("error") log.debug("Entity: " + entity) log.debug("Translation: " + string) log.debug("Locale: " + locale) try: e = Entity.objects.get(pk=entity) except Entity.DoesNotExist as error: log.error(str(error)) return HttpResponse("error") try: l = Locale.objects.get(code__iexact=locale) except Locale.DoesNotExist as error: log.error(str(error)) return HttpResponse("error") if plural_form == "-1": plural_form = None user = request.user if not request.user.is_authenticated(): if e.resource.project.pk != 1: log.error("Not authenticated") return HttpResponse("error") else: user = None try: quality_checks = UserProfile.objects.get(user=user).quality_checks except UserProfile.DoesNotExist as error: quality_checks = True ignore = False if ignore_check == "true" or not quality_checks: ignore = True now = timezone.now() can_localize = request.user.has_perm("base.can_localize") translations = Translation.objects.filter(entity=e, locale=l, plural_form=plural_form) # Newlines are not allowed in .lang files (bug 1190754) if e.resource.format == "lang" and "\n" in string: return HttpResponse("Newline characters are not allowed.") # Translations exist if len(translations) > 0: # Same translation exists try: t = translations.get(string=string) # If added by privileged user, approve and unfuzzy it if can_localize: # Unless there's nothing to be changed if t.user is not None and t.approved and t.approved_user and t.approved_date and not t.fuzzy: return HttpResponse("Same translation already exists.") warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings unapprove(translations) unfuzzy(translations) if t.user is None: t.user = user t.approved = True t.approved_date = timezone.now() t.fuzzy = False if t.approved_user is None: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() return HttpResponse( json.dumps({"type": "updated", "translation": t.serialize()}), content_type="application/json" ) # If added by non-privileged user, unfuzzy it else: if t.fuzzy: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings if t.user is None: t.user = user t.approved = False t.approved_user = None t.approved_date = None t.fuzzy = False if request.user.is_authenticated(): t.save() return HttpResponse( json.dumps({"type": "updated", "translation": t.serialize()}), content_type="application/json" ) return HttpResponse("Same translation already exists.") # Different translation added except: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings if can_localize: unapprove(translations) unfuzzy(translations) t = Translation( entity=e, locale=l, user=user, string=string, plural_form=plural_form, date=now, approved=can_localize ) if can_localize: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() active = get_translation(entity=e, locale=l, plural_form=plural_form) return HttpResponse( json.dumps({"type": "added", "translation": active.serialize()}), content_type="application/json" ) # No translations saved yet else: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings t = Translation( entity=e, locale=l, user=user, string=string, plural_form=plural_form, date=now, approved=can_localize ) if can_localize: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() return HttpResponse( json.dumps({"type": "saved", "translation": t.serialize()}), content_type="application/json" )
def translation_memory(request): """Get translations from internal translations.""" log.debug("Get translations from internal translations.") try: text = request.GET['text'] locale = request.GET['locale'] pk = request.GET['pk'] except MultiValueDictKeyError as e: log.error(str(e)) return HttpResponse("error") try: locale = Locale.objects.get(code__iexact=locale) except Locale.DoesNotExist as e: log.error(e) return HttpResponse("error") min_quality = 0.7 max_results = 5 length = len(text) min_dist = math.ceil(max(length * min_quality, 2)) max_dist = math.floor(min(length / min_quality, 1000)) # Only check entities with similar length entities = Entity.objects.all().extra( where=["CHAR_LENGTH(string) BETWEEN %s AND %s" % (min_dist, max_dist)]) # Exclude existing entity if pk: entities = entities.exclude(pk=pk) translations = {} for e in entities: source = e.string quality = Levenshtein.ratio(text, source) if quality > min_quality: plural_form = None if e.string_plural == "" else 0 translation = get_translation(entity=e, locale=locale, fuzzy=False, plural_form=plural_form) if translation.string != '' or translation.pk is not None: count = 1 quality = quality * 100 if translation.string in translations: existing = translations[translation.string] count = existing['count'] + 1 # Store data for best match among equal translations only if quality < existing['quality']: quality = existing['quality'] source = existing['source'] translations[translation.string] = { 'source': source, 'quality': quality, 'count': count, } if len(translations) > 0: # Sort by translation count t = sorted(translations.iteritems(), key=itemgetter(1), reverse=True) translations_array = [] for a, b in t[:max_results]: b["target"] = a translations_array.append(b) return HttpResponse(json.dumps({'translations': translations_array}), content_type='application/json') else: return HttpResponse("no")
def update_translation(request, template=None): """Update entity translation for the specified locale and user.""" log.debug("Update entity translation for the specified locale and user.") if not request.is_ajax(): log.error("Non-AJAX request") raise Http404 if request.method != 'POST': log.error("Non-POST request") raise Http404 try: entity = request.POST['entity'] string = request.POST['translation'] locale = request.POST['locale'] plural_form = request.POST['plural_form'] original = request.POST['original'] ignore_check = request.POST['ignore_check'] except MultiValueDictKeyError as error: log.error(str(error)) return HttpResponse("error") log.debug("Entity: " + entity) log.debug("Translation: " + string) log.debug("Locale: " + locale) try: e = Entity.objects.get(pk=entity) except Entity.DoesNotExist as error: log.error(str(error)) return HttpResponse("error") try: l = Locale.objects.get(code=locale) except Locale.DoesNotExist as error: log.error(str(error)) return HttpResponse("error") if plural_form == "-1": plural_form = None user = request.user if not request.user.is_authenticated(): if e.resource.project.pk != 1: log.error("Not authenticated") return HttpResponse("error") else: user = None try: quality_checks = UserProfile.objects.get(user=user).quality_checks except UserProfile.DoesNotExist as error: quality_checks = True ignore = False if ignore_check == 'true' or not quality_checks: ignore = True now = datetime.datetime.now() can_localize = request.user.has_perm('base.can_localize') translations = Translation.objects.filter( entity=e, locale=l, plural_form=plural_form) # Translations exist if len(translations) > 0: # Same translation exists try: t = translations.get(string=string) # If added by privileged user, approve and unfuzzy it if can_localize: # Unless there's nothing to be changed if t.user is not None and t.approved and t.approved_user \ and t.approved_date and not t.fuzzy: return HttpResponse("Same translation already exist.") warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings unapprove(translations) unfuzzy(translations) if t.user is None: t.user = user t.approved = True t.fuzzy = False if t.approved_user is None: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() return HttpResponse(json.dumps({ 'type': 'updated', 'translation': t.serialize(), }), mimetype='application/json') # If added by non-privileged user, unfuzzy it else: if t.fuzzy: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings if t.user is None: t.user = user t.approved = False t.approved_user = None t.approved_date = None t.fuzzy = False if request.user.is_authenticated(): t.save() return HttpResponse(json.dumps({ 'type': 'updated', 'translation': t.serialize(), }), mimetype='application/json') return HttpResponse("Same translation already exist.") # Different translation added except: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings if can_localize: unapprove(translations) unfuzzy(translations) t = Translation( entity=e, locale=l, user=user, string=string, plural_form=plural_form, date=now, approved=can_localize) if can_localize: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() active = get_translation( entity=e, locale=l, plural_form=plural_form) return HttpResponse(json.dumps({ 'type': 'added', 'translation': active.serialize(), }), mimetype='application/json') # No translations saved yet else: warnings = utils.quality_check(original, string, l, ignore) if warnings: return warnings t = Translation( entity=e, locale=l, user=user, string=string, plural_form=plural_form, date=now, approved=can_localize) if can_localize: t.approved_user = user t.approved_date = now if request.user.is_authenticated(): t.save() return HttpResponse(json.dumps({ 'type': 'saved', 'translation': t.serialize(), }), mimetype='application/json')