Example #1
0
def getting_started(request, year, semester_type):
    '''Intial top level page that greets users'''
    try:
        semester = Semester.objects.get(year=year, type=semester_type)
    except Semester.DoesNotExist:
        raise http.Http404

    try:
        next_semester = Semester.objects.next()
    except Semester.DoesNotExist:
        next_semester = None

    if next_semester and next_semester == semester:
        next_semester = None

    # Redirect user to their timetable
    if request.method == 'POST':
        schedule_form = forms.ScheduleForm(request.POST)

        if schedule_form.is_valid():
            slug = schedule_form.cleaned_data['slug']
            # TODO(adamcik): what should we do if current is empty?
            return schedule_current(request, semester.year, semester.type, slug)
    else:
        schedule_form = forms.ScheduleForm()

    context = Course.get_stats(semester=semester)
    context.update({
        'color_map': utils.ColorMap(hex=True),
        'current': semester,
        'next_semester': next_semester,
        'schedule_form': schedule_form,
    })
    return shortcuts.render(request, 'start.html', context)
Example #2
0
def about(request):
    # Limit ourselves to 400 buckets to display within 940px - i.e. 2.3 pixels per sample.
    cursor = connection.cursor()
    cursor.execute('''
        SELECT CAST(EXTRACT(EPOCH FROM MAX(s.added)) -
                    EXTRACT(EPOCH FROM MIN(s.added)) AS INTEGER)
        FROM common_subscription s;''')
    scale = cursor.fetchone()[0] / 400

    # Fetch number of new subcriptions per time bucket:
    cursor.execute('''
        SELECT COUNT(*), bucket, semester_id FROM (
            SELECT
                cast(EXTRACT(EPOCH FROM date_trunc('day', min(s.added))) / %s as integer) AS bucket,
                s.student_id,
                c.semester_id
            FROM common_subscription s
            JOIN common_course c ON (c.id = s.course_id)
            GROUP BY s.student_id, c.semester_id
        ) AS foo GROUP BY bucket, semester_id ORDER by semester_id, bucket;
        ''' % scale)

    last_semester = None
    colors = utils.ColorMap(hex=True)
    fills, series = [], []
    x, y, max_x, first = 0, 0, 0, 0

    # Use zero indexing for x values to keep payload small.
    for count, bucket, semester in cursor.fetchall():
        if not first:
            first = bucket - 1

        if last_semester != semester:
            last_semester = semester
            x, y = (bucket - 1)-first, 0
            series.append([(x,y)])

        x, y = bucket - first, y+count

        series[-1].append((x, y))
        max_x = max(max_x, x)

    for i, s in enumerate(series):
        fills.append(colors[i])
        s.append((max_x, s[-1][1]))

    # TODO: we can further reduce this by just having one big array for
    # everything and knowing the stride to use

    # Pass on all data we need. First is needed to undo zero indexing, bucket
    # size is needed to rescale x values to proper epochs.
    return shortcuts.render(request, 'about.html', {
            'data':  html.mark_safe(json.dumps({
                'series': series,
                'fills': fills,
                'first': first,
                'scale': scale}, separators=(',',':'))),
        })
Example #3
0
def select_groups(request, year, semester_type, slug):
    '''Form handler for selecting groups to use in schedule'''
    courses = Course.objects.get_courses(year, semester_type, slug)
    course_groups = Course.get_groups(year, semester_type,
                                      [c.id for c in courses])

    if request.method == 'POST':
        with transaction.atomic():
            for c in courses:
                try:
                    groups = course_groups[c.id]
                except KeyError:  # Skip courses without groups
                    continue

                group_form = forms.GroupForm(groups, request.POST, prefix=c.id)

                if group_form.is_valid():
                    subscription = Subscription.objects.get_subscriptions(
                        year, semester_type, slug).get(course=c)

                    subscription.groups = group_form.cleaned_data['groups']

            return shortcuts.redirect('schedule-advanced', year,
                                      Semester.localize(semester_type), slug)

    color_map = utils.ColorMap(hex=True)
    subscription_groups = Subscription.get_groups(year, semester_type, slug)
    all_subscripted_groups = set()

    for groups in subscription_groups.values():
        for group in groups:
            all_subscripted_groups.add(group)

    for c in courses:
        color_map[c.id]
        subscription_id = c.subscription_set.get(student__slug=slug).pk

        try:
            groups = course_groups[c.id]
        except KeyError:  # Skip courses without groups
            continue

        initial_groups = subscription_groups.get(subscription_id,
                                                 all_subscripted_groups)

        c.group_form = forms.GroupForm(groups,
                                       prefix=c.id,
                                       initial={'groups': initial_groups})

    return shortcuts.render(
        request, 'select_groups.html', {
            'semester': Semester(year=year, type=semester_type),
            'slug': slug,
            'courses': courses,
            'color_map': color_map,
        })
Example #4
0
def schedule(request, year, semester_type, slug, advanced=False,
             week=None, all=False):
    '''Page that handels showing schedules'''
    current_week = get_current_week()
    if week:
        week = int(week)
        max_week = utils.max_number_of_weeks(year)
    if week is not None:
        if (week <= 0 or week > max_week):
            raise http.Http404

    # Color mapping for the courses
    color_map = utils.ColorMap(hex=True)

    try:
        semester = Semester.objects.get(year=year, type=semester_type)
    except Semester.DoesNotExist:
        raise http.Http404

    try:
        student = Student.objects.distinct().get(slug=slug, subscription__course__semester=semester)
    except Student.DoesNotExist:
        student = None

    # Start setting up queries
    courses = Course.objects.get_courses(year, semester.type, slug)
    lectures = Lecture.objects.get_lectures(year, semester.type, slug, week)
    exams = {}
    for exam in Exam.objects.get_exams(year, semester.type, slug):
        exams.setdefault(exam.course_id, []).append(exam)

    # Use get_related to cut query counts
    lecturers = Lecture.get_related(Lecturer, lectures)
    groups = Lecture.get_related(Group, lectures, fields=['code'])
    rooms = Lecture.get_related(Room, lectures, fields=['name', 'url'])
    weeks = Lecture.get_related(Week, lectures, fields=['number'], use_extra=False)

    schedule_weeks = set()
    for lecture_week_set in weeks.values():
        for lecture_week in lecture_week_set:
            schedule_weeks.add(lecture_week)

    schedule_weeks = list(schedule_weeks)
    schedule_weeks.sort()

    if schedule_weeks:
        schedule_weeks = range(schedule_weeks[0], schedule_weeks[-1]+1)

    next_week = None
    prev_week = None

    # TODO(adamcik): lookup actuall valid weeks.
    if week and week < max_week:
        next_week = week+1

    if week and week > 1:
        prev_week = week-1

    # Init colors in predictable maner
    for c in courses:
        color_map[c.id]

    # Create Timetable
    table = timetable.Timetable(lectures)

    if week:
        table.set_week(semester.year, week)

    if lectures:
        table.place_lectures()
        table.do_expansion()

    table.insert_times()
    table.add_markers()

    if advanced:
        subscriptions = Subscription.objects.get_subscriptions(year, semester.type, slug)

        # Set up and course name forms
        for course in courses:
            alias = course.alias or ''
            course.alias_form = forms.CourseAliasForm(
                initial={'alias': alias}, prefix=course.id)

    try:
        next_semester = Semester.objects.next()
        next_message = Subscription.objects.get_subscriptions(
            next_semester.year, next_semester.type, slug).count() == 0
    except Semester.DoesNotExist:
        next_semester = None
        next_message = False

    week_is_current = semester.year == today().year and week == current_week

    return shortcuts.render(request, 'schedule.html', {
            'advanced': advanced,
            'all': all,
            'color_map': color_map,
            'courses': courses,
            'current': (week == current_week),
            'current_week': current_week,
            'exams': exams,
            'next_message': next_message,
            'lectures': lectures,
            'semester': semester,
            'week_is_current': week_is_current,
            'next_semester': next_semester,
            'slug': slug,
            'timetable': table,
            'week': week,
            'next_week': next_week,
            'prev_week': prev_week,
            'rooms': rooms,
            'weeks': schedule_weeks,
            'groups': groups,
            'lecturers': lecturers,
            'lecture_weeks': weeks,
            'student': student,
        })