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)
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=(',',':'))), })
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, })
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, })