def add_lectutures(lectures, year, cal, hostname): '''Adds lectures to cal object for current semester''' all_rooms = Lecture.get_related(Room, lectures) all_weeks = Lecture.get_related(Week, lectures, fields=['number'], use_extra=False) for l in lectures: if l.exclude: # Skip excluded continue if l.id not in all_weeks: continue weeks = all_weeks[l.id] rrule_kwargs = { 'byweekno': weeks, 'count': len(weeks), 'byweekday': l.day, 'dtstart': datetime.datetime(int(year), 1, 1) } summary = l.alias or l.course.code rooms = ', '.join(all_rooms.get(l.id, [])) if l.type: desc = u'%s - %s (%s)' % (l.type.name, l.course.name, l.course.code) else: desc = u'%s (%s)' % (l.course.name, l.course.code) for d in rrule.rrule(rrule.WEEKLY, **rrule_kwargs): vevent = cal.add('vevent') vevent.add('summary').value = summary vevent.add('location').value = rooms vevent.add('description').value = desc vevent.add('dtstart').value = d.replace(hour=l.start.hour, minute=l.start.minute, tzinfo=tz.tzlocal()) vevent.add('dtend').value = d.replace(hour=l.end.hour, minute=l.end.minute, tzinfo=tz.tzlocal()) vevent.add('dtstamp').value = datetime.datetime.now(tz.tzlocal()) vevent.add('uid').value = 'lecture-%d-%s@%s' % \ (l.id, d.strftime('%Y%m%d'), hostname) if l.type and l.type.optional: vevent.add('transp').value = 'TRANSPARENT'
def add_lectutures(lectures, year, cal, hostname): '''Adds lectures to cal object for current semester''' all_rooms = Lecture.get_related(Room, lectures) all_weeks = Lecture.get_related(Week, lectures, fields=['number'], use_extra=False) for l in lectures: if l.exclude: # Skip excluded continue if l.id not in all_weeks: continue weeks = all_weeks[l.id] rrule_kwargs = { 'byweekno': weeks, 'count': len(weeks), 'byweekday': l.day, 'dtstart': datetime.datetime(int(year),1,1) } summary = l.alias or l.course.code rooms = ', '.join(all_rooms.get(l.id, [])) if l.type: desc = u'%s - %s (%s)' % (l.type.name, l.course.name, l.course.code) else: desc = u'%s (%s)' % (l.course.name, l.course.code) for d in rrule.rrule(rrule.WEEKLY, **rrule_kwargs): vevent = cal.add('vevent') vevent.add('summary').value = summary vevent.add('location').value = rooms vevent.add('description').value = desc vevent.add('dtstart').value = d.replace(hour=l.start.hour, minute=l.start.minute, tzinfo=tz.tzlocal()) vevent.add('dtend').value = d.replace(hour=l.end.hour, minute=l.end.minute, tzinfo=tz.tzlocal()) vevent.add('dtstamp').value = datetime.datetime.now(tz.tzlocal()) vevent.add('uid').value = 'lecture-%d-%s@%s' % \ (l.id, d.strftime('%Y%m%d'), hostname) if l.type and l.type.optional: vevent.add('transp').value = 'TRANSPARENT'
def add_lectutures(lectures, year, cal, hostname): """Adds lectures to cal object for current semester""" all_rooms = Lecture.get_related(Room, lectures) all_weeks = Lecture.get_related(Week, lectures, fields=["number"], use_extra=False) for l in lectures: if l.exclude: # Skip excluded continue if l.id not in all_weeks: continue weeks = all_weeks[l.id] rrule_kwargs = { "byweekno": weeks, "count": len(weeks), "byweekday": l.day, "dtstart": datetime.datetime(int(year), 1, 1), } summary = l.alias or l.course.code rooms = ", ".join(all_rooms.get(l.id, [])) if l.type: desc = u"%s - %s (%s)" % (l.type.name, l.course.name, l.course.code) else: desc = u"%s (%s)" % (l.course.name, l.course.code) for d in rrule.rrule(rrule.WEEKLY, **rrule_kwargs): vevent = cal.add("vevent") vevent.add("summary").value = summary vevent.add("location").value = rooms vevent.add("description").value = desc vevent.add("dtstart").value = d.replace(hour=l.start.hour, minute=l.start.minute, tzinfo=tz.tzlocal()) vevent.add("dtend").value = d.replace(hour=l.end.hour, minute=l.end.minute, tzinfo=tz.tzlocal()) vevent.add("dtstamp").value = datetime.datetime.now(tz.tzlocal()) vevent.add("uid").value = "lecture-%d-%s@%s" % (l.id, d.strftime("%Y%m%d"), hostname) if l.type and l.type.optional: vevent.add("transp").value = "TRANSPARENT"
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, })
def pdf(request, year, semester_type, slug, size=None, week=None): if size is not None and size not in ['A4', 'A5', 'A6', 'A7']: raise http.Http404 semester = Semester(year=year, type=semester_type) color_map = ColorMap(hex=True) margin = 0.5*units.cm width, height = pagesizes.landscape(pagesizes.A5) width -= 2*margin height -= 2*margin time_width = 0.06 * width day_width = (width-time_width) / 5 filename = '%s-%s-%s' % (year, semester.type, slug) if week: filename += '-%s' % week response = http.HttpResponse(mimetype='application/pdf') response['Content-Disposition'] = 'attachment; filename=%s.pdf' % filename lectures = Lecture.objects.get_lectures(year, semester.type, slug, week) rooms = Lecture.get_related(Room, lectures) courses = Course.objects.get_courses(year, semester.type, slug) for course in courses: color_map[course.id] timetable = Timetable(lectures) if lectures: timetable.place_lectures() timetable.do_expansion() timetable.insert_times() if week: timetable.set_week(semester.year, int(week)) paragraph_style = default_styles['Normal'] paragraph_style.fontName = 'Helvetica-Bold' paragraph_style.fontSize = 10 paragraph_style.leading = 12 table_style = _tablestyle() data = [[platypus.Paragraph(render_title(semester, slug, week), paragraph_style)]] data[-1].extend([''] * sum(timetable.span)) table_style.add('SPAN', (0,0), (-1, 0)) # Add days data.append(['']) for span, date, name in timetable.header(): if date: data[-1].append(dateformat.format(date, 'l - j M.')) else: data[-1].append(unicode(name)) if span > 1: extra = span - 1 table_style.add('SPAN', (len(data[-1])-1, 2), (len(data[-1])-1+extra, 2)) data[-1].extend([''] * extra) # Convert to "simple" datastruct for row in timetable.table: data_row = [] for cells in row: for cell in cells: time = cell.get('time', '') lecture = cell.get('lecture', '') if lecture: if lecture.type and lecture.type.optional: paragraph_style.fontName = 'Helvetica' code = lecture.alias or lecture.course.code content = [platypus.Paragraph(html.escape(code), paragraph_style)] paragraph_style.leading = 8 if lecture.type: content += [platypus.Paragraph(u'<font size=6>%s</font>' % lecture.type.name.replace('/', ' / '), paragraph_style)] content += [platypus.Paragraph(u'<font size=6>%s</font>' % u', '.join(rooms.get(lecture.id, [])), paragraph_style)] paragraph_style.leading = 12 paragraph_style.fontName = 'Helvetica-Bold' elif time: content = time.replace(' - ', '\n') else: content = '' if cell.get('remove', False): data_row.append('') else: data_row.append(content) data.append(data_row) # Calculate widths and line that splits days col_widths = [time_width] for w in timetable.span: x = len(col_widths) table_style.add('LINEBEFORE', (x, 2), (x, -1), 1, outer_border) col_widths.extend([float(day_width)/w] * w) # Set row heights row_heights = [16, 12] row_heights += [(height-(8*2)) / (len(data)-2)] * (len(data)-2) # Create spans, setup backgrounds and put content in KeepInFrame for lecture in timetable.lectures: offset = 0 for o in timetable.span[:lecture['j']]: offset += o x1 = offset + lecture['k'] + 1 y1 = lecture['i']+2 x2 = x1 + lecture['width'] - 1 y2 = y1 + lecture['height'] - 1 table_style.add('SPAN', (x1, y1), (x2, y2)) table_style.add('BACKGROUND', (x1, y1), (x2, y2), colors.HexColor(color_map[lecture['l'].course_id])) content = data[y1][x1] data[y1][x1] = platypus.KeepInFrame(col_widths[x1]*lecture['width'], row_heights[2]*lecture['height'], content, mode='shrink') page = canvas.Canvas(response, pagesizes.A4) page.translate(margin, pagesizes.A4[1]-margin) if 'A4' == size: page.translate(0.5*margin, 2.5*margin-pagesizes.A4[1]) page.scale(1.414, 1.414) page.rotate(90) elif 'A6' == size: page.scale(0.707, 0.707) elif 'A7' == size: page.scale(0.5, 0.5) table = tables.Table(data, colWidths=col_widths, rowHeights=row_heights, style=table_style) table.wrapOn(page, width, height) table.drawOn(page, 0, -height) note = request.META.get('HTTP_HOST', '').split(':')[0] page.setFont('Helvetica', 10) page.setFillColor(colors.HexColor('#666666')) page.drawString(width - page.stringWidth(note) - 2, -height+2, note) page.showPage() page.save() response['X-Robots-Tag'] = 'noindex, nofollow' return response