Example #1
0
def submit(request, unit):
    """Processes translation submissions and stores them in the database.

    :return: An object in JSON notation that contains the previous and last
             units for the unit next to unit ``uid``.
    """
    json = {}

    cantranslate = check_permission("translate", request)
    if not cantranslate:
        raise PermissionDenied(_("You do not have rights to access "
                                 "translation mode."))

    translation_project = request.translation_project
    language = translation_project.language

    if unit.hasplural():
        snplurals = len(unit.source.strings)
    else:
        snplurals = None

    # Update current unit instance's attributes
    unit.submitted_by = request.profile
    unit.submitted_on = datetime.utcnow()

    form_class = unit_form_factory(language, snplurals, request)
    form = form_class(request.POST, instance=unit)

    if form.is_valid():
        if form.updated_fields:
            # Store creation time so that it is the same for all submissions
            creation_time=datetime.utcnow()
            for field, old_value, new_value in form.updated_fields:
                sub = Submission(
                        creation_time=creation_time,
                        translation_project=translation_project,
                        submitter=request.profile,
                        unit=unit,
                        field=field,
                        type=SubmissionTypes.NORMAL,
                        old_value=old_value,
                        new_value=new_value,
                )
                sub.save()

            form.save()
            translation_submitted.send(
                    sender=translation_project,
                    unit=form.instance,
                    profile=request.profile,
            )

        rcode = 200
    else:
        # Form failed
        #FIXME: we should display validation errors here
        rcode = 400
        json["msg"] = _("Failed to process submission.")
    response = jsonify(json)
    return HttpResponse(response, status=rcode, mimetype="application/json")
Example #2
0
def accept_suggestion(request, unit, suggid):
    json = {
        'udbid': unit.id,
        'sugid': suggid,
    }
    translation_project = request.translation_project

    if request.POST.get('accept'):
        try:
            suggestion = unit.suggestion_set.get(id=suggid)
        except ObjectDoesNotExist:
            raise Http404

        old_target = unit.target
        success = unit.accept_suggestion(suggid)

        json['newtargets'] = [highlight_whitespace(target)
                              for target in unit.target.strings]
        json['newdiffs'] = {}
        for sugg in unit.get_suggestions():
            json['newdiffs'][sugg.id] = \
                    [highlight_diffs(unit.target.strings[i], target)
                     for i, target in enumerate(sugg.target.strings)]

        if suggestion is not None and success:
            if suggestion.user:
                translation_submitted.send(sender=translation_project,
                                           unit=unit, profile=suggestion.user)

            # FIXME: we need a totally different model for tracking stats, this
            # is just lame
            suggstat, created = SuggestionStat.objects.get_or_create(
                    translation_project=translation_project,
                    suggester=suggestion.user,
                    state='pending',
                    unit=unit.id,
            )
            suggstat.reviewer = request.profile
            suggstat.state = 'accepted'
            suggstat.save()

            # For now assume the target changed
            # TODO: check all fields for changes
            creation_time = timezone.now()
            sub = Submission(
                    creation_time=creation_time,
                    translation_project=translation_project,
                    submitter=suggestion.user,
                    from_suggestion=suggstat,
                    unit=unit,
                    field=SubmissionFields.TARGET,
                    type=SubmissionTypes.SUGG_ACCEPT,
                    old_value=old_target,
                    new_value=unit.target,
            )
            sub.save()

    response = jsonify(json)
    return HttpResponse(response, mimetype="application/json")
Example #3
0
def process_submit(request, unit, type):
    """
    Processes submissions and suggestions and stores them in the database.

    @return: An object in JSON notation that contains the previous
    and last units for the unit next to unit C{uid}.
    """
    json = {}
    cantranslate = check_permission("translate", request)
    cansuggest = check_permission("suggest", request)
    if type == 'submission' and not cantranslate or type == 'suggestion' and not cansuggest:
        raise PermissionDenied(
            _("You do not have rights to access translation mode."))

    translation_project = request.translation_project
    language = translation_project.language

    if unit.hasplural():
        snplurals = len(unit.source.strings)
    else:
        snplurals = None

    form_class = unit_form_factory(language, snplurals, request)
    form = form_class(request.POST, instance=unit)

    if form.is_valid():
        if type == 'submission':
            if form.instance._target_updated or \
               form.instance._translator_comment_updated or \
               form.instance._state_updated:
                form.save()
                translation_submitted.send(sender=translation_project,
                                           unit=form.instance,
                                           profile=request.profile)

                sub = Submission(translation_project=translation_project,
                                 submitter=request.profile)
                sub.save()
        elif type == 'suggestion':
            if form.instance._target_updated:
                #HACKISH: django 1.2 stupidly modifies instance on
                # model form validation, reload unit from db
                unit = Unit.objects.get(id=unit.id)
                sugg = unit.add_suggestion(form.cleaned_data['target_f'],
                                           request.profile)
                if sugg:
                    SuggestionStat.objects.get_or_create(
                        translation_project=translation_project,
                        suggester=request.profile,
                        state='pending',
                        unit=unit.id)
        rcode = 200
    else:
        # Form failed
        #FIXME: we should display validation errors here
        rcode = 400
        json["msg"] = _("Failed to process submit.")
    response = jsonify(json)
    return HttpResponse(response, status=rcode, mimetype="application/json")
Example #4
0
def process_submit(request, unit, type):
    """
    Processes submissions and suggestions and stores them in the database.

    @return: An object in JSON notation that contains the previous
    and last units for the unit next to unit C{uid}.
    """
    json = {}
    cantranslate = check_permission("translate", request)
    cansuggest = check_permission("suggest", request)
    if type == "submission" and not cantranslate or type == "suggestion" and not cansuggest:
        raise PermissionDenied(_("You do not have rights to access translation mode."))

    translation_project = request.translation_project
    language = translation_project.language

    if unit.hasplural():
        snplurals = len(unit.source.strings)
    else:
        snplurals = None

    form_class = unit_form_factory(language, snplurals, request)
    form = form_class(request.POST, instance=unit)

    if form.is_valid():
        if type == "submission":
            if (
                form.instance._target_updated
                or form.instance._translator_comment_updated
                or form.instance._state_updated
            ):
                form.save()
                translation_submitted.send(sender=translation_project, unit=form.instance, profile=request.profile)

                sub = Submission(translation_project=translation_project, submitter=request.profile)
                sub.save()
        elif type == "suggestion":
            if form.instance._target_updated:
                # HACKISH: django 1.2 stupidly modifies instance on
                # model form validation, reload unit from db
                unit = Unit.objects.get(id=unit.id)
                sugg = unit.add_suggestion(form.cleaned_data["target_f"], request.profile)
                if sugg:
                    SuggestionStat.objects.get_or_create(
                        translation_project=translation_project,
                        suggester=request.profile,
                        state="pending",
                        unit=unit.id,
                    )
        rcode = 200
    else:
        # Form failed
        # FIXME: we should display validation errors here
        rcode = 400
        json["msg"] = _("Failed to process submit.")
    response = jsonify(json)
    return HttpResponse(response, status=rcode, mimetype="application/json")
Example #5
0
File: views.py Project: notz/pootle
def accept_suggestion(request, unit, suggid):
    json = {}
    translation_project = request.translation_project
    json["udbid"] = unit.id
    json["sugid"] = suggid
    if request.POST.get('accept'):
        try:
            suggestion = unit.suggestion_set.get(id=suggid)
        except ObjectDoesNotExist:
            raise Http404

        old_target = unit.target
        success = unit.accept_suggestion(suggid)
        json['newtargets'] = [
            highlight_whitespace(target) for target in unit.target.strings
        ]
        json['newdiffs'] = {}
        for sugg in unit.get_suggestions():
            json['newdiffs'][sugg.id] = [highlight_diffs(unit.target.strings[i], target) \
                                         for i, target in enumerate(sugg.target.strings)]

        if suggestion is not None and success:
            if suggestion.user:
                translation_submitted.send(sender=translation_project,
                                           unit=unit,
                                           profile=suggestion.user)
            #FIXME: we need a totally different model for tracking stats, this is just lame
            if suggestion.user != request.profile:
                suggstat, created = SuggestionStat.objects.get_or_create(
                    translation_project=translation_project,
                    suggester=suggestion.user,
                    state='pending',
                    unit=unit.id)
                suggstat.reviewer = request.profile
                suggstat.state = 'accepted'
                suggstat.save()
            else:
                suggstat = None

            # For now assume the target changed
            # TODO: check all fields for changes
            creation_time = timezone.now()
            sub = Submission(
                creation_time=creation_time,
                translation_project=translation_project,
                submitter=suggestion.user,
                from_suggestion=suggstat,
                unit=unit,
                field=SubmissionFields.TARGET,
                type=SubmissionTypes.SUGG_ACCEPT,
                old_value=old_target,
                new_value=unit.target,
            )
            sub.save()
    response = jsonify(json)
    return HttpResponse(response, mimetype="application/json")
Example #6
0
def accept_suggestion(request, uid, suggid):
    unit = get_object_or_404(Unit, id=uid)
    directory = unit.store.parent
    translation_project = unit.store.translation_project

    if not check_profile_permission(
        get_profile(request.user), 'review', directory):
        raise PermissionDenied

    response = {
        'udbid': unit.id,
        'sugid': suggid,
        }

    if request.POST.get('accept'):
        try:
            suggestion = unit.suggestion_set.get(id=suggid)
        except ObjectDoesNotExist:
            suggestion = None

        response['success'] = unit.accept_suggestion(suggid)
        response['newtargets'] = [
            highlight_whitespace(target) for target in unit.target.strings]
        response['newdiffs'] = {}
        for sugg in unit.get_suggestions():
            response['newdiffs'][sugg.id] = [
                highlight_diffs(unit.target.strings[i], target) \
                for i, target in enumerate(sugg.target.strings)]

        if suggestion is not None and response['success']:
            if suggestion.user:
                translation_submitted.send(
                    sender=translation_project, unit=unit,
                    profile=suggestion.user)
            # FIXME: we need a totally different model for tracking
            # stats, this is just lame
            suggstat, created = SuggestionStat.objects.get_or_create(
                translation_project=translation_project,
                suggester=suggestion.user,
                state='pending',
                unit=unit.id)
            suggstat.reviewer = get_profile(request.user)
            suggstat.state = 'accepted'
            suggstat.save()

            sub = Submission(translation_project=translation_project,
                             submitter=get_profile(request.user),
                             from_suggestion=suggstat)
            sub.save()

    response = simplejson.dumps(response)
    return HttpResponse(response, mimetype="application/json")
Example #7
0
def accept_suggestion(request, uid, suggid):
    unit = get_object_or_404(Unit, id=uid)
    directory = unit.store.parent
    translation_project = unit.store.translation_project

    if not check_profile_permission(get_profile(request.user), 'review',
                                    directory):
        raise PermissionDenied

    response = {
        'udbid': unit.id,
        'sugid': suggid,
    }

    if request.POST.get('accept'):
        try:
            suggestion = unit.suggestion_set.get(id=suggid)
        except ObjectDoesNotExist:
            suggestion = None

        response['success'] = unit.accept_suggestion(suggid)
        response['newtargets'] = [
            highlight_whitespace(target) for target in unit.target.strings
        ]
        response['newdiffs'] = {}
        for sugg in unit.get_suggestions():
            response['newdiffs'][sugg.id] = [highlight_diffs(unit.target.strings[i], target) \
                                             for i, target in enumerate(sugg.target.strings)]

        if suggestion is not None and response['success']:
            if suggestion.user:
                translation_submitted.send(sender=translation_project,
                                           unit=unit,
                                           profile=suggestion.user)
            #FIXME: we need a totally different model for tracking stats, this is just lame
            suggstat, created = SuggestionStat.objects.get_or_create(
                translation_project=translation_project,
                suggester=suggestion.user,
                state='pending',
                unit=unit.id)
            suggstat.reviewer = get_profile(request.user)
            suggstat.state = 'accepted'
            suggstat.save()

            sub = Submission(translation_project=translation_project,
                             submitter=get_profile(request.user),
                             from_suggestion=suggstat)
            sub.save()

    response = simplejson.dumps(response)
    return HttpResponse(response, mimetype="application/json")
Example #8
0
def accept_suggestion(request, unit, suggid):
    json = {}
    translation_project = request.translation_project
    json["udbid"] = unit.id
    json["sugid"] = suggid
    if request.POST.get('accept'):
        try:
            suggestion = unit.suggestion_set.get(id=suggid)
        except ObjectDoesNotExist:
            raise Http404

        success = unit.accept_suggestion(suggid)
        json['newtargets'] = [highlight_whitespace(target) for target in unit.target.strings]
        json['newdiffs'] = {}
        for sugg in unit.get_suggestions():
            json['newdiffs'][sugg.id] = [highlight_diffs(unit.target.strings[i], target) \
                                         for i, target in enumerate(sugg.target.strings)]

        if suggestion is not None and success:
            if suggestion.user:
                translation_submitted.send(sender=translation_project, unit=unit, profile=suggestion.user)
            #FIXME: we need a totally different model for tracking stats, this is just lame
            if suggestion.user != request.profile:
                suggstat, created = SuggestionStat.objects.get_or_create(translation_project=translation_project,
                                                                     suggester=suggestion.user,
                                                                     state='pending',
                                                                     unit=unit.id)
                suggstat.reviewer = request.profile
                suggstat.state = 'accepted'
                suggstat.save()
            else:
                suggstat = None
            sub = Submission(translation_project=translation_project,
                             submitter=suggestion.user,
                             from_suggestion=suggstat)
            sub.save()
    response = jsonify(json)
    return HttpResponse(response, mimetype="application/json")
Example #9
0
def process_submit(request, unit, type):
    """Processes submissions and suggestions and stores them in the database.

    :return: An object in JSON notation that contains the previous and last
             units for the unit next to unit ``uid``.
    """
    json = {}
    cantranslate = check_permission("translate", request)
    cansuggest = check_permission("suggest", request)
    if type == 'submission' and not cantranslate or type == 'suggestion' and not cansuggest:
        raise PermissionDenied(_("You do not have rights to access translation mode."))

    translation_project = request.translation_project
    language = translation_project.language

    if unit.hasplural():
        snplurals = len(unit.source.strings)
    else:
        snplurals = None

    import copy
    old_unit = copy.copy(unit)
    form_class = unit_form_factory(language, snplurals, request)
    form = form_class(request.POST, instance=unit)

    if form.is_valid():
        if type == 'submission' and form.updated_fields:
            # Store creation time so that it is the same for all submissions:
            creation_time=datetime.utcnow()
            for field, old_value, new_value in form.updated_fields:
                sub = Submission(
                        creation_time=creation_time,
                        translation_project=translation_project,
                        submitter=request.profile,
                        unit=unit,
                        field=field,
                        type=NORMAL,
                        old_value=old_value,
                        new_value=new_value,
                )
                sub.save()

            form.save()
            translation_submitted.send(
                    sender=translation_project,
                    unit=form.instance,
                    profile=request.profile,
            )

        elif type == 'suggestion':
            if form.instance._target_updated:
                #HACKISH: django 1.2 stupidly modifies instance on
                # model form validation, reload unit from db
                unit = Unit.objects.get(id=unit.id)
                sugg = unit.add_suggestion(form.cleaned_data['target_f'], request.profile)
                if sugg:
                    SuggestionStat.objects.get_or_create(translation_project=translation_project,
                                                         suggester=request.profile,
                                                         state='pending', unit=unit.id)
        rcode = 200
    else:
        # Form failed
        #FIXME: we should display validation errors here
        rcode = 400
        json["msg"] = _("Failed to process submit.")
    response = jsonify(json)
    return HttpResponse(response, status=rcode, mimetype="application/json")
Example #10
0
def translate_page(request, units_queryset, store=None):
    if not check_permission("view", request):
        raise PermissionDenied(_("You do not have rights to access this translation project."))

    cantranslate = check_permission("translate", request)
    cansuggest = check_permission("suggest", request)
    canreview = check_permission("review", request)
    translation_project = request.translation_project
    language = translation_project.language
    # shouldn't we globalize profile context
    profile = get_profile(request.user)

    step_queryset = None

    # Process search first
    search_form = None
    if 'search' in request.GET and 'sfields' in request.GET:
        search_form = SearchForm(request.GET)
        if search_form.is_valid():
            step_queryset = get_search_step_query(request.translation_project, search_form, units_queryset)
    else:
        search_form = SearchForm()

    # which units are we interested in?
    if step_queryset is None:
        step_queryset = get_step_query(request, units_queryset)

    prev_unit, edit_unit, pager = get_current_units(request, step_queryset, units_queryset)

    # time to process POST submission
    form = None
    if prev_unit is not None and ('submit' in request.POST or 'suggest' in request.POST):
        # check permissions
        if 'submit'  in request.POST and not cantranslate or \
           'suggest' in request.POST and not cansuggest:
            raise PermissionDenied

        if prev_unit.hasplural():
            snplurals = len(prev_unit.source.strings)
        else:
            snplurals = None
        form_class = unit_form_factory(language, snplurals)
        form = form_class(request.POST, instance=prev_unit)
        if form.is_valid():
            if cantranslate and 'submit' in request.POST:
                if form.instance._target_updated or form.instance._translator_comment_updated or \
                       form.instance._state_updated:
                    form.save()
                    translation_submitted.send(sender=translation_project,
                                               unit=form.instance, profile=profile)

                    sub = Submission(translation_project=translation_project,
                                     submitter=get_profile(request.user))
                    sub.save()

            elif cansuggest and 'suggest' in request.POST:
                if form.instance._target_updated:
                    #HACKISH: django 1.2 stupidly modifies instance on
                    # model form validation, reload unit from db
                    prev_unit = Unit.objects.get(id=prev_unit.id)
                    sugg = prev_unit.add_suggestion(form.cleaned_data['target_f'], get_profile(request.user))
                    if sugg:
                        SuggestionStat.objects.get_or_create(translation_project=translation_project,
                                                             suggester=get_profile(request.user),
                                                             state='pending', unit=prev_unit.id)
        else:
            # form failed, don't skip to next unit
            edit_unit = prev_unit

    if edit_unit is None:
        # no more units to step through, display end of translation message
        return translate_end(request, translation_project)

    # only create form for edit_unit if prev_unit was processed successfully
    if form is None or form.is_valid():
        if edit_unit.hasplural():
            snplurals = len(edit_unit.source.strings)
        else:
            snplurals = None
        form_class = unit_form_factory(language, snplurals)
        form = form_class(instance=edit_unit)

    if store is None:
        store = edit_unit.store
        pager_query = units_queryset
        preceding = (pager_query.filter(store=store, index__lt=edit_unit.index) | \
                     pager_query.filter(store__pootle_path__lt=store.pootle_path)).count()
        store_preceding = store.units.filter(index__lt=edit_unit.index).count()
    else:
        pager_query = store.units
        preceding = pager_query.filter(index__lt=edit_unit.index).count()
        store_preceding = preceding

    unit_rows = profile.get_unit_rows()

    # regardless of the query used to step through units, we will
    # display units in their original context, and display a pager for
    # the store not for the unit_step query
    if pager is None:
        page = preceding / unit_rows + 1
        pager = paginate(request, pager_query, items=unit_rows, page=page, orphans=0)

    # we always display the active unit in the middle of the page to
    # provide context for translators
    context_rows = (unit_rows - 1) / 2
    if store_preceding > context_rows:
        unit_position = store_preceding % unit_rows
        page_length = pager.end_index() - pager.start_index() + 1
        if page_length < unit_rows:
            if pager.has_other_pages():
                units_query = store.units[page_length:]
            else:
                units_query = store.units
            page = store_preceding / unit_rows
            units = paginate(request, units_query, items=unit_rows, page=page, orphans=0).object_list
        elif unit_position < context_rows:
            # units too close to the top of the batch
            offset = unit_rows - (context_rows - unit_position)
            units_query = store.units[offset:]
            page = store_preceding / unit_rows
            units = paginate(request, units_query, items=unit_rows, page=page, orphans=0).object_list
        elif unit_position >= unit_rows - context_rows:
            # units too close to the bottom of the batch
            offset = context_rows - (unit_rows - unit_position - 1)
            units_query = store.units[offset:]
            page = store_preceding / unit_rows + 1
            units = paginate(request, units_query, items=unit_rows, page=page, orphans=0).object_list
        else:
            units = pager.object_list
    else:
        units = store.units[:unit_rows]

    # caluclate url querystring so state is retained on POST
    # we can't just use request URL cause unit and page GET vars cancel state
    GET_vars = []
    for key, values in request.GET.lists():
        if key not in ('page', 'unit'):
            for value in values:
                GET_vars.append('%s=%s' % (key, value))

    # links for quality check documentation
    checks = []
    for check in request.GET.get('matchnames','').split(','):
        if not check:
            continue
        safe_check = escape(check)
        link = '<a href="http://translate.sourceforge.net/wiki/toolkit/pofilter_tests#%s" target="_blank">%s</a>' % (safe_check, safe_check)
        checks.append(_('checking %s', link))

    # precalculate alternative source languages
    alt_src_langs = get_alt_src_langs(request, profile, translation_project)
    alt_src_codes = alt_src_langs.values_list('code', flat=True)

    context = {
        'unit_rows': unit_rows,
        'alt_src_langs': alt_src_langs,
        'alt_src_codes': alt_src_codes,
        'cantranslate': cantranslate,
        'cansuggest': cansuggest,
        'canreview': canreview,
        'form': form,
        'search_form': search_form,
        'edit_unit': edit_unit,
        'store': store,
        'pager': pager,
        'units': units,
        'language': language,
        'translation_project': translation_project,
        'project': translation_project.project,
        'profile': profile,
        'source_language': translation_project.project.source_language,
        'directory': store.parent,
        'GET_state': '&'.join(GET_vars),
        'checks': checks,
        'MT_BACKENDS': settings.MT_BACKENDS,
        }
    return render_to_response('store/translate.html', context, context_instance=RequestContext(request))
Example #11
0
File: views.py Project: notz/pootle
def submit(request, unit):
    """Processes translation submissions and stores them in the database.

    :return: An object in JSON notation that contains the previous and last
             units for the unit next to unit ``uid``.
    """
    json = {}

    cantranslate = check_permission("translate", request)
    if not cantranslate:
        raise PermissionDenied(
            _("You do not have rights to access "
              "translation mode."))

    translation_project = request.translation_project
    language = translation_project.language

    if unit.hasplural():
        snplurals = len(unit.source.strings)
    else:
        snplurals = None

    # Update current unit instance's attributes
    unit.submitted_by = request.profile
    unit.submitted_on = timezone.now()

    form_class = unit_form_factory(language, snplurals, request)
    form = form_class(request.POST, instance=unit)

    if form.is_valid():
        if form.updated_fields:
            # Store creation time so that it is the same for all submissions
            creation_time = timezone.now()
            for field, old_value, new_value in form.updated_fields:
                sub = Submission(
                    creation_time=creation_time,
                    translation_project=translation_project,
                    submitter=request.profile,
                    unit=unit,
                    field=field,
                    type=SubmissionTypes.NORMAL,
                    old_value=old_value,
                    new_value=new_value,
                )
                sub.save()

            form.save()
            translation_submitted.send(
                sender=translation_project,
                unit=form.instance,
                profile=request.profile,
            )

        rcode = 200
    else:
        # Form failed
        #FIXME: we should display validation errors here
        rcode = 400
        json["msg"] = _("Failed to process submission.")
    response = jsonify(json)
    return HttpResponse(response, status=rcode, mimetype="application/json")
Example #12
0
def translate_page(request, units_queryset, store=None):
    if not check_permission("view", request):
        raise PermissionDenied(
            _("You do not have rights to access this translation project."))

    cantranslate = check_permission("translate", request)
    cansuggest = check_permission("suggest", request)
    canreview = check_permission("review", request)
    translation_project = request.translation_project
    language = translation_project.language
    # shouldn't we globalize profile context
    profile = get_profile(request.user)

    step_queryset = None

    # Process search first
    search_form = None
    if 'search' in request.GET and 'sfields' in request.GET:
        search_form = SearchForm(request.GET)
        if search_form.is_valid():
            step_queryset = get_search_step_query(request.translation_project,
                                                  search_form, units_queryset)
    else:
        search_form = SearchForm()

    # which units are we interested in?
    if step_queryset is None:
        step_queryset = get_step_query(request, units_queryset)

    prev_unit, edit_unit, pager = get_current_units(request, step_queryset,
                                                    units_queryset)

    # time to process POST submission
    form = None
    if prev_unit is not None and ('submit' in request.POST
                                  or 'suggest' in request.POST):
        # check permissions
        if 'submit'  in request.POST and not cantranslate or \
           'suggest' in request.POST and not cansuggest:
            raise PermissionDenied

        if prev_unit.hasplural():
            snplurals = len(prev_unit.source.strings)
        else:
            snplurals = None
        form_class = unit_form_factory(language, snplurals)
        form = form_class(request.POST, instance=prev_unit)
        if form.is_valid():
            if cantranslate and 'submit' in request.POST:
                if form.instance._target_updated or form.instance._translator_comment_updated or \
                       form.instance._state_updated:
                    form.save()
                    translation_submitted.send(sender=translation_project,
                                               unit=form.instance,
                                               profile=profile)

                    sub = Submission(translation_project=translation_project,
                                     submitter=get_profile(request.user))
                    sub.save()

            elif cansuggest and 'suggest' in request.POST:
                if form.instance._target_updated:
                    #HACKISH: django 1.2 stupidly modifies instance on
                    # model form validation, reload unit from db
                    prev_unit = Unit.objects.get(id=prev_unit.id)
                    sugg = prev_unit.add_suggestion(
                        form.cleaned_data['target_f'],
                        get_profile(request.user))
                    if sugg:
                        SuggestionStat.objects.get_or_create(
                            translation_project=translation_project,
                            suggester=get_profile(request.user),
                            state='pending',
                            unit=prev_unit.id)
        else:
            # form failed, don't skip to next unit
            edit_unit = prev_unit

    if edit_unit is None:
        # no more units to step through, display end of translation message
        return translate_end(request, translation_project)

    # only create form for edit_unit if prev_unit was processed successfully
    if form is None or form.is_valid():
        if edit_unit.hasplural():
            snplurals = len(edit_unit.source.strings)
        else:
            snplurals = None
        form_class = unit_form_factory(language, snplurals)
        form = form_class(instance=edit_unit)

    if store is None:
        store = edit_unit.store
        pager_query = units_queryset
        preceding = (pager_query.filter(store=store, index__lt=edit_unit.index) | \
                     pager_query.filter(store__pootle_path__lt=store.pootle_path)).count()
        store_preceding = store.units.filter(index__lt=edit_unit.index).count()
    else:
        pager_query = store.units
        preceding = pager_query.filter(index__lt=edit_unit.index).count()
        store_preceding = preceding

    unit_rows = profile.get_unit_rows()

    # regardless of the query used to step through units, we will
    # display units in their original context, and display a pager for
    # the store not for the unit_step query
    if pager is None:
        page = preceding / unit_rows + 1
        pager = paginate(request,
                         pager_query,
                         items=unit_rows,
                         page=page,
                         orphans=0)

    # we always display the active unit in the middle of the page to
    # provide context for translators
    context_rows = (unit_rows - 1) / 2
    if store_preceding > context_rows:
        unit_position = store_preceding % unit_rows
        page_length = pager.end_index() - pager.start_index() + 1
        if page_length < unit_rows:
            if pager.has_other_pages():
                units_query = store.units[page_length:]
            else:
                units_query = store.units
            page = store_preceding / unit_rows
            units = paginate(request,
                             units_query,
                             items=unit_rows,
                             page=page,
                             orphans=0).object_list
        elif unit_position < context_rows:
            # units too close to the top of the batch
            offset = unit_rows - (context_rows - unit_position)
            units_query = store.units[offset:]
            page = store_preceding / unit_rows
            units = paginate(request,
                             units_query,
                             items=unit_rows,
                             page=page,
                             orphans=0).object_list
        elif unit_position >= unit_rows - context_rows:
            # units too close to the bottom of the batch
            offset = context_rows - (unit_rows - unit_position - 1)
            units_query = store.units[offset:]
            page = store_preceding / unit_rows + 1
            units = paginate(request,
                             units_query,
                             items=unit_rows,
                             page=page,
                             orphans=0).object_list
        else:
            units = pager.object_list
    else:
        units = store.units[:unit_rows]

    # caluclate url querystring so state is retained on POST
    # we can't just use request URL cause unit and page GET vars cancel state
    GET_vars = []
    for key, values in request.GET.lists():
        if key not in ('page', 'unit'):
            for value in values:
                GET_vars.append('%s=%s' % (key, value))

    # links for quality check documentation
    checks = []
    for check in request.GET.get('matchnames', '').split(','):
        if not check:
            continue
        safe_check = escape(check)
        link = '<a href="http://translate.sourceforge.net/wiki/toolkit/pofilter_tests#%s" target="_blank">%s</a>' % (
            safe_check, safe_check)
        checks.append(_('checking %s', link))

    # precalculate alternative source languages
    alt_src_langs = get_alt_src_langs(request, profile, translation_project)
    alt_src_codes = alt_src_langs.values_list('code', flat=True)

    context = {
        'unit_rows': unit_rows,
        'alt_src_langs': alt_src_langs,
        'alt_src_codes': alt_src_codes,
        'cantranslate': cantranslate,
        'cansuggest': cansuggest,
        'canreview': canreview,
        'form': form,
        'search_form': search_form,
        'edit_unit': edit_unit,
        'store': store,
        'pager': pager,
        'units': units,
        'language': language,
        'translation_project': translation_project,
        'project': translation_project.project,
        'profile': profile,
        'source_language': translation_project.project.source_language,
        'directory': store.parent,
        'GET_state': '&'.join(GET_vars),
        'checks': checks,
        'MT_BACKENDS': settings.MT_BACKENDS,
    }
    return render_to_response('store/translate.html',
                              context,
                              context_instance=RequestContext(request))
Example #13
0
def submit(request, unit):
    """Processes translation submissions and stores them in the database.

    :return: An object in JSON notation that contains the previous and last
             units for the unit next to unit ``uid``.
    """
    json = {}

    cantranslate = check_permission("translate", request)
    if not cantranslate:
        raise PermissionDenied(_("You do not have rights to access "
                                 "translation mode."))

    translation_project = request.translation_project
    language = translation_project.language

    if unit.hasplural():
        snplurals = len(unit.source.strings)
    else:
        snplurals = None

    # Store current time so that it is the same for all submissions
    current_time = timezone.now()

    # Update current unit instance's attributes
    unit.submitted_by = request.profile
    unit.submitted_on = current_time

    form_class = unit_form_factory(language, snplurals, request)
    form = form_class(request.POST, instance=unit)

    if form.is_valid():
        if form.updated_fields:
            for field, old_value, new_value in form.updated_fields:
                # (jgonzale|2014-09-05|INTL-591): log unsolicited modification to the source field
                if field == SubmissionFields.SOURCE:
                    logging.warning(
                        u'Corrupted submission for (unit_id, {0}) - ' \
                        u'(submitter, {1}) ' \
                        u'(source_old_value, {2}) ' \
                        u'(request info - {3})'.format(unit.id, request.profile, old_value, repr(request))
                    )
                sub = Submission(
                        creation_time=current_time,
                        translation_project=translation_project,
                        submitter=request.profile,
                        unit=unit,
                        field=field,
                        type=SubmissionTypes.NORMAL,
                        old_value=old_value,
                        new_value=new_value,
                )
                sub.save()

            form.save()
            translation_submitted.send(
                    sender=translation_project,
                    unit=form.instance,
                    profile=request.profile,
            )

        rcode = 200
    else:
        # Form failed
        #FIXME: we should display validation errors here
        rcode = 400
        json["msg"] = _("Failed to process submission.")
    response = jsonify(json)
    return HttpResponse(response, status=rcode, mimetype="application/json")