def test_validate_schedule(self): """Check the behaviour of validate schedule We also test check_schedule, since the logic of the two funcions is so similar it doesn't make sense to have a second test case for it.""" day1 = ScheduleBlock.objects.create( start_time=D.datetime(2013, 9, 22, 9, 0, 0, tzinfo=timezone.utc), end_time=D.datetime(2013, 9, 22, 19, 0, 0, tzinfo=timezone.utc)) venue1 = Venue.objects.create(order=1, name='Venue 1') venue1.blocks.add(day1) page = Page.objects.create(name="test page", slug="test") start1 = D.datetime(2013, 9, 22, 10, 0, 0, tzinfo=timezone.utc) start2 = D.datetime(2013, 9, 22, 11, 0, 0, tzinfo=timezone.utc) end = D.datetime(2013, 9, 22, 12, 0, 0, tzinfo=timezone.utc) slot1 = Slot.objects.create(start_time=start1, end_time=start2) slot2 = Slot.objects.create(start_time=start2, end_time=end) item1 = ScheduleItem.objects.create(venue=venue1, page_id=page.pk, details="Item 1") # Create an invalid item item2 = ScheduleItem.objects.create(venue=venue1, details="Item 2") # Create a simple venue/slot clash item1.slots.add(slot1) item2.slots.add(slot1) # Schedule shoudln't validate check_schedule.invalidate() self.assertFalse(check_schedule()) # Invalid item & clash should be reported errors = validate_schedule() self.assertEqual(len(errors), 2) # Fix the invalid item item2.page_id = page.pk item2.save() # Schedule is still invalid, but only the clash remains check_schedule.invalidate() self.assertFalse(check_schedule()) errors = validate_schedule() self.assertEqual(len(errors), 1) # Fix clashes item2.slots.remove(slot1) item2.slots.add(slot2) item2.save() # Schedule should now be valid check_schedule.invalidate() self.assertTrue(check_schedule()) errors = validate_schedule() self.assertEqual(len(errors), 0)
def test_validate_schedule(self): """Check the behaviour of validate schedule We also test check_schedule, since the logic of the two funcions is so similar it doesn't make sense to have a second test case for it.""" day1 = Day.objects.create(date=D.date(2013, 9, 22)) venue1 = Venue.objects.create(order=1, name='Venue 1') venue1.days.add(day1) page = Page.objects.create(name="test page", slug="test") start1 = D.time(10, 0, 0) start2 = D.time(11, 0, 0) end = D.time(12, 0, 0) slot1 = Slot.objects.create(start_time=start1, end_time=start2, day=day1) slot2 = Slot.objects.create(start_time=start2, end_time=end, day=day1) item1 = ScheduleItem.objects.create(venue=venue1, page_id=page.pk, details="Item 1") # Create an invalid item item2 = ScheduleItem.objects.create(venue=venue1, details="Item 2") # Create a simple venue/slot clash item1.slots.add(slot1) item2.slots.add(slot1) # Schedule shoudln't validate check_schedule.invalidate() self.assertFalse(check_schedule()) # Invalid item & clash should be reported errors = validate_schedule() self.assertEqual(len(errors), 2) # Fix the invalid item item2.page_id = page.pk item2.save() # Schedule is still invalid, but only the clash remains check_schedule.invalidate() self.assertFalse(check_schedule()) errors = validate_schedule() self.assertEqual(len(errors), 1) # Fix clashes item2.slots.remove(slot1) item2.slots.add(slot2) item2.save() # Schedule should now be valid check_schedule.invalidate() self.assertTrue(check_schedule()) errors = validate_schedule() self.assertEqual(len(errors), 0)
def get_context_data(self, **kwargs): context = super(CurrentView, self).get_context_data(**kwargs) # If the schedule is invalid, return a context with active=False context['active'] = False if not check_schedule(): return context # The schedule is valid, so add active=True and empty slots context['active'] = True context['slots'] = [] # Allow refresh time to be overridden context['refresh'] = self.request.GET.get('refresh', None) # If there are no items scheduled for today, return an empty slots list schedule_page = self._parse_today(self.request.GET.get('day', None)) if schedule_page is None: return context context['schedule_page'] = schedule_page # Allow current time to be overridden time = self._parse_time(self.request.GET.get('day', None), self.request.GET.get('time', None)) highlight_venue = lookup_highlighted_venue(self.request) context['highlight_venue_pk'] = -1 if highlight_venue is not None: context['highlight_venue_pk'] = highlight_venue cur_slot, current_rows = self._current_slots(schedule_page, time) context['cur_slot'] = cur_slot context['slots'].extend(current_rows) return context
def get_context_data(self, **kwargs): context = super(ScheduleView, self).get_context_data(**kwargs) # Check if the schedule is valid context['active'] = False context['prev_block'] = None context['next_block'] = None if not check_schedule(): return context context['active'] = True try: block_id = int(self.request.GET.get('block', -1)) except ValueError: block_id = -1 blocks = ScheduleBlock.objects.all() try: this_block = blocks.get(id=block_id) except ObjectDoesNotExist: # We choose to return the full schedule if given an invalid block id this_block = None highlight_venue = lookup_highlighted_venue(self.request) context['highlight_venue_pk'] = -1 if highlight_venue is not None: context['highlight_venue_pk'] = highlight_venue if this_block: # Add next / prev blocks links # blocks are sorted by time by default blocks = list(blocks) pos = blocks.index(this_block) if pos > 0: context['prev_block'] = blocks[pos - 1] if pos < len(blocks) - 1: context['next_block'] = blocks[pos + 1] context['schedule_pages'] = generate_schedule(this_block) return context
def get_context_data(self, **kwargs): context = super(ScheduleView, self).get_context_data(**kwargs) # Check if the schedule is valid context["active"] = False if not check_schedule(): return context context["active"] = True day = self.request.GET.get("day", None) dates = dict([(x.date.strftime("%Y-%m-%d"), x) for x in Day.objects.all()]) # We choose to return the full schedule if given an invalid date day = dates.get(day, None) context["schedule_days"] = generate_schedule(day) return context
def get_context_data(self, **kwargs): context = super(ScheduleView, self).get_context_data(**kwargs) # Check if the schedule is valid context['active'] = False if not check_schedule(): return context context['active'] = True day = self.request.GET.get('day', None) dates = dict([(x.date.strftime('%Y-%m-%d'), x) for x in Day.objects.all()]) # We choose to return the full schedule if given an invalid date day = dates.get(day, None) context['schedule_days'] = generate_schedule(day) return context
def get_context_data(self, **kwargs): context = super(CurrentView, self).get_context_data(**kwargs) # If the schedule is invalid, return a context with active=False context['active'] = False if not check_schedule(): return context # The schedule is valid, so add active=True and empty slots context['active'] = True context['slots'] = [] # Allow refresh time to be overridden context['refresh'] = self.request.GET.get('refresh', None) # If there are no items scheduled for today, return an empty slots list schedule_day = self._parse_today(self.request.GET.get('day', None)) if schedule_day is None: return context context['schedule_day'] = schedule_day # Allow current time to be overridden time = self._parse_time(self.request.GET.get('time', None)) cur_slot, current_rows = self._current_slots(schedule_day, time) context['cur_slot'] = cur_slot context['slots'].extend(current_rows) return context
def get_context_data(self, **kwargs): context = super(ScheduleView, self).get_context_data(**kwargs) # Check if the schedule is valid context['active'] = False context['prev_day'] = None context['next_day'] = None if not check_schedule(): return context context['active'] = True day = self.request.GET.get('day', None) dates = dict([(x.date.strftime('%Y-%m-%d'), x) for x in Day.objects.all()]) # We choose to return the full schedule if given an invalid date schedule_day = dates.get(day, None) if schedule_day is not None: # Add next / prev day links sorted_days = sorted(dates) pos = sorted_days.index(day) if pos > 0: context['prev_day'] = sorted_days[pos - 1] if pos < len(sorted_days) - 1: context['next_day'] = sorted_days[pos + 1] context['schedule_days'] = generate_schedule(schedule_day) return context
def get_context_data(self, **kwargs): context = super(CurrentView, self).get_context_data(**kwargs) # Check if the schedule is valid context['active'] = False if not check_schedule(): return context # schedule is valid, so context['active'] = True context['slots'] = [] # We allow url parameters to override the default context['refresh'] = self.request.GET.get('refresh', None) day = self.request.GET.get('day', str(datetime.date.today())) dates = dict([(x.date.strftime('%Y-%m-%d'), x) for x in Day.objects.all()]) if day not in dates: # Nothing happening today return context # get the associated day object today = dates[day] now = datetime.datetime.now().time() if 'time' in self.request.GET: time = self.request.GET['time'] try: time = datetime.datetime.strptime(time, '%H:%M').time() except ValueError: time = now else: time = now # Find the slot that includes now cur_slot = None prev_slot = None next_slot = None schedule_day = None for slot in Slot.objects.all(): if slot.get_day() != today: continue if schedule_day is None: schedule_day = ScheduleDay(slot.get_day()) if slot.get_start_time() <= time and slot.end_time > time: cur_slot = slot elif slot.end_time <= time: if prev_slot: if prev_slot.end_time < slot.end_time: prev_slot = slot else: prev_slot = slot elif slot.get_start_time() >= time: if next_slot: if next_slot.end_time > slot.end_time: next_slot = slot else: next_slot = slot seen_items = {} context['cur_slot'] = None context['schedule_day'] = schedule_day if prev_slot: prev_row = make_schedule_row(schedule_day, prev_slot, seen_items) context['slots'].append(prev_row) if cur_slot: cur_row = make_schedule_row(schedule_day, cur_slot, seen_items) for item in cur_row.items.values(): item['note'] = 'current' context['slots'].append(cur_row) context['cur_slot'] = cur_slot if next_slot: next_row = make_schedule_row(schedule_day, next_slot, seen_items) context['slots'].append(next_row) # Add styling hints. Needs to be after all the schedule rows are # created so the spans are set correctly if prev_slot: for item in prev_row.items.values(): if item['rowspan'] == 1: item['note'] = 'complete' else: # Must overlap with current slot item['note'] = 'current' if next_slot: for item in next_row.items.values(): if item['rowspan'] == 1: item['note'] = 'forthcoming' else: # Must overlap with current slot item['note'] = 'current' return context