def _render(self, team_number): self.response.headers['content-type'] = 'text/plain; charset="utf-8"' user = self.request.get('user') if user: user_str = '@{}, '.format(user) else: user_str = '' team_event_or_error = validate_team(user_str, team_number) if type(team_event_or_error) == str: return team_event_or_error _, event = team_event_or_error event_code_upper = event.event_short.upper() matches_future = TeamEventMatchesQuery('frc{}'.format(team_number), event.key.id()).fetch_async() matches = MatchHelper.play_order_sort_matches(matches_future.get_result()) # No match schedule yet if not matches: return "{}[{}] Team {} has no scheduled matches yet.".format(user_str, event_code_upper, team_number) next_match = None for match in matches: if not match.has_been_played: next_match = match break if next_match is None: return "{}[{}] Team {} has no more scheduled matches.".format(user_str, event_code_upper, team_number) return "{}[{}] Team {} will be playing in match {}.".format(user_str, event_code_upper, team_number, match.short_name)
def _render(self, team_number, tz_str=None): import pytz from pytz.exceptions import UnknownTimeZoneError user = self.request.get('user') if user: user_str = '@{}, '.format(user) else: user_str = '' try: arg_tz = pytz.timezone(tz_str) if tz_str else None except UnknownTimeZoneError: arg_tz = None team_event_or_error = validate_team(user_str, team_number) if type(team_event_or_error) == str: return team_event_or_error _, event = team_event_or_error event_code_upper = event.event_short.upper() matches_future = TeamEventMatchesQuery('frc{}'.format(team_number), event.key.id()).fetch_async() matches = MatchHelper.play_order_sort_matches( matches_future.get_result()) # No match schedule yet if not matches: return "{}[{}] Team {} has no scheduled matches yet.".format( user_str, event_code_upper, team_number) next_match = None for match in matches: if not match.has_been_played: next_match = match break if next_match is None: return "{}[{}] Team {} has no more scheduled matches.".format( user_str, event_code_upper, team_number) predicted_str = "predicted" if next_match.predicted_time else "scheduled" match_time = next_match.predicted_time if next_match.predicted_time else next_match.time timezone = arg_tz if arg_tz else pytz.timezone(event.timezone_id) predicted_time_local = pytz.utc.localize(match_time).astimezone( timezone) if timezone else match_time time_string = ", {} to start at {}".format( predicted_str, predicted_time_local.strftime("%a %H:%M %Z")) if match_time else "" return "{}[{}] Team {} will be playing in match {}{}".format( user_str, event_code_upper, team_number, next_match.short_name, time_string)
def get(self, event_key): event = Event.get_by_id(event_key) matchstats_dict = MatchstatsHelper.calculate_matchstats( event.matches, event.year) if any([v != {} for v in matchstats_dict.values()]): pass else: logging.warn( "Matchstat calculation for {} failed!".format(event_key)) matchstats_dict = None predictions_dict = None if event.year in { 2016, 2017, 2018, 2019, 2020 } and event.event_type_enum in EventType.SEASON_EVENT_TYPES or event.enable_predictions: sorted_matches = MatchHelper.play_order_sort_matches(event.matches) match_predictions, match_prediction_stats, stat_mean_vars = PredictionHelper.get_match_predictions( sorted_matches) ranking_predictions, ranking_prediction_stats = PredictionHelper.get_ranking_predictions( sorted_matches, match_predictions) predictions_dict = { 'match_predictions': match_predictions, 'match_prediction_stats': match_prediction_stats, 'stat_mean_vars': stat_mean_vars, 'ranking_predictions': ranking_predictions, 'ranking_prediction_stats': ranking_prediction_stats } event_insights = EventInsightsHelper.calculate_event_insights( event.matches, event.year) event_details = EventDetails( id=event_key, matchstats=matchstats_dict, predictions=predictions_dict, insights=event_insights, ) EventDetailsManipulator.createOrUpdate(event_details) template_values = { 'matchstats_dict': matchstats_dict, } 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/math/event_matchstats_do.html') self.response.out.write(template.render(path, template_values))
def _render(self, team_number, tz_str=None): import pytz from pytz.exceptions import UnknownTimeZoneError user = self.request.get('user') if user: user_str = '@{}, '.format(user) else: user_str = '' try: arg_tz = pytz.timezone(tz_str) if tz_str else None except UnknownTimeZoneError: arg_tz = None team_event_or_error = validate_team(user_str, team_number) if type(team_event_or_error) == str: return team_event_or_error _, event = team_event_or_error event_code_upper = event.event_short.upper() matches_future = TeamEventMatchesQuery('frc{}'.format(team_number), event.key.id()).fetch_async() matches = MatchHelper.play_order_sort_matches(matches_future.get_result()) # No match schedule yet if not matches: return "{}[{}] Team {} has no scheduled matches yet.".format(user_str, event_code_upper, team_number) next_match = None for match in matches: if not match.has_been_played: next_match = match break if next_match is None: return "{}[{}] Team {} has no more scheduled matches.".format(user_str, event_code_upper, team_number) predicted_str = "predicted" if next_match.predicted_time else "scheduled" match_time = next_match.predicted_time if next_match.predicted_time else next_match.time timezone = arg_tz if arg_tz else pytz.timezone(event.timezone_id) predicted_time_local = pytz.utc.localize(match_time).astimezone(timezone) if timezone else match_time time_string = ", {} to start at {}".format(predicted_str, predicted_time_local.strftime("%a %H:%M %Z")) if match_time else "" return "{}[{}] Team {} will be playing in match {}{}".format(user_str, event_code_upper, team_number, next_match.short_name, time_string)
def get(self, event_key): event = Event.get_by_id(event_key) matchstats_dict = MatchstatsHelper.calculate_matchstats(event.matches, event.year) if any([v != {} for v in matchstats_dict.values()]): pass else: logging.warn("Matchstat calculation for {} failed!".format(event_key)) matchstats_dict = None predictions_dict = None if event.year in {2016, 2017, 2018} and event.event_type_enum in EventType.SEASON_EVENT_TYPES or event.enable_predictions: sorted_matches = MatchHelper.play_order_sort_matches(event.matches) match_predictions, match_prediction_stats, stat_mean_vars = PredictionHelper.get_match_predictions(sorted_matches) ranking_predictions, ranking_prediction_stats = PredictionHelper.get_ranking_predictions(sorted_matches, match_predictions) predictions_dict = { 'match_predictions': match_predictions, 'match_prediction_stats': match_prediction_stats, 'stat_mean_vars': stat_mean_vars, 'ranking_predictions': ranking_predictions, 'ranking_prediction_stats': ranking_prediction_stats } event_insights = EventInsightsHelper.calculate_event_insights(event.matches, event.year) event_details = EventDetails( id=event_key, matchstats=matchstats_dict, predictions=predictions_dict, insights=event_insights, ) EventDetailsManipulator.createOrUpdate(event_details) template_values = { 'matchstats_dict': matchstats_dict, } 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/math/event_matchstats_do.html') self.response.out.write(template.render(path, template_values))
def test_event_smulator_batch_advance(self): es = EventSimulator(batch_advance=True) # Before anything has happened event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertEqual(event.details, None) self.assertEqual(event.matches, []) # Qual match schedule added es.step() event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertNotEqual(event.details, None) for rank in event.details.rankings2: self.assertEqual(rank['sort_orders'][0], 0) self.assertEqual(len(event.matches), 72) for match in event.matches: self.assertEqual(match.comp_level, 'qm') self.assertFalse(match.has_been_played) self.assertEqual(match.actual_time, None) # After each qual match for i in xrange(72): es.step() event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertEqual(event.details.alliance_selections, None) self.assertEqual(len(event.matches), 72) matches = MatchHelper.play_order_sort_matches(event.matches) for j, match in enumerate(matches): if j <= i: self.assertTrue(match.has_been_played) self.assertNotEqual(match.actual_time, None) else: self.assertFalse(match.has_been_played) # Check some final rankings self.assertEqual(event.details.rankings2[0]['sort_orders'][0], 22) self.assertEqual(event.details.rankings2[-1]['sort_orders'][0], 4) # After alliance selections es.step() event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertEqual(event.details.alliance_selections, self._alliance_selections) self.assertEqual(len(event.matches), 72) # QF schedule added es.step() event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertEqual(event.details.alliance_selections, self._alliance_selections) self.assertEqual(len(event.matches), 84) for match in event.matches: if match.comp_level == 'qm': self.assertTrue(match.has_been_played) self.assertNotEqual(match.actual_time, None) else: self.assertEqual(match.comp_level, 'qf') self.assertFalse(match.has_been_played) self.assertEqual(match.actual_time, None) # After each QF match for i in xrange(72, 82): es.step() event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertEqual(event.details.alliance_selections, self._alliance_selections) if i <= 75: self.assertEqual(len(event.matches), 84) elif i <= 77: self.assertEqual(len(event.matches), 83) else: self.assertEqual(len(event.matches), 82) matches = MatchHelper.play_order_sort_matches(event.matches) for j, match in enumerate(matches): if match.key.id() in {'2016nytr_qf1m3', '2016nytr_qf3m3'}: # Unneeded tiebreak matches self.assertFalse(match.has_been_played) elif j <= i: self.assertTrue(match.has_been_played) self.assertNotEqual(match.actual_time, None) else: self.assertFalse(match.has_been_played) # SF schedule added es.step() event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertEqual(event.details.alliance_selections, self._alliance_selections) self.assertEqual(len(event.matches), 88) for match in event.matches: if match.comp_level in {'qm', 'qf'}: self.assertTrue(match.has_been_played) self.assertNotEqual(match.actual_time, None) else: self.assertEqual(match.comp_level, 'sf') self.assertFalse(match.has_been_played) self.assertEqual(match.actual_time, None) # After each SF match for i in xrange(82, 87): es.step() event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) if i < 85: self.assertEqual(event.details.alliance_selections, self._alliance_selections) else: self.assertEqual(event.details.alliance_selections, self._alliance_selections_with_backup) if i <= 83: self.assertEqual(len(event.matches), 88) else: self.assertEqual(len(event.matches), 87) matches = MatchHelper.play_order_sort_matches(event.matches) for j, match in enumerate(matches): if match.key.id() == '2016nytr_sf1m3': # Unneeded tiebreak matches self.assertFalse(match.has_been_played) elif j <= i: self.assertTrue(match.has_been_played) self.assertNotEqual(match.actual_time, None) else: self.assertFalse(match.has_been_played) # F schedule added es.step() event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertEqual(event.details.alliance_selections, self._alliance_selections_with_backup) self.assertEqual(len(event.matches), 90) for match in event.matches: if match.comp_level in {'qm', 'qf', 'sf'}: self.assertTrue(match.has_been_played) self.assertNotEqual(match.actual_time, None) else: self.assertEqual(match.comp_level, 'f') self.assertFalse(match.has_been_played) self.assertEqual(match.actual_time, None) # After each F match for i in xrange(87, 90): es.step() event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertEqual(event.details.alliance_selections, self._alliance_selections_with_backup) self.assertEqual(len(event.matches), 90) matches = MatchHelper.play_order_sort_matches(event.matches) for j, match in enumerate(matches): if j <= i: self.assertTrue(match.has_been_played) self.assertNotEqual(match.actual_time, None) else: self.assertFalse(match.has_been_played)
def test_event_smulator(self): es = EventSimulator() # Before anything has happened event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertEqual(event.details, None) self.assertEqual(event.matches, []) # Qual match schedule added es.step() event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertNotEqual(event.details, None) for rank in event.details.rankings2: self.assertEqual(rank['sort_orders'][0], 0) self.assertEqual(len(event.matches), 72) for match in event.matches: self.assertEqual(match.comp_level, 'qm') self.assertFalse(match.has_been_played) self.assertEqual(match.actual_time, None) # After each qual match for i in xrange(72): es.step() event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertEqual(event.details.alliance_selections, None) self.assertEqual(len(event.matches), 72) matches = MatchHelper.play_order_sort_matches(event.matches) for j, match in enumerate(matches): if j <= i: self.assertTrue(match.has_been_played) self.assertNotEqual(match.actual_time, None) else: self.assertFalse(match.has_been_played) # Check some final rankings self.assertEqual(event.details.rankings2[0]['sort_orders'][0], 22) self.assertEqual(event.details.rankings2[-1]['sort_orders'][0], 4) # After alliance selections es.step() event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertEqual(event.details.alliance_selections, self._alliance_selections) self.assertEqual(len(event.matches), 72) # QF schedule added es.step() event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertEqual(event.details.alliance_selections, self._alliance_selections) self.assertEqual(len(event.matches), 84) for match in event.matches: if match.comp_level == 'qm': self.assertTrue(match.has_been_played) self.assertNotEqual(match.actual_time, None) else: self.assertEqual(match.comp_level, 'qf') self.assertFalse(match.has_been_played) self.assertEqual(match.actual_time, None) # After each QF match for i in xrange(72, 82): es.step() event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertEqual(event.details.alliance_selections, self._alliance_selections) if i <= 75: self.assertEqual(len(event.matches), 84) elif i <= 77: self.assertEqual(len(event.matches), 86) # 1 match removed, 3 added else: self.assertEqual(len(event.matches), 88) # 1 match removed, 3 added matches = MatchHelper.play_order_sort_matches(event.matches) for j, match in enumerate(matches): if match.key.id() in {'2016nytr_qf1m3', '2016nytr_qf3m3'}: # Unneeded tiebreak matches self.assertFalse(match.has_been_played) elif j <= i: self.assertTrue(match.has_been_played) self.assertNotEqual(match.actual_time, None) else: self.assertFalse(match.has_been_played) # Check SF Matches event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertEqual(event.details.alliance_selections, self._alliance_selections) self.assertEqual(len(event.matches), 88) for match in event.matches: if match.comp_level in {'qm', 'qf'}: self.assertTrue(match.has_been_played) self.assertNotEqual(match.actual_time, None) else: self.assertEqual(match.comp_level, 'sf') self.assertFalse(match.has_been_played) self.assertEqual(match.actual_time, None) # After each SF match for i in xrange(82, 87): es.step() event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) if i < 85: self.assertEqual(event.details.alliance_selections, self._alliance_selections) else: self.assertEqual(event.details.alliance_selections, self._alliance_selections_with_backup) if i <= 83: self.assertEqual(len(event.matches), 88) else: self.assertEqual(len(event.matches), 90) # 1 match removed, 3 added matches = MatchHelper.play_order_sort_matches(event.matches) for j, match in enumerate(matches): if match.key.id() == '2016nytr_sf1m3': # Unneeded tiebreak matches self.assertFalse(match.has_been_played) elif j <= i: self.assertTrue(match.has_been_played) self.assertNotEqual(match.actual_time, None) else: self.assertFalse(match.has_been_played) # Check F Matches event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertEqual(event.details.alliance_selections, self._alliance_selections_with_backup) self.assertEqual(len(event.matches), 90) for match in event.matches: if match.comp_level in {'qm', 'qf', 'sf'}: self.assertTrue(match.has_been_played) self.assertNotEqual(match.actual_time, None) else: self.assertEqual(match.comp_level, 'f') self.assertFalse(match.has_been_played) self.assertEqual(match.actual_time, None) # After each F match for i in xrange(87, 90): es.step() event = Event.get_by_id('2016nytr') self.assertNotEqual(event, None) self.assertEqual(event.details.alliance_selections, self._alliance_selections_with_backup) self.assertEqual(len(event.matches), 90) matches = MatchHelper.play_order_sort_matches(event.matches) for j, match in enumerate(matches): if j <= i: self.assertTrue(match.has_been_played) self.assertNotEqual(match.actual_time, None) else: self.assertFalse(match.has_been_played)
def _getteam_nextmatch(cls, request): team_number = request['result']['parameters']['team_number'] team_key = 'frc{}'.format(team_number) team = Team.get_by_id(team_key) if team: events = TeamYearEventsQuery(team_key, datetime.datetime.now().year).fetch() EventHelper.sort_events(events) # Find first current or future event for event in events: if event.now: matches = TeamEventMatchesQuery(team_key, event.key.id()).fetch() matches = MatchHelper.play_order_sort_matches(matches) if matches: next_match = None for match in matches: if not match.has_been_played: next_match = match break if next_match is not None: if match.predicted_time: eta = match.predicted_time - datetime.datetime.now( ) eta_str = None if eta < datetime.timedelta(minutes=5): fmt = 'Team {0} will be playing in {1} soon at the {3}.' else: eta_str = '' days = eta.days hours, rem = divmod(eta.seconds, 3600) minutes, _ = divmod(rem, 60) if days: eta_str += ' {} day{}'.format( days, '' if days == 1 else 's') if hours: eta_str += ' {} hour{}'.format( hours, '' if hours == 1 else 's') if minutes: eta_str += ' {} minute{}'.format( minutes, '' if minutes == 1 else 's') fmt = 'Team {0} will be playing in {1} in about{2} at the {3}.' text = fmt.format(team_number, match.verbose_name, eta_str, event.normalized_name) tts = fmt.format( cls._team_number_tts(team_number), match.verbose_name, eta_str, event.normalized_name) else: fmt = 'Team {0} will be playing in {1} at the {2}.' text = fmt.format(team_number, match.verbose_name, event.normalized_name) tts = fmt.format( cls._team_number_tts(team_number), match.verbose_name, event.normalized_name) add_messages = cls._create_link_chip( match.verbose_name, 'https://www.thebluealliance.com/match/{}'. format(match.key.id())) else: fmt = 'Team {0} has no more scheduled matches at the {1}.' text = fmt.format(team_number, event.normalized_name) tts = fmt.format(cls._team_number_tts(team_number), event.normalized_name) add_messages = [] else: fmt = 'Team {0} has no scheduled matches at the {1}.' text = fmt.format(team_number, event.normalized_name) tts = fmt.format(cls._team_number_tts(team_number), event.normalized_name) add_messages = [] break elif event.future: fmt = 'Team {0} will be competing at the {1} which begins on {2}.' event_date = event.start_date.strftime("%B %d") text = fmt.format(team_number, event.normalized_name, event_date) tts = fmt.format(cls._team_number_tts(team_number), event.normalized_name, event_date) add_messages = cls._create_link_chip( 'event page', 'https://www.thebluealliance.com/event/{}'.format( event.key.id())) break else: fmt = 'Team {0} is not registered for any more events this season.' text = fmt.format(team_number) tts = fmt.format(cls._team_number_tts(team_number)) add_messages = [] fmt = ' Would you like to know more about {} or another team?' text += fmt.format(team_number) tts += fmt.format(cls._team_number_tts(team_number)) add_messages += cls._create_suggestion_chips([ 'Current status', 'Location', 'Rookie year', 'Another team', 'No thanks', ]) else: fmt = 'Team {0} does not exist. Please ask about another team.' text = fmt.format(team_number) tts = fmt.format(cls._team_number_tts(team_number)) add_messages = [] return { 'speech': text, 'messages': cls._create_simple_response(text, tts=tts) + add_messages, }
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 _getteam_nextmatch(cls, request): team_number = request['result']['parameters']['team_number'] team_key = 'frc{}'.format(team_number) team = Team.get_by_id(team_key) if team: events = TeamYearEventsQuery(team_key, datetime.datetime.now().year).fetch() EventHelper.sort_events(events) # Find first current or future event for event in events: if event.now: matches = TeamEventMatchesQuery(team_key, event.key.id()).fetch() matches = MatchHelper.play_order_sort_matches(matches) if matches: next_match = None for match in matches: if not match.has_been_played: next_match = match break if next_match is not None: if match.predicted_time: eta = match.predicted_time - datetime.datetime.now() eta_str = None if eta < datetime.timedelta(minutes=5): fmt = 'Team {0} will be playing in {1} soon at the {3}.' else: eta_str = '' days = eta.days hours, rem = divmod(eta.seconds, 3600) minutes, _ = divmod(rem, 60) if days: eta_str += ' {} day{}'.format(days, '' if days == 1 else 's') if hours: eta_str += ' {} hour{}'.format(hours, '' if hours == 1 else 's') if minutes: eta_str += ' {} minute{}'.format(minutes, '' if minutes == 1 else 's') fmt = 'Team {0} will be playing in {1} in about{2} at the {3}.' text = fmt.format(team_number, match.verbose_name, eta_str, event.normalized_name) tts = fmt.format(cls._team_number_tts(team_number), match.verbose_name, eta_str, event.normalized_name) else: fmt = 'Team {0} will be playing in {1} at the {2}.' text = fmt.format(team_number, match.verbose_name, event.normalized_name) tts = fmt.format(cls._team_number_tts(team_number), match.verbose_name, event.normalized_name) add_messages = cls._create_link_chip( match.verbose_name, 'https://www.thebluealliance.com/match/{}'.format(match.key.id())) else: fmt = 'Team {0} has no more scheduled matches at the {1}.' text = fmt.format(team_number, event.normalized_name) tts = fmt.format(cls._team_number_tts(team_number), event.normalized_name) add_messages = [] else: fmt = 'Team {0} has no scheduled matches at the {1}.' text = fmt.format(team_number, event.normalized_name) tts = fmt.format(cls._team_number_tts(team_number), event.normalized_name) add_messages = [] break elif event.future: fmt = 'Team {0} will be competing at the {1} which begins on {2}.' event_date = event.start_date.strftime("%B %d") text = fmt.format(team_number, event.normalized_name, event_date) tts = fmt.format(cls._team_number_tts(team_number), event.normalized_name, event_date) add_messages = cls._create_link_chip( 'event page', 'https://www.thebluealliance.com/event/{}'.format(event.key.id())) break else: fmt = 'Team {0} is not registered for any more events this season.' text = fmt.format(team_number) tts = fmt.format(cls._team_number_tts(team_number)) add_messages = [] fmt = ' Would you like to know more about {} or another team?' text += fmt.format(team_number) tts += fmt.format(cls._team_number_tts(team_number)) add_messages += cls._create_suggestion_chips([ 'Current status', 'Location', 'Rookie year', 'Another team', 'No thanks', ]) else: fmt = 'Team {0} does not exist. Please ask about another team.' text = fmt.format(team_number) tts = fmt.format(cls._team_number_tts(team_number)) add_messages = [] return { 'speech': text, 'messages': cls._create_simple_response(text, tts=tts) + add_messages, }