-
Jean-Sébastien Caux authorede9a0729b
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
views.py 18.87 KiB
__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
__license__ = "AGPL v3"
from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required
from django.core.urlresolvers import reverse, reverse_lazy
from django.db.models import Count
from django.http import Http404
from django.shortcuts import get_object_or_404, render, redirect
from django.utils import timezone
from django.views.generic.detail import DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.views.generic.list import ListView
from submissions.models import Submission
from .constants import (
POTENTIAL_FELLOWSHIP_STATUSES, POTENTIAL_FELLOWSHIP_EVENT_STATUSUPDATED,
POTENTIAL_FELLOWSHIP_INVITED, potential_fellowship_statuses_dict,
POTENTIAL_FELLOWSHIP_EVENT_VOTED_ON, POTENTIAL_FELLOWSHIP_EVENT_EMAILED)
from .forms import FellowshipForm, FellowshipTerminateForm, FellowshipRemoveSubmissionForm,\
FellowshipAddSubmissionForm, AddFellowshipForm, SubmissionAddFellowshipForm,\
FellowshipRemoveProceedingsForm, FellowshipAddProceedingsForm, SubmissionAddVotingFellowForm,\
FellowVotingRemoveSubmissionForm,\
PotentialFellowshipForm, PotentialFellowshipStatusForm, PotentialFellowshipEventForm
from .models import Fellowship, PotentialFellowship, PotentialFellowshipEvent
from scipost.constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS, subject_areas_raw_dict
from scipost.mixins import PermissionsMixin, PaginationMixin, RequestViewMixin
from mails.views import MailView
class EditorialCollegesView(ListView):
model = Fellowship
template_name = 'colleges/colleges.html'
def get_queryset(self):
queryset = Fellowship.objects.none()
return queryset
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['disciplines'] = {}
for discipline in SCIPOST_DISCIPLINES:
qs = Fellowship.objects.active().regular().filter(
contributor__profile__discipline=discipline[0])
if qs:
context['disciplines'][discipline[1]] = (qs, subject_areas_raw_dict[discipline[1]])
return context
class FellowshipListView(PermissionsMixin, PaginationMixin, ListView):
"""
List Fellowship instances (accessible to College managers).
"""
permission_required = 'scipost.can_manage_college_composition'
model = Fellowship
paginate_by = 25
def get_queryset(self):
"""
Return a queryset of Fellowships filtered by optional GET data.
"""
queryset = Fellowship.objects.all()
if self.kwargs.get('discipline', None):
queryset = queryset.filter(
contributor__profile__discipline=self.kwargs['discipline'].lower())
if self.kwargs.get('expertise', None):
queryset = queryset.filter(
contributor__profile__expertises__contains=[self.kwargs['expertise']])
if self.request.GET.get('type', None):
if self.request.GET.get('type') == 'regular':
queryset = queryset.filter(guest=False)
elif self.request.GET.get('type') == 'guest':
queryset = queryset.filter(guest=True)
return queryset
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['subject_areas'] = SCIPOST_SUBJECT_AREAS
return context
class FellowshipDetailView(PermissionsMixin, DetailView):
permission_required = 'scipost.can_manage_college_composition'
model = Fellowship
@login_required
@permission_required('scipost.can_manage_college_composition', raise_exception=True)
def fellowship_add(request):
"""
Create a new Fellowship.
"""
form = AddFellowshipForm(request.POST or None, initial=request.GET or None)
if form.is_valid():
fellowship = form.save()
messages.success(request, 'Fellowship added.')
return redirect(fellowship.get_absolute_url())
context = {
'form': form
}
return render(request, 'colleges/fellowship_add.html', context)
@login_required
@permission_required('scipost.can_manage_college_composition', raise_exception=True)
def fellowship_edit(request, id):
"""
Edit basic information about fellowship.
"""
fellowship = get_object_or_404(Fellowship, id=id)
form = FellowshipForm(request.POST or None, instance=fellowship)
if form.is_valid():
form.save()
messages.success(request, 'Fellowship updated.')
return redirect(fellowship.get_absolute_url())
context = {
'fellowship': fellowship,
'form': form
}
return render(request, 'colleges/fellowship_edit.html', context)
@login_required
@permission_required('scipost.can_manage_college_composition', raise_exception=True)
def fellowship_terminate(request, id):
"""
Terminate Fellowship by setting the until_date to today's date.
"""
fellowship = get_object_or_404(Fellowship, id=id)
form = FellowshipTerminateForm(request.POST or None, instance=fellowship)
if form.is_valid():
form.save()
messages.success(request, 'Fellowship terminated.')
else:
messages.warning(request, 'Fellowship has not been terminated, please try again.')
return redirect(fellowship.get_absolute_url())
@login_required
@permission_required('scipost.can_manage_college_composition', raise_exception=True)
def submission_pool(request, identifier_w_vn_nr):
"""
List all Fellowships related to Submission.
"""
submission = get_object_or_404(Submission, preprint__identifier_w_vn_nr=identifier_w_vn_nr)
context = {
'submission': submission
}
return render(request, 'colleges/submission_pool.html', context)
@login_required
@permission_required('scipost.can_manage_college_composition', raise_exception=True)
def submission_voting_fellows(request, identifier_w_vn_nr):
"""
List all Fellowships selected for voting on the EIC related to Submission.
"""
submission = get_object_or_404(Submission, preprint__identifier_w_vn_nr=identifier_w_vn_nr)
context = {
'submission': submission
}
return render(request, 'colleges/submission_voting_fellows.html', context)
@login_required
@permission_required('scipost.can_manage_college_composition', raise_exception=True)
def submission_add_fellowship_voting(request, identifier_w_vn_nr):
"""Add Fellowship to the Fellows voting on the EICRecommendation of a Submission."""
submission = get_object_or_404(Submission, preprint__identifier_w_vn_nr=identifier_w_vn_nr)
form = SubmissionAddVotingFellowForm(request.POST or None, instance=submission)
if form.is_valid():
form.save()
messages.success(request, 'Fellowship {fellowship} ({id}) added to voting Fellows.'.format(
fellowship=form.cleaned_data['fellowship'].contributor,
id=form.cleaned_data['fellowship'].id))
return redirect(reverse('colleges:submission_voting_fellows',
args=(submission.preprint.identifier_w_vn_nr,)))
context = {
'submission': submission,
'form': form,
}
return render(request, 'colleges/submission_add_for_voting.html', context)
@login_required
@permission_required('scipost.can_manage_college_composition', raise_exception=True)
def fellowship_remove_submission_voting(request, id, identifier_w_vn_nr):
"""Remove Fellow from the EICRecommendation voting group for the Submission."""
fellowship = get_object_or_404(Fellowship, id=id)
submission = get_object_or_404(
fellowship.voting_pool.all(), preprint__identifier_w_vn_nr=identifier_w_vn_nr)
form = FellowVotingRemoveSubmissionForm(request.POST or None,
submission=submission, instance=fellowship)
if form.is_valid() and request.POST:
form.save()
messages.success(request, 'Submission {submission_id} removed from Fellowship.'.format(
submission_id=identifier_w_vn_nr))
return redirect(reverse('colleges:submission_voting_fellows',
args=(submission.preprint.identifier_w_vn_nr,)))
context = {
'fellowship': fellowship,
'form': form,
'submission': submission
}
return render(request, 'colleges/fellowship_submission_remove_voting.html', context)
@login_required
@permission_required('scipost.can_manage_college_composition', raise_exception=True)
def submission_add_fellowship(request, identifier_w_vn_nr):
"""Add Fellowship to the pool of a Submission."""
submission = get_object_or_404(Submission, preprint__identifier_w_vn_nr=identifier_w_vn_nr)
form = SubmissionAddFellowshipForm(request.POST or None, instance=submission)
if form.is_valid():
form.save()
messages.success(request, 'Fellowship {fellowship} ({id}) added to Submission.'.format(
fellowship=form.cleaned_data['fellowship'].contributor,
id=form.cleaned_data['fellowship'].id))
return redirect(reverse('colleges:submission',
args=(submission.preprint.identifier_w_vn_nr,)))
context = {
'submission': submission,
'form': form,
}
return render(request, 'colleges/submission_add.html', context)
@login_required
@permission_required('scipost.can_manage_college_composition', raise_exception=True)
def fellowship_remove_submission(request, id, identifier_w_vn_nr):
"""Remove Submission from the pool of a Fellowship."""
fellowship = get_object_or_404(Fellowship, id=id)
submission = get_object_or_404(
fellowship.pool.all(), preprint__identifier_w_vn_nr=identifier_w_vn_nr)
form = FellowshipRemoveSubmissionForm(request.POST or None,
submission=submission, instance=fellowship)
if form.is_valid() and request.POST:
form.save()
messages.success(request, 'Submission {submission_id} removed from Fellowship.'.format(
submission_id=identifier_w_vn_nr))
return redirect(fellowship.get_absolute_url())
context = {
'fellowship': fellowship,
'form': form,
'submission': submission
}
return render(request, 'colleges/fellowship_submission_remove.html', context)
@login_required
@permission_required('scipost.can_manage_college_composition', raise_exception=True)
def fellowship_add_submission(request, id):
"""Add Submission to the pool of a Fellowship."""
fellowship = get_object_or_404(Fellowship, id=id)
form = FellowshipAddSubmissionForm(request.POST or None, instance=fellowship)
if form.is_valid():
form.save()
messages.success(request, 'Submission {submission_id} added to Fellowship.'.format(
submission_id=form.cleaned_data['submission'].preprint.identifier_w_vn_nr))
return redirect(fellowship.get_absolute_url())
context = {
'fellowship': fellowship,
'form': form,
}
return render(request, 'colleges/fellowship_submission_add.html', context)
@login_required
@permission_required('scipost.can_manage_college_composition', raise_exception=True)
def fellowship_remove_proceedings(request, id, proceedings_id):
"""
Remove Proceedings from the pool of a Fellowship.
"""
fellowship = get_object_or_404(Fellowship, id=id)
proceedings = get_object_or_404(fellowship.proceedings.all(), id=proceedings_id)
form = FellowshipRemoveProceedingsForm(request.POST or None,
proceedings=proceedings, instance=fellowship)
if form.is_valid() and request.POST:
form.save()
messages.success(request, 'Proceedings %s removed from Fellowship.' % str(proceedings))
return redirect(fellowship.get_absolute_url())
context = {
'fellowship': fellowship,
'form': form,
'proceedings': proceedings
}
return render(request, 'colleges/fellowship_proceedings_remove.html', context)
@login_required
@permission_required('scipost.can_manage_college_composition', raise_exception=True)
def fellowship_add_proceedings(request, id):
"""
Add Proceedings to the pool of a Fellowship.
"""
fellowship = get_object_or_404(Fellowship, id=id)
form = FellowshipAddProceedingsForm(request.POST or None, instance=fellowship)
if form.is_valid():
form.save()
proceedings = form.cleaned_data.get('proceedings', '')
messages.success(request, 'Proceedings %s added to Fellowship.' % str(proceedings))
return redirect(fellowship.get_absolute_url())
context = {
'fellowship': fellowship,
'form': form,
}
return render(request, 'colleges/fellowship_proceedings_add.html', context)
# Potential Fellowships
class PotentialFellowshipCreateView(PermissionsMixin, RequestViewMixin, CreateView):
"""
Formview to create a new Potential Fellowship.
"""
permission_required = 'scipost.can_add_potentialfellowship'
form_class = PotentialFellowshipForm
template_name = 'colleges/potentialfellowship_form.html'
success_url = reverse_lazy('colleges:potential_fellowships')
class PotentialFellowshipUpdateView(PermissionsMixin, RequestViewMixin, UpdateView):
"""
Formview to update a Potential Fellowship.
"""
permission_required = 'scipost.can_manage_college_composition'
model = PotentialFellowship
form_class = PotentialFellowshipForm
template_name = 'colleges/potentialfellowship_form.html'
success_url = reverse_lazy('colleges:potential_fellowships')
class PotentialFellowshipUpdateStatusView(PermissionsMixin, UpdateView):
"""
Formview to update the status of a Potential Fellowship.
"""
permission_required = 'scipost.can_manage_college_composition'
model = PotentialFellowship
fields = ['status']
success_url = reverse_lazy('colleges:potential_fellowships')
def form_valid(self, form):
event = PotentialFellowshipEvent(
potfel=self.object,
event=POTENTIAL_FELLOWSHIP_EVENT_STATUSUPDATED,
comments=('Status updated to %s'
% potential_fellowship_statuses_dict[form.cleaned_data['status']]),
noted_on=timezone.now(),
noted_by=self.request.user.contributor)
event.save()
return super().form_valid(form)
class PotentialFellowshipDeleteView(PermissionsMixin, DeleteView):
"""
Delete a Potential Fellowship.
"""
permission_required = 'scipost.can_manage_college_composition'
model = PotentialFellowship
success_url = reverse_lazy('colleges:potential_fellowships')
class PotentialFellowshipListView(PermissionsMixin, PaginationMixin, ListView):
"""
List the PotentialFellowship object instances.
"""
permission_required = 'scipost.can_view_potentialfellowship_list'
model = PotentialFellowship
paginate_by = 25
def get_queryset(self):
"""
Return a queryset of PotentialFellowships using optional GET data.
"""
queryset = PotentialFellowship.objects.all()
if self.kwargs.get('discipline', None):
queryset = queryset.filter(profile__discipline=self.kwargs['discipline'].lower())
if self.kwargs.get('expertise', None):
queryset = queryset.filter(profile__expertises__contains=[self.kwargs['expertise']])
if self.request.GET.get('status', None):
queryset = queryset.filter(status=self.request.GET.get('status'))
return queryset
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['potfels_to_vote_on'] = PotentialFellowship.objects.to_vote_on(
self.request.user.contributor)
context['potfels_voted_on'] = PotentialFellowship.objects.voted_on(
self.request.user.contributor)
context['subject_areas'] = SCIPOST_SUBJECT_AREAS
context['statuses'] = POTENTIAL_FELLOWSHIP_STATUSES
return context
class PotentialFellowshipDetailView(PermissionsMixin, DetailView):
permission_required = 'scipost.can_view_potentialfellowship_list'
model = PotentialFellowship
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['pfstatus_form'] = PotentialFellowshipStatusForm(
initial={'status': self.object.status})
context['pfevent_form'] = PotentialFellowshipEventForm()
return context
@login_required
@permission_required('scipost.can_vote_on_potentialfellowship', raise_exception=True)
def vote_on_potential_fellowship(request, potfel_id, vote):
potfel = get_object_or_404(PotentialFellowship, pk=potfel_id)
potfel.in_agreement.remove(request.user.contributor)
potfel.in_abstain.remove(request.user.contributor)
potfel.in_disagreement.remove(request.user.contributor)
if vote == 'A':
potfel.in_agreement.add(request.user.contributor)
comments = 'Voted Agree'
elif vote == 'N':
potfel.in_abstain.add(request.user.contributor)
comments = 'Voted Abstain'
elif vote == 'D':
potfel.in_disagreement.add(request.user.contributor)
comments = 'Voted Disagree'
else:
raise Http404
newevent = PotentialFellowshipEvent(
potfel=potfel, event=POTENTIAL_FELLOWSHIP_EVENT_VOTED_ON,
comments=comments, noted_by=request.user.contributor)
newevent.save()
return redirect(reverse('colleges:potential_fellowships'))
class PotentialFellowshipInitialEmailView(PermissionsMixin, MailView):
"""Send a templated email to a Potential Fellow."""
permission_required = 'scipost.can_manage_college_composition'
queryset = PotentialFellowship.objects.all()
mail_code = 'potentialfellowships/invite_potential_fellow_initial'
success_url = reverse_lazy('colleges:potential_fellowships')
def form_valid(self, form):
"""Create an event associated to this outgoing email."""
event = PotentialFellowshipEvent(
potfel=self.object,
event=POTENTIAL_FELLOWSHIP_EVENT_EMAILED,
comments='Emailed initial template to potential Fellow',
noted_on=timezone.now(),
noted_by=self.request.user.contributor)
event.save()
self.object.status = POTENTIAL_FELLOWSHIP_INVITED
self.object.save()
return super().form_valid(form)
class PotentialFellowshipEventCreateView(PermissionsMixin, CreateView):
"""
Add an event for a Potential Fellowship.
"""
permission_required = 'scipost.can_manage_college_composition'
form_class = PotentialFellowshipEventForm
success_url = reverse_lazy('colleges:potential_fellowships')
def form_valid(self, form):
form.instance.potfel = get_object_or_404(PotentialFellowship, id=self.kwargs['pk'])
form.instance.noted_on = timezone.now()
form.instance.noted_by = self.request.user.contributor
messages.success(self.request, 'Event added successfully')
return super().form_valid(form)