def district_updated(affected_refs): years = _filter(affected_refs['year']) district_abbrevs = _filter(affected_refs['abbreviation']) district_keys = _filter(affected_refs['key']) district_team_keys_future = DistrictTeam.query(DistrictTeam.district_key.IN(list(district_keys))).fetch_async(None, keys_only=True) district_event_keys_future = Event.query(Event.district_key.IN(list(district_keys))).fetch_async(keys_only=True) queries_and_keys = [] for year in years: queries_and_keys.append(DistrictsInYearQuery(year)) for abbrev in district_abbrevs: queries_and_keys.append(DistrictHistoryQuery(abbrev)) for key in district_keys: queries_and_keys.append(DistrictQuery(key.id())) for dt_key in district_team_keys_future.get_result(): team_key = dt_key.id().split('_')[1] queries_and_keys.append(TeamDistrictsQuery(team_key)) # Necessary because APIv3 Event models include the District model affected_event_refs = { 'key': set(), 'year': set(), 'district_key': district_keys, } for event_key in district_event_keys_future.get_result(): affected_event_refs['key'].add(event_key) affected_event_refs['year'].add(int(event_key.id()[:4])) queries_and_keys += event_updated(affected_event_refs) return queries_and_keys
def _render(self, district_key, model_type=None): district, self._last_modified = DistrictQuery(district_key).fetch( return_updated=True) return json.dumps(district.rankings, ensure_ascii=True, indent=True, sort_keys=True)
def test_district_updated(self): affected_refs = { 'key': {ndb.Key(District, '2016ne')}, 'year': {2015, 2016}, 'abbreviation': {'ne', 'chs'} } cache_keys = [ q.cache_key for q in get_affected_queries.district_updated(affected_refs) ] self.assertEqual(len(cache_keys), 11) self.assertTrue(DistrictsInYearQuery(2015).cache_key in cache_keys) self.assertTrue(DistrictsInYearQuery(2016).cache_key in cache_keys) self.assertTrue(DistrictHistoryQuery('ne').cache_key in cache_keys) self.assertTrue(DistrictHistoryQuery('chs').cache_key in cache_keys) self.assertTrue(DistrictQuery('2016ne').cache_key in cache_keys) self.assertTrue(TeamDistrictsQuery('frc604').cache_key in cache_keys) # Necessary because APIv3 Event models include the District model self.assertTrue(EventQuery('2016necmp').cache_key in cache_keys) self.assertTrue(EventListQuery(2016).cache_key in cache_keys) self.assertTrue(DistrictEventsQuery('2016ne').cache_key in cache_keys) self.assertTrue(TeamEventsQuery('frc125').cache_key in cache_keys) self.assertTrue( TeamYearEventsQuery('frc125', 2016).cache_key in cache_keys)
def event_district_str(self): from database.district_query import DistrictQuery if self.district_key is None: return None district = DistrictQuery(self.district_key.id()).fetch() return district.display_name if district else None
def _render(self, event_key): event = EventQuery(event_key).fetch() if not event: self.abort(404) event.prepAwardsMatchesTeams() event.prep_details() medias_future = media_query.EventTeamsPreferredMediasQuery(event_key).fetch_async() district_future = DistrictQuery(event.district_key.id()).fetch_async() if event.district_key else None event_medias_future = media_query.EventMediasQuery(event_key).fetch_async() status_sitevar_future = Sitevar.get_by_id_async('apistatus.down_events') event_divisions_future = None event_codivisions_future = None parent_event_future = None if event.divisions: event_divisions_future = ndb.get_multi_async(event.divisions) elif event.parent_event: parent_event_future = event.parent_event.get_async() event_codivisions_future = EventDivisionsQuery(event.parent_event.id()).fetch_async() awards = AwardHelper.organizeAwards(event.awards) cleaned_matches = MatchHelper.deleteInvalidMatches(event.matches, event) matches = MatchHelper.organizeMatches(cleaned_matches) teams = TeamHelper.sortTeams(event.teams) # Organize medias by team image_medias = MediaHelper.get_images([media for media in medias_future.get_result()]) team_medias = defaultdict(list) for image_media in image_medias: for reference in image_media.references: team_medias[reference].append(image_media) team_and_medias = [] for team in teams: team_and_medias.append((team, team_medias.get(team.key, []))) num_teams = len(team_and_medias) middle_value = num_teams / 2 if num_teams % 2 != 0: middle_value += 1 teams_a, teams_b = team_and_medias[:middle_value], team_and_medias[middle_value:] oprs = [i for i in event.matchstats['oprs'].items()] if (event.matchstats is not None and 'oprs' in event.matchstats) else [] oprs = sorted(oprs, key=lambda t: t[1], reverse=True) # sort by OPR oprs = oprs[:15] # get the top 15 OPRs if event.now: matches_recent = MatchHelper.recentMatches(cleaned_matches) matches_upcoming = MatchHelper.upcomingMatches(cleaned_matches) else: matches_recent = None matches_upcoming = None bracket_table = MatchHelper.generateBracket(matches, event, event.alliance_selections) playoff_advancement = None playoff_template = None double_elim_matches = None if EventHelper.is_2015_playoff(event_key): playoff_advancement = MatchHelper.generatePlayoffAdvancement2015(matches, event.alliance_selections) playoff_template = 'playoff_table' for comp_level in ['qf', 'sf']: if comp_level in bracket_table: del bracket_table[comp_level] elif event.playoff_type == PlayoffType.ROUND_ROBIN_6_TEAM: playoff_advancement = MatchHelper.generatePlayoffAdvancementRoundRobin(matches, event.year, event.alliance_selections) playoff_template = 'playoff_round_robin_6_team' comp_levels = bracket_table.keys() for comp_level in comp_levels: if comp_level != 'f': del bracket_table[comp_level] elif event.playoff_type == PlayoffType.BO3_FINALS or event.playoff_type == PlayoffType.BO5_FINALS: comp_levels = bracket_table.keys() for comp_level in comp_levels: if comp_level != 'f': del bracket_table[comp_level] elif event.playoff_type == PlayoffType.DOUBLE_ELIM_8_TEAM: double_elim_matches = MatchHelper.organizeDoubleElimMatches(matches) district_points_sorted = None if event.district_key and event.district_points: district_points_sorted = sorted(event.district_points['points'].items(), key=lambda (team, points): -points['total']) event_insights = event.details.insights if event.details else None event_insights_template = None if event_insights: event_insights_template = 'event_partials/event_insights_{}.html'.format(event.year) district = district_future.get_result() if district_future else None event_divisions = None if event_divisions_future: event_divisions = [e.get_result() for e in event_divisions_future] elif event_codivisions_future: event_divisions = event_codivisions_future.get_result() medias_by_slugname = MediaHelper.group_by_slugname([media for media in event_medias_future.get_result()]) has_time_predictions = matches_upcoming and any(match.predicted_time for match in matches_upcoming) status_sitevar = status_sitevar_future.get_result() self.template_values.update({ "event": event, "event_down": status_sitevar and event_key in status_sitevar.contents, "district_name": district.display_name if district else None, "district_abbrev": district.abbreviation if district else None, "matches": matches, "matches_recent": matches_recent, "matches_upcoming": matches_upcoming, 'has_time_predictions': has_time_predictions, "awards": awards, "teams_a": teams_a, "teams_b": teams_b, "num_teams": num_teams, "oprs": oprs, "bracket_table": bracket_table, "playoff_advancement": playoff_advancement, "playoff_template": playoff_template, "district_points_sorted": district_points_sorted, "event_insights_qual": event_insights['qual'] if event_insights else None, "event_insights_playoff": event_insights['playoff'] if event_insights else None, "event_insights_template": event_insights_template, "medias_by_slugname": medias_by_slugname, "event_divisions": event_divisions, 'parent_event': parent_event_future.get_result() if parent_event_future else None, 'double_elim_matches': double_elim_matches, 'double_elim_playoff_types': PlayoffType.DOUBLE_ELIM_TYPES, }) if event.within_a_day: self._cache_expiration = self.SHORT_CACHE_EXPIRATION return jinja2_engine.render('event_details.html', self.template_values)
def _render(self, event_key): event = EventQuery(event_key).fetch() if not event: self.abort(404) event.prepAwardsMatchesTeams() event.prep_details() medias_future = media_query.EventTeamsPreferredMediasQuery(event_key).fetch_async() district_future = DistrictQuery(event.district_key.id()).fetch_async() if event.district_key else None event_medias_future = media_query.EventMediasQuery(event_key).fetch_async() awards = AwardHelper.organizeAwards(event.awards) cleaned_matches = MatchHelper.deleteInvalidMatches(event.matches) matches = MatchHelper.organizeMatches(cleaned_matches) teams = TeamHelper.sortTeams(event.teams) # Organize medias by team image_medias = MediaHelper.get_images([media for media in medias_future.get_result()]) team_medias = defaultdict(list) for image_media in image_medias: for reference in image_media.references: team_medias[reference].append(image_media) team_and_medias = [] for team in teams: team_and_medias.append((team, team_medias.get(team.key, []))) num_teams = len(team_and_medias) middle_value = num_teams / 2 if num_teams % 2 != 0: middle_value += 1 teams_a, teams_b = team_and_medias[:middle_value], team_and_medias[middle_value:] oprs = [i for i in event.matchstats['oprs'].items()] if (event.matchstats is not None and 'oprs' in event.matchstats) else [] oprs = sorted(oprs, key=lambda t: t[1], reverse=True) # sort by OPR oprs = oprs[:15] # get the top 15 OPRs if event.now: matches_recent = MatchHelper.recentMatches(cleaned_matches) matches_upcoming = MatchHelper.upcomingMatches(cleaned_matches) else: matches_recent = None matches_upcoming = None bracket_table = MatchHelper.generateBracket(matches, event.alliance_selections) is_2015_playoff = EventHelper.is_2015_playoff(event_key) if is_2015_playoff: playoff_advancement = MatchHelper.generatePlayoffAdvancement2015(matches, event.alliance_selections) for comp_level in ['qf', 'sf']: if comp_level in bracket_table: del bracket_table[comp_level] else: playoff_advancement = None district_points_sorted = None if event.district_points: district_points_sorted = sorted(event.district_points['points'].items(), key=lambda (team, points): -points['total']) event_insights = event.details.insights if event.details else None event_insights_template = None if event_insights: event_insights_template = 'event_partials/event_insights_{}.html'.format(event.year) district = district_future.get_result() if district_future else None medias_by_slugname = MediaHelper.group_by_slugname([media for media in event_medias_future.get_result()]) self.template_values.update({ "event": event, "district_name": district.display_name if district else None, "district_abbrev": district.abbreviation if district else None, "matches": matches, "matches_recent": matches_recent, "matches_upcoming": matches_upcoming, "awards": awards, "teams_a": teams_a, "teams_b": teams_b, "num_teams": num_teams, "oprs": oprs, "bracket_table": bracket_table, "playoff_advancement": playoff_advancement, "district_points_sorted": district_points_sorted, "is_2015_playoff": is_2015_playoff, "event_insights_qual": event_insights['qual'] if event_insights else None, "event_insights_playoff": event_insights['playoff'] if event_insights else None, "event_insights_template": event_insights_template, "medias_by_slugname": medias_by_slugname, }) if event.within_a_day: self._cache_expiration = self.SHORT_CACHE_EXPIRATION return jinja2_engine.render('event_details.html', self.template_values)
def _render(self, district_abbrev, year=None, explicit_year=False): district = DistrictQuery('{}{}'.format(year, district_abbrev)).fetch() if not district: self.abort(404) events_future = DistrictEventsQuery(district.key_name).fetch_async() # needed for district teams district_teams_future = DistrictTeamsQuery(district.key_name).fetch_async() # needed for valid_years history_future = DistrictHistoryQuery(district.abbreviation).fetch_async() # needed for valid_districts districts_in_year_future = DistrictsInYearQuery(district.year).fetch_async() # Temp disabled on 2017-02-18 -fangeugene # # Needed for active team statuses # live_events = [] # if year == datetime.datetime.now().year: # Only show active teams for current year # live_events = EventHelper.getWeekEvents() # live_eventteams_futures = [] # for event in live_events: # live_eventteams_futures.append(EventTeamsQuery(event.key_name).fetch_async()) events = events_future.get_result() EventHelper.sort_events(events) events_by_key = {} for event in events: events_by_key[event.key.id()] = event week_events = EventHelper.groupByWeek(events) valid_districts = set() districts_in_year = districts_in_year_future.get_result() for dist in districts_in_year: valid_districts.add((dist.display_name, dist.abbreviation)) valid_districts = sorted(valid_districts, key=lambda (name, _): name) teams = TeamHelper.sortTeams(district_teams_future.get_result()) num_teams = len(teams) middle_value = num_teams / 2 if num_teams % 2 != 0: middle_value += 1 teams_a, teams_b = teams[:middle_value], teams[middle_value:] # Temp disabled on 2017-02-18 -fangeugene # # Currently Competing Team Status # live_events_with_teams = EventTeamStatusHelper.buildEventTeamStatus(live_events, live_eventteams_futures, teams) # live_events_with_teams.sort(key=lambda x: x[0].name) # Get valid years district_history = history_future.get_result() valid_years = map(lambda d: d.year, district_history) valid_years = sorted(valid_years) self.template_values.update({ 'explicit_year': explicit_year, 'year': year, 'valid_years': valid_years, 'valid_districts': valid_districts, 'district_name': district.display_name, 'district_abbrev': district_abbrev, 'week_events': week_events, 'events_by_key': events_by_key, 'rankings': district.rankings, 'teams_a': teams_a, 'teams_b': teams_b, # 'live_events_with_teams': live_events_with_teams, # Temp disabled on 2017-02-18 -fangeugene }) return jinja2_engine.render('district_details.html', self.template_values)
def _render(self, district_abbrev, year=None, explicit_year=False): district = DistrictQuery('{}{}'.format(year, district_abbrev)).fetch() if not district: self.abort(404) events_future = DistrictEventsQuery(district.key_name).fetch_async() # needed for district teams district_teams_future = DistrictTeamsQuery( district.key_name).fetch_async() # needed for valid_years history_future = DistrictHistoryQuery( district.abbreviation).fetch_async() # needed for valid_districts districts_in_year_future = DistrictsInYearQuery( district.year).fetch_async() # needed for active team statuses live_events = [] if year == datetime.datetime.now( ).year: # Only show active teams for current year live_events = EventHelper.getWeekEvents() live_eventteams_futures = [] for event in live_events: live_eventteams_futures.append( EventTeamsQuery(event.key_name).fetch_async()) events = events_future.get_result() EventHelper.sort_events(events) events_by_key = {} for event in events: events_by_key[event.key.id()] = event week_events = EventHelper.groupByWeek(events) valid_districts = set() districts_in_year = districts_in_year_future.get_result() for dist in districts_in_year: valid_districts.add((dist.display_name, dist.abbreviation)) valid_districts = sorted(valid_districts, key=lambda (name, _): name) teams = TeamHelper.sortTeams(district_teams_future.get_result()) team_keys = set([t.key.id() for t in teams]) num_teams = len(teams) middle_value = num_teams / 2 if num_teams % 2 != 0: middle_value += 1 teams_a, teams_b = teams[:middle_value], teams[middle_value:] # Currently Competing Team Status event_team_keys = [] for event, teams_future in zip(live_events, live_eventteams_futures): for team in teams_future.get_result(): if team.key.id() in team_keys: event_team_keys.append( ndb.Key(EventTeam, '{}_{}'.format( event.key.id(), team.key.id()))) # Should be in context cache ndb.get_multi(event_team_keys) # Warms context cache live_events_with_teams = [] for event, teams_future in zip(live_events, live_eventteams_futures): teams_and_statuses = [] has_teams = False for team in teams_future.get_result(): if team.key.id() in team_keys: has_teams = True event_team = EventTeam.get_by_id('{}_{}'.format( event.key.id(), team.key.id())) # Should be in context cache status_str = { 'alliance': EventTeamStatusHelper. generate_team_at_event_alliance_status_string( team.key.id(), event_team.status), 'playoff': EventTeamStatusHelper. generate_team_at_event_playoff_status_string( team.key.id(), event_team.status), } teams_and_statuses.append( (team, event_team.status, status_str)) if has_teams: teams_and_statuses.sort(key=lambda x: x[0].team_number) live_events_with_teams.append((event, teams_and_statuses)) live_events_with_teams.sort(key=lambda x: x[0].name) live_events_with_teams.sort( key=lambda x: EventHelper.distantFutureIfNoStartDate(x[0])) live_events_with_teams.sort( key=lambda x: EventHelper.distantFutureIfNoEndDate(x[0])) # Get valid years district_history = history_future.get_result() valid_years = map(lambda d: d.year, district_history) valid_years = sorted(valid_years) self.template_values.update({ 'explicit_year': explicit_year, 'year': year, 'valid_years': valid_years, 'valid_districts': valid_districts, 'district_name': district.display_name, 'district_abbrev': district_abbrev, 'week_events': week_events, 'events_by_key': events_by_key, 'rankings': district.rankings, 'advancement': district.advancement, 'teams_a': teams_a, 'teams_b': teams_b, 'live_events_with_teams': live_events_with_teams, }) return jinja2_engine.render('district_details.html', self.template_values)