Esempio n. 1
0
def compare(request, document_slug, document_locale):
    """
    Compare two wiki document revisions.

    The ids are passed as query string parameters (to and from).
    """
    locale = request.GET.get('locale', document_locale)
    if 'from' not in request.GET or 'to' not in request.GET:
        raise Http404

    doc = get_object_or_404(Document, locale=locale, slug=document_slug)

    from_id = smart_int(request.GET.get('from'))
    to_id = smart_int(request.GET.get('to'))

    revisions = Revision.objects.prefetch_related('document')
    revision_from = get_object_or_404(revisions, id=from_id, document=doc)
    revision_to = get_object_or_404(revisions, id=to_id, document=doc)

    context = {
        'document': doc,
        'revision_from': revision_from,
        'revision_to': revision_to,
    }

    if request.GET.get('raw', False):
        template = 'wiki/includes/revision_diff_table.html'
    else:
        template = 'wiki/compare_revisions.html'

    return render(request, template, context)
Esempio n. 2
0
def compare(request, document_slug, document_locale):
    """
    Compare two wiki document revisions.

    The ids are passed as query string parameters (to and from).
    """
    locale = request.GET.get('locale', document_locale)
    if 'from' not in request.GET or 'to' not in request.GET:
        raise Http404

    doc = get_object_or_404(Document,
                            locale=locale,
                            slug=document_slug)

    from_id = smart_int(request.GET.get('from'))
    to_id = smart_int(request.GET.get('to'))

    revisions = Revision.objects.prefetch_related('document')
    revision_from = get_object_or_404(revisions, id=from_id, document=doc)
    revision_to = get_object_or_404(revisions, id=to_id, document=doc)

    context = {
        'document': doc,
        'revision_from': revision_from,
        'revision_to': revision_to,
    }

    if request.GET.get('raw', False):
        template = 'wiki/includes/revision_diff_table.html'
    else:
        template = 'wiki/compare_revisions.html'

    return render(request, template, context)
Esempio n. 3
0
def compare(request, document_slug, document_locale):
    """
    Compare two wiki document revisions.

    The ids are passed as query string parameters (to and from).
    """
    locale = request.GET.get("locale", document_locale)
    if "from" not in request.GET or "to" not in request.GET:
        raise Http404

    doc = get_object_or_404(Document, locale=locale, slug=document_slug)

    from_id = smart_int(request.GET.get("from"))
    to_id = smart_int(request.GET.get("to"))

    revisions = Revision.objects.prefetch_related("document")
    # It should also be possible to compare from the parent document revision
    try:
        revision_from = revisions.get(id=from_id, document=doc)
    except Revision.DoesNotExist:
        revision_from = get_object_or_404(revisions,
                                          id=from_id,
                                          document=doc.parent)

    revision_to = get_object_or_404(revisions, id=to_id, document=doc)

    context = {
        "document": doc,
        "revision_from": revision_from,
        "revision_to": revision_to,
    }

    if request.GET.get("raw", False):
        template = "wiki/includes/revision_diff_table.html"
    else:
        template = "wiki/compare_revisions.html"

    return render(request, template, context)
Esempio n. 4
0
def test_smart_int():
    # Sanity check
    assert 10 == smart_int("10")
    assert 10 == smart_int("10.5")

    # Test int
    assert 10 == smart_int(10)

    # Invalid string
    assert 0 == smart_int("invalid")

    # Empty string
    assert 0 == smart_int("")

    # Wrong type
    assert 0 == smart_int(None)
    assert 10 == smart_int([], 10)
Esempio n. 5
0
def test_smart_int():
    # Sanity check
    assert 10 == smart_int('10')
    assert 10 == smart_int('10.5')

    # Test int
    assert 10 == smart_int(10)

    # Invalid string
    assert 0 == smart_int('invalid')

    # Empty string
    assert 0 == smart_int('')

    # Wrong type
    assert 0 == smart_int(None)
    assert 10 == smart_int([], 10)
Esempio n. 6
0
def translate(request, document_slug, document_locale):
    """
    Create a new translation of a wiki document.

    * document_slug is for the default locale
    * translation is to the request locale
    """
    # TODO: Refactor this view into two views? (new, edit)
    # That might help reduce the headache-inducing branchiness.

    # The parent document to translate from
    parent_doc = get_object_or_404(Document,
                                   locale=settings.WIKI_DEFAULT_LANGUAGE,
                                   slug=document_slug)

    # HACK: Seems weird, but sticking the translate-to locale in a query
    # param is the best way to avoid the MindTouch-legacy locale
    # redirection logic.
    document_locale = request.GET.get('tolocale', document_locale)

    # Set a "Discard Changes" page
    discard_href = ''

    if settings.WIKI_DEFAULT_LANGUAGE == document_locale:
        # Don't translate to the default language.
        return redirect(
            reverse('wiki.edit',
                    locale=settings.WIKI_DEFAULT_LANGUAGE,
                    args=[parent_doc.slug]))

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

    based_on_rev = parent_doc.current_or_latest_revision()

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

    try:
        doc = parent_doc.translations.get(locale=document_locale)
        slug_dict = split_slug(doc.slug)
    except Document.DoesNotExist:
        doc = None
        disclose_description = True
        slug_dict = split_slug(document_slug)

        # Find the "real" parent topic, which is its translation
        if parent_doc.parent_topic:
            try:
                parent_topic_translated_doc = (
                    parent_doc.parent_topic.translations.get(
                        locale=document_locale))
                slug_dict = split_slug(parent_topic_translated_doc.slug + '/' +
                                       slug_dict['specific'])
            except ObjectDoesNotExist:
                pass

    user_has_doc_perm = (not doc) or (doc
                                      and doc.allows_editing_by(request.user))

    doc_form = None
    if user_has_doc_perm:
        if doc:
            # If there's an existing doc, populate form from it.
            discard_href = doc.get_absolute_url()
            doc.slug = slug_dict['specific']
            doc_initial = document_form_initial(doc)
        else:
            # If no existing doc, bring over the original title and slug.
            discard_href = parent_doc.get_absolute_url()
            doc_initial = {
                'title': based_on_rev.title,
                'slug': slug_dict['specific']
            }
        doc_form = DocumentForm(initial=doc_initial,
                                parent_slug=slug_dict['parent'])

    initial = {
        'based_on': based_on_rev.id,
        'current_rev': doc.current_or_latest_revision().id if doc else None,
        'comment': '',
        'toc_depth': based_on_rev.toc_depth,
        'localization_tags': ['inprogress'],
    }
    content = None
    if not doc:
        content = based_on_rev.content
    if content:
        # TODO: There will be no need to "filterEditorSafety" when the code
        #       that calls "clean_content" on Revision.save is deployed to
        #       production, AND the current revisions of all docs have had
        #       their content cleaned with "clean_content".
        initial.update(content=kuma.wiki.content.parse(
            content).filterEditorSafety().serialize())
    instance = doc and doc.current_or_latest_revision()
    rev_form = RevisionForm(request=request,
                            instance=instance,
                            initial=initial,
                            parent_slug=slug_dict['parent'])

    if request.method == 'POST':
        which_form = request.POST.get('form-type', 'both')
        doc_form_invalid = False

        # Grab the posted slug value in case it's invalid
        posted_slug = request.POST.get('slug', slug_dict['specific'])

        if user_has_doc_perm and which_form in ['doc', 'both']:
            disclose_description = True
            post_data = request.POST.copy()

            post_data.update({'locale': document_locale})

            doc_form = DocumentForm(post_data,
                                    instance=doc,
                                    parent_slug=slug_dict['parent'])
            doc_form.instance.locale = document_locale
            doc_form.instance.parent = parent_doc

            if which_form == 'both':
                # Sending a new copy of post so the slug change above
                # doesn't cause problems during validation
                rev_form = RevisionForm(request=request,
                                        data=post_data,
                                        parent_slug=slug_dict['parent'])

            # 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=parent_doc)

                if which_form == 'doc':
                    url = urlparams(doc.get_edit_url(), opendescription=1)
                    return redirect(url)
            else:
                doc_form.data['slug'] = posted_slug
                doc_form_invalid = True

        if doc and which_form in ['rev', 'both']:
            post_data = request.POST.copy()
            if 'slug' not in post_data:
                post_data['slug'] = posted_slug

            # update the post data with the toc_depth of original
            post_data['toc_depth'] = based_on_rev.toc_depth

            # Pass in the locale for the akistmet "blog_lang".
            post_data['locale'] = document_locale

            rev_form = RevisionForm(request=request,
                                    data=post_data,
                                    parent_slug=slug_dict['parent'])
            rev_form.instance.document = doc  # for rev_form.clean()

            if rev_form.is_valid() and not doc_form_invalid:
                parent_id = request.POST.get('parent_id', '')

                # Attempt to set a parent
                if parent_id:
                    try:
                        parent_doc = get_object_or_404(Document, id=parent_id)
                        rev_form.instance.document.parent = parent_doc
                        doc.parent = parent_doc
                        rev_form.instance.based_on.document = doc.original
                    except Document.DoesNotExist:
                        pass

                rev_form.save(doc)
                # If this is an Ajax POST, then return a JsonResponse
                if request.is_ajax():
                    data = {
                        'error': False,
                        'new_revision_id': rev_form.instance.id,
                    }

                    return JsonResponse(data)

                # Construct the redirect URL, adding any needed parameters
                url = doc.get_absolute_url()
                params = {}
                # Parameter for the document saved, so that we can delete the cached draft on load
                params['rev_saved'] = request.POST.get('current_rev', '')
                url = '%s?%s' % (url, urlencode(params))
                return redirect(url)
            else:
                # If this is an Ajax POST, then return a JsonResponse with error
                if request.is_ajax():
                    if 'current_rev' in rev_form._errors:
                        # Make the error message safe so the '<' and '>' don't
                        # get turned into '&lt;' and '&gt;', respectively
                        rev_form.errors['current_rev'][0] = mark_safe(
                            rev_form.errors['current_rev'][0])
                    errors = [
                        rev_form.errors[key][0]
                        for key in rev_form.errors.keys()
                    ]
                    data = {
                        "error": True,
                        "error_message": errors,
                        "new_revision_id": rev_form.instance.id,
                    }
                    return JsonResponse(data=data)

    if doc:
        from_id = smart_int(request.GET.get('from'), None)
        to_id = smart_int(request.GET.get('to'), None)

        revision_from = get_object_or_none(Revision,
                                           pk=from_id,
                                           document=doc.parent)
        revision_to = get_object_or_none(Revision,
                                         pk=to_id,
                                         document=doc.parent)
    else:
        revision_from = revision_to = None

    parent_split = split_slug(parent_doc.slug)

    language_mapping = get_language_mapping()
    language = language_mapping[document_locale.lower()]
    default_locale = language_mapping[settings.WIKI_DEFAULT_LANGUAGE.lower()]

    context = {
        'parent': parent_doc,
        'document': doc,
        'document_form': doc_form,
        'revision_form': rev_form,
        'locale': document_locale,
        'default_locale': default_locale,
        'language': language,
        'based_on': based_on_rev,
        'disclose_description': disclose_description,
        'discard_href': discard_href,
        'attachment_form': AttachmentRevisionForm(),
        'specific_slug': parent_split['specific'],
        'parent_slug': parent_split['parent'],
        'revision_from': revision_from,
        'revision_to': revision_to,
    }
    return render(request, 'wiki/translate.html', context)
Esempio n. 7
0
def translate(request, document_slug, document_locale, revision_id=None):
    """
    Create a new translation of a wiki document.

    * document_slug is for the default locale
    * translation is to the request locale
    """
    # TODO: Refactor this view into two views? (new, edit)
    # That might help reduce the headache-inducing branchiness.
    parent_doc = get_object_or_404(Document,
                                   locale=settings.WIKI_DEFAULT_LANGUAGE,
                                   slug=document_slug)
    user = request.user

    if not revision_id:
        # HACK: Seems weird, but sticking the translate-to locale in a query
        # param is the best way to avoid the MindTouch-legacy locale
        # redirection logic.
        document_locale = request.GET.get('tolocale',
                                          document_locale)

    # Set a "Discard Changes" page
    discard_href = ''

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

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

    if revision_id:
        get_object_or_404(Revision, pk=revision_id)

    based_on_rev = parent_doc.current_or_latest_revision()

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

    try:
        doc = parent_doc.translations.get(locale=document_locale)
        slug_dict = split_slug(doc.slug)
    except Document.DoesNotExist:
        doc = None
        disclose_description = True
        slug_dict = split_slug(document_slug)

        # Find the "real" parent topic, which is its translation
        try:
            parent_topic_translated_doc = (
                parent_doc.parent_topic.translations.get(
                    locale=document_locale))
            slug_dict = split_slug(
                parent_topic_translated_doc.slug + '/' + slug_dict['specific'])
        except:
            pass

    user_has_doc_perm = ((not doc) or (doc and doc.allows_editing_by(user)))
    user_has_rev_perm = ((not doc) or (doc and doc.allows_revision_by(user)))
    if not user_has_doc_perm and not user_has_rev_perm:
        # User has no perms, bye.
        raise PermissionDenied

    doc_form = rev_form = None

    if user_has_doc_perm:
        if doc:
            # If there's an existing doc, populate form from it.
            discard_href = doc.get_absolute_url()
            doc.slug = slug_dict['specific']
            doc_initial = document_form_initial(doc)
        else:
            # If no existing doc, bring over the original title and slug.
            discard_href = parent_doc.get_absolute_url()
            doc_initial = {'title': based_on_rev.title,
                           'slug': slug_dict['specific']}
        doc_form = DocumentForm(initial=doc_initial)

    if user_has_rev_perm:
        initial = {'based_on': based_on_rev.id, 'comment': '',
                   'toc_depth': based_on_rev.toc_depth,
                   'localization_tags': ['inprogress']}
        content = None
        if revision_id:
            content = Revision.objects.get(pk=revision_id).content
        elif not doc:
            content = based_on_rev.content
        if content:
            initial.update(content=kuma.wiki.content.parse(content)
                                                    .filterEditorSafety()
                                                    .serialize())
        instance = doc and doc.current_or_latest_revision()
        rev_form = RevisionForm(instance=instance, initial=initial)

    if request.method == 'POST':
        which_form = request.POST.get('form', 'both')
        doc_form_invalid = False

        # Grab the posted slug value in case it's invalid
        posted_slug = request.POST.get('slug', slug_dict['specific'])
        destination_slug = join_slug(slug_dict['parent_split'], posted_slug)

        if user_has_doc_perm and which_form in ['doc', 'both']:
            disclose_description = True
            post_data = request.POST.copy()

            post_data.update({'locale': document_locale})
            post_data.update({'slug': destination_slug})

            doc_form = DocumentForm(post_data, instance=doc)
            doc_form.instance.locale = document_locale
            doc_form.instance.parent = parent_doc
            if which_form == 'both':
                # Sending a new copy of post so the slug change above
                # doesn't cause problems during validation
                rev_form = RevisionValidationForm(request.POST.copy())
                rev_form.parent_slug = slug_dict['parent']

            # 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()):
                rev_form = RevisionForm(post_data)

                if rev_form.is_valid():
                    doc = doc_form.save(parent_doc)

                    if which_form == 'doc':
                        url = urlparams(reverse('wiki.edit_document',
                                                args=[doc.slug],
                                                locale=doc.locale),
                                        opendescription=1)
                        return redirect(url)
                else:
                    doc_form.data['slug'] = posted_slug
                    doc_form_invalid = True
            else:
                doc_form.data['slug'] = posted_slug
                doc_form_invalid = True

        if doc and user_has_rev_perm and which_form in ['rev', 'both']:
            post_data = request.POST.copy()
            if 'slug' not in post_data:
                post_data['slug'] = posted_slug

            rev_form = RevisionValidationForm(post_data)
            rev_form.parent_slug = slug_dict['parent']
            rev_form.instance.document = doc  # for rev_form.clean()

            if rev_form.is_valid() and not doc_form_invalid:
                # append final slug
                post_data['slug'] = destination_slug

                # update the post data with the toc_depth of original
                post_data['toc_depth'] = based_on_rev.toc_depth

                rev_form = RevisionForm(post_data)
                rev_form.instance.document = doc  # for rev_form.clean()

                if rev_form.is_valid():
                    parent_id = request.POST.get('parent_id', '')

                    # Attempt to set a parent
                    if parent_id:
                        try:
                            parent_doc = get_object_or_404(Document,
                                                           id=parent_id)
                            rev_form.instance.document.parent = parent_doc
                            doc.parent = parent_doc
                            rev_form.instance.based_on.document = doc.original
                        except Document.DoesNotExist:
                            pass

                    save_revision_and_notify(rev_form, request, doc)
                    return redirect(doc)

    if doc:
        from_id = smart_int(request.GET.get('from'), None)
        to_id = smart_int(request.GET.get('to'), None)

        revision_from = get_object_or_none(Revision,
                                           pk=from_id,
                                           document=doc.parent)
        revision_to = get_object_or_none(Revision,
                                         pk=to_id,
                                         document=doc.parent)
    else:
        revision_from = revision_to = None

    parent_split = split_slug(parent_doc.slug)
    allow_add_attachment = (
        Attachment.objects.allow_add_attachment_by(request.user))

    attachments = []
    if doc and doc.attachments:
        attachments = attachments_json(doc.attachments)

    language_mapping = get_language_mapping()
    language = language_mapping[document_locale.lower()]
    default_locale = language_mapping[settings.WIKI_DEFAULT_LANGUAGE.lower()]

    context = {
        'parent': parent_doc,
        'document': doc,
        'document_form': doc_form,
        'revision_form': rev_form,
        'locale': document_locale,
        'default_locale': default_locale,
        'language': language,
        'based_on': based_on_rev,
        'disclose_description': disclose_description,
        'discard_href': discard_href,
        'allow_add_attachment': allow_add_attachment,
        'attachment_form': AttachmentRevisionForm(),
        'attachment_data': attachments,
        'attachment_data_json': json.dumps(attachments),
        'WIKI_DOCUMENT_TAG_SUGGESTIONS': config.WIKI_DOCUMENT_TAG_SUGGESTIONS,
        'specific_slug': parent_split['specific'],
        'parent_slug': parent_split['parent'],
        'revision_from': revision_from,
        'revision_to': revision_to,
    }
    return render(request, 'wiki/translate.html', context)
Esempio n. 8
0
def translate(request, document_slug, document_locale):
    """
    Create a new translation of a wiki document.

    * document_slug is for the default locale
    * translation is to the request locale
    """
    # TODO: Refactor this view into two views? (new, edit)
    # That might help reduce the headache-inducing branchiness.

    # The parent document to translate from
    try:
        # Use '.all_objects' because the parent might have been soft deleted.
        # And if we don't respect that fact, it would become impossible to
        # edit a the child of it.
        parent_doc = Document.all_objects.get(
            locale=settings.WIKI_DEFAULT_LANGUAGE, slug=document_slug
        )
    except Document.DoesNotExist:
        raise Http404("Parent document does not exist")

    # Get the mapping here and now so it can be used for input validation
    language_mapping = get_language_mapping()

    # HACK: Seems weird, but sticking the translate-to locale in a query
    # param is the best way to avoid the MindTouch-legacy locale
    # redirection logic.
    document_locale = request.GET.get("tolocale", document_locale)
    if document_locale.lower() not in language_mapping:
        # The 'tolocale' query string parameters aren't free-text. They're
        # explicitly listed on the "Select language" page (`...$locales`)
        # If a locale was entered that wasn't a link it's a user bug.
        raise Http404

    # Set a "Discard Changes" page
    discard_href = ""

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

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

    based_on_rev = parent_doc.current_or_latest_revision()

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

    try:
        doc = parent_doc.translations.get(locale=document_locale)
        slug_dict = split_slug(doc.slug)
    except Document.DoesNotExist:
        doc = None
        disclose_description = True
        slug_dict = split_slug(document_slug)

        # Find the "real" parent topic, which is its translation
        if parent_doc.parent_topic:
            try:
                parent_topic_translated_doc = parent_doc.parent_topic.translations.get(
                    locale=document_locale
                )
                slug_dict = split_slug(
                    parent_topic_translated_doc.slug + "/" + slug_dict["specific"]
                )
            except ObjectDoesNotExist:
                pass

    user_has_doc_perm = (not doc) or (doc and doc.allows_editing_by(request.user))

    doc_form = None
    if user_has_doc_perm:
        if doc:
            # If there's an existing doc, populate form from it.
            discard_href = doc.get_absolute_url()
            doc.slug = slug_dict["specific"]
            doc_initial = document_form_initial(doc)
        else:
            # If no existing doc, bring over the original title and slug.
            discard_href = parent_doc.get_absolute_url()
            doc_initial = {"title": based_on_rev.title, "slug": slug_dict["specific"]}
        doc_form = DocumentForm(initial=doc_initial, parent_slug=slug_dict["parent"])

    initial = {
        "based_on": based_on_rev.id,
        "current_rev": doc.current_or_latest_revision().id if doc else None,
        "comment": "",
        "toc_depth": based_on_rev.toc_depth,
        "localization_tags": ["inprogress"],
    }
    content = None
    if not doc:
        content = based_on_rev.content
    if content:
        # TODO: There will be no need to "filterEditorSafety" when the code
        #       that calls "clean_content" on Revision.save is deployed to
        #       production, AND the current revisions of all docs have had
        #       their content cleaned with "clean_content".
        initial.update(
            content=kuma.wiki.content.parse(content).filterEditorSafety().serialize()
        )
    instance = doc and doc.current_or_latest_revision()
    rev_form = RevisionForm(
        request=request,
        instance=instance,
        initial=initial,
        parent_slug=slug_dict["parent"],
    )

    if request.method == "POST":
        which_form = request.POST.get("form-type", "both")
        doc_form_invalid = False

        # Grab the posted slug value in case it's invalid
        posted_slug = request.POST.get("slug", slug_dict["specific"])

        if user_has_doc_perm and which_form in ["doc", "both"]:
            disclose_description = True
            post_data = request.POST.copy()

            post_data.update({"locale": document_locale})

            doc_form = DocumentForm(
                post_data, instance=doc, parent_slug=slug_dict["parent"]
            )
            doc_form.instance.locale = document_locale
            doc_form.instance.parent = parent_doc

            if which_form == "both":
                # Sending a new copy of post so the slug change above
                # doesn't cause problems during validation
                rev_form = RevisionForm(
                    request=request, data=post_data, parent_slug=slug_dict["parent"]
                )

            # 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=parent_doc)

                if which_form == "doc":
                    url = urlparams(doc.get_edit_url(), opendescription=1)
                    return redirect(url)
            else:
                doc_form.data["slug"] = posted_slug
                doc_form_invalid = True

        if doc and which_form in ["rev", "both"]:
            post_data = request.POST.copy()
            if "slug" not in post_data:
                post_data["slug"] = posted_slug

            # update the post data with the toc_depth of original
            post_data["toc_depth"] = based_on_rev.toc_depth

            # Pass in the locale for the akistmet "blog_lang".
            post_data["locale"] = document_locale

            rev_form = RevisionForm(
                request=request, data=post_data, parent_slug=slug_dict["parent"]
            )
            rev_form.instance.document = doc  # for rev_form.clean()

            if rev_form.is_valid() and not doc_form_invalid:
                parent_id = request.POST.get("parent_id", "")

                # Attempt to set a parent
                if parent_id:
                    try:
                        try:
                            parent_doc = Document.all_objects.get(id=parent_id)
                        except Document.DoesNotExist:
                            raise Http404("Parent document does not exist")
                        rev_form.instance.document.parent = parent_doc
                        doc.parent = parent_doc
                        rev_form.instance.based_on.document = doc.original
                    except Document.DoesNotExist:
                        pass

                rev_form.save(doc)
                # If this is an Ajax POST, then return a JsonResponse
                if request.is_ajax():
                    data = {
                        "error": False,
                        "new_revision_id": rev_form.instance.id,
                    }

                    return JsonResponse(data)

                # Construct the redirect URL, adding any needed parameters
                url = doc.get_absolute_url()
                params = {}
                # Parameter for the document saved, so that we can delete the cached draft on load
                params["rev_saved"] = request.POST.get("current_rev", "")
                url = "%s?%s" % (url, urlencode(params))
                return redirect(url)
            else:
                # If this is an Ajax POST, then return a JsonResponse with error
                if request.is_ajax():
                    if "current_rev" in rev_form._errors:
                        # Make the error message safe so the '<' and '>' don't
                        # get turned into '&lt;' and '&gt;', respectively
                        rev_form.errors["current_rev"][0] = mark_safe(
                            rev_form.errors["current_rev"][0]
                        )
                    errors = [rev_form.errors[key][0] for key in rev_form.errors.keys()]
                    data = {
                        "error": True,
                        "error_message": errors,
                        "new_revision_id": rev_form.instance.id,
                    }
                    return JsonResponse(data=data)

    if doc:
        from_id = smart_int(request.GET.get("from"), None)
        to_id = smart_int(request.GET.get("to"), None)

        revision_from = get_object_or_none(Revision, pk=from_id, document=doc.parent)
        revision_to = get_object_or_none(Revision, pk=to_id, document=doc.parent)
    else:
        revision_from = revision_to = None

    parent_split = split_slug(parent_doc.slug)

    language = language_mapping[document_locale.lower()]
    default_locale = language_mapping[settings.WIKI_DEFAULT_LANGUAGE.lower()]

    context = {
        "parent": parent_doc,
        "document": doc,
        "document_form": doc_form,
        "revision_form": rev_form,
        "locale": document_locale,
        "default_locale": default_locale,
        "language": language,
        "based_on": based_on_rev,
        "disclose_description": disclose_description,
        "discard_href": discard_href,
        "attachment_form": AttachmentRevisionForm(),
        "specific_slug": parent_split["specific"],
        "parent_slug": parent_split["parent"],
        "revision_from": revision_from,
        "revision_to": revision_to,
    }
    return render(request, "wiki/translate.html", context)
Esempio n. 9
0
def translate(request, document_slug, document_locale, revision_id=None):
    """
    Create a new translation of a wiki document.

    * document_slug is for the default locale
    * translation is to the request locale
    """
    # TODO: Refactor this view into two views? (new, edit)
    # That might help reduce the headache-inducing branchiness.

    # The parent document to translate from
    parent_doc = get_object_or_404(Document,
                                   locale=settings.WIKI_DEFAULT_LANGUAGE,
                                   slug=document_slug)

    if not revision_id:
        # HACK: Seems weird, but sticking the translate-to locale in a query
        # param is the best way to avoid the MindTouch-legacy locale
        # redirection logic.
        document_locale = request.GET.get('tolocale',
                                          document_locale)

    # Set a "Discard Changes" page
    discard_href = ''

    if settings.WIKI_DEFAULT_LANGUAGE == document_locale:
        # Don't translate to the default language.
        return redirect(reverse(
            'wiki.edit', locale=settings.WIKI_DEFAULT_LANGUAGE,
            args=[parent_doc.slug]))

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

    if revision_id:
        revision = get_object_or_404(Revision, pk=revision_id)
    else:
        revision = None

    based_on_rev = parent_doc.current_or_latest_revision()

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

    try:
        doc = parent_doc.translations.get(locale=document_locale)
        slug_dict = split_slug(doc.slug)
    except Document.DoesNotExist:
        doc = None
        disclose_description = True
        slug_dict = split_slug(document_slug)

        # Find the "real" parent topic, which is its translation
        if parent_doc.parent_topic:
            try:
                parent_topic_translated_doc = (parent_doc.parent_topic
                                                         .translations
                                                         .get(locale=document_locale))
                slug_dict = split_slug(parent_topic_translated_doc.slug +
                                       '/' +
                                       slug_dict['specific'])
            except ObjectDoesNotExist:
                pass

    user_has_doc_perm = (not doc) or (doc and doc.allows_editing_by(request.user))
    user_has_rev_perm = (not doc) or (doc and doc.allows_revision_by(request.user))
    if not user_has_doc_perm and not user_has_rev_perm:
        # User has no perms, bye.
        raise PermissionDenied

    doc_form = rev_form = None

    if user_has_doc_perm:
        if doc:
            # If there's an existing doc, populate form from it.
            discard_href = doc.get_absolute_url()
            doc.slug = slug_dict['specific']
            doc_initial = document_form_initial(doc)
        else:
            # If no existing doc, bring over the original title and slug.
            discard_href = parent_doc.get_absolute_url()
            doc_initial = {'title': based_on_rev.title,
                           'slug': slug_dict['specific']}
        doc_form = DocumentForm(initial=doc_initial,
                                parent_slug=slug_dict['parent'])

    if user_has_rev_perm:
        initial = {
            'based_on': based_on_rev.id,
            'comment': '',
            'toc_depth': based_on_rev.toc_depth,
            'localization_tags': ['inprogress'],
        }
        content = None
        if revision is not None:
            content = revision.content
        elif not doc:
            content = based_on_rev.content
        if content:
            initial.update(content=kuma.wiki.content.parse(content)
                                                    .filterEditorSafety()
                                                    .serialize())
        instance = doc and doc.current_or_latest_revision()
        rev_form = RevisionForm(request=request,
                                instance=instance,
                                initial=initial,
                                parent_slug=slug_dict['parent'])

    if request.method == 'POST':
        which_form = request.POST.get('form', 'both')
        doc_form_invalid = False

        # Grab the posted slug value in case it's invalid
        posted_slug = request.POST.get('slug', slug_dict['specific'])

        if user_has_doc_perm and which_form in ['doc', 'both']:
            disclose_description = True
            post_data = request.POST.copy()

            post_data.update({'locale': document_locale})

            doc_form = DocumentForm(post_data, instance=doc,
                                    parent_slug=slug_dict['parent'])
            doc_form.instance.locale = document_locale
            doc_form.instance.parent = parent_doc

            if which_form == 'both':
                # Sending a new copy of post so the slug change above
                # doesn't cause problems during validation
                rev_form = RevisionForm(request=request,
                                        data=request.POST,
                                        parent_slug=slug_dict['parent'])

            # 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=parent_doc)

                if which_form == 'doc':
                    url = urlparams(doc.get_edit_url(), opendescription=1)
                    return redirect(url)
            else:
                doc_form.data['slug'] = posted_slug
                doc_form_invalid = True

        if doc and user_has_rev_perm and which_form in ['rev', 'both']:
            post_data = request.POST.copy()
            if 'slug' not in post_data:
                post_data['slug'] = posted_slug

            # update the post data with the toc_depth of original
            post_data['toc_depth'] = based_on_rev.toc_depth

            rev_form = RevisionForm(request=request,
                                    data=post_data,
                                    parent_slug=slug_dict['parent'])
            rev_form.instance.document = doc  # for rev_form.clean()

            if rev_form.is_valid() and not doc_form_invalid:
                parent_id = request.POST.get('parent_id', '')

                # Attempt to set a parent
                if parent_id:
                    try:
                        parent_doc = get_object_or_404(Document, id=parent_id)
                        rev_form.instance.document.parent = parent_doc
                        doc.parent = parent_doc
                        rev_form.instance.based_on.document = doc.original
                    except Document.DoesNotExist:
                        pass

                rev_form.save(doc)
                return redirect(doc)

    if doc:
        from_id = smart_int(request.GET.get('from'), None)
        to_id = smart_int(request.GET.get('to'), None)

        revision_from = get_object_or_none(Revision,
                                           pk=from_id,
                                           document=doc.parent)
        revision_to = get_object_or_none(Revision,
                                         pk=to_id,
                                         document=doc.parent)
    else:
        revision_from = revision_to = None

    parent_split = split_slug(parent_doc.slug)

    language_mapping = get_language_mapping()
    language = language_mapping[document_locale.lower()]
    default_locale = language_mapping[settings.WIKI_DEFAULT_LANGUAGE.lower()]

    context = {
        'parent': parent_doc,
        'document': doc,
        'document_form': doc_form,
        'revision_form': rev_form,
        'locale': document_locale,
        'default_locale': default_locale,
        'language': language,
        'based_on': based_on_rev,
        'disclose_description': disclose_description,
        'discard_href': discard_href,
        'attachment_form': AttachmentRevisionForm(),
        'specific_slug': parent_split['specific'],
        'parent_slug': parent_split['parent'],
        'revision_from': revision_from,
        'revision_to': revision_to,
    }
    return render(request, 'wiki/translate.html', context)
Esempio n. 10
0
 def test_wrong_type(self):
     assert 0 == smart_int(None)
     assert 10 == smart_int([], 10)
Esempio n. 11
0
 def test_empty_string(self):
     assert 0 == smart_int('')
Esempio n. 12
0
 def test_invalid_string(self):
     assert 0 == smart_int('invalid')
Esempio n. 13
0
 def test_int(self):
     assert 10 == smart_int(10)
Esempio n. 14
0
 def test_sanity(self):
     assert 10 == smart_int('10')
     assert 10 == smart_int('10.5')
Esempio n. 15
0
def translate(request, document_slug, document_locale):
    """
    Create a new translation of a wiki document.

    * document_slug is for the default locale
    * translation is to the request locale
    """
    # TODO: Refactor this view into two views? (new, edit)
    # That might help reduce the headache-inducing branchiness.

    # The parent document to translate from
    parent_doc = get_object_or_404(Document,
                                   locale=settings.WIKI_DEFAULT_LANGUAGE,
                                   slug=document_slug)

    # HACK: Seems weird, but sticking the translate-to locale in a query
    # param is the best way to avoid the MindTouch-legacy locale
    # redirection logic.
    document_locale = request.GET.get('tolocale', document_locale)

    # Set a "Discard Changes" page
    discard_href = ''

    if settings.WIKI_DEFAULT_LANGUAGE == document_locale:
        # Don't translate to the default language.
        return redirect(reverse(
            'wiki.edit', locale=settings.WIKI_DEFAULT_LANGUAGE,
            args=[parent_doc.slug]))

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

    based_on_rev = parent_doc.current_or_latest_revision()

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

    try:
        doc = parent_doc.translations.get(locale=document_locale)
        slug_dict = split_slug(doc.slug)
    except Document.DoesNotExist:
        doc = None
        disclose_description = True
        slug_dict = split_slug(document_slug)

        # Find the "real" parent topic, which is its translation
        if parent_doc.parent_topic:
            try:
                parent_topic_translated_doc = (parent_doc.parent_topic
                                                         .translations
                                                         .get(locale=document_locale))
                slug_dict = split_slug(parent_topic_translated_doc.slug +
                                       '/' +
                                       slug_dict['specific'])
            except ObjectDoesNotExist:
                pass

    user_has_doc_perm = (not doc) or (doc and doc.allows_editing_by(request.user))

    doc_form = None
    if user_has_doc_perm:
        if doc:
            # If there's an existing doc, populate form from it.
            discard_href = doc.get_absolute_url()
            doc.slug = slug_dict['specific']
            doc_initial = document_form_initial(doc)
        else:
            # If no existing doc, bring over the original title and slug.
            discard_href = parent_doc.get_absolute_url()
            doc_initial = {'title': based_on_rev.title,
                           'slug': slug_dict['specific']}
        doc_form = DocumentForm(initial=doc_initial,
                                parent_slug=slug_dict['parent'])

    initial = {
        'based_on': based_on_rev.id,
        'current_rev': doc.current_or_latest_revision().id if doc else None,
        'comment': '',
        'toc_depth': based_on_rev.toc_depth,
        'localization_tags': ['inprogress'],
    }
    content = None
    if not doc:
        content = based_on_rev.content
    if content:
        # TODO: There will be no need to "filterEditorSafety" when the code
        #       that calls "clean_content" on Revision.save is deployed to
        #       production, AND the current revisions of all docs have had
        #       their content cleaned with "clean_content".
        initial.update(content=kuma.wiki.content.parse(content)
                                                .filterEditorSafety()
                                                .serialize())
    instance = doc and doc.current_or_latest_revision()
    rev_form = RevisionForm(request=request,
                            instance=instance,
                            initial=initial,
                            parent_slug=slug_dict['parent'])

    if request.method == 'POST':
        which_form = request.POST.get('form-type', 'both')
        doc_form_invalid = False

        # Grab the posted slug value in case it's invalid
        posted_slug = request.POST.get('slug', slug_dict['specific'])

        if user_has_doc_perm and which_form in ['doc', 'both']:
            disclose_description = True
            post_data = request.POST.copy()

            post_data.update({'locale': document_locale})

            doc_form = DocumentForm(post_data, instance=doc,
                                    parent_slug=slug_dict['parent'])
            doc_form.instance.locale = document_locale
            doc_form.instance.parent = parent_doc

            if which_form == 'both':
                # Sending a new copy of post so the slug change above
                # doesn't cause problems during validation
                rev_form = RevisionForm(request=request,
                                        data=post_data,
                                        parent_slug=slug_dict['parent'])

            # 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=parent_doc)

                if which_form == 'doc':
                    url = urlparams(doc.get_edit_url(), opendescription=1)
                    return redirect(url)
            else:
                doc_form.data['slug'] = posted_slug
                doc_form_invalid = True

        if doc and which_form in ['rev', 'both']:
            post_data = request.POST.copy()
            if 'slug' not in post_data:
                post_data['slug'] = posted_slug

            # update the post data with the toc_depth of original
            post_data['toc_depth'] = based_on_rev.toc_depth

            # Pass in the locale for the akistmet "blog_lang".
            post_data['locale'] = document_locale

            rev_form = RevisionForm(request=request,
                                    data=post_data,
                                    parent_slug=slug_dict['parent'])
            rev_form.instance.document = doc  # for rev_form.clean()

            if rev_form.is_valid() and not doc_form_invalid:
                parent_id = request.POST.get('parent_id', '')

                # Attempt to set a parent
                if parent_id:
                    try:
                        parent_doc = get_object_or_404(Document, id=parent_id)
                        rev_form.instance.document.parent = parent_doc
                        doc.parent = parent_doc
                        rev_form.instance.based_on.document = doc.original
                    except Document.DoesNotExist:
                        pass

                rev_form.save(doc)
                # If this is an Ajax POST, then return a JsonResponse
                if request.is_ajax():
                    data = {
                        'error': False,
                        'new_revision_id': rev_form.instance.id,
                    }

                    return JsonResponse(data)

                # Construct the redirect URL, adding any needed parameters
                url = doc.get_absolute_url()
                params = {}
                # Parameter for the document saved, so that we can delete the cached draft on load
                params['rev_saved'] = request.POST.get('current_rev', '')
                url = '%s?%s' % (url, urlencode(params))
                return redirect(url)
            else:
                # If this is an Ajax POST, then return a JsonResponse with error
                if request.is_ajax():
                    if 'current_rev' in rev_form._errors:
                        # Make the error message safe so the '<' and '>' don't
                        # get turned into '&lt;' and '&gt;', respectively
                        rev_form.errors['current_rev'][0] = mark_safe(
                            rev_form.errors['current_rev'][0])
                    errors = [rev_form.errors[key][0] for key in rev_form.errors.keys()]
                    data = {
                        "error": True,
                        "error_message": errors,
                        "new_revision_id": rev_form.instance.id,
                    }
                    return JsonResponse(data=data)

    if doc:
        from_id = smart_int(request.GET.get('from'), None)
        to_id = smart_int(request.GET.get('to'), None)

        revision_from = get_object_or_none(Revision,
                                           pk=from_id,
                                           document=doc.parent)
        revision_to = get_object_or_none(Revision,
                                         pk=to_id,
                                         document=doc.parent)
    else:
        revision_from = revision_to = None

    parent_split = split_slug(parent_doc.slug)

    language_mapping = get_language_mapping()
    language = language_mapping[document_locale.lower()]
    default_locale = language_mapping[settings.WIKI_DEFAULT_LANGUAGE.lower()]

    context = {
        'parent': parent_doc,
        'document': doc,
        'document_form': doc_form,
        'revision_form': rev_form,
        'locale': document_locale,
        'default_locale': default_locale,
        'language': language,
        'based_on': based_on_rev,
        'disclose_description': disclose_description,
        'discard_href': discard_href,
        'attachment_form': AttachmentRevisionForm(),
        'specific_slug': parent_split['specific'],
        'parent_slug': parent_split['parent'],
        'revision_from': revision_from,
        'revision_to': revision_to,
    }
    return render(request, 'wiki/translate.html', context)