def enroll(request, **kwargs): """ Enroll student error codes: 2 - Group you chosen is full 3 - You have too much secondary groups 4 - You can't enroll to a group you have already enrolled to 6 - Enroll with insufficient medical group """ serializer = EnrollSerializer(data=request.data) serializer.is_valid(raise_exception=True) group = get_object_or_404(Group, pk=serializer.validated_data["group_id"]) student = request.user.student if group.minimum_medical_group_id is not None \ and student.medical_group_id * group.minimum_medical_group_id <= \ 0 \ and not ( student.medical_group_id == 0 and group.minimum_medical_group_id == 0): return Response(status=status.HTTP_400_BAD_REQUEST, data=error_detail(*EnrollErrors.MEDICAL_DISALLOWANCE)) try: enroll_student(group, student) except IntegrityError: return Response(status=status.HTTP_400_BAD_REQUEST, data=error_detail(*EnrollErrors.DOUBLE_ENROLL)) except InternalError as e: if "too much groups" in str(e): return Response(status=status.HTTP_400_BAD_REQUEST, data=error_detail(*EnrollErrors.TOO_MUCH_GROUPS)) else: return Response(status=status.HTTP_400_BAD_REQUEST, data=error_detail(*EnrollErrors.GROUP_IS_FULL)) return Response({})
def reference_upload(request, **kwargs): serializer = ReferenceUploadSerializer(data=request.data) serializer.is_valid(raise_exception=True) image = image_optimizer( serializer.validated_data['image'], resize_method="thumbnail", ) if image.size > settings.MAX_IMAGE_SIZE: return Response( status=status.HTTP_400_BAD_REQUEST, data=error_detail(*ReferenceErrors.IMAGE_FILE_SIZE_TOO_BIG)) width, height = image.image.size if not (settings.MIN_IMAGE_DIMENSION <= width <= settings.MAX_IMAGE_DIMENSION and settings.MIN_IMAGE_DIMENSION <= height <= settings.MAX_IMAGE_DIMENSION): return Response(status=status.HTTP_400_BAD_REQUEST, data=error_detail(*ReferenceErrors.INVALID_IMAGE_SIZE)) student = request.user # user.pk == user.student.pk try: with transaction.atomic(): ref = serializer.save(semester=get_ongoing_semester(), student_id=student.pk) count = Reference.objects.filter( student_id=student.pk, uploaded__date=ref.uploaded.date()).count() assert count == 1 except AssertionError: return Response( status=status.HTTP_400_BAD_REQUEST, data=error_detail(*ReferenceErrors.TOO_MUCH_UPLOADS_PER_DAY)) return Response({})
def mark_attendance(request, **kwargs): serializer = AttendanceMarkSerializer(data=request.data) serializer.is_valid(raise_exception=True) trainer = request.user # trainer.pk == trainer.user.pk try: training = Training.objects.select_related("group").only( "group__trainer", "start", "end").get(pk=serializer.validated_data["training_id"]) except Training.DoesNotExist: raise NotFound() is_training_group(training.group, trainer) now = timezone.now() if not training.start <= now <= training.start + \ settings.TRAINING_EDITABLE_INTERVAL: return Response( status=status.HTTP_400_BAD_REQUEST, data=error_detail(*AttendanceErrors.TRAINING_NOT_EDITABLE)) id_to_hours = dict([(item["student_id"], item["hours"]) for item in serializer.validated_data["students_hours"] ]) max_hours = training.academic_duration students = User.objects.filter(pk__in=id_to_hours.keys()).only("email") hours_to_mark = [] negative_mark = [] overflow_mark = [] for student in students: hours_put = id_to_hours[student.pk] if hours_put < 0: negative_mark.append( compose_bad_grade_report(student.email, hours_put)) elif hours_put > max_hours: overflow_mark.append( compose_bad_grade_report(student.email, hours_put)) else: hours_to_mark.append((student, hours_put)) if negative_mark or overflow_mark: return Response(status=status.HTTP_400_BAD_REQUEST, data={ **error_detail(*AttendanceErrors.OUTBOUND_GRADES), "negative_marks": negative_mark, "overflow_marks": overflow_mark, }) else: mark_data = [(x[0].pk, x[1]) for x in hours_to_mark] mark_hours(training, mark_data) return Response( list( map(lambda x: compose_bad_grade_report(x[0].email, x[1]), hours_to_mark)))
def self_sport_upload(request, **kwargs): serializer = SelfSportReportUploadSerializer(data=request.data) serializer.is_valid(raise_exception=True) student = request.user # user.pk == user.student.pk if request.user.student.medical_group_id \ < settings.SELFSPORT_MINIMUM_MEDICAL_GROUP_ID: return Response( status=400, data=error_detail(*SelfSportErrors.MEDICAL_DISALLOWANCE), ) image = None link = serializer.validated_data.get('link', None) if 'image' in serializer.validated_data: image, error = process_image(serializer.validated_data['image']) if error is not None: return error serializer.save( image=image, link=link, semester=get_ongoing_semester(), student_id=student.pk ) return Response({})
def process_image(image): """ :return: (processed image, error response) """ if image.size > settings.MAX_IMAGE_SIZE: return None, Response( status=status.HTTP_400_BAD_REQUEST, data=error_detail(*ImageErrors.IMAGE_FILE_SIZE_TOO_BIG)) width, height = image.image.size if not (settings.MIN_IMAGE_DIMENSION <= width <= settings.MAX_IMAGE_DIMENSION and settings.MIN_IMAGE_DIMENSION <= height <= settings.MAX_IMAGE_DIMENSION): return None, Response( status=status.HTTP_400_BAD_REQUEST, data=error_detail(*ImageErrors.INVALID_IMAGE_SIZE)) return image, None
def unenroll(request, **kwargs): """ Unenroll student Error codes: 5 - Can't unenroll from primary group """ serializer = EnrollSerializer(data=request.data) serializer.is_valid(raise_exception=True) group = get_object_or_404(Group, pk=serializer.validated_data["group_id"]) student = request.user.student removed_count = unenroll_student(group, student) if removed_count == 0: return Response(status=status.HTTP_400_BAD_REQUEST, data=error_detail(*EnrollErrors.INCONSISTENT_UNENROLL)) return Response({})
def unenroll_by_trainer(request, **kwargs): """ Unenroll student Error codes: 5 - Can't unenroll from primary group """ serializer = UnenrollStudentSerializer(data=request.data) serializer.is_valid(raise_exception=True) group = get_object_or_404(Group, pk=serializer.validated_data["group_id"]) is_training_group(group, request.user) student = get_object_or_404(Student, pk=serializer.validated_data["student_id"]) removed_count = unenroll_student(group, student) if removed_count == 0: return Response(status=status.HTTP_400_BAD_REQUEST, data=error_detail(*EnrollErrors.NOT_ENROLLED)) return Response({})
def reference_upload(request, **kwargs): serializer = ReferenceUploadSerializer(data=request.data) serializer.is_valid(raise_exception=True) image, error = process_image(serializer.validated_data['image']) if error is not None: return error student = request.user # user.pk == user.student.pk try: with transaction.atomic(): ref = serializer.save(semester=get_ongoing_semester(), student_id=student.pk) count = Reference.objects.filter( student_id=student.pk, uploaded__date=ref.uploaded.date()).count() assert count == 1 except AssertionError: return Response( status=status.HTTP_400_BAD_REQUEST, data=error_detail(*ReferenceErrors.TOO_MUCH_UPLOADS_PER_DAY)) return Response({})