示例#1
0
 def genEventTable(status):
     status_map = {
         'future': "Future Events",
         'running': "Ongoing Events",
         'done': "Completed Events"
     }
     events = EventAPI(self.request).filterSelf(
         event_status=status,
         event_season=self.season).order_by('event_start_date')
     event_dict = list(
         map(
             lambda event:
             dict(event_name=event.event_name,
                  event_link=reverse('client.view_dispatch_param',
                                     args=["event_scoring", event.id]),
                  event_type=EventTypeAPI(self.request).getSelf(
                      id=event.event_type).event_type_name,
                  event_status=status_map[event.event_status] if event.
                  event_status in status_map else event.event_status,
                  event_region=RegionAPI(self.request).getSelf(
                      id=event.event_region).region_name,
                  event_host=SchoolAPI(self.request).getSelf(
                      id=event.event_host).school_name,
                  event_start_date=event.event_start_date.strftime(
                      "%B %d, %Y"),
                  event_start_date_num=int(
                      event.event_start_date.strftime("%Y%m%d"))),
             list(events)))
     event_dict = sorted(event_dict,
                         key=(lambda x: x['event_start_date_num']),
                         reverse=True)
     return event_dict
 def buildEventDetailsDict(self, event):
     status_map = {
         'future': "Future Events",
         'running': "Ongoing Events",
         'done': "Completed Events"
     }
     result = dict(
         name=event.event_name,
         description=event.event_description,
         scoring=('Scoring Page',
                  reverse('client.view_dispatch_param',
                          args=['event_scoring', event.id])),
         rotation=('Rotation Page',
                   reverse('client.view_dispatch_param',
                           args=['event_rotation', event.id])),
         season=(SeasonAPI(
             self.request).getSelf(id=event.event_season).season_name,
                 UrlFunctions.getClientViewLink('seasons')),
         region=(lambda region_name: (region_name, "{}#{}".format(
             UrlFunctions.getClientViewLink('schools'), region_name)))(
                 RegionAPI(self.request).getSelf(
                     id=event.event_region).region_name, ),
         host=(SchoolAPI(
             self.request).getSelf(id=event.event_host).school_name,
               UrlFunctions.getClientViewLink('school_specific',
                                              event.event_host)),
         location=event.event_location,
         status=status_map[event.event_status],
         start=event.event_start_date.strftime("%B %d, %Y"),
         end=event.event_end_date.strftime("%B %d, %Y"))
     return result
 def getCurrentLeagueScoreBySchool(self,
                                   school_id,
                                   compiled=False,
                                   subcompiled=False):
     school = SchoolAPI(self.request).getSelf(id=school_id)
     if compiled:
         return self.getCompiledScoreForSchool(school, error=False)
     else:
         events = SchoolAPI(self.request).getParticipatedNormalEvents(
             school_id, Event.EVENT_STATUS_DONE, self.season)
         # TODO: Optimize the current n x m queries ;_;
         scores = [
             score for score, event in self.getReverseSortedEventScoresList(
                 school, events, subcompiled)
         ]
         average_score = self.getAverageScore(scores, school.school_region)
         final_race_score = self.getFinalRaceScore(school, self.season)
         total_score = average_score + final_race_score
         return total_score
    def computeLeagueScores(self, initialize=True, override=None):
        league_scoring_data = self.getPanelLeagueScoreData()
        league_scoring_map = {
            data.get('school_id'): data
            for data in league_scoring_data
        }

        # TODO: Have an indicator for finished season and use it to determine whether to recompile league scores
        # We only recompute if initialize is true and all recorded scores are not None
        if not (initialize or reduce(
                lambda x, y: x and
            (y['recorded_score'] is not None), league_scoring_data, True)):
            return

        # We initialize override as all None values if the override variable is not set
        if override is None:
            override = [(school_id, False)
                        for school_id in league_scoring_map.keys()]

        # Update the DB according to override values, otherwise, compute the calculated values again
        for school_id, override_score in override:
            league_scoring_api = LeagueScoringAPI(self.request)
            school_id = int(school_id)
            school = SchoolAPI(self.request).getSelf(id=school_id)
            calculated_score = league_scoring_map.get(school_id).get(
                'calculated_score')
            if not override_score:
                override_score = Score.DEFAULT_LEAGUE_SCORE
            participated_events = SchoolAPI(
                self.request).getParticipatedEvents(school_id,
                                                    Event.EVENT_STATUS_DONE,
                                                    self.season)
            school_score_dict = {
                event.id: league_scoring_api.getScoreForEventBySchool(
                    event, school, False)
                for event in participated_events
            }
            league_scoring_api.setNormalOverrideLeagueScore(
                school, (calculated_score, override_score))
            league_scoring_api.setNormalOverrideSummaryScores(
                school, school_score_dict)
 def __buildRotationTable(self, event):
     rotation_detail = event.event_rotation_detail
     boat_identifiers = event.event_boat_rotation_name.split(',')
     rotation_table = dict()
     schools = SchoolAPI(self.request).filterSelf(id__in=list(map(lambda x: int(x), event.event_school_ids)))
     teams = EventAPI(self.request).getEventCascadeTeams(event.id)
     team_flatten_ids = [team.id for team in teams]
     team_school_link = dict()
     team_name_link = dict()
     for team in TeamAPI(self.request).filterSelf(id__in=team_flatten_ids):
         team_school_link[team.id] = schools.get(id=team.team_school)
         team_name_link[team.id] = team_school_link[team.id].school_name + ' - ' + team.team_name
     for event_tag_id, teams in rotation_detail.items():
         event_tag_name = EventTagAPI(self.request).getSelf(id=event_tag_id).event_tag_name
         rotation_table[event_tag_name] = dict()
         for team_id, rotations in teams.items():
             team_id = int(team_id)
             rotation_table[event_tag_name][team_id] = dict()
             rotation_table[event_tag_name][team_id]['team_name'] = team_name_link[team_id]
             rotation_table[event_tag_name][team_id]['rotations'] = [
                 boat_identifiers[int(r_num)-1] for r_num in rotations
             ]
     return dict(rotation_table)
 def getClientLeagueScoreData(self):
     schools = SchoolAPI(self.request).getAll()
     result = list()
     for school in schools:
         school_id = school.id
         school_name = school.school_name
         score = self.getCompiledScoreForSchool(school, error=False)
         if score is None:
             compiled = False
             score = self.tryCompileThenCalculateScore(school)
         else:
             compiled = True
         response = dict(compiled=compiled,
                         school_id=school_id,
                         school_name=school_name,
                         display_score=score,
                         num_race=SchoolAPI(
                             self.request).getParticipatedEvents(
                                 school_id=school_id,
                                 status=Event.EVENT_STATUS_DONE,
                                 season=self.season,
                             ).count())
         result.append(response)
     return result
 def getPanelLeagueScoreData(self):
     schools = SchoolAPI(self.request).getAll()
     result = list()
     for school in schools:
         school_id = school.id
         school_name = school.school_name
         participated_events = SchoolAPI(
             self.request).getParticipatedEvents(school_id,
                                                 Event.EVENT_STATUS_DONE,
                                                 self.season)
         participated_events_num = participated_events.count()
         calculated_score = self.getCurrentLeagueScoreBySchool(
             school_id=school.id, compiled=False)
         recorded_score = self.getCurrentLeagueScoreBySchool(
             school_id=school.id, compiled=True)
         response = dict(
             school_id=school_id,
             school_name=school_name,
             participated_events_num=participated_events_num,
             calculated_score=calculated_score,
             recorded_score=recorded_score,
         )
         result.append(response)
     return result
    def getAverageFactor(self, region, num_race):
        num_school_in_region = SchoolAPI(
            self.request).filterSelf(school_region=region).count()
        # Specific region has different race num average
        if num_school_in_region in [1, 2]:
            base_average_race_num = 1
        elif num_school_in_region >= 3:
            base_average_race_num = 3
        else:
            raise Exception(
                "Try to retrieve a region with less than or equal to 0 school."
            )

        average_factor = max(base_average_race_num,
                             min(math.ceil(num_race / 2), 4))
        return average_factor
示例#9
0
    def updateSchools(self, school_ids):
        schools = SchoolAPI(self.request).filterSelf(id__in=school_ids)
        # Return error if one or more of the school ids could not be found
        if not len(schools) == len(school_ids):
            raise Exception(
                "At least one of the school ids is invalid in updateSchools")
        old_school_ids = list(
            map(lambda x: int(x), self.event.event_school_ids))

        # Finding all the elements in school_ids that are not already in old_school_ids, and its converse
        additionList = [e for e in school_ids if e not in old_school_ids]
        removalList = [e for e in old_school_ids if e not in school_ids]

        self.event.event_school_ids = school_ids
        self.event.event_team_number = len(school_ids)
        # Remove some boat identifiers if less schools, or add more non duplicate numbers if more schools
        boat_ids = self.event.event_boat_rotation_name.split(',')
        next_boat_id = (lambda m: m if m is not None else 0)(
            MiscFunctions.findMaxInStrArr(boat_ids)) + 1
        new_boat_ids = boat_ids[:min(self.event.event_team_number, len(boat_ids))] + \
                                              [str(next_boat_id + i) for i in range(
                                                  max(0, self.event.event_team_number - len(boat_ids))
                                              )]
        self.event.event_boat_rotation_name = ','.join(new_boat_ids)
        self.event.save()

        # Handling Addition first before deletion
        self.updateSummaryBySchool(additionList, AuthenticationActionType.ADD)
        self.updateEventTeams(additionList, AuthenticationActionType.ADD)
        self.updateEventActivities(additionList, AuthenticationActionType.ADD)
        self.updateEventTeamLinks(additionList, AuthenticationActionType.ADD)

        # Handling Deletion
        self.updateSummaryBySchool(removalList,
                                   AuthenticationActionType.DELETE)
        self.updateEventActivities(removalList,
                                   AuthenticationActionType.DELETE)
        self.updateEventTeamLinks(removalList, AuthenticationActionType.DELETE)
        self.updateEventTeams(removalList, AuthenticationActionType.DELETE)

        # Update rotation, previous doesn't have information about new teams
        self.event.event_rotation_detail = self.regenerateRotation()
        self.event.save()

        # Update Summary and League Scores
        self.recalculateScores()
 def genSchoolTable(region):
     schools = SchoolAPI(self.request).filterSelf(
         school_region=region).order_by('school_name')
     school_dict = list(
         map(
             lambda school: dict(
                 school_name=school.school_name,
                 school_team_name=school.school_default_team_name,
                 school_status=school.school_status,
                 school_season_score=MiscFunctions.truncateDisplayScore(
                     LeagueScoringAPI(self.request).
                     tryCompileThenCalculateScore(school)),
                 school_link=reverse('client.view_dispatch_param',
                                     args=
                                     ["school_specific", school.id])),
             list(schools)))
     return school_dict
示例#11
0
 def updateEventTeams(self, school_ids, action):
     event_tags = EventTagAPI(
         self.request).filterSelf(event_tag_event_id=self.event.id)
     if action == AuthenticationActionType.ADD:
         schools = SchoolAPI(self.request).filterSelf(id__in=school_ids)
         for school in schools:
             for idx, tag in enumerate(event_tags):
                 team_name = '{} {} {}'.format(
                     school.school_default_team_name, Team.TEAM_NAME_SUFFIX,
                     MiscFunctions.getAlphabet(idx))
                 TeamAPI(self.request).createSelf(team_name=team_name,
                                                  team_school=school.id,
                                                  team_status="active",
                                                  team_tag_id=tag.id)
     elif action == AuthenticationActionType.DELETE:
         TeamAPI(self.request).deleteSelf(
             legacy=False,
             team_tag_id__in=[e.id for e in event_tags],
             team_school__in=school_ids).delete()
 def genContent(self, event_id):
     content = dict()
     event = EventAPI(self.request).getSelf(id=event_id)
     schools = SchoolAPI(self.request).getAll()
     participating_school_ids = [int(school_id) for school_id in event.event_school_ids]
     for idx, school in enumerate(schools):
         content[idx] = dict(
             school_id=school.id,
             school_url=reverse(
                 'client.view_dispatch_param',
                 args=['school_specific', school.id]
             ),
             school_name=school.school_name,
             participated=school.id in participating_school_ids,
         )
     content_list = [
         v for v in sorted(
             content.values(),
             key=lambda x: (x['participated'], -x['school_id']),
             reverse=True
         )
     ]
     return content_list
    def __buildFleetTable(self, event, force_compile):
        def __buildFleetScoreTable():
            race_table = dict()
            event_score_map = self.__compileScoreMap(event)
            for tag_id, tag in zip(event_activity_id_tags,
                                   event_activity_name_tags):
                race_table[tag] = dict()
                restricted_eas = event_activities.filter(
                    event_activity_event_tag=tag_id).order_by(
                        'event_activity_order')
                for ea in restricted_eas:
                    result = ea.event_activity_result
                    if bool(result):
                        for team, rank in result.items():
                            team_id = int(team)
                            team_name = team_name_link[team_id]
                            rank = rank if rank not in event_score_map else rank + ' (' + str(
                                event_score_map[rank]) + ')'
                            if team_id not in race_table[tag]:
                                race_table[tag][team_id] = dict(
                                    team_name=team_name,
                                    scores=list(),
                                    final_score=0)
                            race_table[tag][team_id]["scores"].append(rank)
                    else:
                        for team in team_ids[tag]:
                            team_name = team_name_link[team]
                            if team not in race_table[tag]:
                                race_table[tag][team] = dict(
                                    team_name=team_name,
                                    scores=list(),
                                    final_score=0)
                            race_table[tag][team]["scores"].append(0)

            for tag in event_activity_name_tags:
                for team in team_ids[tag]:
                    score = reduce(
                        (lambda x, y: self.__scoreAdd(x, y, event_score_map)),
                        race_table[tag][team]["scores"])
                    race_table[tag][team]["final_score"] = int(score)

            for tag in event_activity_name_tags:
                temp_table = sorted(
                    race_table[tag].items(),
                    key=lambda x: x[1]["final_score"]
                    if x[1]["final_score"] != 0 else ScoreMappingAPI(
                        self.request).getMaxSentinel())
                race_table[tag] = {data[0]: data[1] for data in temp_table}

            for tag in event_activity_name_tags:
                prevRanking = 1
                prevScore = 0
                for index, team in enumerate(race_table[tag]):
                    if race_table[tag][team]["final_score"] == 0:
                        race_table[tag][team]["rank"] = '#'
                    else:
                        if race_table[tag][team]["final_score"] > prevScore:
                            prevRanking = index + 1
                            prevScore = race_table[tag][team]["final_score"]
                        race_table[tag][team]["rank"] = prevRanking
            # Sort the race_table by rank (takes care of unassigned rank cases)
            return race_table

        def __buildFleetRankingTable():
            if not event.event_status == Event.EVENT_STATUS_DONE or force_compile:
                ranking_table = dict()
                for school in schools:
                    ranking_table[school.id] = 0
                for tag in event_activity_name_tags:
                    for team in team_ids[tag]:
                        ranking_table[team_school_link[
                            team].id] += score_table[tag][team]["final_score"]
                school_ranking_list = [
                    dict(school_id=school_id,
                         school_name=schools.get(id=school_id).school_name,
                         score=data,
                         ranking='#',
                         base_ranking='#',
                         override_ranking=0,
                         need_override=False,
                         note='-')
                    for school_id, data in ranking_table.items()
                ]
                school_ranking_list = sorted(
                    school_ranking_list,
                    key=lambda x: x['score']
                    if x['score'] != 0 else ScoreMappingAPI(self.request
                                                            ).getMaxSentinel())
                prevRanking = 1
                prevScore = 0
                for index, school_ranking_data in enumerate(
                        school_ranking_list):
                    if school_ranking_data['score'] != 0:
                        if school_ranking_data['score'] > prevScore:
                            prevRanking = index + 1
                            prevScore = school_ranking_data['score']
                        school_ranking_list[index]['ranking'] = prevRanking
                        school_ranking_list[index][
                            'base_ranking'] = prevRanking
            else:
                summaries = list(
                    SummaryAPI(self.request).filterSelf(
                        summary_event_parent=event.id))
                school_ranking_list = [
                    dict(
                        school_id=summary.summary_event_school,
                        school_name=schools.get(
                            id=summary.summary_event_school).school_name,
                        score=summary.summary_event_race_score,
                        ranking=summary.summary_event_ranking +
                        summary.summary_event_override_ranking,
                        base_ranking=summary.summary_event_ranking,
                        override_ranking=summary.
                        summary_event_override_ranking,
                        need_override=True if
                        summary.summary_event_override_ranking != 0 else False,
                        note='Tie-breaker' if
                        summary.summary_event_override_ranking != 0 else '-')
                    for index, summary in enumerate(summaries)
                ]
            # Takes care of unassigned ranking cases
            school_ranking_list = sorted(
                school_ranking_list,
                key=lambda x: x['ranking']
                if isinstance(x['ranking'], int) else ScoreMappingAPI(
                    self.request).getMaxSentinel())
            # TODO: Refactor, this code does not belong to the frontend API, it is for the backend score compilation
            # Loop to check if entry needs override
            for index, school_ranking_data in enumerate(school_ranking_list):
                duplicates = sum((1 if result['base_ranking'] ==
                                  school_ranking_data['base_ranking'] else 0)
                                 for result in school_ranking_list)
                if duplicates > 1:
                    school_ranking_list[index]['need_override'] = True
            return school_ranking_list

        event_activities = EventActivityAPI(
            self.request).filterSelf(event_activity_event_parent=event.id)
        schools = SchoolAPI(self.request).filterSelf(
            id__in=list(map(lambda x: int(x), event.event_school_ids)))
        teams = EventAPI(self.request).getEventCascadeTeams(event.id)
        event_activity_id_tags = list()
        event_activity_name_tags = list()
        team_ids = dict()
        team_school_link = dict()
        team_name_link = dict()
        distinct_eas = event_activities.distinct('event_activity_event_tag')
        team_flatten_ids = [team.id for team in teams]
        for ea in distinct_eas:
            event_tag_name = EventTagAPI(self.request).getSelf(
                id=ea.event_activity_event_tag).event_tag_name
            event_activity_name_tags.append(event_tag_name)
            event_activity_id_tags.append(ea.event_activity_event_tag)
            team_ids[event_tag_name] = [
                team.id for team in teams.filter(
                    team_tag_id=ea.event_activity_event_tag)
            ]
        for team in TeamAPI(self.request).filterSelf(id__in=team_flatten_ids):
            team_school_link[team.id] = schools.get(id=team.team_school)
            team_name_link[team.id] = team_school_link[
                team.id].school_name + ' - ' + team.team_name

        score_table = __buildFleetScoreTable()
        rank_table = __buildFleetRankingTable()
        return dict(ranking=rank_table, score=score_table)