def get(self, competition_id, schedule_version=-1): if not self.SetSchedule(int(schedule_version)): return template = JINJA_ENVIRONMENT.get_template( 'scheduling/groups_display.html') groups_by_day_and_stage = collections.defaultdict( lambda: collections.defaultdict(list)) all_days = set() for group in ScheduleGroup.query( ScheduleGroup.schedule == self.schedule.key).iter(): groups_by_day_and_stage[group.start_time.date()][ group.stage].append(group) all_days.add(group.start_time.date()) for groups_set in groups_by_day_and_stage.itervalues(): for groups in groups_set.itervalues(): groups.sort(key=lambda g: g.start_time) all_days = sorted(all_days) all_stages = (ScheduleStage.query( ScheduleStage.schedule == self.schedule.key).order( ScheduleStage.number).fetch()) self.response.write( template.render({ 'c': common.Common(self), 'timezones': timezones, 'competition': self.competition, 'groups_by_day_and_stage': groups_by_day_and_stage, 'all_stages': all_stages, 'all_days': all_days, }))
def get(self, schedule_version): if not self.SetSchedule(int(schedule_version)): return template = JINJA_ENVIRONMENT.get_template( 'scheduling/edit_schedule.html') event_keys = set([ r.event for r in ScheduleRound.query( ScheduleRound.schedule == self.schedule.key).iter() ]) events = [ e.get() for e in sorted(event_keys, key=lambda e: e.get().rank) ] stages = (ScheduleStage.query( ScheduleRound.schedule == self.schedule.key).order( ScheduleRound.number).fetch()) self.response.write( template.render({ 'c': common.Common(self), 'competition': self.competition, 'schedule': self.schedule, 'events': events, 'stages': stages, 'new_stage_id': random.randint(2**4, 2**10), 'colors': sorted(Colors.keys()), }))
def GetImpl(handler, schedule, event): rounds = ScheduleRound.query( ndb.AND(ScheduleRound.schedule == schedule.key, ScheduleRound.event == event.key)).order( ScheduleRound.number).fetch() time_blocks_by_round = collections.defaultdict(list) for time_block in (ScheduleTimeBlock.query( ScheduleTimeBlock.schedule == schedule.key).order( ScheduleTimeBlock.start_time).iter()): time_blocks_by_round[time_block.round].append(time_block) stages = (ScheduleStage.query( ScheduleStage.schedule == schedule.key).order( ScheduleStage.number).fetch()) competition_days = [] current_date = schedule.start_date while current_date <= schedule.end_date: competition_days.append(current_date) current_date += datetime.timedelta(days=1) template = JINJA_ENVIRONMENT.get_template( 'scheduling/event_details.html') return template.render({ 'c': common.Common(handler), 'rounds': rounds, 'event': event, 'time_blocks': time_blocks_by_round, 'new_ids': { r.key: '%s_%d' % (r.key.id(), random.randint(2**4, 2**32)) for r in rounds }, 'stages': stages, 'competition_days': competition_days, })
def ImportStage(room_data, schedule, out, stages, time_blocks, groups): if 'id' not in room_data: out.errors.append('Room is missing id field.') return if 'name' not in room_data: out.errors.append('Room %d is missing name field.' % room_data['id']) return stage_id = '%s_%d' % (schedule.key.id(), room_data['id']) if stage_id in stages: stage = stages.pop(stage_id) else: stage = ScheduleStage(id=stage_id) extension = GetExtension('ScheduleStage', room_data) stage.schedule = schedule.key stage.name = room_data['name'] if 'numTimers' in extension: stage.timers = extension['numTimers'] else: stage.timers = 0 if 'colorCss' in extension: stage.color = extension['colorCss'] out.entities_to_put.append(stage) if 'activities' in room_data: for activity_data in room_data['activities']: ImportTimeBlock(activity_data, schedule, stage, out, time_blocks, groups)
def post(self, schedule_version): if not self.SetSchedule(int(schedule_version)): return stage_id = self.request.POST['id'] old_stage = ScheduleStage.get_by_id(stage_id) is_new_stage = not old_stage if old_stage and old_stage.schedule != self.schedule.key: return stage = old_stage or ScheduleStage(id=stage_id) stage.schedule = self.schedule.key stage.name = self.request.POST['name'] if self.request.POST['color'] in Colors: stage.color = self.request.POST['color'] else: del stage.color stage.timers = int(self.request.POST['timers']) if not stage.number: max_stage = (ScheduleStage.query( ScheduleStage.schedule == self.schedule.key).order( -ScheduleStage.number).get()) if max_stage: stage.number = max_stage.number + 1 else: stage.number = 1 stage.put() template = JINJA_ENVIRONMENT.get_template('scheduling/stages.html') stages = (ScheduleStage.query( ScheduleRound.schedule == self.schedule.key).order( ScheduleRound.number).fetch()) if is_new_stage: stages.append(stage) self.response.write( template.render({ 'c': common.Common(self), 'stages': stages, 'new_stage_id': '%s_%d' % (schedule_version, random.randint(2**4, 2**32)), 'colors': sorted(Colors.keys()), }))
def get(self, schedule_version, event_id): if not self.SetSchedule(int(schedule_version)): return event = Event.get_by_id(event_id) if not event: self.response.set_code(400) return rounds = ScheduleRound.query( ndb.AND(ScheduleRound.schedule == self.schedule.key, ScheduleRound.event == event.key)).order( ScheduleRound.number).fetch() time_blocks_by_round = collections.defaultdict(list) for time_block in (ScheduleTimeBlock.query( ScheduleTimeBlock.schedule == self.schedule.key).order( ScheduleTimeBlock.start_time).iter()): time_blocks_by_round[time_block.round].append(time_block) # Immediately after adding a TimeBlock, it may not have propagated to the datastore. # So we force retrieval of the just-added TimeBlock. if 'include_time_block' in self.request.GET: time_block = ScheduleTimeBlock.get_by_id( self.request.GET['include_time_block']) found = False for old_time_block in time_blocks_by_round[time_block.round]: if old_time_block.key == time_block.key: found = True if not found: time_blocks_by_round[time_block.round].append(time_block) time_blocks_by_round[time_block.round].sort( key=lambda tb: tb.GetStartTime()) stages = (ScheduleStage.query( ScheduleStage.schedule == self.schedule.key).order( ScheduleStage.number).fetch()) competition_days = [] current_date = self.schedule.start_date while current_date <= self.schedule.end_date: competition_days.append(current_date) current_date += datetime.timedelta(days=1) template = JINJA_ENVIRONMENT.get_template( 'scheduling/event_details.html') self.response.write( template.render({ 'c': common.Common(self), 'rounds': rounds, 'event': event, 'time_blocks': time_blocks_by_round, 'new_ids': { r.key: '%s_%d' % (r.key.id(), random.randint(2**4, 2**32)) for r in rounds }, 'stages': stages, 'competition_days': competition_days, }))
def ScheduleToWcif(schedule, competition, wca_competition): output_dict = {} if schedule.start_date: output_dict['startDate'] = schedule.start_date.strftime('%Y-%m-%d') output_dict['numberOfDays'] = ( (schedule.end_date - schedule.start_date).days + 1) # The CubingUSA scheduling system is not designed to support competitions # with more than one venue. venue_dict = {} venue_dict['id'] = 0 # TODO: pass along the venue information from the WCA export. if wca_competition: venue_dict['latitude'] = wca_competition.latitude / 1000000. venue_dict['longitude'] = wca_competition.longitude / 1000000. venue_dict['timezone'] = competition.timezone all_stages = ScheduleStage.query( ScheduleStage.schedule == schedule.key).fetch() all_rounds = ScheduleRound.query( ScheduleRound.schedule == schedule.key).fetch() time_blocks_by_stage = collections.defaultdict(list) for t in (ScheduleTimeBlock.query( ScheduleTimeBlock.schedule == schedule.key).order( ScheduleTimeBlock.start_time).iter()): time_blocks_by_stage[t.stage.id()].append(t) groups_by_stage_and_time_block = ( collections.defaultdict(lambda: collections.defaultdict(list))) for g in (ScheduleGroup.query( ScheduleGroup.schedule == schedule.key).order( ScheduleGroup.start_time).iter()): groups_by_stage_and_time_block[g.stage.id()][g.time_block.id()].append( g) venue_dict['rooms'] = [] for stage in all_stages: venue_dict['rooms'].append( StageToWcif(stage, time_blocks_by_stage[stage.key.id()], groups_by_stage_and_time_block[stage.key.id()])) output_dict['venues'] = [venue_dict] extension_dict = {} extension_dict['datastoreId'] = schedule.key.id() extension_dict['creationTime'] = (ToLocalizedTime( schedule.creation_time, competition.timezone).isoformat()) extension_dict['lastUpdateTime'] = (ToLocalizedTime( schedule.last_update_time, competition.timezone).isoformat()) AddExtension('Schedule', extension_dict, output_dict) return output_dict
def ImportSchedule(wcif_data, schedule, out): if 'schedule' not in wcif_data: out.errors.append('schedule field missing from WCIF data.') return schedule_data = wcif_data['schedule'] if 'startDate' not in schedule_data: out.errors.append('startDate missing from WCIF data.') return if 'numberOfDays' not in schedule_data: out.errors.append('numberOfDays missing from WCIF data.') return num_days = schedule_data['numberOfDays'] if num_days < 1: out.errors.append('numberOfDays must be at least 1.') return try: schedule.startDate = datetime.datetime.strptime( schedule_data['startDate'], '%Y-%m-%d').date() except ValueError: out.errors.append('startDate must be in YYYY-mm-dd format.') return schedule.endDate = schedule.startDate + datetime.timedelta(days=num_days) if len(schedule_data['venues']) > 1: out.errors.append('The CubingUSA scheduling system does not support ' + 'competitions with multiple venues.') return stages = { s.key.id(): s for s in ScheduleStage.query( ScheduleStage.schedule == schedule.key).iter() } time_blocks = { t.key.id(): t for t in ScheduleTimeBlock.query( ScheduleTimeBlock.schedule == schedule.key).iter() } groups = { g.key.id(): g for g in ScheduleGroup.query( ScheduleGroup.schedule == schedule.key).iter() } for venue_data in schedule_data['venues']: for room_data in venue_data['rooms']: ImportStage(room_data, schedule, out, stages, time_blocks, groups) out.entities_to_delete.extend(stages.values() + time_blocks.values() + groups.values())