def getEventAwards(self, event): """ Works reliably for regional events from 2002-present and championship events from 2007-present """ if event.year < 2002 or (event.event_type_enum in EventType.CMP_EVENT_TYPES and event.year < 2007): # award pages malformatted logging.warning("Skipping awards parsing for event: {}".format(event.key_name)) return [] url = self.EVENT_AWARDS_URL_PATTERN % (event.year, self.EVENT_SHORT_EXCEPTIONS.get(event.event_short, event.event_short)) awards, _ = self.parse(url, self.YEAR_AWARD_PARSER.get(event.year, self.DEFAULT_AWARD_PARSER)) return [Award( id=Award.render_key_name(event.key_name, award['award_type_enum']), name_str=award['name_str'], award_type_enum=award['award_type_enum'], year=event.year, event=event.key, event_type_enum=event.event_type_enum, team_list=[ndb.Key(Team, 'frc{}'.format(team_number)) for team_number in award['team_number_list']], recipient_json_list=award['recipient_json_list'] ) for award in awards]
def _process_request(self, request, event_key): event = Event.get_by_id(event_key) awards = [] for award in JSONAwardsParser.parse(request.body, event_key): awards.append( Award(id=Award.render_key_name(event.key_name, award['award_type_enum']), name_str=award['name_str'], award_type_enum=award['award_type_enum'], year=event.year, event=event.key, event_type_enum=event.event_type_enum, team_list=[ ndb.Key(Team, team_key) for team_key in award['team_key_list'] ], recipient_json_list=award['recipient_json_list'])) # it's easier to clear all awards and add new ones than try to find the difference old_award_keys = Award.query(Award.event == event.key).fetch( None, keys_only=True) AwardManipulator.delete_keys(old_award_keys) if event.remap_teams: EventHelper.remapteams_awards(awards, event.remap_teams) AwardManipulator.createOrUpdate(awards) self.response.out.write( json.dumps({'Success': "Awards successfully updated"}))
def add_awards_from_csv(cls, awards_csv): events = {} # for reducing datastore fetches of events and teams awards = [] for award in CSVAwardsParser.parse(awards_csv): event_key_name = '{}{}'.format(award['year'], award['event_short']) if event_key_name in events: event = events[event_key_name] else: event = Event.get_by_id(event_key_name) if event is None: logging.warning("Event: {} doesn't exist!".format(event_key_name)) continue events[event_key_name] = event awards.append(Award( id=Award.render_key_name(event.key_name, award['award_type_enum']), name_str=award['name_str'], award_type_enum=award['award_type_enum'], year=event.year, event=event.key, event_type_enum=event.event_type_enum, team_list=[ndb.Key(Team, 'frc{}'.format(team_number)) for team_number in award['team_number_list']], recipient_json_list=award['recipient_json_list'] )) new_awards = AwardManipulator.createOrUpdate(awards) if type(new_awards) != list: new_awards = [new_awards] return new_awards
def _process_request(self, request, event_key): event = Event.get_by_id(event_key) awards = [] for award in JSONAwardsParser.parse(request.body, event_key): awards.append(Award( id=Award.render_key_name(event.key_name, award['award_type_enum']), name_str=award['name_str'], award_type_enum=award['award_type_enum'], year=event.year, event=event.key, event_type_enum=event.event_type_enum, team_list=[ndb.Key(Team, team_key) for team_key in award['team_key_list']], recipient_json_list=award['recipient_json_list'] )) # it's easier to clear all awards and add new ones than try to find the difference old_award_keys = Award.query(Award.event == event.key).fetch(None, keys_only=True) AwardManipulator.delete_keys(old_award_keys) if event.remap_teams: EventHelper.remapteams_awards(awards, event.remap_teams) AwardManipulator.createOrUpdate(awards) self.response.out.write(json.dumps({'Success': "Awards successfully updated"}))
def add_awards_from_csv(cls, awards_csv): events = {} # for reducing datastore fetches of events and teams awards = [] for award in CSVAwardsParser.parse(awards_csv): event_key_name = '{}{}'.format(award['year'], award['event_short']) if event_key_name in events: event = events[event_key_name] else: event = Event.get_by_id(event_key_name) if event is None: logging.warning( "Event: {} doesn't exist!".format(event_key_name)) continue events[event_key_name] = event awards.append( Award(id=Award.render_key_name(event.key_name, award['award_type_enum']), name_str=award['name_str'], award_type_enum=award['award_type_enum'], year=event.year, event=event.key, event_type_enum=event.event_type_enum, team_list=[ ndb.Key(Team, 'frc{}'.format(team_number)) for team_number in award['team_number_list'] ], recipient_json_list=award['recipient_json_list'])) new_awards = AwardManipulator.createOrUpdate(awards) if type(new_awards) != list: new_awards = [new_awards] return new_awards
def get(self, event_key): # Fetch for later event_future = Event.get_by_id_async(event_key) matches_future = match_query.EventMatchesQuery(event_key).fetch_async() # Rebuild event teams taskqueue.add( url='/tasks/math/do/eventteam_update/' + event_key, method='GET') # Create Winner/Finalist awards for offseason events awards = [] event = event_future.get_result() if event.event_type_enum in {EventType.OFFSEASON, EventType.FOC}: matches = MatchHelper.organizeMatches(matches_future.get_result()) bracket = MatchHelper.generateBracket(matches, event, event.alliance_selections) if 'f' in bracket: winning_alliance = '{}_alliance'.format(bracket['f'][1]['winning_alliance']) if winning_alliance == 'red_alliance': losing_alliance = 'blue_alliance' else: losing_alliance = 'red_alliance' awards.append(Award( id=Award.render_key_name(event.key_name, AwardType.WINNER), name_str="Winner", award_type_enum=AwardType.WINNER, year=event.year, event=event.key, event_type_enum=event.event_type_enum, team_list=[ndb.Key(Team, 'frc{}'.format(team)) for team in bracket['f'][1][winning_alliance] if team.isdigit()], recipient_json_list=[json.dumps({'team_number': team, 'awardee': None}) for team in bracket['f'][1][winning_alliance]], )) awards.append(Award( id=Award.render_key_name(event.key_name, AwardType.FINALIST), name_str="Finalist", award_type_enum=AwardType.FINALIST, year=event.year, event=event.key, event_type_enum=event.event_type_enum, team_list=[ndb.Key(Team, 'frc{}'.format(team)) for team in bracket['f'][1][losing_alliance] if team.isdigit()], recipient_json_list=[json.dumps({'team_number': team, 'awardee': None}) for team in bracket['f'][1][losing_alliance]], )) AwardManipulator.createOrUpdate(awards) self.response.out.write("Finished post-event tasks for {}. Created awards: {}".format(event_key, awards))
def parse(cls, data): """ Parse CSV that contains awards Format is as follows: year, event_short, award_name_str, team_number (can be blank), awardee (can be blank) Example: 2000,mi,Regional Finalist,45, """ awards_by_key = {} csv_data = list(csv.reader(StringIO.StringIO(data), delimiter=',', skipinitialspace=True)) for award in csv_data: year = int(award[0]) event_short = award[1] name_str = award[2] team_number = award[3] awardee = award[4] if team_number == '': team_number = None else: team_number = int(team_number) if awardee == '': awardee = None # an award must have either an awardee or a team_number if awardee is None and team_number is None: continue if team_number is not None: team_number_list = [team_number] else: team_number_list = [] recipient_json = json.dumps({ 'team_number': team_number, 'awardee': awardee, }) award_type_enum = AwardHelper.parse_award_type(name_str) if award_type_enum is None: # If we can't figure it out, fall back to OTHER (good for offseason events) award_type_enum = AwardType.OTHER award_key_name = Award.render_key_name('{}{}'.format(year, event_short), award_type_enum) if award_key_name in awards_by_key: if team_number is not None: awards_by_key[award_key_name]['team_number_list'].append(team_number) awards_by_key[award_key_name]['recipient_json_list'].append(recipient_json) else: awards_by_key[award_key_name] = { 'year': year, 'event_short': event_short, 'name_str': name_str, 'award_type_enum': award_type_enum, 'team_number_list': team_number_list, 'recipient_json_list': [recipient_json], } return awards_by_key.values()
def setUp(self): self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_memcache_stub() ndb.get_context().clear_cache( ) # Prevent data from leaking between tests self.testbed.init_taskqueue_stub(root_path=".") self.event = Event( id="2013casj", event_short="casj", year=2013, event_type_enum=EventType.REGIONAL, ) self.old_award = Award( id=Award.render_key_name(self.event.key_name, AwardType.WINNER), name_str="Regional Winner", award_type_enum=AwardType.WINNER, year=2013, event=self.event.key, event_type_enum=EventType.REGIONAL, team_list=[ndb.Key(Team, 'frc111'), ndb.Key(Team, 'frc234')], recipient_json_list=[ json.dumps({ 'team_number': 111, 'awardee': None }), json.dumps({ 'team_number': 234, 'awardee': None }) ], ) self.new_award = Award( id="2013casj_1", name_str="Regional Champion", award_type_enum=AwardType.WINNER, year=2013, event=self.event.key, event_type_enum=EventType.REGIONAL, team_list=[ndb.Key(Team, 'frc359')], recipient_json_list=[ json.dumps({ 'team_number': 359, 'awardee': None }) ], )
def test_team_awards(self): # Insert some Teams frc1 = Team( id='frc1', team_number=1 ) frc1.put() frc2 = Team( id='frc2', team_number=2 ) frc2.put() frc3 = Team( id='frc3', team_number=3 ) frc3.put() # Insert some Awards for some Teams award = Award( id=Award.render_key_name(self.event_ends_today.key_name, AwardType.INDUSTRIAL_DESIGN), name_str='Industrial Design Award sponsored by General Motors', award_type_enum=AwardType.INDUSTRIAL_DESIGN, event=self.event_ends_today.key, event_type_enum=EventType.REGIONAL, team_list=[ndb.Key(Team, 'frc1')], year=2020 ) award.put() winner_award = Award( id=Award.render_key_name(self.event_ends_today.key_name, AwardType.WINNER), name_str='Regional Event Winner', award_type_enum=AwardType.WINNER, event=self.event_ends_today.key, event_type_enum=EventType.REGIONAL, team_list=[ndb.Key(Team, 'frc2'), ndb.Key(Team, 'frc1')], year=2020 ) winner_award.put() self.assertItemsEqual(self.event_ends_today.team_awards().keys(), [frc1.key, frc2.key])
def setUp(self): self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_memcache_stub() ndb.get_context().clear_cache() self.testbed.init_taskqueue_stub(root_path='.') self.event = Event( id='2020miket', event_type_enum=EventType.DISTRICT, short_name='Kettering University #1', name='FIM District Kettering University Event #1', event_short='miket', year=2020 ) self.team = Team( id='frc7332', team_number=7332 ) self.award = Award( id=Award.render_key_name(self.event.key_name, AwardType.INDUSTRIAL_DESIGN), name_str='Industrial Design Award sponsored by General Motors', award_type_enum=AwardType.INDUSTRIAL_DESIGN, event=self.event.key, event_type_enum=EventType.DISTRICT, year=2020 ) self.winner_award = Award( id=Award.render_key_name(self.event.key_name, AwardType.WINNER), name_str='District Event Winner', award_type_enum=AwardType.WINNER, event=self.event.key, event_type_enum=EventType.DISTRICT, year=2020 )
def parse(self, response): awards_by_type = {} for award in response['Awards']: team_number = award['teamNumber'] if self.valid_team_nums is not None and team_number not in self.valid_team_nums: continue award_type_enum = AwardHelper.parse_award_type(award['name']) if award_type_enum is None: continue recipient_json = json.dumps({ 'team_number': team_number, 'awardee': award['person'], }) if award_type_enum in awards_by_type: if team_number is not None: awards_by_type[award_type_enum]['team_number_list'].append( team_number) awards_by_type[award_type_enum]['recipient_json_list'].append( recipient_json) else: awards_by_type[award_type_enum] = { 'name_str': award['name'], 'award_type_enum': award_type_enum, 'team_number_list': [team_number] if team_number is not None else [], 'recipient_json_list': [recipient_json], } awards = [] for award in awards_by_type.values(): awards.append( Award(id=Award.render_key_name(self.event.key_name, award['award_type_enum']), name_str=award['name_str'], award_type_enum=award['award_type_enum'], year=self.event.year, event=self.event.key, event_type_enum=self.event.event_type_enum, team_list=[ ndb.Key(Team, 'frc{}'.format(team_number)) for team_number in award['team_number_list'] ], recipient_json_list=award['recipient_json_list'])) return awards
def parse(self, awards_json, event_key): """ Parse JSON that contains a list of awards where each award is a dict of: name_str: String of award name. ex: "Tournament Winner" or "Dean's List Finalist" team_key: String in the format "frcXXX" for the team that won the award. Can be null. awardee: String corresponding to the name of an individual that won the award. Can be null. """ try: awards = json.loads(awards_json) except: raise ParserInputException("Invalid JSON. Please check input.") awards_by_key = {} for award in awards: if type(award) is not dict: raise ParserInputException("Awards must be dicts.") name_str = award.get('name_str', None) team_key = award.get('team_key', None) awardee = award.get('awardee', None) if name_str is None: raise ParserInputException("Award must have a 'name_str'") if team_key and not re.match(r'frc\d+', str(team_key)): raise ParserInputException("Bad team_key: '{}'. Must follow format 'frcXXX' or be null.".format(team_key)) award_type_enum = AwardHelper.parse_award_type(name_str) if award_type_enum is None: raise ParserInputException("Cannot determine award type from: '{}'. Please contact a www.thebluealliance.com admin.".format(name_str)) recipient_json = json.dumps({ 'team_number': int(team_key[3:]) if team_key else None, 'awardee': awardee, }) award_key_name = Award.render_key_name(event_key, award_type_enum) if award_key_name in awards_by_key: if team_key is not None: awards_by_key[award_key_name]['team_key_list'].append(team_key) awards_by_key[award_key_name]['recipient_json_list'].append(recipient_json) else: awards_by_key[award_key_name] = { 'name_str': name_str, 'award_type_enum': award_type_enum, 'team_key_list': [team_key] if team_key else [], 'recipient_json_list': [recipient_json], } return awards_by_key.values()
def store_award(data, event): award = Award(id=Award.render_key_name(data['event_key'], data['award_type'])) award.event = ndb.Key(Event, data['event_key']) award.award_type_enum = data['award_type'] award.year = data['year'] award.name_str = data['name'] award.event_type_enum = event.event_type_enum recipient_list_fixed = [] team_keys = [] for recipient in data['recipient_list']: if recipient['team_key']: team_keys.append(ndb.Key(Team, recipient['team_key'])) recipient_list_fixed.append(json.dumps({ 'awardee': recipient['awardee'], 'team_number': int(recipient['team_key'][3:]) if recipient['team_key'] else None, })) award.recipient_json_list = recipient_list_fixed return AwardManipulator.createOrUpdate(award)
def parse(self, response): awards_by_type = {} for award in response['Awards']: team_number = award['teamNumber'] if self.valid_team_nums is not None and team_number not in self.valid_team_nums: continue award_type_enum = AwardHelper.parse_award_type(award['name']) if award_type_enum is None: continue recipient_json = json.dumps({ 'team_number': team_number, 'awardee': award['person'], }) if award_type_enum in awards_by_type: if team_number is not None: awards_by_type[award_type_enum]['team_number_list'].append(team_number) awards_by_type[award_type_enum]['recipient_json_list'].append(recipient_json) else: awards_by_type[award_type_enum] = { 'name_str': award['name'], 'award_type_enum': award_type_enum, 'team_number_list': [team_number] if team_number is not None else [], 'recipient_json_list': [recipient_json], } awards = [] for award in awards_by_type.values(): awards.append(Award( id=Award.render_key_name(self.event.key_name, award['award_type_enum']), name_str=award['name_str'], award_type_enum=award['award_type_enum'], year=self.event.year, event=self.event.key, event_type_enum=self.event.event_type_enum, team_list=[ndb.Key(Team, 'frc{}'.format(team_number)) for team_number in award['team_number_list']], recipient_json_list=award['recipient_json_list'] )) return awards
def post(self): self._require_admin() awards_csv = self.request.get('awards_csv') events = {} # for reducing datastore fetches of events and teams awards = [] for award in CSVAwardsParser.parse(awards_csv): event_key_name = '{}{}'.format(award['year'], award['event_short']) if event_key_name in events: event = events[event_key_name] else: event = Event.get_by_id(event_key_name) if event is None: logging.warning( "Event: {} doesn't exist!".format(event_key_name)) continue events[event_key_name] = event awards.append( Award(id=Award.render_key_name(event.key_name, award['award_type_enum']), name_str=award['name_str'], award_type_enum=award['award_type_enum'], year=event.year, event=event.key, event_type_enum=event.event_type_enum, team_list=[ ndb.Key(Team, 'frc{}'.format(team_number)) for team_number in award['team_number_list'] ], recipient_json_list=award['recipient_json_list'])) new_awards = AwardManipulator.createOrUpdate(awards) if type(new_awards) != list: new_awards = [new_awards] self.template_values = { 'awards': new_awards, } path = os.path.join(os.path.dirname(__file__), '../../templates/admin/awards_add.html') self.response.out.write(template.render(path, self.template_values))
def setUp(self): self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_memcache_stub() ndb.get_context().clear_cache() # Prevent data from leaking between tests self.testbed.init_taskqueue_stub(root_path=".") self.event = Event( id="2013casj", event_short="casj", year=2013, event_type_enum=EventType.REGIONAL, ) self.old_award = Award( id=Award.render_key_name(self.event.key_name, AwardType.WINNER), name_str="Regional Winner", award_type_enum=AwardType.WINNER, year=2013, event=self.event.key, event_type_enum=EventType.REGIONAL, team_list=[ndb.Key(Team, 'frc111'), ndb.Key(Team, 'frc234')], recipient_json_list=[json.dumps({'team_number': 111, 'awardee': None}), json.dumps({'team_number': 234, 'awardee': None})], ) self.new_award = Award( id="2013casj_1", name_str="Regional Champion", award_type_enum=AwardType.WINNER, year=2013, event=self.event.key, event_type_enum=EventType.REGIONAL, team_list=[ndb.Key(Team, 'frc359')], recipient_json_list=[json.dumps({'team_number': 359, 'awardee': None})], )
def post(self): self._require_admin() awards_csv = self.request.get('awards_csv') events = {} # for reducing datastore fetches of events and teams awards = [] for award in CSVAwardsParser.parse(awards_csv): event_key_name = '{}{}'.format(award['year'], award['event_short']) if event_key_name in events: event = events[event_key_name] else: event = Event.get_by_id(event_key_name) if event is None: logging.warning("Event: {} doesn't exist!".format(event_key_name)) continue events[event_key_name] = event awards.append(Award( id=Award.render_key_name(event.key_name, award['award_type_enum']), name_str=award['name_str'], award_type_enum=award['award_type_enum'], year=event.year, event=event.key, event_type_enum=event.event_type_enum, team_list=[ndb.Key(Team, 'frc{}'.format(team_number)) for team_number in award['team_number_list']], recipient_json_list=award['recipient_json_list'] )) new_awards = AwardManipulator.createOrUpdate(awards) if type(new_awards) != list: new_awards = [new_awards] self.template_values = { 'awards': new_awards, } path = os.path.join(os.path.dirname(__file__), '../../templates/admin/awards_add.html') self.response.out.write(template.render(path, self.template_values))
def get(self, event_key): if tba_config.CONFIG["env"] == "prod": # disable in prod for now logging.error("Tried to restore {} from CSV in prod! No can do.".format(event_key)) return event = Event.get_by_id(event_key) # alliances result = urlfetch.fetch(self.ALLIANCES_URL.format(event.year, event_key, event_key)) if result.status_code != 200: logging.warning('Unable to retreive url: ' + (self.ALLIANCES_URL.format(event.year, event_key, event_key))) else: data = result.content.replace('frc', '') alliance_selections = CSVAllianceSelectionsParser.parse(data) event_details = EventDetails( id=event_key, alliance_selections=alliance_selections ) EventDetailsManipulator.createOrUpdate(event_details) # awards result = urlfetch.fetch(self.AWARDS_URL.format(event.year, event_key, event_key)) if result.status_code != 200: logging.warning('Unable to retreive url: ' + (self.AWARDS_URL.format(event.year, event_key, event_key))) else: # convert into expected input format data = StringIO.StringIO() writer = csv.writer(data, delimiter=',') for row in csv.reader(StringIO.StringIO(result.content), delimiter=','): writer.writerow([event.year, event.event_short, row[1], row[2].replace('frc', ''), row[3]]) awards = [] for award in CSVAwardsParser.parse(data.getvalue()): awards.append(Award( id=Award.render_key_name(event.key_name, award['award_type_enum']), name_str=award['name_str'], award_type_enum=award['award_type_enum'], year=event.year, event=event.key, event_type_enum=event.event_type_enum, team_list=[ndb.Key(Team, 'frc{}'.format(team_number)) for team_number in award['team_number_list']], recipient_json_list=award['recipient_json_list'] )) AwardManipulator.createOrUpdate(awards) # matches result = urlfetch.fetch(self.MATCHES_URL.format(event.year, event_key, event_key)) if result.status_code != 200: logging.warning('Unable to retreive url: ' + (self.MATCHES_URL.format(event.year, event_key, event_key))) else: data = result.content.replace('frc', '').replace('{}_'.format(event_key), '') match_dicts, _ = OffseasonMatchesParser.parse(data) matches = [ Match( id=Match.renderKeyName( event.key.id(), match.get("comp_level", None), match.get("set_number", 0), match.get("match_number", 0)), event=event.key, year=event.year, set_number=match.get("set_number", 0), match_number=match.get("match_number", 0), comp_level=match.get("comp_level", None), team_key_names=match.get("team_key_names", None), alliances_json=match.get("alliances_json", None) ) for match in match_dicts] MatchManipulator.createOrUpdate(matches) # rankings result = urlfetch.fetch(self.RANKINGS_URL.format(event.year, event_key, event_key)) if result.status_code != 200: logging.warning('Unable to retreive url: ' + (self.RANKINGS_URL.format(event.year, event_key, event_key))) else: # convert into expected input format rankings = list(csv.reader(StringIO.StringIO(result.content), delimiter=',')) event_details = EventDetails( id=event_key, rankings=rankings ) EventDetailsManipulator.createOrUpdate(event_details) self.response.out.write("Done restoring {}!".format(event_key))
def parse(self, data): """ Parse CSV that contains awards Format is as follows: year, event_short, award_name_str, team_number (can be blank), awardee (can be blank) Example: 2000,mi,Regional Finalist,45, """ awards_by_key = {} csv_data = list( csv.reader(StringIO.StringIO(data), delimiter=',', skipinitialspace=True)) for award in csv_data: year = int(award[0]) event_short = award[1] name_str = award[2] team_number = award[3] awardee = award[4] if team_number == '': team_number = None else: team_number = int(team_number) if awardee == '': awardee = None # an award must have either an awardee or a team_number if awardee is None and team_number is None: continue if team_number is not None: team_number_list = [team_number] else: team_number_list = [] recipient_json = json.dumps({ 'team_number': team_number, 'awardee': awardee, }) award_type_enum = AwardHelper.parse_award_type(name_str) if award_type_enum is None: continue award_key_name = Award.render_key_name( '{}{}'.format(year, event_short), award_type_enum) if award_key_name in awards_by_key: if team_number is not None: awards_by_key[award_key_name]['team_number_list'].append( team_number) awards_by_key[award_key_name]['recipient_json_list'].append( recipient_json) else: awards_by_key[award_key_name] = { 'year': year, 'event_short': event_short, 'name_str': name_str, 'award_type_enum': award_type_enum, 'team_number_list': team_number_list, 'recipient_json_list': [recipient_json], } return awards_by_key.values()