Example #1
0
def show_component(request, project, component):
    obj = get_component(request, project, component)
    user = request.user

    last_changes = Change.objects.prefetch().order().filter(component=obj)[:10]

    translations = prefetch_stats(list(obj.translation_set.prefetch()))

    # Show ghost translations for user languages
    add_ghost_translations(obj, user, translations, GhostTranslation)

    translations = sort_unicode(
        translations,
        lambda x: "{}-{}".format(user.profile.get_language_order(x.language), x
                                 .language),
    )

    return render(
        request,
        "component.html",
        {
            "allow_index":
            True,
            "object":
            obj,
            "project":
            obj.project,
            "translations":
            translations,
            "reports_form":
            ReportsForm(),
            "last_changes":
            last_changes,
            "last_changes_url":
            urlencode({
                "component": obj.slug,
                "project": obj.project.slug
            }),
            "replace_form":
            optional_form(ReplaceForm, user, "unit.edit", obj),
            "bulk_state_form":
            optional_form(
                BulkEditForm,
                user,
                "translation.auto",
                obj,
                user=user,
                obj=obj,
                project=obj.project,
                auto_id="id_bulk_%s",
            ),
            "announcement_form":
            optional_form(AnnouncementForm, user, "component.edit", obj),
            "delete_form":
            optional_form(
                ComponentDeleteForm, user, "component.edit", obj, obj=obj),
            "rename_form":
            optional_form(
                ComponentRenameForm,
                user,
                "component.edit",
                obj,
                request=request,
                instance=obj,
            ),
            "move_form":
            optional_form(
                ComponentMoveForm,
                user,
                "component.edit",
                obj,
                request=request,
                instance=obj,
            ),
            "search_form":
            SearchForm(request.user),
            "alerts":
            obj.all_alerts,
        },
    )
Example #2
0
def show_translation(request, project, component, lang):
    obj = get_translation(request, project, component, lang)
    obj.stats.ensure_all()
    last_changes = Change.objects.prefetch().order().filter(
        translation=obj)[:10]
    user = request.user

    # Get form
    form = get_upload_form(user, obj)

    search_form = SearchForm(request.user)

    other_translations = prefetch_stats(
        list(Translation.objects.prefetch().filter(
            component__project=obj.component.project,
            language=obj.language).exclude(pk=obj.pk)))

    # Include ghost translations for other components
    existing = {
        translation.component.slug
        for translation in other_translations
    }
    existing.add(obj.component.slug)
    for component in obj.component.project.component_set.exclude(
            slug__in=existing):
        if component.can_add_new_language(user):
            other_translations.append(GhostTranslation(component,
                                                       obj.language))

    return render(
        request,
        "translation.html",
        {
            "allow_index":
            True,
            "object":
            obj,
            "project":
            obj.component.project,
            "form":
            form,
            "download_form":
            DownloadForm(auto_id="id_dl_%s"),
            "autoform":
            optional_form(
                AutoForm, user, "translation.auto", obj, obj=obj.component),
            "search_form":
            search_form,
            "replace_form":
            optional_form(ReplaceForm, user, "unit.edit", obj),
            "bulk_state_form":
            optional_form(
                BulkEditForm,
                user,
                "translation.auto",
                obj,
                user=user,
                obj=obj,
                project=obj.component.project,
                auto_id="id_bulk_%s",
            ),
            "new_unit_form":
            NewUnitForm(user,
                        initial={"value": Unit(translation=obj, id_hash=-1)}),
            "announcement_form":
            optional_form(AnnouncementForm, user, "component.edit", obj),
            "delete_form":
            optional_form(TranslationDeleteForm,
                          user,
                          "translation.delete",
                          obj,
                          obj=obj),
            "last_changes":
            last_changes,
            "last_changes_url":
            urlencode(obj.get_reverse_url_kwargs()),
            "other_translations":
            other_translations,
            "exporters":
            list_exporters(obj),
        },
    )
Example #3
0
def search(request, project=None, component=None, lang=None):
    """Perform site-wide search on units."""
    is_ratelimited = not check_rate_limit("search", request)
    search_form = SearchForm(user=request.user, data=request.GET)
    sort = get_sort_name(request)
    context = {"search_form": search_form}
    if component:
        obj = get_component(request, project, component)
        context["component"] = obj
        context["project"] = obj.project
        context["back_url"] = obj.get_absolute_url()
    elif project:
        obj = get_project(request, project)
        context["project"] = obj
        context["back_url"] = obj.get_absolute_url()
    else:
        obj = None
        context["back_url"] = None
    if lang:
        s_language = get_object_or_404(Language, code=lang)
        context["language"] = s_language
        if obj:
            if component:
                context["back_url"] = obj.translation_set.get(
                    language=s_language).get_absolute_url()
            else:
                context["back_url"] = reverse("project-language",
                                              kwargs={
                                                  "project": project,
                                                  "lang": lang
                                              })
        else:
            context["back_url"] = s_language.get_absolute_url()

    if not is_ratelimited and request.GET and search_form.is_valid():
        # This is ugly way to hide query builder when showing results
        search_form = SearchForm(user=request.user,
                                 data=request.GET,
                                 show_builder=False)
        search_form.is_valid()
        # Filter results by ACL
        units = Unit.objects.prefetch_full().prefetch()
        if component:
            units = units.filter(translation__component=obj)
        elif project:
            units = units.filter(translation__component__project=obj)
        else:
            units = units.filter_access(request.user)
        units = units.search(search_form.cleaned_data.get("q", "")).distinct()
        if lang:
            units = units.filter(translation__language=context["language"])

        units = get_paginator(request,
                              units.order_by_request(search_form.cleaned_data))
        # Rebuild context from scratch here to get new form
        context = {
            "search_form": search_form,
            "show_results": True,
            "page_obj": units,
            "title": _("Search for %s") % (search_form.cleaned_data["q"]),
            "query_string": search_form.urlencode(),
            "search_query": search_form.cleaned_data["q"],
            "search_items": search_form.items(),
            "filter_name": search_form.get_name(),
            "sort_name": sort["name"],
            "sort_query": sort["query"],
        }
    elif is_ratelimited:
        messages.error(request,
                       _("Too many search queries, please try again later."))
    elif request.GET:
        messages.error(request, _("Invalid search query!"))
        show_form_errors(request, search_form)

    return render(request, "search.html", context)
Example #4
0
def show_project(request, project):
    obj = get_project(request, project)
    user = request.user

    last_changes = Change.objects.prefetch().order().filter(project=obj)[:10]
    last_announcements = (Change.objects.prefetch().order().filter(
        project=obj, action=Change.ACTION_ANNOUNCEMENT)[:10])

    language_stats = obj.stats.get_language_stats()
    # Show ghost translations for user languages
    component = None
    for component in obj.component_set.all():
        if component.can_add_new_language(user):
            break
    if component:
        add_ghost_translations(component, user, language_stats,
                               GhostProjectLanguageStats)

    language_stats = sort_unicode(
        language_stats,
        lambda x: "{}-{}".format(user.profile.get_language_order(x.language), x
                                 .language),
    )

    # Paginate components of project.
    all_components = obj.component_set.prefetch().order()
    components = prefetch_stats(get_paginator(request, all_components))

    return render(
        request,
        "project.html",
        {
            "allow_index":
            True,
            "object":
            obj,
            "project":
            obj,
            "last_changes":
            last_changes,
            "last_announcements":
            last_announcements,
            "reports_form":
            ReportsForm(),
            "last_changes_url":
            urlencode({"project": obj.slug}),
            "language_stats":
            language_stats,
            "search_form":
            SearchForm(request.user),
            "announcement_form":
            optional_form(AnnouncementForm, user, "project.edit", obj),
            "delete_form":
            optional_form(
                ProjectDeleteForm, user, "project.edit", obj, obj=obj),
            "rename_form":
            optional_form(
                ProjectRenameForm,
                user,
                "project.edit",
                obj,
                request=request,
                instance=obj,
            ),
            "replace_form":
            optional_form(ReplaceForm, user, "unit.edit", obj),
            "bulk_state_form":
            optional_form(
                BulkEditForm,
                user,
                "translation.auto",
                obj,
                user=user,
                obj=obj,
                project=obj,
                auto_id="id_bulk_%s",
            ),
            "components":
            components,
            "licenses":
            obj.component_set.exclude(license="").order_by("license"),
        },
    )
Example #5
0
def show_translation(request, project, component, lang):
    obj = get_translation(request, project, component, lang)
    component = obj.component
    project = component.project
    obj.stats.ensure_all()
    last_changes = obj.change_set.prefetch().order()[:10]
    user = request.user

    # Get form
    form = get_upload_form(user, obj)

    search_form = SearchForm(request.user, language=obj.language)

    # Translations to same language from other components in this project
    other_translations = prefetch_stats(
        list(Translation.objects.prefetch().filter(
            component__project=project,
            language=obj.language).exclude(pk=obj.pk)))

    # Include ghost translations for other components, this
    # adds quick way to create translations in other components
    existing = {
        translation.component.slug
        for translation in other_translations
    }
    existing.add(component.slug)
    for test_component in project.child_components.filter_access(user).exclude(
            slug__in=existing):
        if test_component.can_add_new_language(user, fast=True):
            other_translations.append(
                GhostTranslation(test_component, obj.language))

    # Limit the number of other components displayed to 10, preferring untranslated ones
    other_translations = sorted(other_translations,
                                key=lambda t: t.stats.translated_percent)[:10]

    return render(
        request,
        "translation.html",
        {
            "allow_index":
            True,
            "object":
            obj,
            "project":
            project,
            "form":
            form,
            "download_form":
            DownloadForm(auto_id="id_dl_%s"),
            "autoform":
            optional_form(
                AutoForm, user, "translation.auto", obj, obj=component),
            "search_form":
            search_form,
            "replace_form":
            optional_form(ReplaceForm, user, "unit.edit", obj),
            "bulk_state_form":
            optional_form(
                BulkEditForm,
                user,
                "translation.auto",
                obj,
                user=user,
                obj=obj,
                project=project,
                auto_id="id_bulk_%s",
            ),
            "new_unit_form":
            get_new_unit_form(obj, user),
            "announcement_form":
            optional_form(AnnouncementForm, user, "component.edit", obj),
            "delete_form":
            optional_form(TranslationDeleteForm,
                          user,
                          "translation.delete",
                          obj,
                          obj=obj),
            "last_changes":
            last_changes,
            "last_changes_url":
            urlencode(obj.get_reverse_url_kwargs()),
            "other_translations":
            other_translations,
            "exporters":
            EXPORTERS.list_exporters(obj),
        },
    )
Example #6
0
def show_translation(request, project, component, lang):
    obj = get_translation(request, project, component, lang)
    obj.stats.ensure_all()
    last_changes = Change.objects.for_translation(obj)[:10]

    # Get form
    form = get_upload_form(request.user, obj)

    # Is user allowed to do automatic translation?
    if request.user.has_perm('translation.auto', obj):
        mass_state_form = MassStateForm(request.user, obj)
    else:
        mass_state_form = None

    # Is user allowed to do automatic translation?
    if request.user.has_perm('translation.auto', obj):
        autoform = AutoForm(obj, request.user)
    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={'exclude_user': request.user.username})

    if request.user.has_perm('unit.edit', obj):
        replace_form = ReplaceForm()
    else:
        replace_form = None

    return render(
        request, 'translation.html', {
            'allow_index':
            True,
            'object':
            obj,
            'project':
            obj.component.project,
            'form':
            form,
            'download_form':
            DownloadForm(),
            'autoform':
            autoform,
            'search_form':
            search_form,
            'review_form':
            review_form,
            'replace_form':
            replace_form,
            'mass_state_form':
            mass_state_form,
            'new_unit_form':
            NewUnitForm(
                request.user,
                initial={
                    'value': Unit(translation=obj, id_hash=-1),
                },
            ),
            'last_changes':
            last_changes,
            'last_changes_url':
            urlencode(obj.get_reverse_url_kwargs()),
            'show_only_component':
            True,
            'other_translations':
            prefetch_stats(Translation.objects.prefetch().filter(
                component__project=obj.component.project,
                language=obj.language,
            ).exclude(pk=obj.pk)),
            'exporters':
            list_exporters(),
        })
Example #7
0
def show_project(request, project):
    obj = get_project(request, project)
    obj.stats.ensure_basic()
    user = request.user

    last_changes = obj.change_set.prefetch().order()[:10]
    last_announcements = (Change.objects.prefetch().order().filter(
        project=obj, action=Change.ACTION_ANNOUNCEMENT)[:10])

    all_components = obj.child_components.filter_access(
        user).prefetch().order()
    for component in all_components:
        component.is_shared = None if component.project == obj else component.project

    language_stats = obj.stats.get_language_stats()
    # Show ghost translations for user languages
    component = None
    for component in all_components:
        if component.can_add_new_language(user, fast=True):
            break
    if component:
        add_ghost_translations(
            component,
            user,
            language_stats,
            GhostProjectLanguageStats,
            is_shared=component.is_shared,
        )

    language_stats = sort_unicode(
        language_stats,
        lambda x: "{}-{}".format(user.profile.get_language_order(x.language), x
                                 .language),
    )

    components = prefetch_tasks(prefetch_stats(all_components))

    return render(
        request,
        "project.html",
        {
            "allow_index":
            True,
            "object":
            obj,
            "project":
            obj,
            "last_changes":
            last_changes,
            "last_announcements":
            last_announcements,
            "reports_form":
            ReportsForm(),
            "last_changes_url":
            urlencode({"project": obj.slug}),
            "language_stats": [stat.obj or stat for stat in language_stats],
            "search_form":
            SearchForm(request.user),
            "announcement_form":
            optional_form(AnnouncementForm, user, "project.edit", obj),
            "delete_form":
            optional_form(
                ProjectDeleteForm, user, "project.edit", obj, obj=obj),
            "rename_form":
            optional_form(
                ProjectRenameForm,
                user,
                "project.edit",
                obj,
                request=request,
                instance=obj,
            ),
            "replace_form":
            optional_form(ReplaceForm, user, "unit.edit", obj),
            "bulk_state_form":
            optional_form(
                BulkEditForm,
                user,
                "translation.auto",
                obj,
                user=user,
                obj=obj,
                project=obj,
                auto_id="id_bulk_%s",
            ),
            "components":
            components,
            "licenses":
            sorted(
                (component
                 for component in all_components if component.license),
                key=lambda component: component.license,
            ),
        },
    )
Example #8
0
def search(request, project=None, component=None, lang=None):
    """Perform site-wide search on units."""
    is_ratelimited = not check_rate_limit("search", request)
    search_form = SearchForm(request.user, request.GET)
    sort = get_sort_name(request)
    context = {"search_form": search_form}
    if component:
        obj = get_component(request, project, component)
        context["component"] = obj
        context["project"] = obj.project
        context["back_url"] = obj.get_absolute_url()
    elif project:
        obj = get_project(request, project)
        context["project"] = obj
        context["back_url"] = obj.get_absolute_url()
    else:
        obj = None
        context["back_url"] = None
    if lang:
        s_language = get_object_or_404(Language, code=lang)
        context["language"] = s_language
        if obj:
            if component:
                context["back_url"] = obj.translation_set.get(
                    language=s_language).get_absolute_url()
            else:
                context["back_url"] = reverse("project-language",
                                              kwargs={
                                                  "project": project,
                                                  "lang": lang
                                              })
        else:
            context["back_url"] = s_language.get_absolute_url()

    if not is_ratelimited and request.GET and search_form.is_valid():
        # Filter results by ACL
        if component:
            units = Unit.objects.filter(translation__component=obj)
        elif project:
            units = Unit.objects.filter(translation__component__project=obj)
        else:
            units = Unit.objects.filter(
                translation__component__project_id__in=request.user.
                allowed_project_ids)
        units = units.search(search_form.cleaned_data.get("q", "")).distinct()
        if lang:
            units = units.filter(translation__language=context["language"])

        units = get_paginator(request,
                              units.order_by_request(search_form.cleaned_data))

        context["show_results"] = True
        context["page_obj"] = units
        context["title"] = _("Search for %s") % (search_form.cleaned_data["q"])
        context["query_string"] = search_form.urlencode()
        context["search_query"] = search_form.cleaned_data["q"]
        context["search_items"] = search_form.items()
        context["filter_name"] = search_form.get_name()
        context["sort_name"] = sort["name"]
        context["sort_query"] = sort["query"]
    elif is_ratelimited:
        messages.error(request,
                       _("Too many search queries, please try again later."))
    elif request.GET:
        messages.error(request, _("Invalid search query!"))
        show_form_errors(request, search_form)

    return render(request, "search.html", context)
Example #9
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 redirect(translation)

        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_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 redirect(translation)

    # 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 redirect(translation)

    # 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
Example #10
0
def translate(request, project, subproject, lang):
    '''
    Generic entry point for translating, suggesting and searching.
    '''
    translation = get_translation(request, project, subproject, lang)

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

    # Search results
    search_result = search(translation, request)

    # Handle redirects
    if isinstance(search_result, HttpResponse):
        return search_result

    # Get numer of results
    num_results = len(search_result['ids'])

    # Search offset
    try:
        offset = int(request.GET.get('offset', search_result.get('offset', 0)))
    except ValueError:
        offset = 0

    # Check boundaries
    if offset < 0 or offset >= num_results:
        messages.info(request, _('You have reached end of translating.'))
        # Delete search
        del request.session['search_%s' % search_result['search_id']]
        # Redirect to translation
        return redirect(translation)

    # Some URLs we will most likely use
    base_unit_url = '%s?sid=%s&offset=' % (
        translation.get_translate_url(),
        search_result['search_id'],
    )
    this_unit_url = base_unit_url + str(offset)
    next_unit_url = base_unit_url + str(offset + 1)

    response = None

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

        # Handle accepting/deleting suggestions
        if ('accept' not in request.POST
                and 'delete' not in request.POST
                and 'upvote' not in request.POST
                and 'downvote' not in request.POST):
            response = handle_translate(
                translation, request, user_locked,
                this_unit_url, next_unit_url
            )
        elif not locked:
            response = handle_suggestions(
                translation, request, this_unit_url
            )

    # Handle translation merging
    elif 'merge' in request.GET and not locked:
        response = handle_merge(
            translation, request, next_unit_url
        )

    # Handle reverting
    elif 'revert' in request.GET and not locked:
        response = handle_revert(
            translation, request, this_unit_url
        )

    # Pass possible redirect further
    if response is not None:
        return response

    # Grab actual unit
    try:
        unit = translation.unit_set.get(pk=search_result['ids'][offset])
    except Unit.DoesNotExist:
        # Can happen when using SID for other translation
        messages.error(request, _('Invalid search string!'))
        return redirect(translation)

    # Show secondary languages for logged in users
    if request.user.is_authenticated():
        secondary = request.user.profile.get_secondary_units(unit)
    else:
        secondary = None

    # Spam protection
    antispam = AntispamForm()

    # Prepare form
    form = TranslationForm(translation, unit)

    return render_to_response(
        'translate.html',
        RequestContext(
            request,
            {
                'this_unit_url': this_unit_url,
                'first_unit_url': base_unit_url + '0',
                'last_unit_url': base_unit_url + str(num_results - 1),
                'next_unit_url': next_unit_url,
                'prev_unit_url': base_unit_url + str(offset - 1),
                'object': translation,
                'unit': unit,
                'total': translation.unit_set.all().count(),
                'search_id': search_result['search_id'],
                'search_query': search_result['query'],
                'offset': offset,
                'filter_name': search_result['name'],
                'filter_count': num_results,
                'filter_pos': offset + 1,
                'form': form,
                'antispam': antispam,
                'comment_form': CommentForm(),
                'search_form': SearchForm(),
                'update_lock': own_lock,
                'secondary': secondary,
                'locked': locked,
                'user_locked': user_locked,
                'project_locked': project_locked,
            },
        )
    )
Example #11
0
def show_translation(request, project, subproject, lang):
    obj = get_translation(request, project, subproject, lang)
    obj.stats.ensure_all()
    last_changes = Change.objects.for_translation(obj)[:10]

    # Get form
    form = get_upload_form(request.user, obj)

    # Is user allowed to do automatic translation?
    if can_automatic_translation(request.user, obj.subproject.project):
        autoform = AutoForm(obj, request.user)
    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={'exclude_user': request.user.username})

    if can_translate(request.user, translation=obj):
        replace_form = ReplaceForm()
        mass_state_form = MassStateForm(request.user, obj)
    else:
        replace_form = None
        mass_state_form = None

    return render(
        request, 'translation.html', {
            'allow_index':
            True,
            'object':
            obj,
            'project':
            obj.subproject.project,
            'form':
            form,
            'autoform':
            autoform,
            'search_form':
            search_form,
            'review_form':
            review_form,
            'replace_form':
            replace_form,
            'mass_state_form':
            mass_state_form,
            'new_unit_form':
            NewUnitForm(
                request.user,
                initial={
                    'value': Unit(translation=obj, id_hash=-1),
                },
            ),
            'last_changes':
            last_changes,
            'last_changes_url':
            urlencode(obj.get_kwargs()),
            'show_only_component':
            True,
            'pending_fulltext':
            obj.unit_set.filter(id__in=IndexUpdate.objects.filter(
                to_delete=False).values('unitid')).exists(),
            'other_translations':
            prefetch_stats(Translation.objects.prefetch().filter(
                subproject__project=obj.subproject.project,
                language=obj.language,
            ).exclude(pk=obj.pk)),
        })