Exemple #1
0
def show_translation(request, project, subproject, lang):
    obj = get_translation(request, project, subproject, lang)
    last_changes = Change.objects.filter(
        translation=obj).order_by('-timestamp')[:10]

    # Check locks
    obj.is_locked(request)

    # How much is user allowed to configure upload?
    if request.user.has_perm('trans.author_translation'):
        form = ExtraUploadForm()
    elif request.user.has_perm('trans.overwrite_translation'):
        form = UploadForm()
    else:
        form = SimpleUploadForm()

    # Is user allowed to do automatic translation?
    if request.user.has_perm('trans.automatic_translation'):
        autoform = AutoForm(obj)
    else:
        autoform = None

    # Search form for everybody
    search_form = SearchForm()

    # Review form for logged in users
    if request.user.is_anonymous():
        review_form = None
    else:
        review_form = ReviewForm(
            initial={
                'date': datetime.date.today() - datetime.timedelta(days=31)
            })

    return render_to_response(
        'translation.html',
        RequestContext(
            request, {
                'object':
                obj,
                'form':
                form,
                'autoform':
                autoform,
                'search_form':
                search_form,
                'review_form':
                review_form,
                'last_changes':
                last_changes,
                'last_changes_url':
                urlencode(obj.get_kwargs()),
                'last_changes_rss':
                reverse(
                    'rss-translation',
                    kwargs=obj.get_kwargs(),
                ),
            }))
Exemple #2
0
def search(translation, request):
    '''
    Performs search or returns cached search results.
    '''

    # Already performed search
    if 'sid' in request.GET:
        # Grab from session storage
        search_id = 'search_%s' % request.GET['sid']

        # Check if we know the search
        if search_id not in request.session:
            messages.error(request, _('Invalid search string!'))
            return HttpResponseRedirect(translation.get_absolute_url())

        return request.session[search_id]

    # Possible new search
    rqtype = request.GET.get('type', 'all')

    search_form = SearchForm(request.GET)
    review_form = ReviewForm(request.GET)

    search_query = None
    if review_form.is_valid():
        # Review
        allunits = translation.unit_set.review(
            review_form.cleaned_data['date'],
            request.user
        )

        formatted_date = formats.date_format(
            review_form.cleaned_data['date'],
            'SHORT_DATE_FORMAT'
        )
        name = _('Review of translations since %s') % formatted_date
    elif search_form.is_valid():
        # Apply search conditions
        allunits = translation.unit_set.search(
            search_form.cleaned_data['search'],
            search_form.cleaned_data['q'],
            search_form.cleaned_data['src'],
            search_form.cleaned_data['ctx'],
            search_form.cleaned_data['tgt'],
        )

        search_query = search_form.cleaned_data['q']
        name = get_search_name(
            search_form.cleaned_data['search'],
            search_query,
        )
    else:
        # Error reporting
        if 'date' in request.GET:
            show_form_errors(request, review_form)
        elif 'q' in request.GET:
            show_form_errors(request, search_form)

        # Filtering by type
        allunits = translation.unit_set.filter_type(
            rqtype,
            translation,
            ignored='ignored' in request.GET
        )

        name = get_filter_name(rqtype)

    # Grab unit IDs
    unit_ids = list(allunits.values_list('id', flat=True))

    # Check empty search results
    if len(unit_ids) == 0:
        messages.warning(request, _('No string matched your search!'))
        return HttpResponseRedirect(translation.get_absolute_url())

    # Checksum unit access
    offset = 0
    if 'checksum' in request.GET:
        try:
            unit = allunits.filter(checksum=request.GET['checksum'])[0]
            offset = unit_ids.index(unit.id)
        except (Unit.DoesNotExist, IndexError):
            messages.warning(request, _('No string matched your search!'))
            return HttpResponseRedirect(translation.get_absolute_url())

    # Remove old search results
    cleanup_session(request.session)

    # Store in cache and return
    search_id = str(uuid.uuid1())
    search_result = {
        'query': search_query,
        'name': name,
        'ids': unit_ids,
        'search_id': search_id,
        'ttl': int(time.time()) + 86400,
        'offset': offset,
    }

    request.session['search_%s' % search_id] = search_result

    return search_result
Exemple #3
0
def translate(request, project, subproject, lang):
    obj = get_translation(request, project, subproject, lang)

    # Check locks
    project_locked, user_locked, own_lock = obj.is_locked(request, True)
    locked = project_locked or user_locked

    if request.user.is_authenticated():
        profile = request.user.get_profile()
        antispam = None
    else:
        profile = None
        antispam = AntispamForm()

    secondary = None
    unit = None

    search_options = SearchOptions(request)

    # Any form submitted?
    if request.method == 'POST':

        # Antispam protection
        if not request.user.is_authenticated():
            antispam = AntispamForm(request.POST)
            if not antispam.is_valid():
                # Silently redirect to next entry
                return HttpResponseRedirect('%s?type=%s&pos=%d%s' % (
                    obj.get_translate_url(),
                    search_options.rqtype,
                    search_options.pos,
                    search_options.url
                ))

        form = TranslationForm(request.POST)
        if form.is_valid() and not project_locked:
            # Check whether translation is not outdated
            obj.check_sync()
            try:
                try:
                    unit = Unit.objects.get(
                        checksum=form.cleaned_data['checksum'],
                        translation=obj
                    )
                except Unit.MultipleObjectsReturned:
                    # Possible temporary inconsistency caused by ongoing update
                    # of repo, let's pretend everyting is okay
                    unit = Unit.objects.filter(
                        checksum=form.cleaned_data['checksum'],
                        translation=obj
                    )[0]
                if 'suggest' in request.POST:
                    # Handle suggesion saving
                    user = request.user
                    if isinstance(user, AnonymousUser):
                        user = None
                    if form.cleaned_data['target'] == len(form.cleaned_data['target']) * ['']:
                        messages.error(request, _('Your suggestion is empty!'))
                        # Stay on same entry
                        return HttpResponseRedirect(
                            '%s?type=%s&pos=%d&dir=stay%s' % (
                                obj.get_translate_url(),
                                search_options.rqtype,
                                search_options.pos,
                                search_options.url
                            )
                        )
                    # Create the suggestion
                    sug = Suggestion.objects.create(
                        target=join_plural(form.cleaned_data['target']),
                        checksum=unit.checksum,
                        language=unit.translation.language,
                        project=unit.translation.subproject.project,
                        user=user
                    )
                    # Record in change
                    Change.objects.create(
                        unit=unit,
                        action=Change.ACTION_SUGGESTION,
                        translation=unit.translation,
                        user=user
                    )
                    # Invalidate counts cache
                    unit.translation.invalidate_cache('suggestions')
                    # Invite user to become translator if there is nobody else
                    recent_changes = Change.objects.content().filter(
                        translation=unit.translation,
                    ).exclude(
                        user=None
                    )
                    if not recent_changes.exists():
                        messages.info(
                            request,
                            _('There is currently no active translator for this translation, please consider becoming a translator as your suggestion might otherwise remain unreviewed.')
                        )
                    # Notify subscribed users
                    subscriptions = Profile.objects.subscribed_new_suggestion(
                        obj.subproject.project,
                        obj.language,
                        request.user
                    )
                    for subscription in subscriptions:
                        subscription.notify_new_suggestion(obj, sug, unit)
                    # Update suggestion stats
                    if profile is not None:
                        profile.suggested += 1
                        profile.save()
                elif not request.user.is_authenticated():
                    # We accept translations only from authenticated
                    messages.error(
                        request,
                        _('You need to log in to be able to save translations!')
                    )
                elif not request.user.has_perm('trans.save_translation'):
                    # Need privilege to save
                    messages.error(
                        request,
                        _('You don\'t have privileges to save translations!')
                    )
                elif not user_locked:
                    # Remember old checks
                    oldchecks = set(
                        unit.active_checks().values_list('check', flat=True)
                    )
                    # Update unit and save it
                    unit.target = join_plural(form.cleaned_data['target'])
                    unit.fuzzy = form.cleaned_data['fuzzy']
                    saved = unit.save_backend(request)

                    if saved:
                        # Get new set of checks
                        newchecks = set(
                            unit.active_checks().values_list('check', flat=True)
                        )
                        # Did we introduce any new failures?
                        if newchecks > oldchecks:
                            # Show message to user
                            messages.error(
                                request,
                                _('Some checks have failed on your translation!')
                            )
                            # Stay on same entry
                            return HttpResponseRedirect(
                                '%s?type=%s&pos=%d&dir=stay%s' % (
                                    obj.get_translate_url(),
                                    search_options.rqtype,
                                    search_options.pos,
                                    search_options.url
                                )
                            )

                # Redirect to next entry
                return HttpResponseRedirect('%s?type=%s&pos=%d%s' % (
                    obj.get_translate_url(),
                    search_options.rqtype,
                    search_options.pos,
                    search_options.url
                ))
            except Unit.DoesNotExist:
                logger.error(
                    'message %s disappeared!',
                    form.cleaned_data['checksum']
                )
                messages.error(
                    request,
                    _('Message you wanted to translate is no longer available!')
                )

    # Handle translation merging
    if 'merge' in request.GET and not locked:
        if not request.user.has_perm('trans.save_translation'):
            # Need privilege to save
            messages.error(
                request,
                _('You don\'t have privileges to save translations!')
            )
        else:
            try:
                mergeform = MergeForm(request.GET)
                if mergeform.is_valid():
                    try:
                        unit = Unit.objects.get(
                            checksum=mergeform.cleaned_data['checksum'],
                            translation=obj
                        )
                    except Unit.MultipleObjectsReturned:
                        # Possible temporary inconsistency caused by ongoing
                        # update of repo, let's pretend everyting is okay
                        unit = Unit.objects.filter(
                            checksum=mergeform.cleaned_data['checksum'],
                            translation=obj
                        )[0]

                    merged = Unit.objects.get(
                        pk=mergeform.cleaned_data['merge']
                    )

                    if unit.checksum != merged.checksum:
                        messages.error(
                            request,
                            _('Can not merge different messages!')
                        )
                    else:
                        # Store unit
                        unit.target = merged.target
                        unit.fuzzy = merged.fuzzy
                        saved = unit.save_backend(request)
                        # Update stats if there was change
                        if saved:
                            profile.translated += 1
                            profile.save()
                        # Redirect to next entry
                        return HttpResponseRedirect('%s?type=%s&pos=%d%s' % (
                            obj.get_translate_url(),
                            search_options.rqtype,
                            search_options.pos,
                            search_options.url
                        ))
            except Unit.DoesNotExist:
                logger.error(
                    'message %s disappeared!',
                    form.cleaned_data['checksum']
                )
                messages.error(
                    request,
                    _('Message you wanted to translate is no longer available!')
                )

    # Handle accepting/deleting suggestions
    if not locked and ('accept' in request.GET or 'delete' in request.GET):
        # Check for authenticated users
        if not request.user.is_authenticated():
            messages.error(request, _('You need to log in to be able to manage suggestions!'))
            return HttpResponseRedirect('%s?type=%s&pos=%d&dir=stay%s' % (
                obj.get_translate_url(),
                search_options.rqtype,
                search_options.pos,
                search_options.url
            ))

        # Parse suggestion ID
        if 'accept' in request.GET:
            if not request.user.has_perm('trans.accept_suggestion'):
                messages.error(request, _('You do not have privilege to accept suggestions!'))
                return HttpResponseRedirect('%s?type=%s&pos=%d&dir=stay%s' % (
                    obj.get_translate_url(),
                    search_options.rqtype,
                    search_options.pos,
                    search_options.url
                ))
            sugid = request.GET['accept']
        else:
            if not request.user.has_perm('trans.delete_suggestion'):
                messages.error(request, _('You do not have privilege to delete suggestions!'))
                return HttpResponseRedirect('%s?type=%s&pos=%d&dir=stay%s' % (
                    obj.get_translate_url(),
                    search_options.rqtype,
                    search_options.pos,
                    search_options.url
                ))
            sugid = request.GET['delete']
        try:
            sugid = int(sugid)
            suggestion = Suggestion.objects.get(pk=sugid)
        except:
            suggestion = None

        if suggestion is not None:
            if 'accept' in request.GET:
                # Accept suggesiont
                suggestion.accept(request)
            # Invalidate caches
            for unit in Unit.objects.filter(checksum=suggestion.checksum):
                unit.translation.invalidate_cache('suggestions')
            # Delete suggestion in both cases (accepted ones are no longer
            # needed)
            suggestion.delete()
        else:
            messages.error(request, _('Invalid suggestion!'))

        # Redirect to same entry for possible editing
        return HttpResponseRedirect('%s?type=%s&pos=%d&dir=stay%s' % (
            obj.get_translate_url(),
            search_options.rqtype,
            search_options.pos,
            search_options.url
        ))

    reviewform = ReviewForm(request.GET)

    if reviewform.is_valid():
        allunits = obj.unit_set.review(
            reviewform.cleaned_data['date'],
            request.user
        )
        # Review
        if search_options.direction == 'stay':
            units = allunits.filter(
                position=search_options.pos
            )
        elif search_options.direction == 'back':
            units = allunits.filter(
                position__lt=search_options.pos
            ).order_by('-position')
        else:
            units = allunits.filter(
                position__gt=search_options.pos
            )
    elif search_options.query != '':
        # Apply search conditions
        if search_options.type == 'exact':
            query = Q()
            if search_options.source:
                query |= Q(source=search_options.query)
            if search_options.target:
                query |= Q(target=search_options.query)
            if search_options.context:
                query |= Q(context=search_options.query)
            allunits = obj.unit_set.filter(query)
        elif search_options.type == 'substring':
            query = Q()
            if search_options.source:
                query |= Q(source__icontains=search_options.query)
            if search_options.target:
                query |= Q(target__icontains=search_options.query)
            if search_options.context:
                query |= Q(context__icontains=search_options.query)
            allunits = obj.unit_set.filter(query)
        else:
            allunits = obj.unit_set.search(
                search_options.query,
                search_options.source,
                search_options.context,
                search_options.target
            )
        if search_options.direction == 'stay':
            units = obj.unit_set.filter(
                position=search_options.pos
            )
        elif search_options.direction == 'back':
            units = allunits.filter(
                position__lt=search_options.pos
            ).order_by('-position')
        else:
            units = allunits.filter(
                position__gt=search_options.pos
            )
    elif 'checksum' in request.GET:
        allunits = obj.unit_set.filter(checksum=request.GET['checksum'])
        units = allunits
    else:
        allunits = obj.unit_set.filter_type(search_options.rqtype, obj)
        # What unit set is about to show
        if search_options.direction == 'stay':
            units = obj.unit_set.filter(
                position=search_options.pos
            )
        elif search_options.direction == 'back':
            units = allunits.filter(
                position__lt=search_options.pos
            ).order_by('-position')
        else:
            units = allunits.filter(
                position__gt=search_options.pos
            )

    # If we failed to get unit above or on no POST
    if unit is None:
        # Grab actual unit
        try:
            unit = units[0]
        except IndexError:
            messages.info(request, _('You have reached end of translating.'))
            return HttpResponseRedirect(obj.get_absolute_url())

        # Show secondary languages for logged in users
        if profile:
            secondary_langs = profile.secondary_languages.exclude(
                id=unit.translation.language.id
            )
            project = unit.translation.subproject.project
            secondary = Unit.objects.filter(
                checksum=unit.checksum,
                translated=True,
                translation__subproject__project=project,
                translation__language__in=secondary_langs,
            )
            # distinct('target') works with Django 1.4 so let's emulate that
            # based on presumption we won't get too many results
            targets = {}
            res = []
            for lang in secondary:
                if lang.target in targets:
                    continue
                targets[lang.target] = 1
                res.append(lang)
            secondary = res

        # Prepare form
        form = TranslationForm(initial={
            'checksum': unit.checksum,
            'target': (unit.translation.language, unit.get_target_plurals()),
            'fuzzy': unit.fuzzy,
        })

    total = obj.unit_set.all().count()
    filter_count = allunits.count()

    return render_to_response(
        'translate.html',
        RequestContext(
            request,
            {
                'object': obj,
                'unit': unit,
                'last_changes': unit.change_set.all()[:10],
                'total': total,
                'type': search_options.rqtype,
                'filter_name': get_filter_name(
                    search_options.rqtype, search_options.query
                ),
                'filter_count': filter_count,
                'filter_pos': filter_count + 1 - units.count(),
                'form': form,
                'antispam': antispam,
                'comment_form': CommentForm(),
                'target_language': obj.language.code.replace('_', '-').lower(),
                'update_lock': own_lock,
                'secondary': secondary,
                'search_query': search_options.query,
                'search_url': search_options.url,
                'search_source': bool2str(search_options.source),
                'search_type': search_options.type,
                'search_target': bool2str(search_options.target),
                'search_context': bool2str(search_options.context),
                'locked': locked,
                'user_locked': user_locked,
                'project_locked': project_locked,
            },
        )
    )
Exemple #4
0
def search(translation, request):
    '''
    Performs search or retuns cached search results.
    '''

    # Already performed search
    if 'sid' in request.GET:
        # Grab from session storage
        search_id = 'search_%s' % request.GET['sid']

        # Check if we know the search
        if search_id not in request.session:
            messages.error(request, _('Invalid search string!'))
            return HttpResponseRedirect(translation.get_absolute_url())

        return request.session[search_id]

    # Possible new search
    rqtype = request.GET.get('type', 'all')

    search_form = SearchForm(request.GET)
    review_form = ReviewForm(request.GET)

    if review_form.is_valid():
        # Review
        allunits = translation.unit_set.review(
            review_form.cleaned_data['date'],
            request.user
        )

        formatted_date = formats.date_format(
            review_form.cleaned_data['date'],
            'SHORT_DATE_FORMAT'
        )
        name = _('Review of translations since %s') % formatted_date
    elif search_form.is_valid():
        # Apply search conditions
        allunits = translation.unit_set.search(
            search_form.cleaned_data['search'],
            search_form.cleaned_data['q'],
            search_form.cleaned_data['src'],
            search_form.cleaned_data['ctx'],
            search_form.cleaned_data['tgt'],
        )

        name = get_search_name(
            search_form.cleaned_data['search'],
            search_form.cleaned_data['q'],
        )
    else:
        # Filtering by type
        allunits = translation.unit_set.filter_type(rqtype, translation)

        name = get_filter_name(rqtype)

    # Grab unit IDs
    unit_ids = list(allunits.values_list('id', flat=True))

    # Check empty search results
    if len(unit_ids) == 0:
        messages.warning(request, _('No string matched your search!'))
        return HttpResponseRedirect(translation.get_absolute_url())

    # Checksum unit access
    offset = 0
    if 'checksum' in request.GET:
        try:
            unit = allunits.filter(checksum=request.GET['checksum'])[0]
            offset = unit_ids.index(unit.id)
        except (Unit.DoesNotExist, IndexError):
            messages.warning(request, _('No string matched your search!'))
            return HttpResponseRedirect(translation.get_absolute_url())

    # Remove old search results
    cleanup_session(request.session)

    # Store in cache and return
    search_id = str(uuid.uuid1())
    search_result = {
        'name': name,
        'ids': unit_ids,
        'search_id': search_id,
        'ttl': int(time.time()) + 86400,
        'offset': offset,
    }

    request.session['search_%s' % search_id] = search_result

    return search_result
Exemple #5
0
def search(translation, request):
    """
    Performs search or returns cached search results.
    """

    # Already performed search
    if "sid" in request.GET:
        # Grab from session storage
        search_id = "search_%s" % request.GET["sid"]

        # Check if we know the search
        if search_id not in request.session:
            messages.error(request, _("Invalid search string!"))
            return HttpResponseRedirect(translation.get_absolute_url())

        return request.session[search_id]

    # Possible new search
    rqtype = request.GET.get("type", "all")

    search_form = SearchForm(request.GET)
    review_form = ReviewForm(request.GET)

    search_query = None
    if review_form.is_valid():
        # Review
        allunits = translation.unit_set.review(review_form.cleaned_data["date"], request.user)

        formatted_date = formats.date_format(review_form.cleaned_data["date"], "SHORT_DATE_FORMAT")
        name = _("Review of translations since %s") % formatted_date
    elif search_form.is_valid():
        # Apply search conditions
        allunits = translation.unit_set.search(
            search_form.cleaned_data["search"],
            search_form.cleaned_data["q"],
            search_form.cleaned_data["src"],
            search_form.cleaned_data["ctx"],
            search_form.cleaned_data["tgt"],
        )

        search_query = search_form.cleaned_data["q"]
        name = get_search_name(search_form.cleaned_data["search"], search_query)
    else:
        # Filtering by type
        allunits = translation.unit_set.filter_type(rqtype, translation, ignored="ignored" in request.GET)

        name = get_filter_name(rqtype)

    # Grab unit IDs
    unit_ids = list(allunits.values_list("id", flat=True))

    # Check empty search results
    if len(unit_ids) == 0:
        messages.warning(request, _("No string matched your search!"))
        return HttpResponseRedirect(translation.get_absolute_url())

    # Checksum unit access
    offset = 0
    if "checksum" in request.GET:
        try:
            unit = allunits.filter(checksum=request.GET["checksum"])[0]
            offset = unit_ids.index(unit.id)
        except (Unit.DoesNotExist, IndexError):
            messages.warning(request, _("No string matched your search!"))
            return HttpResponseRedirect(translation.get_absolute_url())

    # Remove old search results
    cleanup_session(request.session)

    # Store in cache and return
    search_id = str(uuid.uuid1())
    search_result = {
        "query": search_query,
        "name": name,
        "ids": unit_ids,
        "search_id": search_id,
        "ttl": int(time.time()) + 86400,
        "offset": offset,
    }

    request.session["search_%s" % search_id] = search_result

    return search_result