summaryrefslogtreecommitdiff
path: root/api/views.py
diff options
context:
space:
mode:
Diffstat (limited to 'api/views.py')
-rw-r--r--api/views.py330
1 files changed, 330 insertions, 0 deletions
diff --git a/api/views.py b/api/views.py
new file mode 100644
index 0000000..14e04f0
--- /dev/null
+++ b/api/views.py
@@ -0,0 +1,330 @@
+from yaksh.models import (
+ Question, Quiz, QuestionPaper, QuestionSet, AnswerPaper, Course, Answer
+)
+from api.serializers import (
+ QuestionSerializer, QuizSerializer, QuestionPaperSerializer,
+ AnswerPaperSerializer
+)
+from rest_framework.views import APIView
+from rest_framework.response import Response
+from rest_framework import status
+from rest_framework import permissions
+from django.http import Http404
+from yaksh.code_server import get_result as get_result_from_code_server
+from yaksh.settings import SERVER_POOL_PORT, SERVER_HOST_NAME
+import json
+
+
+class QuestionList(APIView):
+ """ List all questions or create a new question. """
+
+ def get(self, request, format=None):
+ questions = Question.objects.filter(user=request.user)
+ serializer = QuestionSerializer(questions, many=True)
+ return Response(serializer.data)
+
+
+ def post(self, request, format=None):
+ serializer = QuestionSerializer(data=request.data)
+ if serializer.is_valid():
+ serializer.save()
+ return Response(serializer.data, status=status.HTTP_201_CREATED)
+ return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
+
+
+class QuestionDetail(APIView):
+ """ Retrieve, update or delete a question """
+
+ def get_question(self, pk, user):
+ try:
+ return Question.objects.get(pk=pk, user=user)
+ except Question.DoesNotExist:
+ raise Http404
+
+ def get(self, request, pk, format=None):
+ question = self.get_question(pk, request.user)
+ serializer = QuestionSerializer(question)
+ return Response(serializer.data)
+
+ def put(self, request, pk, format=None):
+ question = self.get_question(pk, request.user)
+ serializer = QuestionSerializer(question, data=request.data)
+ if serializer.is_valid():
+ serializer.save()
+ return Response(serializer.data)
+ return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
+
+ def delete(self, request, pk, format=None):
+ question = self.get_question(pk, request.user)
+ question.delete()
+ return Response(status=status.HTTP_204_NO_CONTENT)
+
+
+class AnswerPaperList(APIView):
+
+ def get_questionpaper(self, pk):
+ try:
+ return QuestionPaper.objects.get(pk=pk)
+ except QuestionPaper.DoesNotExist:
+ raise Http404
+
+ def get_course(self, pk):
+ try:
+ return Course.objects.get(pk=pk)
+ except Course.DoesNotExist:
+ raise Http404
+
+ def get_answerpapers(self, user):
+ return AnswerPaper.objects.filter(question_paper__quiz__creator=user)
+
+ def get(self, request, format=None):
+ user = request.user
+ answerpapers = self.get_answerpapers(user)
+ serializer = AnswerPaperSerializer(answerpapers, many=True)
+ return Response(serializer.data)
+
+ def is_user_allowed(self, user, course):
+ ''' if user is student or teacher or creator then allow '''
+ return user in course.students.all() or user in course.teachers.all() or user == course.creator
+
+ def post(self, request, format=None):
+ try:
+ questionpaperid = request.data['question_paper']
+ attempt_number = request.data['attempt_number']
+ course_id = request.data['course']
+ except KeyError:
+ return Response(status=status.HTTP_400_BAD_REQUEST)
+ user = request.user
+ ip = request.META['REMOTE_ADDR']
+ questionpaper = self.get_questionpaper(questionpaperid)
+ course = self.get_course(course_id)
+ if not self.is_user_allowed(user, course):
+ return Response(status=status.HTTP_400_BAD_REQUEST)
+ answerpaper = questionpaper.make_answerpaper(user, ip, attempt_number, course_id)
+ serializer = AnswerPaperSerializer(answerpaper)
+ return Response(serializer.data, status=status.HTTP_201_CREATED)
+
+
+class AnswerValidator(APIView):
+
+ def get_answerpaper(self, pk, user):
+ try:
+ return AnswerPaper.objects.get(pk=pk, user=user)
+ except AnswerPaper.DoesNotExist:
+ raise Http404
+
+ def get_question(self, pk, answerpaper):
+ try:
+ question = Question.objects.get(pk=pk)
+ if question in answerpaper.questions.all():
+ return question
+ else:
+ raise Http404
+ except AnswerPaper.DoesNotExist:
+ raise Http404
+
+ def get_answer(self, pk):
+ try:
+ return Answer.objects.get(pk=pk)
+ except Answer.DoesNotExist:
+ raise Http404
+
+ def post(self, request, answerpaper_id, question_id, format=None):
+ try:
+ user_answer = request.data['answer']
+ except KeyError:
+ return Response(status=status.HTTP_400_BAD_REQUEST)
+ user = request.user
+ answerpaper = self.get_answerpaper(answerpaper_id, user)
+ question = self.get_question(question_id, answerpaper)
+ # save answer uid
+ answer = Answer.objects.create(question=question, answer=user_answer)
+ answerpaper.answers.add(answer)
+ answerpaper.save()
+ json_data = None
+ if question.type in ['code', 'upload']:
+ json_data = question.consolidate_answer_data(user_answer, user)
+ result = answerpaper.validate_answer(user_answer, question, json_data, answer.id)
+
+ # updaTE RESult
+ if question.type not in ['code', 'upload']:
+ if result.get('success'):
+ answer.correct = True
+ answer.marks = question.points
+ answer.error = json.dumps(result.get('error'))
+ answer.save()
+ answerpaper.update_marks(state='inprogress')
+ return Response(result)
+
+ def get(self, request, uid):
+ answer = self.get_answer(uid)
+ url = '{0}:{1}'.format(SERVER_HOST_NAME, SERVER_POOL_PORT)
+ result = get_result_from_code_server(url, uid)
+ # update result
+ if result['status'] == 'done':
+ final_result = json.loads(result.get('result'))
+ answer.error = json.dumps(result.get('error'))
+ if final_result.get('success'):
+ answer.correct = True
+ answer.marks = answer.question.points
+ answer.save()
+ answerpaper = answer.answerpaper_set.get()
+ answerpaper.update_marks(state='inprogress')
+ return Response(result)
+
+
+class QuizList(APIView):
+ """ List all quizzes or create a new quiz """
+
+ def get(self, request, format=None):
+ quizzes = Quiz.objects.filter(creator=request.user)
+ serializer = QuizSerializer(quizzes, many=True)
+ return Response(serializer.data)
+
+ def post(self, request, format=None):
+ serializer = QuizSerializer(data=request.data)
+ if serializer.is_valid():
+ serializer.save()
+ return Response(serializer.data, status=status.HTTP_201_CREATED)
+ return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
+
+
+class QuizDetail(APIView):
+ """ Retrieve, update or delete a quiz """
+
+ def get_quiz(self, pk, user):
+ try:
+ return Quiz.objects.get(pk=pk, creator=user)
+ except Quiz.DoesNotExist:
+ raise Http404
+
+ def get(self, request, pk, format=None):
+ quiz = self.get_quiz(pk, request.user)
+ serializer = QuizSerializer(quiz)
+ return Response(serializer.data)
+
+ def put(self, request, pk, format=None):
+ quiz = self.get_quiz(pk, request.user)
+ serializer = QuizSerializer(quiz, data=request.data)
+ if serializer.is_valid():
+ serializer.save()
+ return Response(serializer.data)
+ return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
+
+ def delete(self, request, pk, format=None):
+ quiz = self.get_quiz(pk, request.user)
+ quiz.delete()
+ return Response(status=status.HTTP_204_NO_CONTENT)
+
+
+class QuestionPaperList(APIView):
+ """ List all question papers or create a new question paper """
+
+ def get_questionpapers(self, user):
+ return QuestionPaper.objects.filter(quiz__creator=user)
+
+ def questionpaper_exists(self, quiz_id):
+ return QuestionPaper.objects.filter(quiz=quiz_id).exists()
+
+ def check_quiz_creator(self, user, quiz_id):
+ try:
+ Quiz.objects.get(pk=quiz_id, creator=user)
+ except Quiz.DoesNotExist:
+ raise Http404
+
+ def check_questions_creator(self, user, question_ids):
+ for question_id in question_ids:
+ try:
+ Question.objects.get(pk=question_id, user=user)
+ except Question.DoesNotExist:
+ raise Http404
+
+ def check_questionsets_creator(self, user, questionset_ids):
+ for question_id in questionset_ids:
+ try:
+ questionset = QuestionSet.objects.get(pk=question_id)
+ for question in questionset.questions.all():
+ Question.objects.get(pk=question.id, user=user)
+ except (QuestionSet.DoesNotExist, Question.DoesNotExist):
+ raise Http404
+
+ def get(self, request, format=None):
+ questionpapers = self.get_questionpapers(request.user)
+ serializer = QuestionPaperSerializer(questionpapers, many=True)
+ return Response(serializer.data)
+
+ def post(self, request, format=None):
+ serializer = QuestionPaperSerializer(data=request.data)
+ if serializer.is_valid():
+ user = request.user
+ quiz_id = request.data.get('quiz')
+ question_ids = request.data.get('fixed_questions', [])
+ questionset_ids = request.data.get('random_questions', [])
+ if self.questionpaper_exists(quiz_id):
+ return Response({'error': 'Already exists'},
+ status=status.HTTP_409_CONFLICT)
+ self.check_quiz_creator(user, quiz_id)
+ self.check_questions_creator(user, question_ids)
+ self.check_questionsets_creator(user, questionset_ids)
+ serializer.save()
+ return Response(serializer.data, status=status.HTTP_201_CREATED)
+ return Response(serializer.errors, status.HTTP_400_BAD_REQUEST)
+
+
+class QuestionPaperDetail(APIView):
+ """ Retrieve, update or delete a question paper"""
+
+ def get_questionpaper(self, pk, user):
+ try:
+ return QuestionPaper.objects.get(pk=pk, quiz__creator=user)
+ except QuestionPaper.DoesNotExist:
+ raise Http404
+
+ def get(self, request, pk, format=None):
+ questionpaper = self.get_questionpaper(pk, request.user)
+ serializer = QuestionPaperSerializer(questionpaper)
+ return Response(serializer.data)
+
+ def check_quiz_creator(self, user, quiz_id):
+ try:
+ Quiz.objects.get(pk=quiz_id, creator=user)
+ except Quiz.DoesNotExist:
+ raise Http404
+
+ def check_questions_creator(self, user, question_ids):
+ for question_id in question_ids:
+ try:
+ Question.objects.get(pk=question_id, user=user)
+ except Question.DoesNotExist:
+ raise Http404
+
+ def check_questionsets_creator(self, user, questionset_ids):
+ for question_id in questionset_ids:
+ try:
+ questionset = QuestionSet.objects.get(pk=question_id)
+ for question in questionset.questions.all():
+ Question.objects.get(pk=question.id, user=user)
+ except (QuestionSet.DoesNotExist, Question.DoesNotExist):
+ raise Http404
+
+ def put(self, request, pk, format=None):
+ user = request.user
+ questionpaper = self.get_questionpaper(pk, user)
+ serializer = QuestionPaperSerializer(questionpaper, data=request.data)
+ if serializer.is_valid():
+ user = request.user
+ quiz_id = request.data.get('quiz')
+ question_ids = request.data.get('fixed_questions', [])
+ questionset_ids = request.data.get('random_questions', [])
+ self.check_quiz_creator(user, quiz_id)
+ self.check_questions_creator(user, question_ids)
+ self.check_questionsets_creator(user, questionset_ids)
+ serializer.save()
+ return Response(serializer.data)
+ return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
+
+ def delete(self, request, pk, format=None):
+ questionpaper = self.get_questionpaper(pk, request.user)
+ questionpaper.delete()
+ return Response(status=status.HTTP_204_NO_CONTENT)
+