import csv import datetime from django.contrib.auth import get_user_model from django.core.exceptions import ValidationError from django.http import HttpResponse from rest_framework.permissions import IsAuthenticated from rest_framework.renderers import JSONRenderer from rest_framework.response import Response from rest_framework.views import APIView from progress.models import ProgressLesson, Progress from progress.serializers import ProgressAnalyticSerializer, ProgressLessonSerializer from courses.api import CourseProgressApi from progress.tasks import add_next_lesson class CourseProgressDynamicView(APIView): renderer_classes = (JSONRenderer,) @staticmethod def get(request, token): if request.user.is_authenticated() and request.user.is_staff: try: progresses = Progress.objects.filter(course_token=token) res = {} for i in progresses: key = i.progresslesson_set.filter(status="done").count() res[key] = 1 if not key in res.keys() else res[key] + 1 return Response(res, status=200) except ValidationError: return Response("Bad request", status=400) return Response(status=403) class CourseProgressUserView(APIView): renderer_classes = (JSONRenderer,) @staticmethod def get(request, token): if request.user.is_authenticated() and request.user.is_staff: try: res = [] sorted_token_list = CourseProgressApi.get_topic_lesson(token) for p in Progress.objects.filter(course_token=token): progress = ProgressAnalyticSerializer(p).data progress['progress_course'] = p.progress_status(sorted_token_list) res.append(progress) return Response(res, status=200) except ValidationError: return Response("Bad request", status=400) return Response(status=403) class UpdateProgress(APIView): renderer_classes = (JSONRenderer,) @staticmethod def post(request): """ На вход обязательно передаётся параметр id (id узла). """ lesson_token = request.JSON.get('lesson_token', None) course_token = request.JSON.get('course_token', None) student_out_key = request.JSON.get('student_out_key', None) action = request.JSON.get('action', 'wait') comment = request.JSON.get('comment', None) if lesson_token is None or course_token is None: return Response('Не передан слаг курса или токен урока', status=400) try: is_student = student_out_key is None student = request.user if is_student else get_user_model().objects.get(out_key=student_out_key) if is_student: p = Progress.objects.get(user=student, course_token=course_token) else: p = Progress.objects.get( user=student, teacher=request.user, course_token=course_token, ) if p.active_lesson == lesson_token: return Response("Ошибка доступа", status=403) try: pv = ProgressLesson.objects.get( progress=p, lesson_token=p.active_lesson, ) if is_student and pv.status == ProgressLesson.STATUSES.fail and action == "wait": pv.status = ProgressLesson.STATUSES.wait elif not is_student and pv.status == ProgressLesson.STATUSES.wait: pv.status = action else: return Response("Ошибка прав доступа", status=403) pv.comment_tokens.append(comment) except ProgressLesson.DoesNotExist: pv = ProgressLesson.objects.create( date=datetime.datetime.now(), teacher=p.teacher, progress=p, lesson_token=p.active_lesson, status=ProgressLesson.STATUSES.done ) pv.save() if pv.status == ProgressLesson.STATUSES.done: #TODO: Ассинхроннаязадача для celery add_next_lesson(p) return Response(ProgressLessonSerializer(pv).data, status=200) except Progress.DoesNotExist: return Response('Не найден прогресс по заданным параметрам', status=404) class UploadCourseProgressUserView(APIView): renderer_classes = (JSONRenderer,) @staticmethod def get(request, token): if request.user.is_authenticated() and request.user.is_staff: try: response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="%s.csv"' % token sorted_token_list = CourseProgressApi.get_topic_lesson(token) writer = csv.writer(response) writer.writerow(['Имя', 'Почта', 'Последняя тема', 'Последний урок']) for p in Progress.objects.filter(course_token=token): progress = ProgressAnalyticSerializer(p).data progress['progress_course'] = p.progress_status(sorted_token_list) writer.writerow([ progress['name'], progress['email'], progress['progress_course'] and progress['progress_course'][0], progress['progress_course'] and progress['progress_course'][1], ]) return response except ValidationError: return Response("Bad request", status=400) return Response(status=403) class UserGuardView(APIView): renderer_classes = (JSONRenderer,) permission_classes = (IsAuthenticated,) @staticmethod def get(request, pk, page): try: user = get_user_model().objects.get(out_key=pk) except get_user_model().DoesNotExist: return Response("User doesn't exist", status=404) is_i = request.user == user res_403 = Response('Permission denied', status=403) res_204 = Response(status=204) if is_i and not request.user.groups.filter(name='teachers').exists() and page == 'homeworks': return res_403 if is_i and not \ request.user.groups.filter(name__in=['students', 'managers', 'lead_managers']).exists() \ and page == 'payment': return res_403 if is_i: return res_204 if page == 'profile' and (request.user.is_superuser or request.user.is_staff): return res_204 return res_403