def translate()

in kitsune/wiki/views.py [0:0]


def translate(request, document_slug, revision_id=None):
    """Create a new translation of a wiki document.

    * document_slug is for the default locale
    * translation is to the request.LANGUAGE_CODE

    """

    # Inialization and checks
    user = request.user
    parent_doc = get_visible_document_or_404(
        user, locale=settings.WIKI_DEFAULT_LANGUAGE, slug=document_slug
    )

    if settings.WIKI_DEFAULT_LANGUAGE == request.LANGUAGE_CODE:
        # Don't translate to the default language.
        return HttpResponseRedirect(
            reverse(
                "wiki.edit_document", locale=settings.WIKI_DEFAULT_LANGUAGE, args=[parent_doc.slug]
            )
        )

    if not parent_doc.is_localizable:
        message = _lazy("You cannot translate this document.")
        return render(request, "handlers/400.html", {"message": message}, status=400)

    based_on_rev = parent_doc.localizable_or_latest_revision(include_rejected=True)

    disclose_description = bool(request.GET.get("opendescription"))

    try:
        doc = parent_doc.translations.get(locale=request.LANGUAGE_CODE)
    except Document.DoesNotExist:
        doc = None
        disclose_description = True
    else:
        if not doc.is_visible_for(user):
            # A translation has been started, but isn't approved yet for
            # public visibility, and this user doesn't have permission
            # to see/work on it.
            raise PermissionDenied

    user_has_doc_perm = not doc or doc.allows(user, "edit")
    user_has_rev_perm = not doc or doc.allows(user, "create_revision")

    if not user_has_doc_perm and not user_has_rev_perm:
        # User has no perms, bye.
        raise PermissionDenied

    # Check if the user has draft revision saved for the parent document with requeted locale
    draft = DraftRevision.objects.filter(
        creator=user, document=parent_doc, locale=request.LANGUAGE_CODE
    ).first()

    base_rev = doc_form = rev_form = None

    if user_has_doc_perm:
        # Restore draft if draft is available and user requested to restore
        doc_initial = _document_form_initial(doc) if doc else {}
        doc_form = DocumentForm(initial=doc_initial)

    if user_has_rev_perm:
        rev_initial = {"based_on": based_on_rev.id, "comment": ""}

        if revision_id:
            base_rev = Revision.objects.get(pk=revision_id)
            rev_initial.update(
                content=base_rev.content, summary=base_rev.summary, keywords=base_rev.keywords
            )
        elif not doc:
            rev_initial.update(
                content=based_on_rev.content,
                summary=based_on_rev.summary,
                keywords=based_on_rev.keywords,
            )

        # Get a revision of the translation to plonk into the page as a
        # starting point. Since translations are never "ready for
        # localization", this will first try to find an approved revision, then
        # an unrejected one, then give up.
        instance = doc and doc.localizable_or_latest_revision()

        rev_form = RevisionForm(instance=instance, initial=rev_initial)
        base_rev = base_rev or instance

    if request.method == "POST":
        # Use POST for restoring and deleting drafts to avoid CSRF
        restore_draft = "restore" in request.POST and bool(draft)
        discard_draft = "discard" in request.POST and bool(draft)
        # Make sure that one of the two is True but not both
        if discard_draft ^ restore_draft:
            if discard_draft:
                draft.delete()
                return HttpResponseRedirect(
                    urlparams(reverse("wiki.translate", args=[document_slug]))
                )

            # If we are here - we have a draft to restore
            if user_has_doc_perm:
                doc_initial.update({"title": draft.title, "slug": draft.slug})
                doc_form = DocumentForm(initial=doc_initial)
            if user_has_rev_perm:
                rev_initial.update(
                    {
                        "content": draft.content,
                        "summary": draft.summary,
                        "keywords": draft.keywords,
                        "based_on": draft.based_on.id,
                    }
                )
                based_on_rev = draft.based_on
                rev_form = RevisionForm(instance=instance, initial=rev_initial)
        else:
            which_form = request.POST.get("form", "both")
            doc_form_invalid = False

            if doc:
                _document_lock_clear(doc.id, user.username)

            if user_has_doc_perm and which_form in ["doc", "both"]:
                disclose_description = True
                post_data = request.POST.copy()
                post_data.update({"locale": request.LANGUAGE_CODE})
                doc_form = DocumentForm(post_data, instance=doc)
                doc_form.instance.locale = request.LANGUAGE_CODE
                doc_form.instance.parent = parent_doc
                if which_form == "both":
                    rev_form = RevisionForm(request.POST)

                # If we are submitting the whole form, we need to check that
                # the Revision is valid before saving the Document.
                if doc_form.is_valid() and (which_form == "doc" or rev_form.is_valid()):
                    doc = doc_form.save(parent_doc)

                    # Possibly schedule a rebuild.
                    _maybe_schedule_rebuild(doc_form)

                    if which_form == "doc":
                        url = urlparams(
                            reverse("wiki.edit_document", args=[doc.slug]), opendescription=1
                        )
                        return HttpResponseRedirect(url)

                    doc_slug = doc_form.cleaned_data["slug"]
                else:
                    doc_form_invalid = True
            else:
                doc_slug = doc.slug

            if doc and user_has_rev_perm and which_form in ["rev", "both"]:
                rev_form = RevisionForm(request.POST)
                rev_form.instance.document = doc  # for rev_form.clean()

                if rev_form.is_valid() and not doc_form_invalid:
                    if "no-update" in request.POST:
                        # Keep the old based_on.
                        based_on_id = base_rev.based_on_id
                    else:
                        # Keep what was in the form.
                        based_on_id = None
                    if draft:
                        draft.delete()
                    _save_rev_and_notify(
                        rev_form, request.user, doc, based_on_id, base_rev=base_rev
                    )

                    if "notify-future-changes" in request.POST:
                        EditDocumentEvent.notify(request.user, doc)

                    return HttpResponseRedirect(
                        reverse("wiki.document_revisions", args=[doc_slug])
                    )

    show_revision_warning = _show_revision_warning(doc, base_rev)

    # A list of the revisions that have been approved since the last
    # translation.
    recent_approved_revs = parent_doc.revisions.filter(is_approved=True, id__lte=based_on_rev.id)
    if doc and doc.current_revision and doc.current_revision.based_on_id:
        recent_approved_revs = recent_approved_revs.filter(id__gt=doc.current_revision.based_on_id)

    if doc:
        locked, locked_by = _document_lock(doc.id, user.username)
        # Most updated rev according to based on revision
        more_updated_rev = (
            doc.revisions.filter(based_on__id__gt=based_on_rev.id).order_by("based_on__id").last()
        )
    else:
        locked, locked_by = False, None
        more_updated_rev = None

    return render(
        request,
        "wiki/translate.html",
        {
            "parent": parent_doc,
            "document": doc,
            "document_form": doc_form,
            "revision_form": rev_form,
            "locale": request.LANGUAGE_CODE,
            "based_on": based_on_rev,
            "disclose_description": disclose_description,
            "show_revision_warning": show_revision_warning,
            "recent_approved_revs": recent_approved_revs,
            "locked": locked,
            "locked_by": locked_by,
            "draft_revision": draft,
            "more_updated_rev": more_updated_rev,
        },
    )