diff --git a/symposion/schedule/models.py b/symposion/schedule/models.py index 151ecab2..962027fd 100644 --- a/symposion/schedule/models.py +++ b/symposion/schedule/models.py @@ -48,5 +48,9 @@ class Slot(models.Model): def rooms(self): attr = "_rooms" if not hasattr(self, attr): - setattr(self, attr, InlineSet(obj=self, field="room_set", delimiter=" ")) + class RoomInlineSet(InlineSet): + def consective_count(self): + return len(self) + value = RoomInlineSet(obj=self, field="room_set", delimiter=" ") + setattr(self, attr, value) return getattr(self, attr) diff --git a/symposion/schedule/timetable.py b/symposion/schedule/timetable.py new file mode 100644 index 00000000..8c9f072e --- /dev/null +++ b/symposion/schedule/timetable.py @@ -0,0 +1,37 @@ +import itertools + + +class Timetable(object): + + def __init__(self, day): + self.day = day + + def slots_qs(self): + return Slot.objects.filter(day=self.day) + + def rooms(self): + return Room.objects.filter(day=self.day.schedule) + + def __iter__(self): + times = sorted(set(itertools.chain(*self.slots_qs().values_list("start", "end")))) + slots = list(self.slots_qs().order_by("start")) + row = [] + for time, next_time in pairwise(times): + row = {"time": time, "slots": []} + for slot in slots: + if slot.start == time: + slot.rowspan = Timetable.rowspan(times, slot.start, slot.end) + row["slots"].append(slot) + row["colspan"] = self.rooms.consecutive_count() + if row["slots"] or next_time is None: + yield row + + @staticmethod + def rowspan(times, start, end): + return times.index(end) - times.index(start) + + +def pairwise(iterable): + a, b = itertools.tee(iterable) + b.next() + return itertools.izip_longest(a, b) diff --git a/symposion/schedule/views.py b/symposion/schedule/views.py index a22ae976..4e968d3f 100644 --- a/symposion/schedule/views.py +++ b/symposion/schedule/views.py @@ -25,7 +25,10 @@ def schedule_edit(request, slug=None): raise Http404() else: schedule = get_object_or_404(qs, slug=slug) + days_qs = Day.objects.filter(schedule=schedule) + days = [TimeTable(day) for day in days_qs] ctx = { "schedule": schedule, + "days": days, } return render(request, "schedule/schedule_edit.html")