Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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))
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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')
Ejemplo n.º 5
0
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')
Ejemplo n.º 6
0
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')
Ejemplo n.º 7
0
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')
Ejemplo n.º 8
0
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,
    })
Ejemplo n.º 9
0
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")
Ejemplo n.º 10
0
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')
Ejemplo n.º 11
0
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(),
        })
Ejemplo n.º 12
0
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)
Ejemplo n.º 13
0
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')
Ejemplo n.º 14
0
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"
        )
Ejemplo n.º 15
0
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")
Ejemplo n.º 16
0
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')