Пример #1
0
def course_view_data(request,
                     slug) -> Tuple[Optional[CourseInstance], Optional[Dict]]:
    """Retrieves course and relevant data for the request.

    If course does not exist it returns two None objects.
    """
    course: CourseInstance = None
    try:
        course = CourseInstance.objects.filter(slug=slug).select_related(
            'semester', 'course_type').prefetch_related('tags',
                                                        'effects').get()
    except CourseInstance.DoesNotExist:
        return None, None

    student: Student = None
    if request.user.is_authenticated and request.user.student:
        student = request.user.student

    groups = course.groups.exclude(extra='hidden').select_related(
        'teacher',
        'teacher__user',
    ).prefetch_related('term', 'term__classrooms', 'guaranteed_spots',
                       'guaranteed_spots__role')

    # Collect the general groups statistics.
    groups_stats = Record.groups_stats(groups)
    # Collect groups information related to the student.
    student_status_groups = Record.is_recorded_in_groups(student, groups)
    student_can_enqueue = Record.can_enqueue_groups(student,
                                                    course.groups.all())
    student_can_dequeue = Record.can_dequeue_groups(student,
                                                    course.groups.all())

    for group in groups:
        group.num_enrolled = groups_stats.get(group.pk).get('num_enrolled')
        group.num_enqueued = groups_stats.get(group.pk).get('num_enqueued')
        group.is_enrolled = student_status_groups.get(group.pk).get('enrolled')
        group.is_enqueued = student_status_groups.get(group.pk).get('enqueued')
        group.priority = student_status_groups.get(group.pk).get('priority')
        group.can_enqueue = student_can_enqueue.get(group.pk)
        group.can_dequeue = student_can_dequeue.get(group.pk)

    teachers = {g.teacher for g in groups}

    course.is_enrollment_on = any(g.can_enqueue for g in groups)

    waiting_students = {}
    if request.user.employee:
        waiting_students = Record.list_waiting_students([course])[course.id]

    data = {
        'course': course,
        'teachers': teachers,
        'groups': groups,
        'waiting_students': waiting_students,
    }
    return course, data
Пример #2
0
def prototype_get_course(request, course_id):
    """Retrieves the annotated groups of a single course."""
    student = request.user.student
    course = CourseInstance.objects.get(pk=course_id)
    groups = course.groups.exclude(extra='hidden').select_related(
        'course', 'teacher', 'course__semester', 'teacher__user'
    ).prefetch_related('term', 'term__classrooms', 'guaranteed_spots', 'guaranteed_spots__role')
    can_enqueue_dict = Record.can_enqueue_groups(student, groups)
    can_dequeue_dict = Record.can_dequeue_groups(student, groups)
    for group in groups:
        group.can_enqueue = can_enqueue_dict.get(group.pk)
        group.can_dequeue = can_dequeue_dict.get(group.pk)
    group_dicts = build_group_list(groups)
    return JsonResponse(group_dicts, safe=False)
Пример #3
0
def my_prototype(request):
    """Renders the prototype with enrolled, enqueued, and pinned groups."""
    student = request.user.student
    semester = Semester.objects.get_next()

    # This costs an additional join, but works if there is no current semester.
    records = Record.objects.filter(
        student=student,
        group__course__semester=semester).exclude(status=RecordStatus.REMOVED).select_related(
            'group__teacher', 'group__teacher__user',
            'group__course', 'group__course__semester').prefetch_related(
                'group__term', 'group__term__classrooms', 'group__guaranteed_spots',
                'group__guaranteed_spots__role')
    pinned = Pin.student_pins_in_semester(student, semester)
    pinned = list(pinned)
    all_groups_by_id = {r.group_id: r.group for r in records}
    all_groups_by_id.update({p.pk: p for p in pinned})
    all_groups = list(all_groups_by_id.values())
    can_enqueue_dict = Record.can_enqueue_groups(student, all_groups)
    can_dequeue_dict = Record.can_dequeue_groups(student, all_groups)

    for record in records:
        group = all_groups_by_id.get(record.group_id)
        group.is_enrolled = record.status == RecordStatus.ENROLLED
        group.is_enqueued = record.status == RecordStatus.QUEUED

    for pin in pinned:
        group = all_groups_by_id.get(pin.pk)
        group.is_pinned = True

    all_groups = all_groups_by_id.values()
    for group in all_groups:
        group.can_enqueue = can_enqueue_dict.get(group.pk)
        group.can_dequeue = can_dequeue_dict.get(group.pk)

    group_dicts = build_group_list(all_groups)
    filters_dict = CourseInstance.prepare_filter_data(
        CourseInstance.objects.filter(semester=semester))
    courses_json = list_courses_in_semester(semester)
    data = {
        'groups_json': json.dumps(group_dicts, cls=DjangoJSONEncoder),
        'filters_json': json.dumps(filters_dict, cls=DjangoJSONEncoder),
        'courses_json': courses_json,
    }
    return render(request, 'timetable/prototype.html', data)
Пример #4
0
def prototype_update_groups(request):
    """Retrieves the updated group annotations.

    The list of groups ids to update will be sent in JSON body of the request.
    """
    student = request.user.student
    semester = Semester.objects.get_next()
    # Axios sends POST data in json rather than _Form-Encoded_.
    ids: List[int] = json.loads(request.body.decode('utf-8'))
    num_enrolled = Count('record', filter=Q(record__status=RecordStatus.ENROLLED))
    is_enrolled = Count(
        'record',
        filter=(Q(record__status=RecordStatus.ENROLLED, record__student_id=student.pk)))
    is_enqueued = Count(
        'record',
        filter=(Q(record__status=RecordStatus.QUEUED, record__student_id=student.pk)))

    groups_from_ids = Group.objects.filter(pk__in=ids)
    groups_enrolled_or_enqueued = Group.objects.filter(
        course__semester=semester,
        record__status__in=[RecordStatus.QUEUED, RecordStatus.ENROLLED],
        record__student=student)
    groups_all = groups_from_ids | groups_enrolled_or_enqueued
    groups = groups_all.annotate(num_enrolled=num_enrolled).annotate(
        is_enrolled=is_enrolled).annotate(is_enqueued=is_enqueued).select_related(
            'course', 'teacher', 'course__semester', 'teacher__user').prefetch_related(
                'term', 'term__classrooms', 'guaranteed_spots', 'guaranteed_spots__role')

    can_enqueue_dict = Record.can_enqueue_groups(student, groups)
    can_dequeue_dict = Record.can_dequeue_groups(student, groups)
    for group in groups:
        group.can_enqueue = can_enqueue_dict.get(group.pk)
        group.can_dequeue = can_dequeue_dict.get(group.pk)
        group.is_enqueued = bool(group.is_enqueued)
        group.is_enrolled = bool(group.is_enrolled)
    group_dicts = build_group_list(groups)
    return JsonResponse(group_dicts, safe=False)