diff --git a/luna-gateway/luna_gateway/luna_gateway/settings/base.py b/luna-gateway/luna_gateway/luna_gateway/settings/base.py index 5e580e2..6b697ed 100644 --- a/luna-gateway/luna_gateway/luna_gateway/settings/base.py +++ b/luna-gateway/luna_gateway/luna_gateway/settings/base.py @@ -136,7 +136,7 @@ REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': - ('rest_framework.permissions.IsAuthenticatedOrReadOnly', ), + ('rest_framework.permissions.IsAuthenticated', ), 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', diff --git a/luna-gateway/luna_gateway/tasks/urls.py b/luna-gateway/luna_gateway/tasks/urls.py index 214f5f5..69c4e31 100644 --- a/luna-gateway/luna_gateway/tasks/urls.py +++ b/luna-gateway/luna_gateway/tasks/urls.py @@ -4,7 +4,7 @@ router = routers.DefaultRouter() -router.register(r'tasks', views.TaskViewSet) +router.register(r'tasks', views.TaskViewSet, base_name='task') router.register(r'testcases', views.TescaseViewSet) urlpatterns = [ diff --git a/luna-gateway/luna_gateway/tasks/views.py b/luna-gateway/luna_gateway/tasks/views.py index 029686e..44d304e 100644 --- a/luna-gateway/luna_gateway/tasks/views.py +++ b/luna-gateway/luna_gateway/tasks/views.py @@ -2,7 +2,10 @@ from rest_framework import viewsets from rest_framework.decorators import action from rest_framework.response import Response +from rest_framework import status +from answers.models import Answer +from answers.serializers import AnswerSerializer from .models import Task, Testcase from .serializers import TaskSerializer, TestcaseSerializer @@ -14,6 +17,32 @@ class TaskViewSet(viewsets.ModelViewSet): ordering_fields = '__all__' ordering = ('pk', ) + def retrieve(self, request, *args, **kwargs): + task = self.get_object() + user = request.user + + if (task.order == 1): + return self._get_task_or_task_with_answer(task, user) + + elif (task.order is None): + return self._get_task_or_task_with_answer(task, user) + + else: + before_task = Task.objects.get(order=task.order - 1) + try: + Answer.objects.get( + owned_by=user, + task=before_task, + ) + return self._get_task_or_task_with_answer(task, user) + except Answer.DoesNotExist: + return Response( + { + "messages": "You should to solve the before task" + }, + status=status.HTTP_403_FORBIDDEN + ) + @action(detail=True) def testcases(self, request, pk=None): testcases = Testcase.objects.filter(task__pk=pk, is_hidden=False) @@ -24,6 +53,23 @@ def testcases(self, request, pk=None): ) return Response(serializer.data) + def _get_task_or_task_with_answer(self, task, user): + task_json = self.get_serializer(task).data + try: + answer_data = Answer.objects.get( + owned_by=user, + task=task, + ) + answer = AnswerSerializer(answer_data).data + return Response({ + **task_json, + "answer": answer, + }) + except Answer.DoesNotExist: + return Response({ + **task_json, + }) + class TescaseViewSet(viewsets.ModelViewSet): queryset = Testcase.objects.all() diff --git a/luna-gateway/luna_gateway/topics/serializers.py b/luna-gateway/luna_gateway/topics/serializers.py index 29f6806..2f35b9a 100644 --- a/luna-gateway/luna_gateway/topics/serializers.py +++ b/luna-gateway/luna_gateway/topics/serializers.py @@ -9,6 +9,7 @@ class Meta: 'pk', 'url', 'topic_name', + 'description', ) diff --git a/luna-gateway/luna_gateway/topics/urls.py b/luna-gateway/luna_gateway/topics/urls.py index fca9b1f..74664ec 100644 --- a/luna-gateway/luna_gateway/topics/urls.py +++ b/luna-gateway/luna_gateway/topics/urls.py @@ -4,7 +4,7 @@ router = routers.DefaultRouter() -router.register(r'topics', views.TopicViewSet) +router.register(r'topics', views.TopicViewSet, base_name='topic') router.register(r'levels', views.LevelViewSet) router.register(r'topic-levels', views.TopicLevelViewSet) diff --git a/luna-gateway/luna_gateway/topics/views.py b/luna-gateway/luna_gateway/topics/views.py index 12bd798..6e3f1ab 100644 --- a/luna-gateway/luna_gateway/topics/views.py +++ b/luna-gateway/luna_gateway/topics/views.py @@ -3,6 +3,7 @@ from rest_framework.decorators import action from rest_framework.response import Response +from answers.models import Answer from tasks.models import Task from tasks.serializers import TaskSerializer from .models import Topic, Level, TopicLevel @@ -16,15 +17,72 @@ class TopicViewSet(viewsets.ModelViewSet): ordering_fields = '__all__' ordering = ('pk', ) + def list(self, request, *args, **kwargs): + user = request.user + queryset = self.filter_queryset(self.get_queryset()) + + topics_data = self.get_serializer(queryset, many=True).data + topics = [ + self._get_topic_detail_by_user(topic, user) + for topic in topics_data + ] + + return Response(topics) + @action(detail=True) def tasks(self, request, pk=None): - tasks = Task.objects.filter(main_topic__topic__pk=pk) - serializer = TaskSerializer( + # Get User from request + user = request.user + + # Get Answered tasks from Answer that User've solved + answered_task_pks = Answer.objects.filter( + owned_by=user, + task__main_topic__pk=pk, + ).values_list( + 'task', flat=True + ) + + tasks = Task.objects.filter( + main_topic__topic__pk=pk, + order__isnull=False, + ) + + tasks_data = TaskSerializer( tasks, many=True, - context={'request': request}, - ) - return Response(serializer.data) + context={ + 'request': request + }, + ).data + + # Add `"answered": True,` for answered tasks + tasks_serializer = [ + self._add_answered_status(task, answered_task_pks) + for task in tasks_data + ] + + return Response(tasks_serializer) + + def _add_answered_status(self, task, answered_task_pks): + if task['id'] in answered_task_pks: + task['answered'] = True + return task + + def _get_topic_detail_by_user(self, topic, user): + completed_task = Answer.objects.filter( + owned_by=user, + task__main_topic__pk=topic['pk'], + ).count() + total_tasks = Task.objects.filter( + main_topic__topic__pk=topic['pk'], + order__isnull=False, + ).count() + + return { + **topic, + "total_tasks": total_tasks, + "completed_tasks": completed_task, + } class LevelViewSet(viewsets.ModelViewSet):