Source code for commentaries.views

__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
__license__ = "AGPL v3"


from django.shortcuts import get_object_or_404, render
from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required
from django.core.mail import EmailMessage
from django.urls import reverse, reverse_lazy
from django.db import transaction
from django.shortcuts import redirect
from django.template.loader import render_to_string
from django.views.generic.edit import CreateView
from django.views.generic.list import ListView
from django.utils.decorators import method_decorator
from django.http import Http404

from .models import Commentary
from .forms import (
    DOIToQueryForm,
    ArxivQueryForm,
    VetCommentaryForm,
    RequestCommentaryForm,
    CommentaryListSearchForm,
    RequestPublishedArticleForm,
    RequestArxivPreprintForm,
    CommentSciPostPublication,
)

from comments.models import Comment
from comments.forms import CommentForm
from common.utils import get_current_domain
from journals.models import Publication
from scipost.mixins import PaginationMixin

import strings


[docs]@login_required @permission_required("scipost.can_request_commentary_pages", raise_exception=True) def request_commentary(request): return render(request, "commentaries/request_commentary.html")
[docs]@method_decorator(login_required, name="dispatch") @method_decorator( permission_required("scipost.can_request_commentary_pages", raise_exception=True), name="dispatch", ) class RequestCommentary(CreateView): success_url = reverse_lazy("scipost:personal_page")
[docs] def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs["requested_by"] = self.request.user.contributor return kwargs
[docs] def form_valid(self, form): messages.success( self.request, strings.acknowledge_request_commentary, fail_silently=True ) return super().form_valid(form)
[docs]class RequestPublishedArticle(RequestCommentary): form_class = RequestPublishedArticleForm template_name = "commentaries/request_published_article.html"
[docs] def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["query_form"] = DOIToQueryForm() return context
[docs]class RequestArxivPreprint(RequestCommentary): form_class = RequestArxivPreprintForm template_name = "commentaries/request_arxiv_preprint.html"
[docs] def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["query_form"] = ArxivQueryForm() return context
[docs]@permission_required("scipost.can_request_commentary_pages", raise_exception=True) def prefill_using_DOI(request): if request.method == "POST": query_form = DOIToQueryForm(request.POST) # The form checks if doi is valid and commentary doesn't already exist. if query_form.is_valid(): prefill_data = query_form.request_published_article_form_prefill_data() form = RequestPublishedArticleForm(initial=prefill_data) messages.success(request, strings.acknowledge_doi_query, fail_silently=True) else: form = RequestPublishedArticleForm() context = { "form": form, "query_form": query_form, } return render(request, "commentaries/request_published_article.html", context) else: raise Http404
[docs]@permission_required("scipost.can_request_commentary_pages", raise_exception=True) def prefill_using_arxiv_identifier(request): if request.method == "POST": query_form = ArxivQueryForm(request.POST) if query_form.is_valid(): prefill_data = query_form.request_arxiv_preprint_form_prefill_data() form = RequestArxivPreprintForm(initial=prefill_data) messages.success( request, strings.acknowledge_arxiv_query, fail_silently=True ) else: form = RequestArxivPreprintForm() context = { "form": form, "query_form": query_form, } return render(request, "commentaries/request_arxiv_preprint.html", context) else: raise Http404
[docs]@permission_required("scipost.can_vet_commentary_requests", raise_exception=True) def vet_commentary_requests(request, commentary_id=None): """Show the first commentary thats awaiting vetting""" queryset = Commentary.objects.awaiting_vetting().exclude( requested_by=request.user.contributor ) if commentary_id: # Security fix: Smart asses can vet their own commentary without this line. commentary_to_vet = get_object_or_404(queryset, id=commentary_id) else: commentary_to_vet = queryset.first() form = VetCommentaryForm( request.POST or None, user=request.user, commentary_id=commentary_id ) if form.is_valid(): domain = get_current_domain() # Get commentary commentary = form.get_commentary() email_context = {"commentary": commentary, "domain": domain} # Retrieve email_template for action if form.commentary_is_accepted(): email_template = "commentaries/vet_commentary_email_accepted.html" elif form.commentary_is_refused(): email_template = "commentaries/vet_commentary_email_rejected.html" email_context["refusal_reason"] = form.get_refusal_reason() email_context["further_explanation"] = form.cleaned_data[ "email_response_field" ] elif form.commentary_is_modified(): # For a modified commentary, redirect to request_commentary_form return redirect( reverse("commentaries:modify_commentary_request", args=(commentary.id,)) ) # Send email and process form email_text = render_to_string(email_template, email_context) email_args = ( "SciPost Commentary Page activated", email_text, commentary.requested_by.user.email, ["commentaries@%s" % domain], ) emailmessage = EmailMessage(*email_args, reply_to=["commentaries@%s" % domain]) emailmessage.send(fail_silently=False) commentary = form.process_commentary() messages.success(request, "SciPost Commentary request vetted.") return redirect(reverse("commentaries:vet_commentary_requests")) context = {"commentary_to_vet": commentary_to_vet, "form": form} return render(request, "commentaries/vet_commentary_requests.html", context)
[docs]@permission_required("scipost.can_vet_commentary_requests", raise_exception=True) def modify_commentary_request(request, commentary_id): """Modify a commentary request after vetting with status 'modified'.""" commentary = get_object_or_404( ( Commentary.objects.awaiting_vetting().exclude( requested_by=request.user.contributor ) ), id=commentary_id, ) form = RequestCommentaryForm(request.POST or None, instance=commentary) if form.is_valid(): domain = get_current_domain() # Process commentary data commentary = form.save(commit=False) commentary.vetted = True commentary.save() # Send email and process form email_template = "commentaries/vet_commentary_email_modified.html" email_text = render_to_string( email_template, {"commentary": commentary, "domain": domain} ) email_args = ( "SciPost Commentary Page activated", email_text, commentary.requested_by.user.email, ["commentaries@%s" % domain], ) emailmessage = EmailMessage(*email_args, reply_to=["commentaries@%s" % domain]) emailmessage.send(fail_silently=False) messages.success(request, "SciPost Commentary request modified and vetted.") return redirect(reverse("commentaries:vet_commentary_requests")) context = {"commentary": commentary, "form": form} return render(request, "commentaries/modify_commentary_request.html", context)
[docs]class CommentaryListView(PaginationMixin, ListView): model = Commentary form = CommentaryListSearchForm paginate_by = 10 context_object_name = "commentary_list"
[docs] def get_queryset(self): """Perform search form here already to get the right pagination numbers.""" self.form = self.form(self.request.GET) if self.form.is_valid() and self.form.has_changed(): return self.form.search_results() return self.model.objects.vetted().order_by("-latest_activity")
[docs] def get_context_data(self, **kwargs): # Call the base implementation first to get a context context = super().get_context_data(**kwargs) # Get newest comments context["comment_list"] = Comment.objects.vetted().order_by("-date_submitted")[ :10 ] # Form into the context! context["form"] = self.form return context
[docs]def commentary_detail(request, arxiv_or_DOI_string): commentary = get_object_or_404( Commentary.objects.vetted(), arxiv_or_DOI_string=arxiv_or_DOI_string ) form = CommentForm() context = {"commentary": commentary, "form": form} return render(request, "commentaries/commentary_detail.html", context)
[docs]@login_required @permission_required("scipost.can_submit_comments", raise_exception=True) @transaction.atomic def comment_on_publication(request, doi_label): """ This will let authors of an SciPost publication comment on their Publication by automatically creating a Commentary page if not exist already. """ publication = get_object_or_404( Publication.objects.published(), doi_label=doi_label, authors=request.user.contributor, ) form = CommentSciPostPublication( request.POST or None, request.FILES or None, publication=publication, current_user=request.user, ) if form.is_valid(): comment = form.save() messages.success(request, strings.acknowledge_request_commentary) return redirect(comment.content_object.get_absolute_url()) context = {"publication": publication, "form": form} return render(request, "commentaries/comment_on_publication.html", context)