Exemple #1
0
def watch_document(request, document_slug):
    """Start watching a document for edits."""
    document = get_object_or_404(
        Document, locale=request.locale, slug=document_slug)
    EditDocumentEvent.notify(request.user, document)
    statsd.incr('wiki.watches.document')
    return HttpResponseRedirect(document.get_absolute_url())
Exemple #2
0
def unwatch_document(request, document_slug):
    """Stop watching a document for edits."""
    document = get_object_or_404(Document,
                                 locale=request.locale,
                                 slug=document_slug)
    EditDocumentEvent.stop_notifying(request.user, document)
    return HttpResponseRedirect(document.get_absolute_url())
Exemple #3
0
def watch_document(request, document_slug):
    """Start watching a document for edits."""
    document = get_object_or_404(
        Document, locale=request.LANGUAGE_CODE, slug=document_slug)
    EditDocumentEvent.notify(request.user, document)
    statsd.incr('wiki.watches.document')
    return HttpResponseRedirect(document.get_absolute_url())
Exemple #4
0
def _save_rev_and_notify(rev_form, creator, document):
    """Save the given RevisionForm and send notifications."""
    new_rev = rev_form.save(creator, document)

    # Enqueue notifications
    ReviewableRevisionInLocaleEvent(new_rev).fire(exclude=new_rev.creator)
    EditDocumentEvent(new_rev).fire(exclude=new_rev.creator)
Exemple #5
0
def _save_rev_and_notify(rev_form, creator, document, based_on_id=None,
                         base_rev=None):
    """Save the given RevisionForm and send notifications."""
    new_rev = rev_form.save(creator, document, based_on_id, base_rev)
    statsd.incr('wiki.revision')

    # Enqueue notifications
    ReviewableRevisionInLocaleEvent(new_rev).fire(exclude=new_rev.creator)
    EditDocumentEvent(new_rev).fire(exclude=new_rev.creator)
Exemple #6
0
 def is_watched_by(self, user):
     """Return whether `user` is notified of edits to me."""
     from wiki.events import EditDocumentEvent
     return EditDocumentEvent.is_notifying(user, self)
Exemple #7
0
def unwatch_document(request, document_slug):
    """Stop watching a document for edits."""
    document = get_object_or_404(
        Document, locale=request.locale, slug=document_slug)
    EditDocumentEvent.stop_notifying(request.user, document)
    return HttpResponseRedirect(document.get_absolute_url())
Exemple #8
0
def edit_document(request, document_slug, revision_id=None):
    """Create a new revision of a wiki document, or edit document metadata."""
    doc = get_object_or_404(
        Document, locale=request.locale, slug=document_slug)
    user = request.user

    # If this document has a parent, then the edit is handled by the
    # translate view. Pass it on.
    if doc.parent:
        return translate(request, doc.parent.slug, revision_id)
    if revision_id:
        rev = get_object_or_404(Revision, pk=revision_id, document=doc)
    else:
        rev = doc.current_revision or doc.revisions.order_by('-created',
                                                             '-id')[0]

    disclose_description = bool(request.GET.get('opendescription'))
    doc_form = rev_form = None
    if doc.allows_revision_by(user):
        rev_form = RevisionForm(
            instance=rev,
            initial={'based_on': rev.id, 'comment': ''})
    if doc.allows_editing_by(user):
        doc_form = DocumentForm(
            initial=_document_form_initial(doc),
            can_create_tags=user.has_perm('taggit.add_tag'),
            can_archive=user.has_perm('wiki.archive_document'))

    if request.method == 'GET':
        if not (rev_form or doc_form):
            # You can't do anything on this page, so get lost.
            raise PermissionDenied
    else:  # POST
        # Comparing against localized names for the Save button bothers me, so
        # I embedded a hidden input:
        which_form = request.POST.get('form')

        if which_form == 'doc':
            if doc.allows_editing_by(user):
                post_data = request.POST.copy()
                post_data.update({'locale': request.locale})
                doc_form = DocumentForm(
                    post_data,
                    instance=doc,
                    can_create_tags=user.has_perm('taggit.add_tag'),
                    can_archive=user.has_perm('wiki.archive_document'))
                if doc_form.is_valid():
                    # Get the possibly new slug for the imminent redirection:
                    doc = doc_form.save(None)

                    # Do we need to rebuild the KB?
                    _maybe_schedule_rebuild(doc_form)

                    return HttpResponseRedirect(
                        urlparams(reverse('wiki.edit_document',
                                          args=[doc.slug]),
                                  opendescription=1))
                disclose_description = True
            else:
                raise PermissionDenied
        elif which_form == 'rev':
            if doc.allows_revision_by(user):
                rev_form = RevisionForm(request.POST)
                rev_form.instance.document = doc  # for rev_form.clean()
                if rev_form.is_valid():
                    _save_rev_and_notify(rev_form, user, doc)
                    if 'notify-future-changes' in request.POST:
                        EditDocumentEvent.notify(request.user, doc)
                    return HttpResponseRedirect(
                        reverse('wiki.document_revisions',
                                args=[document_slug]))
            else:
                raise PermissionDenied

    show_revision_warning = _show_revision_warning(doc, rev)

    return jingo.render(request, 'wiki/edit_document.html',
                        {'revision_form': rev_form,
                         'document_form': doc_form,
                         'disclose_description': disclose_description,
                         'document': doc,
                         'show_revision_warning': show_revision_warning})
Exemple #9
0
def edit_document(request, document_slug, revision_id=None):
    """Create a new revision of a wiki document, or edit document metadata."""
    doc = get_object_or_404(Document,
                            locale=request.locale,
                            slug=document_slug)
    user = request.user

    # If this document has a parent, then the edit is handled by the
    # translate view. Pass it on.
    if doc.parent:
        return translate(request, doc.parent.slug, revision_id)
    if revision_id:
        rev = get_object_or_404(Revision, pk=revision_id, document=doc)
    else:
        rev = doc.current_revision or doc.revisions.order_by(
            '-created', '-id')[0]

    disclose_description = bool(request.GET.get('opendescription'))
    doc_form = rev_form = None
    if doc.allows_revision_by(user):
        rev_form = RevisionForm(instance=rev,
                                initial={
                                    'based_on': rev.id,
                                    'comment': ''
                                })
    if doc.allows_editing_by(user):
        doc_form = DocumentForm(
            initial=_document_form_initial(doc),
            can_archive=user.has_perm('wiki.archive_document'))

    if request.method == 'GET':
        if not (rev_form or doc_form):
            # You can't do anything on this page, so get lost.
            raise PermissionDenied
    else:  # POST
        # Comparing against localized names for the Save button bothers me, so
        # I embedded a hidden input:
        which_form = request.POST.get('form')

        if which_form == 'doc':
            if doc.allows_editing_by(user):
                post_data = request.POST.copy()
                post_data.update({'locale': request.locale})
                doc_form = DocumentForm(
                    post_data,
                    instance=doc,
                    can_archive=user.has_perm('wiki.archive_document'))
                if doc_form.is_valid():
                    # Get the possibly new slug for the imminent redirection:
                    doc = doc_form.save(None)

                    # Do we need to rebuild the KB?
                    _maybe_schedule_rebuild(doc_form)

                    return HttpResponseRedirect(
                        urlparams(reverse('wiki.edit_document',
                                          args=[doc.slug]),
                                  opendescription=1))
                disclose_description = True
            else:
                raise PermissionDenied
        elif which_form == 'rev':
            if doc.allows_revision_by(user):
                rev_form = RevisionForm(request.POST)
                rev_form.instance.document = doc  # for rev_form.clean()
                if rev_form.is_valid():
                    _save_rev_and_notify(rev_form, user, doc)
                    if 'notify-future-changes' in request.POST:
                        EditDocumentEvent.notify(request.user, doc)
                    return HttpResponseRedirect(
                        reverse('wiki.document_revisions',
                                args=[document_slug]))
            else:
                raise PermissionDenied

    show_revision_warning = _show_revision_warning(doc, rev)

    return jingo.render(
        request, 'wiki/edit.html', {
            'revision_form': rev_form,
            'document_form': doc_form,
            'disclose_description': disclose_description,
            'document': doc,
            'show_revision_warning': show_revision_warning
        })
Exemple #10
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

    """
    # 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 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(u'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

    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
    base_rev = None

    if user_has_doc_perm:
        doc_initial = _document_form_initial(doc) if doc else None
        doc_form = DocumentForm(initial=doc_initial)
    if user_has_rev_perm:
        initial = {'based_on': based_on_rev.id, 'comment': ''}
        if revision_id:
            base_rev = Revision.objects.get(pk=revision_id)
            initial.update(content=base_rev.content,
                           summary=base_rev.summary,
                           keywords=base_rev.keywords)
        elif not doc:
            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=initial)
        base_rev = base_rev or instance

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

        if doc is not None:
            _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

                _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)

                url = reverse('wiki.document_revisions',
                              args=[doc_slug])

                return HttpResponseRedirect(url)

    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)
    else:
        locked, locked_by = False, 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})
Exemple #11
0
 def is_watched_by(self, user):
     """Return whether `user` is notified of edits to me."""
     from wiki.events import EditDocumentEvent
     return EditDocumentEvent.is_notifying(user, self)
Exemple #12
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

    """
    # 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 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(u'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

    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
    base_rev = None

    if user_has_doc_perm:
        doc_initial = _document_form_initial(doc) if doc else None
        doc_form = DocumentForm(initial=doc_initial)
    if user_has_rev_perm:
        initial = {'based_on': based_on_rev.id, 'comment': ''}
        if revision_id:
            base_rev = Revision.objects.get(pk=revision_id)
            initial.update(content=base_rev.content,
                           summary=base_rev.summary,
                           keywords=base_rev.keywords)
        elif not doc:
            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=initial)
        base_rev = base_rev or instance

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

        if doc is not None:
            _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

                _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)

                url = reverse('wiki.document_revisions',
                              args=[doc_slug])

                return HttpResponseRedirect(url)

    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)
    else:
        locked, locked_by = False, 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})