import logging from django.core.exceptions import ObjectDoesNotExist from rest_framework import mixins, status, viewsets from rest_framework.response import Response from core import models, permissions, serializers from core.models import TutorSubmissionAssignment from core.permissions import IsTutorOrReviewer from core.serializers import AssignmentDetailSerializer, AssignmentSerializer log = logging.getLogger(__name__) class SubscriptionApiViewSet( mixins.RetrieveModelMixin, mixins.CreateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet): permission_classes = (permissions.IsTutorOrReviewer,) serializer_class = serializers.SubscriptionSerializer def get_queryset(self): return models.SubmissionSubscription.objects.filter( owner=self.request.user) def _get_subscription_if_type_exists(self, data): try: return models.SubmissionSubscription.objects.get( owner=self.request.user, query_type=data.get('query_type', ''), query_key=data.get('query_key'), feedback_stage=data.get( 'feedback_stage', models.SubmissionSubscription.FEEDBACK_CREATION) ) except ObjectDoesNotExist: return None def create(self, request, *args, **kwargs): subscription = self._get_subscription_if_type_exists(request.data) if subscription and not subscription.deactivated: return Response({'Error': 'Subscriptions have to be unique.'}, status.HTTP_409_CONFLICT) elif subscription and subscription.deactivated: serializer = self.get_serializer(subscription, data=request.data) else: serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) subscription = serializer.save() if subscription.query_type == models.SubmissionSubscription.STUDENT_QUERY: # noqa subscription.reserve_all_assignments_for_a_student() headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) class AssignmentApiViewSet( mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet): permission_classes = (IsTutorOrReviewer,) queryset = TutorSubmissionAssignment.objects.all() serializer_class = AssignmentSerializer def _fetch_assignment(self, serializer): try: serializer.save() except models.SubscriptionEnded as err: return Response({'Error': str(err)}, status=status.HTTP_410_GONE) except models.SubscriptionTemporarilyEnded as err: return Response({'Error': str(err)}, status=status.HTTP_404_NOT_FOUND) except models.NotMoreThanTwoOpenAssignmentsAllowed as err: return Response({'Error': str(err)}, status=status.HTTP_403_FORBIDDEN) return Response(serializer.data, status=status.HTTP_201_CREATED) def get_queryset(self): """ Get only assignments of that user """ return TutorSubmissionAssignment.objects.filter( subscription__owner=self.request.user) def destroy(self, request, pk=None): """ Stop working on the assignment before it is finished """ instance = self.get_object() if instance.is_done: return Response(status=status.HTTP_403_FORBIDDEN) instance.delete() return Response(status=status.HTTP_204_NO_CONTENT) def create(self, request, *args, **kwargs): context = self.get_serializer_context() serializer = AssignmentDetailSerializer(data=request.data, context=context) serializer.is_valid(raise_exception=True) return self._fetch_assignment(serializer) def retrieve(self, request, *args, **kwargs): assignment = self.get_object() serializer = AssignmentDetailSerializer(assignment) return Response(serializer.data)