def test_2017scmb_sequence(self): event = Event( id='2017scmb', event_short='scmb', year=2017, event_type_enum=0, timezone_id='America/New_York' ) event.put() event_code = 'scmb' file_prefix = 'frc-api-response/v2.0/2017/schedule/{}/playoff/hybrid/'.format(event_code) context = ndb.get_context() result = context.urlfetch('https://www.googleapis.com/storage/v1/b/bucket/o?bucket=tbatv-prod-hrd.appspot.com&prefix={}'.format(file_prefix)).get_result() for item in json.loads(result.content)['items']: filename = item['name'] time_str = filename.replace(file_prefix, '').replace('.json', '').strip() file_time = datetime.datetime.strptime(time_str, "%Y-%m-%d %H:%M:%S.%f") query_time = file_time + datetime.timedelta(seconds=30) MatchManipulator.createOrUpdate(DatafeedFMSAPI('v2.0', sim_time=query_time).getMatches('2017{}'.format(event_code)), run_post_update_hook=False) MatchHelper.deleteInvalidMatches(event.matches, event) qf_matches = Match.query(Match.event == ndb.Key(Event, '2017scmb'), Match.comp_level == 'qf').fetch() self.assertEqual(len(qf_matches), 11) sf_matches = Match.query(Match.event == ndb.Key(Event, '2017scmb'), Match.comp_level == 'sf').fetch() self.assertEqual(len(sf_matches), 4) f_matches = Match.query(Match.event == ndb.Key(Event, '2017scmb'), Match.comp_level == 'f').fetch() self.assertEqual(len(f_matches), 3) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').alliances['red']['score'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').alliances['blue']['score'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').score_breakdown['red']['totalPoints'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').score_breakdown['blue']['totalPoints'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m2').alliances['red']['score'], 213) self.assertEqual(Match.get_by_id('2017scmb_qf4m2').alliances['blue']['score'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m2').score_breakdown['red']['totalPoints'], 213) self.assertEqual(Match.get_by_id('2017scmb_qf4m2').score_breakdown['blue']['totalPoints'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m3').alliances['red']['score'], 312) self.assertEqual(Match.get_by_id('2017scmb_qf4m3').alliances['blue']['score'], 255) self.assertEqual(Match.get_by_id('2017scmb_qf4m3').score_breakdown['red']['totalPoints'], 312) self.assertEqual(Match.get_by_id('2017scmb_qf4m3').score_breakdown['blue']['totalPoints'], 255) self.assertEqual(Match.get_by_id('2017scmb_qf4m4').alliances['red']['score'], 310) self.assertEqual(Match.get_by_id('2017scmb_qf4m4').alliances['blue']['score'], 306) self.assertEqual(Match.get_by_id('2017scmb_qf4m4').score_breakdown['red']['totalPoints'], 310) self.assertEqual(Match.get_by_id('2017scmb_qf4m4').score_breakdown['blue']['totalPoints'], 306)
def test_2017flwp(self): event = Event(id='2017flwp', event_short='flwp', year=2017, event_type_enum=0, timezone_id='America/New_York') event.put() MatchManipulator.createOrUpdate( DatafeedFMSAPI('v2.0', sim_time=datetime.datetime( 2017, 3, 04, 21, 22)).getMatches('2017flwp')) MatchHelper.deleteInvalidMatches(event.matches) sf_matches = Match.query(Match.event == ndb.Key(Event, '2017flwp'), Match.comp_level == 'sf').fetch() self.assertEqual(len(sf_matches), 5) old_match = Match.get_by_id('2017flwp_sf1m3') self.assertNotEqual(old_match, None) self.assertEqual(old_match.alliances['red']['score'], 255) self.assertEqual(old_match.alliances['blue']['score'], 255) self.assertEqual(old_match.score_breakdown['red']['totalPoints'], 255) self.assertEqual(old_match.score_breakdown['blue']['totalPoints'], 255) ndb.get_context().clear_cache( ) # Prevent data from leaking between tests MatchManipulator.createOrUpdate( DatafeedFMSAPI('v2.0', sim_time=datetime.datetime( 2017, 3, 04, 21, 35)).getMatches('2017flwp')) MatchHelper.deleteInvalidMatches(event.matches) sf_matches = Match.query(Match.event == ndb.Key(Event, '2017flwp'), Match.comp_level == 'sf').fetch() self.assertEqual(len(sf_matches), 6) new_match = Match.get_by_id('2017flwp_sf1m3') self.assertNotEqual(new_match, None) self.assertEqual(old_match.alliances, new_match.alliances) self.assertEqual(old_match.score_breakdown, new_match.score_breakdown) tiebreaker_match = Match.get_by_id('2017flwp_sf1m4') self.assertNotEqual(tiebreaker_match, None) self.assertEqual(tiebreaker_match.alliances['red']['score'], 165) self.assertEqual(tiebreaker_match.alliances['blue']['score'], 263) self.assertEqual( tiebreaker_match.score_breakdown['red']['totalPoints'], 165) self.assertEqual( tiebreaker_match.score_breakdown['blue']['totalPoints'], 263)
def test_cleanup(self): matches = setupMatches('test_data/cleanup_matches.csv') cleaned_matches = MatchHelper.deleteInvalidMatches(matches) indices = [9, 12, 26] for index in sorted(indices, reverse=True): #need to delete in reverse order so indices don't get messed up del matches[index] self.assertEqual(matches, cleaned_matches)
def get(self, event_key): event = Event.get_by_id(event_key) if not event: self.abort(404) event_future = EventQuery(event_key).fetch_async(return_updated=True) matches_future = EventMatchesQuery(event_key).fetch_async( return_updated=True) event, _ = event_future.get_result() matches, _ = matches_future.get_result() cleaned_matches = MatchHelper.deleteInvalidMatches(matches, event) matches = MatchHelper.organizeMatches(cleaned_matches) bracket_table, playoff_advancement, _, _ = PlayoffAdvancementHelper.generatePlayoffAdvancement( event, matches) event_details = EventDetails( id=event.key_name, playoff_advancement={ 'advancement': playoff_advancement, 'bracket': bracket_table, }, ) EventDetailsManipulator.createOrUpdate(event_details) self.response.out.write("New playoff advancement for {}\n{}".format( event.key_name, json.dumps(event_details.playoff_advancement, indent=2, sort_keys=True)))
def _render(self, event_key): event_future = EventQuery(event_key).fetch_async(return_updated=True) matches_future = EventMatchesQuery(event_key).fetch_async(return_updated=True) event, event_updated = event_future.get_result() matches, matches_updated = matches_future.get_result() self._last_modified = max(event_updated, matches_updated) cleaned_matches = MatchHelper.deleteInvalidMatches(matches, event) matches = MatchHelper.organizeMatches(cleaned_matches) bracket_table, playoff_advancement, _, _ = PlayoffAdvancementHelper.generatePlayoffAdvancement(event, matches) output = [] for level in Match.ELIM_LEVELS: level_ranks = [] if playoff_advancement and playoff_advancement.get(level): if event.playoff_type == PlayoffType.AVG_SCORE_8_TEAM: level_ranks = PlayoffAdvancementHelper.transform2015AdvancementLevelForApi(event, playoff_advancement, level) else: level_ranks = PlayoffAdvancementHelper.transformRoundRobinAdvancementLevelForApi(event, playoff_advancement, level) elif bracket_table and bracket_table.get(level): level_ranks = PlayoffAdvancementHelper.transformBracketLevelForApi(event, bracket_table, level) output.extend(level_ranks) return json.dumps(output, ensure_ascii=True, indent=2, sort_keys=True)
def _render(self, event_key): event = Event.get_by_id(event_key) if not event: self.abort(404) event.prepAwardsMatchesTeams() awards = AwardHelper.organizeAwards(event.awards) cleaned_matches = MatchHelper.deleteInvalidMatches(event.matches) matches = MatchHelper.organizeMatches(cleaned_matches) teams = TeamHelper.sortTeams(event.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:] 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.within_a_day: matches_recent = MatchHelper.recentMatches(cleaned_matches) matches_upcoming = MatchHelper.upcomingMatches(cleaned_matches) else: matches_recent = None matches_upcoming = None bracket_table = {} qf_matches = matches['qf'] sf_matches = matches['sf'] f_matches = matches['f'] if qf_matches: bracket_table['qf'] = MatchHelper.generateBracket(qf_matches) if sf_matches: bracket_table['sf'] = MatchHelper.generateBracket(sf_matches) if f_matches: bracket_table['f'] = MatchHelper.generateBracket(f_matches) template_values = { "event": event, "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, } if event.within_a_day: self._cache_expiration = self.SHORT_CACHE_EXPIRATION path = os.path.join(os.path.dirname(__file__), '../templates/event_details.html') return template.render(path, template_values)
def test_cleanup(self): matches = self.setupMatches("test_data/cleanup_matches.csv") cleaned_matches = MatchHelper.deleteInvalidMatches(matches) indices = {9, 12, 26} correct_matches = [] for i, match in enumerate(matches): if i not in indices: correct_matches.append(match) self.assertEqual(correct_matches, cleaned_matches)
def test_cleanup(self): matches = self.setupMatches('test_data/cleanup_matches.csv') cleaned_matches = MatchHelper.deleteInvalidMatches(matches) indices = {9, 12, 26} correct_matches = [] for i, match in enumerate(matches): if i not in indices: correct_matches.append(match) self.assertEqual(correct_matches, cleaned_matches)
def _render(self, event_key): event = Event.get_by_id(event_key) if not event: self.abort(404) event.prepAwardsMatchesTeams() awards = AwardHelper.organizeAwards(event.awards) cleaned_matches = MatchHelper.deleteInvalidMatches(event.matches) matches = MatchHelper.organizeMatches(cleaned_matches) teams = TeamHelper.sortTeams(event.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:] 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.within_a_day: 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) district_points_sorted = None if event.district_points: district_points_sorted = sorted(event.district_points['points'].items(), key=lambda (team, points): -points['total']) self.template_values.update({ "event": event, "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, "district_points_sorted": district_points_sorted, }) if event.within_a_day: self._cache_expiration = self.SHORT_CACHE_EXPIRATION path = os.path.join(os.path.dirname(__file__), '../templates/event_details.html') return template.render(path, self.template_values)
def test_2017flwp(self): event = Event( id='2017flwp', event_short='flwp', year=2017, event_type_enum=0, timezone_id='America/New_York' ) event.put() MatchManipulator.createOrUpdate(DatafeedFMSAPI('v2.0', sim_time=datetime.datetime(2017, 3, 04, 21, 22)).getMatches('2017flwp')) MatchHelper.deleteInvalidMatches(event.matches, event) sf_matches = Match.query(Match.event == ndb.Key(Event, '2017flwp'), Match.comp_level == 'sf').fetch() self.assertEqual(len(sf_matches), 5) old_match = Match.get_by_id('2017flwp_sf1m3') self.assertNotEqual(old_match, None) self.assertEqual(old_match.alliances['red']['score'], 255) self.assertEqual(old_match.alliances['blue']['score'], 255) self.assertEqual(old_match.score_breakdown['red']['totalPoints'], 255) self.assertEqual(old_match.score_breakdown['blue']['totalPoints'], 255) ndb.get_context().clear_cache() # Prevent data from leaking between tests MatchManipulator.createOrUpdate(DatafeedFMSAPI('v2.0', sim_time=datetime.datetime(2017, 3, 04, 21, 35)).getMatches('2017flwp')) MatchHelper.deleteInvalidMatches(event.matches, event) sf_matches = Match.query(Match.event == ndb.Key(Event, '2017flwp'), Match.comp_level == 'sf').fetch() self.assertEqual(len(sf_matches), 6) new_match = Match.get_by_id('2017flwp_sf1m3') self.assertNotEqual(new_match, None) self.assertEqual(old_match.alliances, new_match.alliances) self.assertEqual(old_match.score_breakdown, new_match.score_breakdown) tiebreaker_match = Match.get_by_id('2017flwp_sf1m4') self.assertNotEqual(tiebreaker_match, None) self.assertEqual(tiebreaker_match.alliances['red']['score'], 165) self.assertEqual(tiebreaker_match.alliances['blue']['score'], 263) self.assertEqual(tiebreaker_match.score_breakdown['red']['totalPoints'], 165) self.assertEqual(tiebreaker_match.score_breakdown['blue']['totalPoints'], 263)
def post(self): self._require_admin() event_key = self.request.get("event_key").strip() event = Event.get_by_id(event_key) if not event: self.redirect("/admin/event/" + event.key_name) return if event.playoff_type != PlayoffType.ROUND_ROBIN_6_TEAM: logging.warning("Can't set advancement for non-round robin events") self.redirect("/admin/event/" + event.key_name) return advancement_csv = self.request.get("advancement_csv") comp_level = self.request.get("comp_level") matches_per_team = int(self.request.get("num_matches")) if comp_level not in Match.ELIM_LEVELS: logging.warning("Bad comp level: {}".format(comp_level)) self.redirect("/admin/event/" + event.key_name) return parsed_advancement = CSVAdvancementParser.parse( advancement_csv, matches_per_team) advancement = PlayoffAdvancementHelper.generatePlayoffAdvancementFromCSV( event, parsed_advancement, comp_level) cleaned_matches = MatchHelper.deleteInvalidMatches( event.matches, event) matches = MatchHelper.organizeMatches(cleaned_matches) bracket_table = PlayoffAdvancementHelper.generateBracket( matches, event, event.alliance_selections) comp_levels = bracket_table.keys() for comp_level in comp_levels: if comp_level != 'f': del bracket_table[comp_level] existing_details = EventDetails.get_by_id(event.key_name) new_advancement = existing_details.playoff_advancement if existing_details and existing_details.playoff_advancement else {} new_advancement.update(advancement) event_details = EventDetails( id=event.key_name, playoff_advancement={ 'advancement': new_advancement, 'bracket': bracket_table, }, ) EventDetailsManipulator.createOrUpdate(event_details) self.redirect("/admin/event/" + event.key_name) return
def get(self, event_key): df = DatafeedFMSAPI('v2.0', save_response=True) new_matches = MatchManipulator.createOrUpdate( MatchHelper.deleteInvalidMatches(df.getMatches(event_key), Event.get_by_id(event_key))) template_values = { 'matches': new_matches, } if 'X-Appengine-Taskname' not in self.request.headers: # Only write out if not in taskqueue path = os.path.join( os.path.dirname(__file__), '../templates/datafeeds/usfirst_matches_get.html') self.response.out.write(template.render(path, template_values))
def get(self, event_key): df = DatafeedFMSAPI('v2.0', save_response=True) new_matches = MatchManipulator.createOrUpdate( MatchHelper.deleteInvalidMatches( df.getMatches(event_key), Event.get_by_id(event_key) ) ) template_values = { 'matches': new_matches, } if 'X-Appengine-Taskname' not in self.request.headers: # Only write out if not in taskqueue path = os.path.join(os.path.dirname(__file__), '../templates/datafeeds/usfirst_matches_get.html') self.response.out.write(template.render(path, template_values))
def _render(self, event_key): event = Event.get_by_id(event_key) if not event or event.year < 2016 or not event.details.predictions: self.abort(404) event.get_matches_async() match_predictions = event.details.predictions.get('match_predictions', None) match_prediction_stats = event.details.predictions.get('match_prediction_stats', None) ranking_predictions = event.details.predictions.get('ranking_predictions', None) ranking_prediction_stats = event.details.predictions.get('ranking_prediction_stats', None) cleaned_matches = MatchHelper.deleteInvalidMatches(event.matches) matches = MatchHelper.organizeMatches(cleaned_matches) # If no matches but there are match predictions, create fake matches # For cases where FIRST doesn't allow posting of match schedule fake_matches = False if not matches['qm'] and match_predictions['qual']: fake_matches = True for i in xrange(len(match_predictions.keys())): match_number = i + 1 alliances = { 'red': { 'score': -1, 'teams': ['frc?', 'frc?', 'frc?'] }, 'blue': { 'score': -1, 'teams': ['frc?', 'frc?', 'frc?'] } } matches['qm'].append(Match( id=Match.renderKeyName( event_key, 'qm', 1, match_number), event=event.key, year=event.year, set_number=1, match_number=match_number, comp_level='qm', alliances_json=json.dumps(alliances), )) # Add actual scores to predictions distribution_info = {} for comp_level in Match.COMP_LEVELS: level = 'qual' if comp_level == 'qm' else 'playoff' for match in matches[comp_level]: distribution_info[match.key.id()] = { 'level': level, 'red_actual_score': match.alliances['red']['score'], 'blue_actual_score': match.alliances['blue']['score'], 'red_mean': match_predictions[level][match.key.id()]['red']['score'], 'blue_mean': match_predictions[level][match.key.id()]['blue']['score'], 'red_var': match_predictions[level][match.key.id()]['red']['score_var'], 'blue_var': match_predictions[level][match.key.id()]['blue']['score_var'], } last_played_match_num = None if ranking_prediction_stats: last_played_match_key = ranking_prediction_stats.get('last_played_match', None) if last_played_match_key: last_played_match_num = last_played_match_key.split('_qm')[1] self.template_values.update({ "event": event, "matches": matches, "fake_matches": fake_matches, "match_predictions": match_predictions, "distribution_info_json": json.dumps(distribution_info), "match_prediction_stats": match_prediction_stats, "ranking_predictions": ranking_predictions, "ranking_prediction_stats": ranking_prediction_stats, "last_played_match_num": last_played_match_num, }) if event.within_a_day: self._cache_expiration = self.SHORT_CACHE_EXPIRATION return jinja2_engine.render('event_insights.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 test_2017ncwin(self): event = Event(id='2017ncwin', event_short='ncwin', year=2017, event_type_enum=0, timezone_id='America/New_York') event.put() MatchManipulator.createOrUpdate( DatafeedFMSAPI('v2.0', sim_time=datetime.datetime( 2017, 3, 05, 21, 2)).getMatches('2017ncwin')) MatchHelper.deleteInvalidMatches(event.matches) sf_matches = Match.query(Match.event == ndb.Key(Event, '2017ncwin'), Match.comp_level == 'sf').fetch() self.assertEqual(len(sf_matches), 6) self.assertEqual( Match.get_by_id('2017ncwin_sf2m1').alliances['red']['score'], 265) self.assertEqual( Match.get_by_id('2017ncwin_sf2m1').alliances['blue']['score'], 150) self.assertEqual( Match.get_by_id('2017ncwin_sf2m1').score_breakdown['red'] ['totalPoints'], 265) self.assertEqual( Match.get_by_id('2017ncwin_sf2m1').score_breakdown['blue'] ['totalPoints'], 150) ndb.get_context().clear_cache( ) # Prevent data from leaking between tests MatchManipulator.createOrUpdate( DatafeedFMSAPI('v2.0', sim_time=datetime.datetime( 2017, 3, 05, 21, 30)).getMatches('2017ncwin')) MatchHelper.deleteInvalidMatches(event.matches) sf_matches = Match.query(Match.event == ndb.Key(Event, '2017ncwin'), Match.comp_level == 'sf').fetch() self.assertEqual(len(sf_matches), 6) self.assertEqual( Match.get_by_id('2017ncwin_sf2m1').alliances['red']['score'], 265) self.assertEqual( Match.get_by_id('2017ncwin_sf2m1').alliances['blue']['score'], 150) self.assertEqual( Match.get_by_id('2017ncwin_sf2m1').score_breakdown['red'] ['totalPoints'], 265) self.assertEqual( Match.get_by_id('2017ncwin_sf2m1').score_breakdown['blue'] ['totalPoints'], 150) self.assertEqual( Match.get_by_id('2017ncwin_sf2m2').alliances['red']['score'], 205) self.assertEqual( Match.get_by_id('2017ncwin_sf2m2').alliances['blue']['score'], 205) self.assertEqual( Match.get_by_id('2017ncwin_sf2m2').score_breakdown['red'] ['totalPoints'], 205) self.assertEqual( Match.get_by_id('2017ncwin_sf2m2').score_breakdown['blue'] ['totalPoints'], 205) ndb.get_context().clear_cache( ) # Prevent data from leaking between tests MatchManipulator.createOrUpdate( DatafeedFMSAPI('v2.0', sim_time=datetime.datetime( 2017, 3, 05, 21, 35)).getMatches('2017ncwin')) MatchHelper.deleteInvalidMatches(event.matches) sf_matches = Match.query(Match.event == ndb.Key(Event, '2017ncwin'), Match.comp_level == 'sf').fetch() self.assertEqual(len(sf_matches), 6) self.assertEqual( Match.get_by_id('2017ncwin_sf2m1').alliances['red']['score'], 265) self.assertEqual( Match.get_by_id('2017ncwin_sf2m1').alliances['blue']['score'], 150) self.assertEqual( Match.get_by_id('2017ncwin_sf2m1').score_breakdown['red'] ['totalPoints'], 265) self.assertEqual( Match.get_by_id('2017ncwin_sf2m1').score_breakdown['blue'] ['totalPoints'], 150) self.assertEqual( Match.get_by_id('2017ncwin_sf2m2').alliances['red']['score'], 205) self.assertEqual( Match.get_by_id('2017ncwin_sf2m2').alliances['blue']['score'], 205) self.assertEqual( Match.get_by_id('2017ncwin_sf2m2').score_breakdown['red'] ['totalPoints'], 205) self.assertEqual( Match.get_by_id('2017ncwin_sf2m2').score_breakdown['blue'] ['totalPoints'], 205) self.assertEqual( Match.get_by_id('2017ncwin_sf2m3').alliances['red']['score'], 145) self.assertEqual( Match.get_by_id('2017ncwin_sf2m3').alliances['blue']['score'], 265) self.assertEqual( Match.get_by_id('2017ncwin_sf2m3').score_breakdown['red'] ['totalPoints'], 145) self.assertEqual( Match.get_by_id('2017ncwin_sf2m3').score_breakdown['blue'] ['totalPoints'], 265) ndb.get_context().clear_cache( ) # Prevent data from leaking between tests MatchManipulator.createOrUpdate( DatafeedFMSAPI('v2.0', sim_time=datetime.datetime( 2017, 3, 05, 21, 51)).getMatches('2017ncwin')) MatchHelper.deleteInvalidMatches(event.matches) sf_matches = Match.query(Match.event == ndb.Key(Event, '2017ncwin'), Match.comp_level == 'sf').fetch() self.assertEqual(len(sf_matches), 7) self.assertEqual( Match.get_by_id('2017ncwin_sf2m1').alliances['red']['score'], 265) self.assertEqual( Match.get_by_id('2017ncwin_sf2m1').alliances['blue']['score'], 150) self.assertEqual( Match.get_by_id('2017ncwin_sf2m1').score_breakdown['red'] ['totalPoints'], 265) self.assertEqual( Match.get_by_id('2017ncwin_sf2m1').score_breakdown['blue'] ['totalPoints'], 150) self.assertEqual( Match.get_by_id('2017ncwin_sf2m2').alliances['red']['score'], 205) self.assertEqual( Match.get_by_id('2017ncwin_sf2m2').alliances['blue']['score'], 205) self.assertEqual( Match.get_by_id('2017ncwin_sf2m2').score_breakdown['red'] ['totalPoints'], 205) self.assertEqual( Match.get_by_id('2017ncwin_sf2m2').score_breakdown['blue'] ['totalPoints'], 205) self.assertEqual( Match.get_by_id('2017ncwin_sf2m3').alliances['red']['score'], 145) self.assertEqual( Match.get_by_id('2017ncwin_sf2m3').alliances['blue']['score'], 265) self.assertEqual( Match.get_by_id('2017ncwin_sf2m3').score_breakdown['red'] ['totalPoints'], 145) self.assertEqual( Match.get_by_id('2017ncwin_sf2m3').score_breakdown['blue'] ['totalPoints'], 265) self.assertEqual( Match.get_by_id('2017ncwin_sf2m4').alliances['red']['score'], 180) self.assertEqual( Match.get_by_id('2017ncwin_sf2m4').alliances['blue']['score'], 305) self.assertEqual( Match.get_by_id('2017ncwin_sf2m4').score_breakdown['red'] ['totalPoints'], 180) self.assertEqual( Match.get_by_id('2017ncwin_sf2m4').score_breakdown['blue'] ['totalPoints'], 305)
def test_2017scmb(self): event = Event(id='2017scmb', event_short='scmb', year=2017, event_type_enum=0, timezone_id='America/New_York') event.put() MatchManipulator.createOrUpdate( DatafeedFMSAPI('v2.0', sim_time=datetime.datetime( 2017, 3, 04, 19, 17)).getMatches('2017scmb')) MatchHelper.deleteInvalidMatches(event.matches) qf_matches = Match.query(Match.event == ndb.Key(Event, '2017scmb'), Match.comp_level == 'qf').fetch() self.assertEqual(len(qf_matches), 12) self.assertEqual( Match.get_by_id('2017scmb_qf4m1').alliances['red']['score'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m1').alliances['blue']['score'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m1').score_breakdown['red'] ['totalPoints'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m1').score_breakdown['blue'] ['totalPoints'], 305) ndb.get_context().clear_cache( ) # Prevent data from leaking between tests MatchManipulator.createOrUpdate( DatafeedFMSAPI('v2.0', sim_time=datetime.datetime( 2017, 3, 04, 19, 50)).getMatches('2017scmb')) MatchHelper.deleteInvalidMatches(event.matches) qf_matches = Match.query(Match.event == ndb.Key(Event, '2017scmb'), Match.comp_level == 'qf').fetch() self.assertEqual(len(qf_matches), 12) self.assertEqual( Match.get_by_id('2017scmb_qf4m1').alliances['red']['score'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m1').alliances['blue']['score'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m1').score_breakdown['red'] ['totalPoints'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m1').score_breakdown['blue'] ['totalPoints'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m2').alliances['red']['score'], 213) self.assertEqual( Match.get_by_id('2017scmb_qf4m2').alliances['blue']['score'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m2').score_breakdown['red'] ['totalPoints'], 213) self.assertEqual( Match.get_by_id('2017scmb_qf4m2').score_breakdown['blue'] ['totalPoints'], 305) ndb.get_context().clear_cache( ) # Prevent data from leaking between tests MatchManipulator.createOrUpdate( DatafeedFMSAPI('v2.0', sim_time=datetime.datetime( 2017, 3, 04, 20, 12)).getMatches('2017scmb')) MatchHelper.deleteInvalidMatches(event.matches) qf_matches = Match.query(Match.event == ndb.Key(Event, '2017scmb'), Match.comp_level == 'qf').fetch() self.assertEqual(len(qf_matches), 12) self.assertEqual( Match.get_by_id('2017scmb_qf4m1').alliances['red']['score'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m1').alliances['blue']['score'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m1').score_breakdown['red'] ['totalPoints'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m1').score_breakdown['blue'] ['totalPoints'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m2').alliances['red']['score'], 213) self.assertEqual( Match.get_by_id('2017scmb_qf4m2').alliances['blue']['score'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m2').score_breakdown['red'] ['totalPoints'], 213) self.assertEqual( Match.get_by_id('2017scmb_qf4m2').score_breakdown['blue'] ['totalPoints'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m3').alliances['red']['score'], 312) self.assertEqual( Match.get_by_id('2017scmb_qf4m3').alliances['blue']['score'], 255) self.assertEqual( Match.get_by_id('2017scmb_qf4m3').score_breakdown['red'] ['totalPoints'], 312) self.assertEqual( Match.get_by_id('2017scmb_qf4m3').score_breakdown['blue'] ['totalPoints'], 255) ndb.get_context().clear_cache( ) # Prevent data from leaking between tests MatchManipulator.createOrUpdate( DatafeedFMSAPI('v2.0', sim_time=datetime.datetime( 2017, 3, 04, 20, 48)).getMatches('2017scmb')) MatchHelper.deleteInvalidMatches(event.matches) qf_matches = Match.query(Match.event == ndb.Key(Event, '2017scmb'), Match.comp_level == 'qf').fetch() self.assertEqual(len(qf_matches), 13) self.assertEqual( Match.get_by_id('2017scmb_qf4m1').alliances['red']['score'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m1').alliances['blue']['score'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m1').score_breakdown['red'] ['totalPoints'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m1').score_breakdown['blue'] ['totalPoints'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m2').alliances['red']['score'], 213) self.assertEqual( Match.get_by_id('2017scmb_qf4m2').alliances['blue']['score'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m2').score_breakdown['red'] ['totalPoints'], 213) self.assertEqual( Match.get_by_id('2017scmb_qf4m2').score_breakdown['blue'] ['totalPoints'], 305) self.assertEqual( Match.get_by_id('2017scmb_qf4m3').alliances['red']['score'], 312) self.assertEqual( Match.get_by_id('2017scmb_qf4m3').alliances['blue']['score'], 255) self.assertEqual( Match.get_by_id('2017scmb_qf4m3').score_breakdown['red'] ['totalPoints'], 312) self.assertEqual( Match.get_by_id('2017scmb_qf4m3').score_breakdown['blue'] ['totalPoints'], 255) self.assertEqual( Match.get_by_id('2017scmb_qf4m4').alliances['red']['score'], 310) self.assertEqual( Match.get_by_id('2017scmb_qf4m4').alliances['blue']['score'], 306) self.assertEqual( Match.get_by_id('2017scmb_qf4m4').score_breakdown['red'] ['totalPoints'], 310) self.assertEqual( Match.get_by_id('2017scmb_qf4m4').score_breakdown['blue'] ['totalPoints'], 306)
def test_2017flwp_sequence(self): event = Event(id='2017flwp', event_short='flwp', year=2017, event_type_enum=0, timezone_id='America/New_York') event.put() event_code = 'flwp' file_prefix = 'frc-api-response/v2.0/2017/schedule/{}/playoff/hybrid/'.format( event_code) context = ndb.get_context() result = context.urlfetch( 'https://www.googleapis.com/storage/v1/b/bucket/o?bucket=tbatv-prod-hrd.appspot.com&prefix={}' .format(file_prefix)).get_result() for item in json.loads(result.content)['items']: filename = item['name'] time_str = filename.replace(file_prefix, '').replace('.json', '').strip() file_time = datetime.datetime.strptime(time_str, "%Y-%m-%d %H:%M:%S.%f") query_time = file_time + datetime.timedelta(seconds=30) MatchManipulator.createOrUpdate(DatafeedFMSAPI( 'v2.0', sim_time=query_time).getMatches('2017{}'.format(event_code)), run_post_update_hook=False) MatchHelper.deleteInvalidMatches(event.matches) sf_matches = Match.query(Match.event == ndb.Key(Event, '2017flwp'), Match.comp_level == 'sf').fetch() self.assertEqual(len(sf_matches), 7) self.assertEqual( Match.get_by_id('2017flwp_sf1m1').alliances['red']['score'], 305) self.assertEqual( Match.get_by_id('2017flwp_sf1m1').alliances['blue']['score'], 255) self.assertEqual( Match.get_by_id('2017flwp_sf1m1').score_breakdown['red'] ['totalPoints'], 305) self.assertEqual( Match.get_by_id('2017flwp_sf1m1').score_breakdown['blue'] ['totalPoints'], 255) self.assertEqual( Match.get_by_id('2017flwp_sf1m2').alliances['red']['score'], 165) self.assertEqual( Match.get_by_id('2017flwp_sf1m2').alliances['blue']['score'], 258) self.assertEqual( Match.get_by_id('2017flwp_sf1m2').score_breakdown['red'] ['totalPoints'], 165) self.assertEqual( Match.get_by_id('2017flwp_sf1m2').score_breakdown['blue'] ['totalPoints'], 258) self.assertEqual( Match.get_by_id('2017flwp_sf1m3').alliances['red']['score'], 255) self.assertEqual( Match.get_by_id('2017flwp_sf1m3').alliances['blue']['score'], 255) self.assertEqual( Match.get_by_id('2017flwp_sf1m3').score_breakdown['red'] ['totalPoints'], 255) self.assertEqual( Match.get_by_id('2017flwp_sf1m3').score_breakdown['blue'] ['totalPoints'], 255) self.assertEqual( Match.get_by_id('2017flwp_sf1m4').alliances['red']['score'], 255) self.assertEqual( Match.get_by_id('2017flwp_sf1m4').alliances['blue']['score'], 255) self.assertEqual( Match.get_by_id('2017flwp_sf1m4').score_breakdown['red'] ['totalPoints'], 255) self.assertEqual( Match.get_by_id('2017flwp_sf1m4').score_breakdown['blue'] ['totalPoints'], 255) self.assertEqual( Match.get_by_id('2017flwp_sf1m5').alliances['red']['score'], 165) self.assertEqual( Match.get_by_id('2017flwp_sf1m5').alliances['blue']['score'], 263) self.assertEqual( Match.get_by_id('2017flwp_sf1m5').score_breakdown['red'] ['totalPoints'], 165) self.assertEqual( Match.get_by_id('2017flwp_sf1m5').score_breakdown['blue'] ['totalPoints'], 263)
def test_2017scmb(self): event = Event( id='2017scmb', event_short='scmb', year=2017, event_type_enum=0, timezone_id='America/New_York' ) event.put() MatchManipulator.createOrUpdate(DatafeedFMSAPI('v2.0', sim_time=datetime.datetime(2017, 3, 04, 19, 17)).getMatches('2017scmb')) MatchHelper.deleteInvalidMatches(event.matches, event) qf_matches = Match.query(Match.event == ndb.Key(Event, '2017scmb'), Match.comp_level == 'qf').fetch() self.assertEqual(len(qf_matches), 12) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').alliances['red']['score'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').alliances['blue']['score'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').score_breakdown['red']['totalPoints'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').score_breakdown['blue']['totalPoints'], 305) ndb.get_context().clear_cache() # Prevent data from leaking between tests MatchManipulator.createOrUpdate(DatafeedFMSAPI('v2.0', sim_time=datetime.datetime(2017, 3, 04, 19, 50)).getMatches('2017scmb')) MatchHelper.deleteInvalidMatches(event.matches, event) qf_matches = Match.query(Match.event == ndb.Key(Event, '2017scmb'), Match.comp_level == 'qf').fetch() self.assertEqual(len(qf_matches), 12) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').alliances['red']['score'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').alliances['blue']['score'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').score_breakdown['red']['totalPoints'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').score_breakdown['blue']['totalPoints'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m2').alliances['red']['score'], 213) self.assertEqual(Match.get_by_id('2017scmb_qf4m2').alliances['blue']['score'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m2').score_breakdown['red']['totalPoints'], 213) self.assertEqual(Match.get_by_id('2017scmb_qf4m2').score_breakdown['blue']['totalPoints'], 305) ndb.get_context().clear_cache() # Prevent data from leaking between tests MatchManipulator.createOrUpdate(DatafeedFMSAPI('v2.0', sim_time=datetime.datetime(2017, 3, 04, 20, 12)).getMatches('2017scmb')) MatchHelper.deleteInvalidMatches(event.matches, event) qf_matches = Match.query(Match.event == ndb.Key(Event, '2017scmb'), Match.comp_level == 'qf').fetch() self.assertEqual(len(qf_matches), 12) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').alliances['red']['score'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').alliances['blue']['score'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').score_breakdown['red']['totalPoints'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').score_breakdown['blue']['totalPoints'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m2').alliances['red']['score'], 213) self.assertEqual(Match.get_by_id('2017scmb_qf4m2').alliances['blue']['score'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m2').score_breakdown['red']['totalPoints'], 213) self.assertEqual(Match.get_by_id('2017scmb_qf4m2').score_breakdown['blue']['totalPoints'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m3').alliances['red']['score'], 312) self.assertEqual(Match.get_by_id('2017scmb_qf4m3').alliances['blue']['score'], 255) self.assertEqual(Match.get_by_id('2017scmb_qf4m3').score_breakdown['red']['totalPoints'], 312) self.assertEqual(Match.get_by_id('2017scmb_qf4m3').score_breakdown['blue']['totalPoints'], 255) ndb.get_context().clear_cache() # Prevent data from leaking between tests MatchManipulator.createOrUpdate(DatafeedFMSAPI('v2.0', sim_time=datetime.datetime(2017, 3, 04, 20, 48)).getMatches('2017scmb')) MatchHelper.deleteInvalidMatches(event.matches, event) qf_matches = Match.query(Match.event == ndb.Key(Event, '2017scmb'), Match.comp_level == 'qf').fetch() self.assertEqual(len(qf_matches), 13) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').alliances['red']['score'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').alliances['blue']['score'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').score_breakdown['red']['totalPoints'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m1').score_breakdown['blue']['totalPoints'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m2').alliances['red']['score'], 213) self.assertEqual(Match.get_by_id('2017scmb_qf4m2').alliances['blue']['score'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m2').score_breakdown['red']['totalPoints'], 213) self.assertEqual(Match.get_by_id('2017scmb_qf4m2').score_breakdown['blue']['totalPoints'], 305) self.assertEqual(Match.get_by_id('2017scmb_qf4m3').alliances['red']['score'], 312) self.assertEqual(Match.get_by_id('2017scmb_qf4m3').alliances['blue']['score'], 255) self.assertEqual(Match.get_by_id('2017scmb_qf4m3').score_breakdown['red']['totalPoints'], 312) self.assertEqual(Match.get_by_id('2017scmb_qf4m3').score_breakdown['blue']['totalPoints'], 255) self.assertEqual(Match.get_by_id('2017scmb_qf4m4').alliances['red']['score'], 310) self.assertEqual(Match.get_by_id('2017scmb_qf4m4').alliances['blue']['score'], 306) self.assertEqual(Match.get_by_id('2017scmb_qf4m4').score_breakdown['red']['totalPoints'], 310) self.assertEqual(Match.get_by_id('2017scmb_qf4m4').score_breakdown['blue']['totalPoints'], 306)
def _render(self, event_key): event = Event.get_by_id(event_key) if not event or event.year < 2016 or not event.details or not event.details.predictions: self.abort(404) event.get_matches_async() match_predictions = event.details.predictions.get('match_predictions', None) match_prediction_stats = event.details.predictions.get('match_prediction_stats', None) ranking_predictions = event.details.predictions.get('ranking_predictions', None) ranking_prediction_stats = event.details.predictions.get('ranking_prediction_stats', None) cleaned_matches = MatchHelper.deleteInvalidMatches(event.matches, event) matches = MatchHelper.organizeMatches(cleaned_matches) # If no matches but there are match predictions, create fake matches # For cases where FIRST doesn't allow posting of match schedule fake_matches = False if match_predictions and (not matches['qm'] and match_predictions['qual']): fake_matches = True for i in xrange(len(match_predictions['qual'].keys())): match_number = i + 1 alliances = { 'red': { 'score': -1, 'teams': ['frc?', 'frc?', 'frc?'] }, 'blue': { 'score': -1, 'teams': ['frc?', 'frc?', 'frc?'] } } matches['qm'].append(Match( id=Match.renderKeyName( event_key, 'qm', 1, match_number), event=event.key, year=event.year, set_number=1, match_number=match_number, comp_level='qm', alliances_json=json.dumps(alliances), )) # Add actual scores to predictions distribution_info = {} for comp_level in Match.COMP_LEVELS: level = 'qual' if comp_level == 'qm' else 'playoff' for match in matches[comp_level]: distribution_info[match.key.id()] = { 'level': level, 'red_actual_score': match.alliances['red']['score'], 'blue_actual_score': match.alliances['blue']['score'], 'red_mean': match_predictions[level][match.key.id()]['red']['score'], 'blue_mean': match_predictions[level][match.key.id()]['blue']['score'], 'red_var': match_predictions[level][match.key.id()]['red']['score_var'], 'blue_var': match_predictions[level][match.key.id()]['blue']['score_var'], } last_played_match_num = None if ranking_prediction_stats: last_played_match_key = ranking_prediction_stats.get('last_played_match', None) if last_played_match_key: last_played_match_num = last_played_match_key.split('_qm')[1] self.template_values.update({ "event": event, "matches": matches, "fake_matches": fake_matches, "match_predictions": match_predictions, "distribution_info_json": json.dumps(distribution_info), "match_prediction_stats": match_prediction_stats, "ranking_predictions": ranking_predictions, "ranking_prediction_stats": ranking_prediction_stats, "last_played_match_num": last_played_match_num, }) if event.within_a_day: self._cache_expiration = self.SHORT_CACHE_EXPIRATION return jinja2_engine.render('event_insights.html', self.template_values)
def _render(self, event_key): event = Event.get_by_id(event_key) if not event: self.abort(404) event.prepAwardsMatchesTeams() medias_future = media_query.EventTeamsPreferredMediasQuery(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 = EventInsightsHelper.calculate_event_insights(cleaned_matches, event.year) event_insights_template = None if event_insights: event_insights_template = 'event_partials/event_insights_{}.html'.format(event.year) # rankings processing for ranking score per match full_rankings = event.rankings rankings_enhanced = event.rankings_enhanced if rankings_enhanced is not None: rp_index = RankingIndexes.CUMULATIVE_RANKING_SCORE[event.year] matches_index = RankingIndexes.MATCHES_PLAYED[event.year] ranking_criterion_name = full_rankings[0][rp_index] full_rankings[0].append(ranking_criterion_name + "/Match*") for row in full_rankings[1:]: team = row[1] if rankings_enhanced["ranking_score_per_match"] is not None: rp_per_match = rankings_enhanced['ranking_score_per_match'][team] row.append(rp_per_match) if rankings_enhanced["match_offset"] is not None: match_offset = rankings_enhanced["match_offset"][team] if match_offset != 0: row[matches_index] = "{} ({})".format(row[matches_index], match_offset) self.template_values.update({ "event": event, "district_name": DistrictType.type_names.get(event.event_district_enum, None), "district_abbrev": DistrictType.type_abbrevs.get(event.event_district_enum, 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, }) if event.within_a_day: self._cache_expiration = self.SHORT_CACHE_EXPIRATION return jinja2_engine.render('event_details.html', self.template_values)
def test_2017ncwin(self): event = Event( id='2017ncwin', event_short='ncwin', year=2017, event_type_enum=0, timezone_id='America/New_York' ) event.put() MatchManipulator.createOrUpdate(DatafeedFMSAPI('v2.0', sim_time=datetime.datetime(2017, 3, 05, 21, 2)).getMatches('2017ncwin')) MatchHelper.deleteInvalidMatches(event.matches, event) sf_matches = Match.query(Match.event == ndb.Key(Event, '2017ncwin'), Match.comp_level == 'sf').fetch() self.assertEqual(len(sf_matches), 6) self.assertEqual(Match.get_by_id('2017ncwin_sf2m1').alliances['red']['score'], 265) self.assertEqual(Match.get_by_id('2017ncwin_sf2m1').alliances['blue']['score'], 150) self.assertEqual(Match.get_by_id('2017ncwin_sf2m1').score_breakdown['red']['totalPoints'], 265) self.assertEqual(Match.get_by_id('2017ncwin_sf2m1').score_breakdown['blue']['totalPoints'], 150) ndb.get_context().clear_cache() # Prevent data from leaking between tests MatchManipulator.createOrUpdate(DatafeedFMSAPI('v2.0', sim_time=datetime.datetime(2017, 3, 05, 21, 30)).getMatches('2017ncwin')) MatchHelper.deleteInvalidMatches(event.matches, event) sf_matches = Match.query(Match.event == ndb.Key(Event, '2017ncwin'), Match.comp_level == 'sf').fetch() self.assertEqual(len(sf_matches), 6) self.assertEqual(Match.get_by_id('2017ncwin_sf2m1').alliances['red']['score'], 265) self.assertEqual(Match.get_by_id('2017ncwin_sf2m1').alliances['blue']['score'], 150) self.assertEqual(Match.get_by_id('2017ncwin_sf2m1').score_breakdown['red']['totalPoints'], 265) self.assertEqual(Match.get_by_id('2017ncwin_sf2m1').score_breakdown['blue']['totalPoints'], 150) self.assertEqual(Match.get_by_id('2017ncwin_sf2m2').alliances['red']['score'], 205) self.assertEqual(Match.get_by_id('2017ncwin_sf2m2').alliances['blue']['score'], 205) self.assertEqual(Match.get_by_id('2017ncwin_sf2m2').score_breakdown['red']['totalPoints'], 205) self.assertEqual(Match.get_by_id('2017ncwin_sf2m2').score_breakdown['blue']['totalPoints'], 205) ndb.get_context().clear_cache() # Prevent data from leaking between tests MatchManipulator.createOrUpdate(DatafeedFMSAPI('v2.0', sim_time=datetime.datetime(2017, 3, 05, 21, 35)).getMatches('2017ncwin')) MatchHelper.deleteInvalidMatches(event.matches, event) sf_matches = Match.query(Match.event == ndb.Key(Event, '2017ncwin'), Match.comp_level == 'sf').fetch() self.assertEqual(len(sf_matches), 6) self.assertEqual(Match.get_by_id('2017ncwin_sf2m1').alliances['red']['score'], 265) self.assertEqual(Match.get_by_id('2017ncwin_sf2m1').alliances['blue']['score'], 150) self.assertEqual(Match.get_by_id('2017ncwin_sf2m1').score_breakdown['red']['totalPoints'], 265) self.assertEqual(Match.get_by_id('2017ncwin_sf2m1').score_breakdown['blue']['totalPoints'], 150) self.assertEqual(Match.get_by_id('2017ncwin_sf2m2').alliances['red']['score'], 205) self.assertEqual(Match.get_by_id('2017ncwin_sf2m2').alliances['blue']['score'], 205) self.assertEqual(Match.get_by_id('2017ncwin_sf2m2').score_breakdown['red']['totalPoints'], 205) self.assertEqual(Match.get_by_id('2017ncwin_sf2m2').score_breakdown['blue']['totalPoints'], 205) self.assertEqual(Match.get_by_id('2017ncwin_sf2m3').alliances['red']['score'], 145) self.assertEqual(Match.get_by_id('2017ncwin_sf2m3').alliances['blue']['score'], 265) self.assertEqual(Match.get_by_id('2017ncwin_sf2m3').score_breakdown['red']['totalPoints'], 145) self.assertEqual(Match.get_by_id('2017ncwin_sf2m3').score_breakdown['blue']['totalPoints'], 265) ndb.get_context().clear_cache() # Prevent data from leaking between tests MatchManipulator.createOrUpdate(DatafeedFMSAPI('v2.0', sim_time=datetime.datetime(2017, 3, 05, 21, 51)).getMatches('2017ncwin')) MatchHelper.deleteInvalidMatches(event.matches, event) sf_matches = Match.query(Match.event == ndb.Key(Event, '2017ncwin'), Match.comp_level == 'sf').fetch() self.assertEqual(len(sf_matches), 7) self.assertEqual(Match.get_by_id('2017ncwin_sf2m1').alliances['red']['score'], 265) self.assertEqual(Match.get_by_id('2017ncwin_sf2m1').alliances['blue']['score'], 150) self.assertEqual(Match.get_by_id('2017ncwin_sf2m1').score_breakdown['red']['totalPoints'], 265) self.assertEqual(Match.get_by_id('2017ncwin_sf2m1').score_breakdown['blue']['totalPoints'], 150) self.assertEqual(Match.get_by_id('2017ncwin_sf2m2').alliances['red']['score'], 205) self.assertEqual(Match.get_by_id('2017ncwin_sf2m2').alliances['blue']['score'], 205) self.assertEqual(Match.get_by_id('2017ncwin_sf2m2').score_breakdown['red']['totalPoints'], 205) self.assertEqual(Match.get_by_id('2017ncwin_sf2m2').score_breakdown['blue']['totalPoints'], 205) self.assertEqual(Match.get_by_id('2017ncwin_sf2m3').alliances['red']['score'], 145) self.assertEqual(Match.get_by_id('2017ncwin_sf2m3').alliances['blue']['score'], 265) self.assertEqual(Match.get_by_id('2017ncwin_sf2m3').score_breakdown['red']['totalPoints'], 145) self.assertEqual(Match.get_by_id('2017ncwin_sf2m3').score_breakdown['blue']['totalPoints'], 265) self.assertEqual(Match.get_by_id('2017ncwin_sf2m4').alliances['red']['score'], 180) self.assertEqual(Match.get_by_id('2017ncwin_sf2m4').alliances['blue']['score'], 305) self.assertEqual(Match.get_by_id('2017ncwin_sf2m4').score_breakdown['red']['totalPoints'], 180) self.assertEqual(Match.get_by_id('2017ncwin_sf2m4').score_breakdown['blue']['totalPoints'], 305)
def _render(self, event_key): event = Event.get_by_id(event_key) if not event: self.abort(404) event.prepAwardsMatchesTeams() awards = AwardHelper.organizeAwards(event.awards) cleaned_matches = MatchHelper.deleteInvalidMatches(event.matches) matches = MatchHelper.organizeMatches(cleaned_matches) teams = TeamHelper.sortTeams(event.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:] 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']) self.template_values.update({ "event": event, "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, }) if event.within_a_day: self._cache_expiration = self.SHORT_CACHE_EXPIRATION path = os.path.join(os.path.dirname(__file__), '../templates/event_details.html') return template.render(path, 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() 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() 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 step(self): event = Event.get_by_id('2016nytr') if self._step == 0: # Qual match schedule added for match in copy.deepcopy(self._all_matches['qm']): for alliance in ['red', 'blue']: match.alliances[alliance]['score'] = -1 match.alliances_json = json.dumps(match.alliances) match.score_breakdown_json = None match.actual_time = None MatchManipulator.createOrUpdate(match) self._step += 1 elif self._step == 1: # After each qual match MatchManipulator.createOrUpdate(self._played_matches['qm'][self._substep]) if self._substep < len(self._played_matches['qm']) - 1: self._substep += 1 else: self._step += 1 self._substep = 0 EventDetailsManipulator.createOrUpdate(EventDetails(id='2016nytr')) elif self._step == 2: # After alliance selections EventDetailsManipulator.createOrUpdate(EventDetails( id='2016nytr', alliance_selections=self._alliance_selections_without_backup )) self._step += 1 elif self._step == 3: # QF schedule added for match in copy.deepcopy(self._all_matches['qf']): for alliance in ['red', 'blue']: match.alliances[alliance]['score'] = -1 match.alliances_json = json.dumps(match.alliances) match.score_breakdown_json = None match.actual_time = None MatchManipulator.createOrUpdate(match) self._step += 1 elif self._step == 4: # After each QF match new_match = MatchHelper.play_order_sort_matches(self._played_matches['qf'])[self._substep] MatchManipulator.createOrUpdate(new_match) if not self._batch_advance: win_counts = { 'red': 0, 'blue': 0, } for i in xrange(new_match.match_number): win_counts[Match.get_by_id( Match.renderKeyName( new_match.event.id(), new_match.comp_level, new_match.set_number, i+1)).winning_alliance] += 1 for alliance, wins in win_counts.items(): if wins == 2: s = new_match.set_number if s in {1, 2}: self._advancement_alliances['sf1']['red' if s == 1 else 'blue'] = new_match.alliances[alliance]['teams'] elif s in {3, 4}: self._advancement_alliances['sf2']['red' if s == 3 else 'blue'] = new_match.alliances[alliance]['teams'] else: raise Exception("Invalid set number: {}".format(s)) for match_set, alliances in self._advancement_alliances.items(): if match_set.startswith('sf'): for i in xrange(3): for match in copy.deepcopy(self._all_matches['sf']): key = '2016nytr_{}m{}'.format(match_set, i+1) if match.key.id() == key: for color in ['red', 'blue']: match.alliances[color]['score'] = -1 match.alliances[color]['teams'] = alliances.get(color, []) match.alliances_json = json.dumps(match.alliances) match.score_breakdown_json = None match.actual_time = None MatchManipulator.createOrUpdate(match) if self._substep < len(self._played_matches['qf']) - 1: self._substep += 1 else: self._step += 1 if self._batch_advance else 2 self._substep = 0 elif self._step == 5: # SF schedule added if self._batch_advance: for match in copy.deepcopy(self._all_matches['sf']): for alliance in ['red', 'blue']: match.alliances[alliance]['score'] = -1 match.alliances_json = json.dumps(match.alliances) match.score_breakdown_json = None match.actual_time = None MatchManipulator.createOrUpdate(match) self._step += 1 elif self._step == 6: # After each SF match new_match = MatchHelper.play_order_sort_matches(self._played_matches['sf'])[self._substep] MatchManipulator.createOrUpdate(new_match) if not self._batch_advance: win_counts = { 'red': 0, 'blue': 0, } for i in xrange(new_match.match_number): win_counts[Match.get_by_id( Match.renderKeyName( new_match.event.id(), new_match.comp_level, new_match.set_number, i+1)).winning_alliance] += 1 for alliance, wins in win_counts.items(): if wins == 2: self._advancement_alliances['f1']['red' if new_match.set_number == 1 else 'blue'] = new_match.alliances[alliance]['teams'] for match_set, alliances in self._advancement_alliances.items(): if match_set.startswith('f'): for i in xrange(3): for match in copy.deepcopy(self._all_matches['f']): key = '2016nytr_{}m{}'.format(match_set, i+1) if match.key.id() == key: for color in ['red', 'blue']: match.alliances[color]['score'] = -1 match.alliances[color]['teams'] = alliances.get(color, []) match.alliances_json = json.dumps(match.alliances) match.score_breakdown_json = None match.actual_time = None MatchManipulator.createOrUpdate(match) # Backup robot introduced if self._substep == 3: EventDetailsManipulator.createOrUpdate(EventDetails( id='2016nytr', alliance_selections=self._event_details.alliance_selections )) if self._substep < len(self._played_matches['sf']) - 1: self._substep += 1 else: self._step += 1 if self._batch_advance else 2 self._substep = 0 elif self._step == 7: # F schedule added if self._batch_advance: for match in copy.deepcopy(self._all_matches['f']): for alliance in ['red', 'blue']: match.alliances[alliance]['score'] = -1 match.alliances_json = json.dumps(match.alliances) match.score_breakdown_json = None match.actual_time = None MatchManipulator.createOrUpdate(match) self._step += 1 elif self._step == 8: # After each F match MatchManipulator.createOrUpdate( MatchHelper.play_order_sort_matches( self._played_matches['f'])[self._substep]) if self._substep < len(self._played_matches['f']) - 1: self._substep += 1 else: self._step += 1 self._substep = 0 ndb.get_context().clear_cache() # Re fetch event matches event = Event.get_by_id('2016nytr') MatchHelper.deleteInvalidMatches(event.matches, event) ndb.get_context().clear_cache() self._update_rankings()
def _render(self, event_key): event = Event.get_by_id(event_key) if not event or event.year != 2016: self.abort(404) event.get_matches_async() match_predictions = event.details.predictions.get('match_predictions', None) match_prediction_stats = event.details.predictions.get('match_prediction_stats', None) ranking_predictions = event.details.predictions.get('ranking_predictions', None) ranking_prediction_stats = event.details.predictions.get('ranking_prediction_stats', None) cleaned_matches = MatchHelper.deleteInvalidMatches(event.matches) matches = MatchHelper.organizeMatches(cleaned_matches) # If no matches but there are match predictions, create fake matches # For cases where FIRST doesn't allow posting of match schedule fake_matches = False if not matches['qm'] and match_predictions: fake_matches = True for i in xrange(len(match_predictions.keys())): match_number = i + 1 alliances = { 'red': { 'score': -1, 'teams': ['frc?', 'frc?', 'frc?'] }, 'blue': { 'score': -1, 'teams': ['frc?', 'frc?', 'frc?'] } } matches['qm'].append(Match( id=Match.renderKeyName( event_key, 'qm', 1, match_number), event=event.key, year=event.year, set_number=1, match_number=match_number, comp_level='qm', alliances_json=json.dumps(alliances), )) last_played_match_num = None if ranking_prediction_stats: last_played_match_key = ranking_prediction_stats.get('last_played_match', None) if last_played_match_key: last_played_match_num = last_played_match_key.split('_qm')[1] self.template_values.update({ "event": event, "matches": matches, "fake_matches": fake_matches, "match_predictions": match_predictions, "match_prediction_stats": match_prediction_stats, "ranking_predictions": ranking_predictions, "ranking_prediction_stats": ranking_prediction_stats, "last_played_match_num": last_played_match_num, }) if event.within_a_day: self._cache_expiration = self.SHORT_CACHE_EXPIRATION return jinja2_engine.render('event_insights.html', self.template_values)
def _render(self, event_key): event = Event.get_by_id(event_key) if not event: self.abort(404) event.prepAwardsMatchesTeams() medias_future = media_query.EventTeamsPreferredMediasQuery( 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 = EventInsightsHelper.calculate_event_insights( cleaned_matches, event.year) event_insights_template = None if event_insights: event_insights_template = 'event_partials/event_insights_{}.html'.format( event.year) self.template_values.update({ "event": event, "district_name": DistrictType.type_names.get(event.event_district_enum, None), "district_abbrev": DistrictType.type_abbrevs.get(event.event_district_enum, 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, }) 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 = Event.get_by_id(event_key) if not event: self.abort(404) event.prepAwardsMatchesTeams() awards = AwardHelper.organizeAwards(event.awards) cleaned_matches = MatchHelper.deleteInvalidMatches(event.matches) matches = MatchHelper.organizeMatches(cleaned_matches) teams = TeamHelper.sortTeams(event.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:] 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 = EventInsightsHelper.calculate_event_insights( cleaned_matches, event.year) self.template_values.update({ "event": event, "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": event_insights }) if event.within_a_day: self._cache_expiration = self.SHORT_CACHE_EXPIRATION return jinja2_engine.render('event_details.html', self.template_values)