from django.core.exceptions import PermissionDenied as DjangoPermissionDenied from django.db.models import Q from rest_framework import generics, permissions, status from rest_framework.response import Response from rest_framework.exceptions import PermissionDenied, ValidationError from django_filters import rest_framework as filters from wagtail.core.models import Page from opentech.api.pagination import StandardResultsSetPagination from opentech.apply.activity.models import Activity, COMMENT from opentech.apply.activity.messaging import messenger, MESSAGES from .models import ApplicationSubmission from .models.applications import SubmittableStreamForm from .serializers import ( CommentSerializer, CommentCreateSerializer, RoundLabSerializer, SubmissionActionSerializer, SubmissionListSerializer, SubmissionDetailSerializer, ) from .permissions import IsApplyStaffUser class RoundLabFilter(filters.ModelChoiceFilter): def filter(self, qs, value): if not value: return qs return qs.filter(Q(round=value) | Q(page=value)) class SubmissionsFilter(filters.FilterSet): # TODO replace with better call to Round and Lab base class round = RoundLabFilter(queryset=Page.objects.type(SubmittableStreamForm)) class Meta: model = ApplicationSubmission fields = ('status', 'round') class SubmissionList(generics.ListAPIView): queryset = ApplicationSubmission.objects.current() serializer_class = SubmissionListSerializer permission_classes = ( permissions.IsAuthenticated, IsApplyStaffUser, ) filter_backends = (filters.DjangoFilterBackend,) filter_class = SubmissionsFilter pagination_class = StandardResultsSetPagination class SubmissionDetail(generics.RetrieveAPIView): queryset = ApplicationSubmission.objects.all() serializer_class = SubmissionDetailSerializer permission_classes = ( permissions.IsAuthenticated, IsApplyStaffUser, ) class SubmissionAction(generics.RetrieveAPIView): queryset = ApplicationSubmission.objects.all() serializer_class = SubmissionActionSerializer permission_classes = ( permissions.IsAuthenticated, IsApplyStaffUser, ) def post(self, request, *args, **kwargs): action = request.data.get('action') if not action: raise ValidationError('Action must be provided.') obj = self.get_object() try: obj.perform_transition(action, self.request.user, request=self.request) except DjangoPermissionDenied as e: raise PermissionDenied(str(e)) return Response(status=status.HTTP_200_OK) class RoundLabDetail(generics.RetrieveAPIView): # TODO replace with better call to Round and Lab base class queryset = Page.objects.type(SubmittableStreamForm) serializer_class = RoundLabSerializer permission_classes = ( permissions.IsAuthenticated, IsApplyStaffUser, ) def get_object(self): return super().get_object().specific class CommentList(generics.ListAPIView): queryset = Activity.comments.all() serializer_class = CommentSerializer permission_classes = ( permissions.IsAuthenticated, IsApplyStaffUser, ) filter_backends = (filters.DjangoFilterBackend,) filter_fields = ('submission', 'visibility') pagination_class = StandardResultsSetPagination def get_queryset(self): return super().get_queryset().visible_to(self.request.user) class CommentListCreate(generics.ListCreateAPIView): queryset = Activity.comments.all() serializer_class = CommentCreateSerializer permission_classes = ( permissions.IsAuthenticated, IsApplyStaffUser, ) filter_backends = (filters.DjangoFilterBackend,) filter_fields = ('visibility',) pagination_class = StandardResultsSetPagination def get_queryset(self): return super().get_queryset().filter( submission=self.kwargs['pk'] ).visible_to(self.request.user) def perform_create(self, serializer): obj = serializer.save( type=COMMENT, user=self.request.user, submission_id=self.kwargs['pk'] ) messenger( MESSAGES.COMMENT, request=self.request, user=self.request.user, submission=obj.submission, related=obj, )