Exemplo n.º 1
0
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({})
Exemplo n.º 2
0
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({})
Exemplo n.º 3
0
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)))
Exemplo n.º 4
0
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({})
Exemplo n.º 5
0
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
Exemplo n.º 6
0
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({})
Exemplo n.º 7
0
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({})
Exemplo n.º 8
0
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({})