def postUpdateHook(cls, districts, updated_attr_list, is_new_list): """ To run after a district has been updated. For new districts, tries to guess the names based on other year's data """ for (district, is_new, updated_attrs) in zip(districts, is_new_list, updated_attr_list): if is_new and (not district.display_name or not district.elasticsearch_name): last_year_key = District.renderKeyName(district.year - 1, district.abbreviation) last_year_district = District.get_by_id(last_year_key) update = False if last_year_district: if not district.display_name: district.display_name = last_year_district.display_name update = True if not district.elasticsearch_name: district.elasticsearch_name = last_year_district.elasticsearch_name update = True if update: cls.createOrUpdate(district, run_post_update_hook=False) if 'display_name' in updated_attrs or 'elasticsearch_name' in updated_attrs: # Set all other instances of this district to have the values all_past_years = DistrictHistoryQuery(district.abbreviation).fetch() to_put = [] for other_district in all_past_years: if other_district.year != district.year: other_district.display_name = district.display_name other_district.elasticsearch_name = district.elasticsearch_name to_put.append(other_district) cls.createOrUpdate(to_put, run_post_update_hook=False)
def store_district(data): district = District(id=data['key']) district.year = data['year'] district.abbreviation = data['abbreviation'] district.display_name = data['display_name'] return DistrictManipulator.createOrUpdate(district)
def setUp(self): app = webapp2.WSGIApplication([ webapp2.Route(r'/<team_key:>', ApiTeamHistoryDistrictsController, methods=['GET']) ], debug=True) self.testapp = webtest.TestApp(app) self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_urlfetch_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.team = Team(id="frc1124", name="UberBots", team_number=1124, nickname="UberBots") self.district_team = DistrictTeam(id="2015ne_frc1124", team=self.team.key, year=2015, district_key=ndb.Key( District, '2015ne')) self.district = District(id='2015ne', year=2015) self.team.put() self.district_team.put() self.district.put()
def postUpdateHook(cls, districts, updated_attr_list, is_new_list): """ To run after a district has been updated. For new districts, tries to guess the names based on other year's data """ for (district, is_new, updated_attrs) in zip(districts, is_new_list, updated_attr_list): if is_new and (not district.display_name or not district.elasticsearch_name): last_year_key = District.renderKeyName(district.year - 1, district.abbreviation) last_year_district = District.get_by_id(last_year_key) update = False if last_year_district: if not district.display_name: district.display_name = last_year_district.display_name update = True if not district.elasticsearch_name: district.elasticsearch_name = last_year_district.elasticsearch_name update = True if update: cls.createOrUpdate(district, run_post_update_hook=False) if 'display_name' in updated_attrs or 'elasticsearch_name' in updated_attrs: # Set all other instances of this district to have the values all_past_years = DistrictHistoryQuery( district.abbreviation).fetch() to_put = [] for other_district in all_past_years: if other_district.year != district.year: other_district.display_name = district.display_name other_district.elasticsearch_name = district.elasticsearch_name to_put.append(other_district) cls.createOrUpdate(to_put, run_post_update_hook=False)
def get(self, year): year = int(year) year_dcmps = DistrictChampsInYearQuery(year).fetch() districts_to_write = [] for dcmp in year_dcmps: district_abbrev = DistrictType.type_abbrevs[ dcmp.event_district_enum] district_key = District.renderKeyName(year, district_abbrev) logging.info("Creating {}".format(district_key)) district = District( id=district_key, year=year, abbreviation=district_abbrev, display_name=DistrictType.type_names[dcmp.event_district_enum], elasticsearch_name=next( (k for k, v in DistrictType.elasticsearch_names.iteritems() if v == dcmp.event_district_enum), None)) districts_to_write.append(district) logging.info("Writing {} new districts".format( len(districts_to_write))) DistrictManipulator.createOrUpdate(districts_to_write, run_post_update_hook=False) for dcmp in year_dcmps: district_abbrev = DistrictType.type_abbrevs[ dcmp.event_district_enum] district_key = District.renderKeyName(year, district_abbrev) district_events_future = DistrictEventsQuery( district_key).fetch_async() district_events = district_events_future.get_result() logging.info("Found {} events to update".format( len(district_events))) events_to_write = [] for event in district_events: event.district_key = ndb.Key(District, district_key) events_to_write.append(event) EventManipulator.createOrUpdate(events_to_write) for dcmp in year_dcmps: district_abbrev = DistrictType.type_abbrevs[ dcmp.event_district_enum] district_key = District.renderKeyName(year, district_abbrev) districtteams_future = DistrictTeam.query( DistrictTeam.year == year, DistrictTeam.district == DistrictType.abbrevs.get( district_abbrev, None)).fetch_async() districtteams = districtteams_future.get_result() logging.info("Found {} DistrictTeams to update".format( len(districtteams))) districtteams_to_write = [] for districtteam in districtteams: districtteam.district_key = ndb.Key(District, district_key) districtteams_to_write.append(districtteam) DistrictTeamManipulator.createOrUpdate(districtteams_to_write)
def update_data(input_data: list[str]): try: for data in input_data: state, district, mandi, crop, crop_variety, date, price = data.split( ', ') # check for the instance of mandi in mandi_instances else create if (mandi, state, district) in mandi_instances: mandi_instance = mandi_instances[(mandi, state, district)] else: mandi_instance = Mandi(mandi, state, district) mandi_instances[(mandi, state, district)] = mandi_instance # add crop for the particular mandi mandi_instance.add_crop(crop) # check for the instance of crop in crop_instances else create if crop in crop_instances: crop_instance = crop_instances[crop] else: crop_instance = Crop(crop) crop_instances[crop] = crop_instance # add crop_variety for the crop crop_instance.add_crop_variety(crop_variety) # check for the instance of crop_variety in crop_variety_instances else create if crop_variety in crop_variety_instances: crop_variety_instance = crop_variety_instances[crop_variety] else: crop_variety_instance = CropVariety(crop_variety) crop_variety_instances[crop_variety] = crop_variety_instance # check for the instance of date, price in price_instance else create if (mandi, crop, crop_variety) in price_instances: price_instance = price_instances[(mandi, crop, crop_variety)] else: price_instance = Price(mandi, crop, crop_variety) price_instances[(mandi, crop, crop_variety)] = price_instance # add date and price for a paticular mandi, crop and crop_variety price_instance.add_date_price(date, price) # check for the instance of mandi in mandi_instance else create if (district, state) in district_instances: district_instance = district_instances[(district, state)] else: district_instance = District(district, state) district_instances[(district, state)] = district_instance # add mandi in district district_instance.add_mandi(mandi) except Exception as e: print(e) raise Exception(e) print("Data successfully updated") return 1
def post(self, *args, **kwargs): district_list = self.get_angular_argument('district_list') if not district_list: return District.update_position(district_list) return
class TestTeamHistoryDistrictsApiController(unittest2.TestCase): def setUp(self): app = webapp2.WSGIApplication([ webapp2.Route(r'/<team_key:>', ApiTeamHistoryDistrictsController, methods=['GET']) ], debug=True) self.testapp = webtest.TestApp(app) self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_urlfetch_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.team = Team( id="frc1124", name="UberBots", team_number=1124, nickname="UberBots", ) self.district_team = DistrictTeam(id="2015ne_frc1124", team=self.team.key, year=2015, district_key=ndb.Key( District, '2015ne')) self.district = District( id='2015ne', year=2015, ) self.team.put() self.district_team.put() self.district.put() def tearDown(self): self.testbed.deactivate() def testDistrictsApi(self): response = self.testapp.get( '/frc1124', headers={ "X-TBA-App-Id": "tba-tests:team-history-districts-controller-test:v01" }) district_dict = json.loads(response.body) self.assertTrue("2015" in district_dict) district_key = district_dict["2015"] self.assertEqual(district_key, "2015ne")
def setUp(self): app = webapp2.WSGIApplication([webapp2.Route(r'/<district_abbrev:>/<year:>', ApiDistrictEventsController, methods=['GET'])], debug=True) self.testapp = webtest.TestApp(app) self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_urlfetch_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.district = District( id='2010ne', year=2010, abbreviation='ne', display_name='New England', ) self.district.put() self.event = Event( id="2010sc", name="Palmetto Regional", event_type_enum=EventType.DISTRICT_CMP, district_key=ndb.Key(District, '2010ne'), short_name="Palmetto", event_short="sc", year=2010, end_date=datetime(2010, 03, 27), official=True, city="Clemson", state_prov="SC", country="USA", venue="Long Beach Arena", venue_address="Long Beach Arena\r\n300 East Ocean Blvd\r\nLong Beach, CA 90802\r\nUSA", start_date=datetime(2010, 03, 24), webcast_json="[{\"type\": \"twitch\", \"channel\": \"frcgamesense\"}]", website="http://www.firstsv.org" ) self.event.put() self.event_details = EventDetails( id=self.event.key.id(), alliance_selections=[ {"declines": [], "picks": ["frc971", "frc254", "frc1662"]}, {"declines": [], "picks": ["frc1678", "frc368", "frc4171"]}, {"declines": [], "picks": ["frc2035", "frc192", "frc4990"]}, {"declines": [], "picks": ["frc1323", "frc846", "frc2135"]}, {"declines": [], "picks": ["frc2144", "frc1388", "frc668"]}, {"declines": [], "picks": ["frc1280", "frc604", "frc100"]}, {"declines": [], "picks": ["frc114", "frc852", "frc841"]}, {"declines": [], "picks": ["frc2473", "frc3256", "frc1868"]} ] ) self.event_details.put()
def post(self, district_key): self._require_admin() district = District(id=District.renderKeyName( self.request.get("year"), self.request.get("abbreviation")), year=int(self.request.get("year")), abbreviation=self.request.get("abbreviation"), display_name=self.request.get("display_name")) DistrictManipulator.createOrUpdate(district) self.redirect('/admin/districts/' + self.request.get("year"))
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.ne_district = District(id='2015ne', abbreviation='ne', year=2015, elasticsearch_name='NE FIRST') self.ne_district.put()
def setUp(self): app = webapp2.WSGIApplication([ webapp2.Route(r'/<district_abbrev:>/<year:([0-9]*)>', ApiDistrictTeamsController, methods=['GET']) ], debug=True) self.testapp = webtest.TestApp(app) self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_urlfetch_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.team = Team( id="frc281", name="Michelin / Caterpillar / Greenville Technical College /\ jcpenney / Baldor / ASME / Gastroenterology Associates /\ Laserflex South & Greenville County Schools & Greenville\ Technical Charter High School", team_number=281, nickname="EnTech GreenVillians", city="Greenville", state_prov="SC", country="USA", website="www.entech.org", motto="Infiltrating Young Minds One Robot at a Time", ) self.district = District( id='2015ne', year=2015, abbreviation='ne', ) self.district_team = DistrictTeam(id="2015ne_frc281", team=self.team.key, year=2015, district_key=ndb.Key( District, '2015ne')) self.team.put() self.district.put() self.district_team.put()
def parse(self, response): districts = [] for district in response['districts']: district_code = district['code'].lower() district_key = District.renderKeyName(self.season, district_code) districts.append( District( id=district_key, abbreviation=district_code, year=self.season, display_name=district['name'], )) return districts
class TestTeamHistoryDistrictsApiController(unittest2.TestCase): def setUp(self): app = webapp2.WSGIApplication([webapp2.Route(r'/<team_key:>', ApiTeamHistoryDistrictsController, methods=['GET'])], debug=True) self.testapp = webtest.TestApp(app) self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_urlfetch_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.team = Team( id="frc1124", name="UberBots", team_number=1124, nickname="UberBots" ) self.district_team = DistrictTeam( id="2015ne_frc1124", team=self.team.key, year=2015, district_key=ndb.Key(District, '2015ne') ) self.district = District( id='2015ne', year=2015 ) self.team.put() self.district_team.put() self.district.put() def tearDown(self): self.testbed.deactivate() def testDistrictsApi(self): response = self.testapp.get('/frc1124', headers={"X-TBA-App-Id": "tba-tests:team-history-districts-controller-test:v01"}) district_dict = json.loads(response.body) self.assertTrue("2015" in district_dict) district_key = district_dict["2015"] self.assertEqual(district_key, "2015ne")
def setUp(self): app = webapp2.WSGIApplication([webapp2.Route(r'/<team_key:>', ApiTeamHistoryDistrictsController, methods=['GET'])], debug=True) self.testapp = webtest.TestApp(app) self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_urlfetch_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.team = Team( id="frc1124", name="UberBots", team_number=1124, nickname="UberBots" ) self.district_team = DistrictTeam( id="2015ne_frc1124", team=self.team.key, year=2015, district_key=ndb.Key(District, '2015ne') ) self.district = District( id='2015ne', year=2015 ) self.team.put() self.district_team.put() self.district.put()
def parse(self, response): events = [] districts = {} for event in response['Events']: code = event['code'].lower() event_type = EventType.PRESEASON if code == 'week0' else self.EVENT_TYPES.get(event['type'].lower(), None) if event_type is None: logging.warn("Event type '{}' not recognized!".format(event['type'])) continue name = event['name'] short_name = EventHelper.getShortName(name) district_enum = EventHelper.parseDistrictName(event['districtCode'].lower()) if event['districtCode'] else DistrictType.NO_DISTRICT district_key = District.renderKeyName(self.season, event['districtCode'].lower()) if event['districtCode'] else None venue = event['venue'] city = event['city'] state_prov = event['stateprov'] country = event['country'] start = datetime.datetime.strptime(event['dateStart'], self.DATE_FORMAT_STR) end = datetime.datetime.strptime(event['dateEnd'], self.DATE_FORMAT_STR) website = event.get('website') # TODO read timezone from API # Special cases for champs if code in self.EVENT_CODE_EXCEPTIONS: code, short_name = self.EVENT_CODE_EXCEPTIONS[code] if code in self.EINSTEIN_CODES: name = '{} Field'.format(short_name) start = end.replace(hour=0, minute=0, second=0, microsecond=0) # Set to beginning of last day else: # Divisions name = '{} Division'.format(short_name) events.append(Event( id="{}{}".format(self.season, code), name=name, short_name=short_name, event_short=code, event_type_enum=event_type, official=True, start_date=start, end_date=end, venue=venue, city=city, state_prov=state_prov, country=country, venue_address=None, # Even though FRC API provides address, ElasticSearch is more detailed year=self.season, event_district_enum=district_enum, district_key=ndb.Key(District, district_key) if district_key else None, website=website, )) # Build District Model if district_key and district_key not in districts: districts[district_key] = District( id=district_key, year=self.season, abbreviation=event['districtCode'].lower(), ) return events, list(districts.values())
def get(self, year): year = int(year) year_dcmps = DistrictChampsInYearQuery(year).fetch() districts_to_write = [] for dcmp in year_dcmps: district_abbrev = DistrictType.type_abbrevs[dcmp.event_district_enum] district_key = District.renderKeyName(year, district_abbrev) logging.info("Creating {}".format(district_key)) district = District( id=district_key, year=year, abbreviation=district_abbrev, display_name=DistrictType.type_names[dcmp.event_district_enum], elasticsearch_name=next((k for k, v in DistrictType.elasticsearch_names.iteritems() if v == dcmp.event_district_enum), None) ) districts_to_write.append(district) logging.info("Writing {} new districts".format(len(districts_to_write))) DistrictManipulator.createOrUpdate(districts_to_write, run_post_update_hook=False) for dcmp in year_dcmps: district_abbrev = DistrictType.type_abbrevs[dcmp.event_district_enum] district_key = District.renderKeyName(year, district_abbrev) district_events_future = DistrictEventsQuery(district_key).fetch_async() district_events = district_events_future.get_result() logging.info("Found {} events to update".format(len(district_events))) events_to_write = [] for event in district_events: event.district_key = ndb.Key(District, district_key) events_to_write.append(event) EventManipulator.createOrUpdate(events_to_write) for dcmp in year_dcmps: district_abbrev = DistrictType.type_abbrevs[dcmp.event_district_enum] district_key = District.renderKeyName(year, district_abbrev) districtteams_future = DistrictTeam.query(DistrictTeam.year == year, DistrictTeam.district == DistrictType.abbrevs.get(district_abbrev, None)).fetch_async() districtteams = districtteams_future.get_result() logging.info("Found {} DistrictTeams to update".format(len(districtteams))) districtteams_to_write = [] for districtteam in districtteams: districtteam.district_key = ndb.Key(District, district_key) districtteams_to_write.append(districtteam) DistrictTeamManipulator.createOrUpdate(districtteams_to_write)
def getShortName(self, name_str, district_code=None): """ Extracts a short name like "Silicon Valley" from an event name like "Silicon Valley Regional sponsored by Google.org". See https://github.com/the-blue-alliance/the-blue-alliance-android/blob/master/android/src/test/java/com/thebluealliance/androidclient/test/helpers/EventHelperTest.java """ district_keys = memcache.get( 'EventHelper.getShortName():district_keys') if not district_keys: codes = set([ d.id()[4:].upper() for d in District.query().fetch(keys_only=True) ]) if district_code: codes.add(district_code.upper()) if 'MAR' in codes: # MAR renamed to FMA in 2019 codes.add('FMA') if 'TX' in codes: # TX and FIT used interchangeably codes.add('FIT') district_keys = '|'.join(codes) memcache.set('EventHelper.getShortName():district_keys', district_keys, 60 * 60) # 2015+ districts # Numbered events with no name re_string = '({}) District Event (#\d+)'.format(district_keys) match = re.match(re_string, name_str) if match: return '{} {}'.format( match.group(1).strip(), match.group(2).strip()) # The rest re_string = '(?:{}) District -?(.+)'.format(district_keys) match = re.match(re_string, name_str) if match: partial = match.group(1).strip() match2 = re.sub(r'(?<=[\w\s])Event\s*(?:[\w\s]*$)?', '', partial) return match2.strip() # 2014- districts # district championships, other districts, and regionals name_str = re.sub(r'\s?Event', '', name_str) match = re.match( r'\s*(?:MAR |PNW |)(?:FIRST Robotics|FRC|)(.+)(?:District|Regional|Region|Provincial|State|Tournament|FRC|Field)(?:\b)(?:[\w\s]+?(#\d*)*)?', name_str) if match: short = ''.join(match.groups('')) match = re.match(r'(.+)(?:FIRST Robotics|FRC)', short) if match: result = match.group(1).strip() else: result = short.strip() if result.startswith('FIRST'): result = result[5:] return result.strip() return name_str.strip()
def _query_async(self): abbreviation = self._query_args[0] district_keys = yield District.query( District.abbreviation.IN( get_equivalent_codes(abbreviation))).fetch_async( keys_only=True) districts = yield ndb.get_multi_async(district_keys) raise ndb.Return(districts)
def parse(self, response): """ Parse team info from FMSAPI Returns a tuple of: list of models (Team, DistrictTeam, Robot), and a Boolean indicating if there are more pages to be fetched """ # Get team json # don't need to null check, if error, HTTP code != 200, so we wont' get here current_page = response['pageCurrent'] total_pages = response['pageTotal'] teams = response['teams'] ret_models = [] for teamData in teams: # Fix issue where FIRST's API returns dummy website for all teams if teamData[ 'website'] is not None and 'www.firstinspires.org' in teamData[ 'website']: website = None else: website = WebsiteHelper.format_url( teamData.get('website', None)) team = Team(id="frc{}".format(teamData['teamNumber']), team_number=teamData['teamNumber'], name=teamData['nameFull'], nickname=teamData['nameShort'], school_name=teamData.get('schoolName'), home_cmp=teamData.get('homeCMP').lower() if teamData.get('homeCMP') else None, city=teamData['city'], state_prov=teamData['stateProv'], country=teamData['country'], website=website, rookie_year=teamData['rookieYear']) districtTeam = None if teamData['districtCode']: districtKey = District.renderKeyName( self.year, teamData['districtCode'].lower()) districtTeam = DistrictTeam( id=DistrictTeam.renderKeyName(districtKey, team.key_name), team=ndb.Key(Team, team.key_name), year=self.year, district_key=ndb.Key(District, districtKey), ) robot = None if teamData['robotName']: robot = Robot(id=Robot.renderKeyName(team.key_name, self.year), team=ndb.Key(Team, team.key_name), year=self.year, robot_name=teamData['robotName'].strip()) ret_models.append((team, districtTeam, robot)) return (ret_models, (current_page < total_pages))
def parse(self, response): """ Parse team info from FMSAPI Returns a tuple of: list of models (Team, DistrictTeam, Robot), and a Boolean indicating if there are more pages to be fetched """ # Get team json # don't need to null check, if error, HTTP code != 200, so we wont' get here current_page = response['pageCurrent'] total_pages = response['pageTotal'] teams = response['teams'] ret_models = [] for teamData in teams: # Fix issue where FIRST's API returns dummy website for all teams if teamData['website'] is not None and 'www.firstinspires.org' in teamData['website']: website = None else: website = WebsiteHelper.format_url(teamData.get('website', None)) team = Team( id="frc{}".format(teamData['teamNumber']), team_number=teamData['teamNumber'], name=teamData['nameFull'], nickname=teamData['nameShort'], school_name=teamData.get('schoolName'), home_cmp=teamData.get('homeCMP').lower() if teamData.get('homeCMP') else None, city=teamData['city'], state_prov=teamData['stateProv'], country=teamData['country'], website=website, rookie_year=teamData['rookieYear'] ) districtTeam = None if teamData['districtCode']: districtAbbrev = DistrictType.abbrevs[teamData['districtCode'].lower()] districtTeam = DistrictTeam( id=DistrictTeam.renderKeyName(self.year, districtAbbrev, team.key_name), team=ndb.Key(Team, team.key_name), year=self.year, district=districtAbbrev, district_key=ndb.Key(District, District.renderKeyName(self.year, teamData['districtCode'].lower())), ) robot = None if teamData['robotName']: robot = Robot( id=Robot.renderKeyName(team.key_name, self.year), team=ndb.Key(Team, team.key_name), year=self.year, robot_name=teamData['robotName'].strip() ) ret_models.append((team, districtTeam, robot)) return (ret_models, (current_page < total_pages))
def setUp(self): app = webapp2.WSGIApplication([webapp2.Route(r'/<district_abbrev:>/<year:>', ApiDistrictEventsController, methods=['GET'])], debug=True) self.testapp = webtest.TestApp(app) self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_urlfetch_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.district = District( id='2010ne', year=2010, abbreviation='ne', display_name='New England', ) self.district.put() self.event = Event( id="2010sc", name="Palmetto Regional", event_type_enum=EventType.DISTRICT_CMP, district_key=ndb.Key(District, '2010ne'), short_name="Palmetto", event_short="sc", year=2010, end_date=datetime(2010, 03, 27), official=True, city="Clemson", state_prov="SC", country="USA", venue="Long Beach Arena", venue_address="Long Beach Arena\r\n300 East Ocean Blvd\r\nLong Beach, CA 90802\r\nUSA", start_date=datetime(2010, 03, 24), webcast_json="[{\"type\": \"twitch\", \"channel\": \"frcgamesense\"}]", website="http://www.firstsv.org", ) self.event.put() self.event_details = EventDetails( id=self.event.key.id(), alliance_selections=[ {"declines": [], "picks": ["frc971", "frc254", "frc1662"]}, {"declines": [], "picks": ["frc1678", "frc368", "frc4171"]}, {"declines": [], "picks": ["frc2035", "frc192", "frc4990"]}, {"declines": [], "picks": ["frc1323", "frc846", "frc2135"]}, {"declines": [], "picks": ["frc2144", "frc1388", "frc668"]}, {"declines": [], "picks": ["frc1280", "frc604", "frc100"]}, {"declines": [], "picks": ["frc114", "frc852", "frc841"]}, {"declines": [], "picks": ["frc2473", "frc3256", "frc1868"]} ] ) self.event_details.put()
def get_all_districts_by_region(self, region_value): self._db_cur.execute( 'SELECT * FROM district_code d WHERE d.region_value = %s', (region_value, )) districts = [] row = self._db_cur.fetchone() while row: district = District(row[0], row[1], row[2]) districts.append(district) row = self._db_cur.fetchone() return districts
def get(self, type): self._require_registration('/account/') user_id = self.user_bundle.account.key.id() logging.info("Sending for {}".format(type)) try: type = int(type) except ValueError: # Not passed a valid int, just stop here logging.info("Invalid number passed") self.redirect('/apidocs/webhooks') return event = Event.get_by_id('2014necmp') match = Match.get_by_id('2014necmp_f1m1') district = District.get_by_id('2014ne') if type == NotificationType.UPCOMING_MATCH: notification = UpcomingMatchNotification(match, event) elif type == NotificationType.MATCH_SCORE: notification = MatchScoreNotification(match) elif type == NotificationType.LEVEL_STARTING: notification = CompLevelStartingNotification(match, event) elif type == NotificationType.ALLIANCE_SELECTION: notification = AllianceSelectionNotification(event) elif type == NotificationType.AWARDS: notification = AwardsUpdatedNotification(event) elif type == NotificationType.MEDIA_POSTED: # Not implemented yet pass elif type == NotificationType.DISTRICT_POINTS_UPDATED: notification = DistrictPointsUpdatedNotification(district) elif type == NotificationType.SCHEDULE_UPDATED: notification = ScheduleUpdatedNotification(event, match) elif type == NotificationType.FINAL_RESULTS: # Not implemented yet pass elif type == NotificationType.MATCH_VIDEO: notification = MatchVideoNotification(match) elif type == NotificationType.EVENT_MATCH_VIDEO: notification = EventMatchVideoNotification(match) else: # Not passed a valid int, return self.redirect('/apidocs/webhooks') return keys = PushHelper.get_client_ids_for_users([user_id]) logging.info("Keys: {}".format(keys)) if notification: # This page should not push notifications to the firebase queue # Nor should its notifications be tracked in analytics notification.send(keys, push_firebase=False, track_call=False) self.redirect('/apidocs/webhooks')
def get(self, district_key): self._require_admin() district = District.get_by_id(district_key) self.template_values.update({ "district": district, }) path = os.path.join(os.path.dirname(__file__), '../../templates/admin/district_edit.html') self.response.out.write(template.render(path, self.template_values))
def parse(self, response): districts = [] for district in response['districts']: district_code = district['code'].lower() district_key = District.renderKeyName(self.season, district_code) districts.append(District( id=district_key, abbreviation=district_code, year=self.season, display_name=district['name'], )) return districts
def setUp(self): self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_memcache_stub() self.testbed.init_taskqueue_stub(root_path=".") ndb.get_context().clear_cache( ) # Prevent data from leaking between tests # Create districts districts = [] for code in [ 'mar', 'isr', 'nc', 'ne', 'pnw', 'pch', 'chs', 'in', 'ont', 'fim', 'tx' ]: year = 2017 districts.append( District( id=District.renderKeyName(year, code), year=year, abbreviation=code, )) DistrictManipulator.createOrUpdate(districts)
def getShortName(self, name_str, district_code=None): """ Extracts a short name like "Silicon Valley" from an event name like "Silicon Valley Regional sponsored by Google.org". See https://github.com/the-blue-alliance/the-blue-alliance-android/blob/master/android/src/test/java/com/thebluealliance/androidclient/test/helpers/EventHelperTest.java """ district_keys = memcache.get('EventHelper.getShortName():district_keys') if not district_keys: codes = set([d.id()[4:].upper() for d in District.query().fetch(keys_only=True)]) if district_code: codes.add(district_code.upper()) if 'MAR' in codes: # MAR renamed to FMA in 2019 codes.add('FMA') if 'TX' in codes: # TX and FIT used interchangeably codes.add('FIT') district_keys = '|'.join(codes) memcache.set('EventHelper.getShortName():district_keys', district_keys, 60*60) # 2015+ districts # Numbered events with no name re_string = '({}) District Event (#\d+)'.format(district_keys) match = re.match(re_string, name_str) if match: return '{} {}'.format(match.group(1).strip(), match.group(2).strip()) # The rest re_string = '(?:{}) District -?(.+)'.format(district_keys) match = re.match(re_string, name_str) if match: partial = match.group(1).strip() match2 = re.sub(r'(?<=[\w\s])Event\s*(?:[\w\s]*$)?', '', partial) return match2.strip() # 2014- districts # district championships, other districts, and regionals name_str = re.sub(r'\s?Event','', name_str) match = re.match(r'\s*(?:MAR |PNW |)(?:FIRST Robotics|FRC|)(.+)(?:District|Regional|Region|Provincial|State|Tournament|FRC|Field)(?:\b)(?:[\w\s]+?(#\d*)*)?', name_str) if match: short = ''.join(match.groups('')) match = re.match(r'(.+)(?:FIRST Robotics|FRC)', short) if match: result = match.group(1).strip() else: result = short.strip() if result.startswith('FIRST'): result = result[5:] return result.strip() return name_str.strip()
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.ne_district = District( id='2015ne', abbreviation='ne', year=2015, elasticsearch_name='NE FIRST' ) self.ne_district.put()
def post(self, *args, **kwargs): name = self.get_angular_argument('name') father_id = self.get_angular_argument('father_id') if not name: self.on_error(**ErrorCodeMessage.no_district_name) return district = District.add(father_district_id=father_id, district_name=name) if not district: self.on_error(**ErrorCodeMessage.database_error) return self.on_success(data=district.to_dict())
def setUp(self): self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_memcache_stub() self.testbed.init_taskqueue_stub(root_path=".") ndb.get_context().clear_cache() # Prevent data from leaking between tests # Create districts districts = [] for code in ['mar', 'isr', 'nc', 'ne', 'pnw', 'pch', 'chs', 'in', 'ont', 'fim', 'tx']: year = 2017 districts.append(District( id=District.renderKeyName(year, code), year=year, abbreviation=code, )) DistrictManipulator.createOrUpdate(districts)
def post(self, *args, **kwargs): district_id = self.get_angular_argument('id') new_name = self.get_angular_argument('name') district = District.init_from_district_id(district_id) if not district: self.on_error(**ErrorCodeMessage.district_not_exists) return if not new_name: self.on_error(**ErrorCodeMessage.no_district_name) return if not district.set_name(new_name): self.on_error(**ErrorCodeMessage.database_error) return self.on_success()
def district_to_db(region_value): fields = {'method': 'getRegionsList', 'region': region_value} payload = utils.create_form_data(fields) res = requests.post('https://extra.egrp365.ru/api/extra/index.php', data=payload, headers=utils.HEADERS) try: json_data = json.loads(res.text) if json_data['success']: db = DB() for x in json_data['data']: district = District(value=x['value'], name=x['name'], region_value=region_value) db.insert(district, 'district_code') except Exception as e: logging.error('District loading error. Response text: ' + res.text) raise e
def setUp(self): app = webapp2.WSGIApplication([webapp2.Route(r'/<district_abbrev:>/<year:([0-9]*)>', ApiDistrictTeamsController, methods=['GET'])], debug=True) self.testapp = webtest.TestApp(app) self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_urlfetch_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.team = Team( id="frc281", name="Michelin / Caterpillar / Greenville Technical College /\ jcpenney / Baldor / ASME / Gastroenterology Associates /\ Laserflex South & Greenville County Schools & Greenville\ Technical Charter High School", team_number=281, nickname="EnTech GreenVillians", city="Greenville", state_prov="SC", country="USA", website="www.entech.org", motto="Infiltrating Young Minds One Robot at a Time" ) self.district = District( id='2015ne', year=2015, abbreviation='ne' ) self.district_team = DistrictTeam( id="2015ne_frc281", team=self.team.key, year=2015, district_key=ndb.Key(District, '2015ne') ) self.team.put() self.district.put() self.district_team.put()
def get(self, year=None): self._require_admin() if year: year = int(year) else: year = datetime.now().year districts = District.query(District.year == year).fetch(10000) self.template_values.update({ "valid_years": self.VALID_YEARS, "selected_year": year, "districts": districts, }) path = os.path.join(os.path.dirname(__file__), '../../templates/admin/district_list.html') self.response.out.write(template.render(path, self.template_values))
def _render(self, district_abbrev, year=None): self._set_district(district_abbrev, self.year) if self.year < 2009: return json.dumps([], ensure_ascii=True) events_future = DistrictEventsQuery( District.renderKeyName(self.year, district_abbrev)).fetch_async() district_teams_future = DistrictTeamsQuery("{}{}".format( year, district_abbrev)).fetch_async() events = events_future.get_result() if not events: return json.dumps([], ensure_ascii=True) EventHelper.sort_events(events) team_totals = DistrictHelper.calculate_rankings( events, district_teams_future.get_result(), self.year) rankings = [] current_rank = 1 for key, points in team_totals: point_detail = {} point_detail["rank"] = current_rank point_detail["team_key"] = key point_detail["event_points"] = {} for event in points["event_points"]: event_key = event[0].key_name point_detail["event_points"][event_key] = event[1] event_details = Event.get_by_id(event_key) point_detail["event_points"][event[0].key_name][ 'district_cmp'] = True if event_details.event_type_enum == EventType.DISTRICT_CMP else False if "rookie_bonus" in points: point_detail["rookie_bonus"] = points["rookie_bonus"] else: point_detail["rookie_bonus"] = 0 point_detail["point_total"] = points["point_total"] rankings.append(point_detail) current_rank += 1 return json.dumps(rankings)
def getDistrictRankings(self, district_key): district = District.get_by_id(district_key) if not district: return None year = int(district_key[:4]) district_short = district_key[4:] advancement = {} for page in range(1, 15): # Ensure this won't loop forever url = self.FMS_API_DISTRICT_RANKINGS_PATTERN % (year, district_short.upper(), page) result = self._parse(url, FMSAPIDistrictRankingsParser(advancement)) if not result: break advancement, more_pages = result if not more_pages: break district.advancement = advancement return [district]
def get(self, district_key): district = District.get_by_id(district_key) if not district: self.response.out.write( "District {} does not exist!".format(district_key)) return events_future = DistrictEventsQuery(district_key).fetch_async() teams_future = DistrictTeamsQuery(district_key).fetch_async() events = events_future.get_result() for event in events: event.prep_details() EventHelper.sort_events(events) team_totals = DistrictHelper.calculate_rankings( events, teams_future, district.year) rankings = [] current_rank = 1 for key, points in team_totals: point_detail = {} point_detail["rank"] = current_rank point_detail["team_key"] = key point_detail["event_points"] = [] for event, event_points in points["event_points"]: event_points['event_key'] = event.key.id() event_points['district_cmp'] = ( event.event_type_enum == EventType.DISTRICT_CMP or event.event_type_enum == EventType.DISTRICT_CMP_DIVISION) point_detail["event_points"].append(event_points) point_detail["rookie_bonus"] = points.get("rookie_bonus", 0) point_detail["point_total"] = points["point_total"] rankings.append(point_detail) current_rank += 1 if rankings: district.rankings = rankings DistrictManipulator.createOrUpdate(district) if 'X-Appengine-Taskname' not in self.request.headers: # Only write out if not in taskqueue self.response.out.write( "Finished calculating rankings for: {}".format(district_key))
def post(self, *args, **kwargs): district_id = self.get_angular_argument('id') action = self.get_angular_argument('action') district = District.init_from_district_id(district_id) if not district: self.on_error(**ErrorCodeMessage.district_not_exists) return if action == 'del': res = district.delete() else: res = district.recover() if res: self.on_success() return self.on_error(**ErrorCodeMessage.database_error)
def getDistrictRankings(self, district_key): district = District.get_by_id(district_key) if not district: return None year = int(district_key[:4]) district_short = district_key[4:] advancement = {} for page in range(1, 15): # Ensure this won't loop forever url = self.FMS_API_DISTRICT_RANKINGS_PATTERN % ( year, district_short.upper(), page) result = self._parse(url, FMSAPIDistrictRankingsParser(advancement)) if not result: break advancement, more_pages = result if not more_pages: break district.advancement = advancement return [district]
def get(self, district_key): district = District.get_by_id(district_key) if not district: self.response.out.write("District {} does not exist!".format(district_key)) return events_future = DistrictEventsQuery(district_key).fetch_async() teams_future = DistrictTeamsQuery(district_key).fetch_async() events = events_future.get_result() for event in events: event.prep_details() EventHelper.sort_events(events) team_totals = DistrictHelper.calculate_rankings(events, teams_future, district.year) rankings = [] current_rank = 1 for key, points in team_totals: point_detail = {} point_detail["rank"] = current_rank point_detail["team_key"] = key point_detail["event_points"] = [] for event, event_points in points["event_points"]: event_points['event_key'] = event.key.id() event_points['district_cmp'] = ( event.event_type_enum == EventType.DISTRICT_CMP or event.event_type_enum == EventType.DISTRICT_CMP_DIVISION) point_detail["event_points"].append(event_points) point_detail["rookie_bonus"] = points.get("rookie_bonus", 0) point_detail["point_total"] = points["point_total"] rankings.append(point_detail) current_rank += 1 if rankings: district.rankings = rankings DistrictManipulator.createOrUpdate(district) if 'X-Appengine-Taskname' not in self.request.headers: # Only write out if not in taskqueue self.response.out.write("Finished calculating rankings for: {}".format(district_key))
def _render(self, district_abbrev, year=None): self._set_district(district_abbrev, self.year) if self.year < 2009: return json.dumps([], ensure_ascii=True) events_future = DistrictEventsQuery(District.renderKeyName(self.year, district_abbrev)).fetch_async() district_teams_future = DistrictTeamsQuery("{}{}".format(year, district_abbrev)).fetch_async() events = events_future.get_result() if not events: return json.dumps([], ensure_ascii=True) EventHelper.sort_events(events) team_totals = DistrictHelper.calculate_rankings(events, district_teams_future.get_result(), self.year) rankings = [] current_rank = 1 for key, points in team_totals: point_detail = {} point_detail["rank"] = current_rank point_detail["team_key"] = key point_detail["event_points"] = {} for event in points["event_points"]: event_key = event[0].key_name point_detail["event_points"][event_key] = event[1] event_details = Event.get_by_id(event_key) point_detail["event_points"][event[0].key_name]['district_cmp'] = True if event_details.event_type_enum == EventType.DISTRICT_CMP else False if "rookie_bonus" in points: point_detail["rookie_bonus"] = points["rookie_bonus"] else: point_detail["rookie_bonus"] = 0 point_detail["point_total"] = points["point_total"] rankings.append(point_detail) current_rank += 1 return json.dumps(rankings)
def getDistrictRankings(self, district_key): district = District.get_by_id(district_key) if not district: return None year = int(district_key[:4]) district_short = district_key[4:] advancement = {} more_pages = True page = 1 while more_pages: url = self.FMS_API_DISTRICT_RANKINGS_PATTERN % (year, district_short.upper(), page) result = self._parse(url, FMSAPIDistrictRankingsParser(advancement)) if not result: break advancement, more_pages = result page = page + 1 district.advancement = advancement return [district]
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.eventteam_2015casj_frc254 = EventTeam( id='2015casj_frc254', event=ndb.Key(Event, '2015casj'), team=ndb.Key(Team, 'frc254'), year=2015, ) self.eventteam_2015cama_frc604 = EventTeam( id='2015cama_frc604', event=ndb.Key(Event, '2015cama'), team=ndb.Key(Team, 'frc604'), year=2015, ) self.eventteam_2010cama_frc604 = EventTeam( id='2010cama_frc604', event=ndb.Key(Event, '2010cama'), team=ndb.Key(Team, 'frc604'), year=2010, ) self.eventteam_2016necmp_frc125 = EventTeam( id='2016necmp_frc125', event=ndb.Key(Event, '2016necmp'), team=ndb.Key(Team, 'frc125'), year=2016, ) self.eventteam_2015casj_frc254.put() self.eventteam_2015cama_frc604.put() self.eventteam_2010cama_frc604.put() self.eventteam_2016necmp_frc125.put() self.districtteam_2015fim_frc254 = DistrictTeam( id='2015fim_frc254', district_key=ndb.Key(District, '2015fim'), team=ndb.Key(Team, 'frc254'), year=2015, ) self.districtteam_2015mar_frc604 = DistrictTeam( id='2015mar_frc604', district_key=ndb.Key(District, '2015mar'), team=ndb.Key(Team, 'frc604'), year=2015, ) self.districtteam_2016ne_frc604 = DistrictTeam( id='2016ne_frc604', district_key=ndb.Key(District, '2016ne'), team=ndb.Key(Team, 'frc604'), year=2016, ) self.districtteam_2015fim_frc254.put() self.districtteam_2015mar_frc604.put() self.districtteam_2016ne_frc604.put() self.district_2015ne = District( id='2015ne', year=2015, abbreviation='ne', ) self.district_2016chs = District( id='2016chs', year=2016, abbreviation='chs', ) self.district_2015ne.put() self.district_2016chs.put() self.event_2016necmp = Event( id='2016necmp', year=2016, district_key=ndb.Key(District, '2016ne'), event_short='necmp', event_type_enum=EventType.DISTRICT_CMP, ) self.event_2016necmp.put()
def get(self, *args, **kwargs): district_instance_list = District.get_all_district() res = [] for district in district_instance_list: res.append(district.to_dict()) self.on_success(res)
class TestFIRSTElasticSearchEventListParser(unittest2.TestCase): 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.ne_district = District( id='2015ne', abbreviation='ne', year=2015, elasticsearch_name='NE FIRST' ) self.ne_district.put() def tearDown(self): self.testbed.deactivate() def test_parse_event_list(self): with open('test_data/first_elasticsearch/2015_event_list.json', 'r') as f: events = FIRSTElasticSearchEventListParser(2015).parse(json.loads(f.read())) self.assertTrue(isinstance(events, list)) self.assertEquals(len(events), 56 + 48 + 5) # 56 regionals, 48 districts, 5 district championships def test_parse_regional_event(self): with open('test_data/first_elasticsearch/2015_event_list.json', 'r') as f: events = FIRSTElasticSearchEventListParser(2015).parse(json.loads(f.read())) for event in events: if event.key_name == '2015nyny': self.assertEquals(event.key_name, "2015nyny") self.assertEquals(event.name, "New York City Regional") self.assertEquals(event.short_name, "New York City") self.assertEquals(event.event_short, "nyny") self.assertEquals(event.official, True) self.assertEquals(event.start_date, datetime.datetime(year=2015, month=3, day=12, hour=0, minute=0, second=0)) self.assertEquals(event.end_date, datetime.datetime(year=2015, month=3, day=15, hour=23, minute=59, second=59)) self.assertEquals(event.venue, "Jacob K. Javits Convention Center") self.assertEquals(event.city, "New York") self.assertEquals(event.state_prov, "NY") self.assertEquals(event.postalcode, "10001") self.assertEquals(event.country, "USA") self.assertEquals(event.venue_address, "Jacob K. Javits Convention Center\n655 West 34th Street\nNew York, NY 10001\nUSA") self.assertEquals(event.year, 2015) self.assertEquals(event.event_type_enum, EventType.REGIONAL) self.assertEquals(event.district_key, None) self.assertEquals(event.first_eid, '13339') self.assertEquals(event.website, 'http://www.nycfirst.org') def test_parse_district_event(self): with open('test_data/first_elasticsearch/2015_event_list.json', 'r') as f: events = FIRSTElasticSearchEventListParser(2015).parse(json.loads(f.read())) for event in events: if event.key_name == '2015cthar': self.assertEquals(event.key_name, "2015cthar") self.assertEquals(event.name, "NE District - Hartford Event") self.assertEquals(event.short_name, "Hartford") self.assertEquals(event.event_short, "cthar") self.assertEquals(event.official, True) self.assertEquals(event.start_date, datetime.datetime(year=2015, month=3, day=27, hour=0, minute=0, second=0)) self.assertEquals(event.end_date, datetime.datetime(year=2015, month=3, day=29, hour=23, minute=59, second=59)) self.assertEquals(event.venue, "Hartford Public High School") self.assertEquals(event.city, "Hartford") self.assertEquals(event.state_prov, "CT") self.assertEquals(event.postalcode, "06105") self.assertEquals(event.country, "USA") self.assertEquals(event.venue_address, "Hartford Public High School\n55 Forest Street\nHartford, CT 06105\nUSA") self.assertEquals(event.year, 2015) self.assertEquals(event.event_type_enum, EventType.DISTRICT) self.assertEquals(event.district_key.id(), '2015ne') self.assertEqual(event.district_key, self.ne_district.key) self.assertEquals(event.first_eid, '13443') self.assertEquals(event.website, 'http://www.nefirst.org/') def test_parse_district_cmp(self): with open('test_data/first_elasticsearch/2015_event_list.json', 'r') as f: events = FIRSTElasticSearchEventListParser(2015).parse(json.loads(f.read())) for event in events: if event.key_name == '2015necmp': self.assertEquals(event.key_name, "2015necmp") self.assertEquals(event.name, "NE FIRST District Championship presented by United Technologies") self.assertEquals(event.short_name, "NE FIRST") self.assertEquals(event.event_short, "necmp") self.assertEquals(event.official, True) self.assertEquals(event.start_date, datetime.datetime(year=2015, month=4, day=8, hour=0, minute=0, second=0)) self.assertEquals(event.end_date, datetime.datetime(year=2015, month=4, day=11, hour=23, minute=59, second=59)) self.assertEquals(event.venue, "Sports and Recreation Center, WPI") self.assertEquals(event.city, "Worcester") self.assertEquals(event.state_prov, "MA") self.assertEquals(event.postalcode, "01609") self.assertEquals(event.country, "USA") self.assertEquals(event.venue_address, "Sports and Recreation Center, WPI\n100 Institute Road\nWorcester, MA 01609\nUSA") self.assertEquals(event.year, 2015) self.assertEquals(event.event_type_enum, EventType.DISTRICT_CMP) self.assertEquals(event.district_key.id(), '2015ne') self.assertEqual(event.district_key, self.ne_district.key) self.assertEquals(event.first_eid, '13423') self.assertEquals(event.website, 'http:///www.nefirst.org/')
def get_districts_async(): district_keys = yield District.query().order(-District.year).fetch_async(keys_only=True) districts = yield ndb.get_multi_async(district_keys) raise ndb.Return(districts)
class TestDatabaseCacheClearer(unittest2.TestCase): 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.eventteam_2015casj_frc254 = EventTeam( id='2015casj_frc254', event=ndb.Key(Event, '2015casj'), team=ndb.Key(Team, 'frc254'), year=2015, ) self.eventteam_2015cama_frc604 = EventTeam( id='2015cama_frc604', event=ndb.Key(Event, '2015cama'), team=ndb.Key(Team, 'frc604'), year=2015, ) self.eventteam_2010cama_frc604 = EventTeam( id='2010cama_frc604', event=ndb.Key(Event, '2010cama'), team=ndb.Key(Team, 'frc604'), year=2010, ) self.eventteam_2016necmp_frc125 = EventTeam( id='2016necmp_frc125', event=ndb.Key(Event, '2016necmp'), team=ndb.Key(Team, 'frc125'), year=2016, ) self.eventteam_2015casj_frc254.put() self.eventteam_2015cama_frc604.put() self.eventteam_2010cama_frc604.put() self.eventteam_2016necmp_frc125.put() self.districtteam_2015fim_frc254 = DistrictTeam( id='2015fim_frc254', district_key=ndb.Key(District, '2015fim'), team=ndb.Key(Team, 'frc254'), year=2015, ) self.districtteam_2015mar_frc604 = DistrictTeam( id='2015mar_frc604', district_key=ndb.Key(District, '2015mar'), team=ndb.Key(Team, 'frc604'), year=2015, ) self.districtteam_2016ne_frc604 = DistrictTeam( id='2016ne_frc604', district_key=ndb.Key(District, '2016ne'), team=ndb.Key(Team, 'frc604'), year=2016, ) self.districtteam_2015fim_frc254.put() self.districtteam_2015mar_frc604.put() self.districtteam_2016ne_frc604.put() self.district_2015ne = District( id='2015ne', year=2015, abbreviation='ne', ) self.district_2016chs = District( id='2016chs', year=2016, abbreviation='chs', ) self.district_2015ne.put() self.district_2016chs.put() self.event_2016necmp = Event( id='2016necmp', year=2016, district_key=ndb.Key(District, '2016ne'), event_short='necmp', event_type_enum=EventType.DISTRICT_CMP, ) self.event_2016necmp.put() def tearDown(self): self.testbed.deactivate() def test_award_updated(self): affected_refs = { 'event': {ndb.Key(Event, '2015casj'), ndb.Key(Event, '2015cama')}, 'team_list': {ndb.Key(Team, 'frc254'), ndb.Key(Team, 'frc604')}, 'year': {2014, 2015} } cache_keys = [q.cache_key for q in get_affected_queries.award_updated(affected_refs)] self.assertEqual(len(cache_keys), 12) self.assertTrue(EventAwardsQuery('2015casj').cache_key in cache_keys) self.assertTrue(EventAwardsQuery('2015cama').cache_key in cache_keys) self.assertTrue(TeamAwardsQuery('frc254').cache_key in cache_keys) self.assertTrue(TeamAwardsQuery('frc604').cache_key in cache_keys) self.assertTrue(TeamYearAwardsQuery('frc254', 2014).cache_key in cache_keys) self.assertTrue(TeamYearAwardsQuery('frc254', 2015).cache_key in cache_keys) self.assertTrue(TeamYearAwardsQuery('frc604', 2014).cache_key in cache_keys) self.assertTrue(TeamYearAwardsQuery('frc604', 2015).cache_key in cache_keys) self.assertTrue(TeamEventAwardsQuery('frc254', '2015casj').cache_key in cache_keys) self.assertTrue(TeamEventAwardsQuery('frc254', '2015cama').cache_key in cache_keys) self.assertTrue(TeamEventAwardsQuery('frc604', '2015casj').cache_key in cache_keys) self.assertTrue(TeamEventAwardsQuery('frc604', '2015cama').cache_key in cache_keys) def test_event_updated(self): affected_refs = { 'key': {ndb.Key(Event, '2015casj'), ndb.Key(Event, '2015cama')}, 'year': {2014, 2015}, 'district_key': {ndb.Key(District, '2015fim'), ndb.Key(District, '2014mar')} } cache_keys = [q.cache_key for q in get_affected_queries.event_updated(affected_refs)] self.assertEqual(len(cache_keys), 10) self.assertTrue(EventQuery('2015casj').cache_key in cache_keys) self.assertTrue(EventQuery('2015cama').cache_key in cache_keys) self.assertTrue(EventListQuery(2014).cache_key in cache_keys) self.assertTrue(EventListQuery(2015).cache_key in cache_keys) self.assertTrue(DistrictEventsQuery('2015fim').cache_key in cache_keys) self.assertTrue(DistrictEventsQuery('2014mar').cache_key in cache_keys) self.assertTrue(TeamEventsQuery('frc254').cache_key in cache_keys) self.assertTrue(TeamEventsQuery('frc604').cache_key in cache_keys) self.assertTrue(TeamYearEventsQuery('frc254', 2015).cache_key in cache_keys) self.assertTrue(TeamYearEventsQuery('frc604', 2015).cache_key in cache_keys) def test_event_details_updated(self): affected_refs = { 'key': {ndb.Key(EventDetails, '2015casj'), ndb.Key(EventDetails, '2015cama')}, } cache_keys = [q.cache_key for q in get_affected_queries.event_details_updated(affected_refs)] self.assertEqual(len(cache_keys), 2) self.assertTrue(EventDetailsQuery('2015casj').cache_key in cache_keys) self.assertTrue(EventDetailsQuery('2015cama').cache_key in cache_keys) def test_match_updated(self): affected_refs = { 'key': {ndb.Key(Match, '2015casj_qm1'), ndb.Key(Match, '2015casj_qm2')}, 'event': {ndb.Key(Event, '2015casj'), ndb.Key(Event, '2015cama')}, 'team_keys': {ndb.Key(Team, 'frc254'), ndb.Key(Team, 'frc604')}, 'year': {2014, 2015}, } cache_keys = [q.cache_key for q in get_affected_queries.match_updated(affected_refs)] self.assertEqual(len(cache_keys), 12) self.assertTrue(MatchQuery('2015casj_qm1').cache_key in cache_keys) self.assertTrue(MatchQuery('2015casj_qm2').cache_key in cache_keys) self.assertTrue(EventMatchesQuery('2015casj').cache_key in cache_keys) self.assertTrue(EventMatchesQuery('2015cama').cache_key in cache_keys) self.assertTrue(TeamEventMatchesQuery('frc254', '2015casj').cache_key in cache_keys) self.assertTrue(TeamEventMatchesQuery('frc254', '2015cama').cache_key in cache_keys) self.assertTrue(TeamEventMatchesQuery('frc604', '2015casj').cache_key in cache_keys) self.assertTrue(TeamEventMatchesQuery('frc604', '2015cama').cache_key in cache_keys) self.assertTrue(TeamYearMatchesQuery('frc254', 2014).cache_key in cache_keys) self.assertTrue(TeamYearMatchesQuery('frc254', 2015).cache_key in cache_keys) self.assertTrue(TeamYearMatchesQuery('frc604', 2014).cache_key in cache_keys) self.assertTrue(TeamYearMatchesQuery('frc604', 2015).cache_key in cache_keys) def test_media_updated_team(self): affected_refs = { 'references': {ndb.Key(Team, 'frc254'), ndb.Key(Team, 'frc604')}, 'year': {2014, 2015}, } cache_keys = [q.cache_key for q in get_affected_queries.media_updated(affected_refs)] self.assertEqual(len(cache_keys), 10) self.assertTrue(TeamYearMediaQuery('frc254', 2014).cache_key in cache_keys) self.assertTrue(TeamYearMediaQuery('frc254', 2015).cache_key in cache_keys) self.assertTrue(TeamSocialMediaQuery('frc254').cache_key in cache_keys) self.assertTrue(TeamYearMediaQuery('frc604', 2014).cache_key in cache_keys) self.assertTrue(TeamYearMediaQuery('frc604', 2015).cache_key in cache_keys) self.assertTrue(TeamSocialMediaQuery('frc604').cache_key in cache_keys) self.assertTrue(EventTeamsMediasQuery('2015cama').cache_key in cache_keys) self.assertTrue(EventTeamsMediasQuery('2015casj').cache_key in cache_keys) self.assertTrue(EventTeamsPreferredMediasQuery('2015cama').cache_key in cache_keys) self.assertTrue(EventTeamsPreferredMediasQuery('2015casj').cache_key in cache_keys) def test_media_updated_event(self): affected_refs = { 'references': {ndb.Key(Event, '2016necmp')}, 'year': {2016}, } cache_keys = [q.cache_key for q in get_affected_queries.media_updated(affected_refs)] self.assertEqual(len(cache_keys), 1) self.assertTrue(EventMediasQuery('2016necmp').cache_key in cache_keys) def test_robot_updated(self): affected_refs = { 'team': {ndb.Key(Team, 'frc254'), ndb.Key(Team, 'frc604')}, } cache_keys = [q.cache_key for q in get_affected_queries.robot_updated(affected_refs)] self.assertEqual(len(cache_keys), 2) self.assertTrue(TeamRobotsQuery('frc254').cache_key in cache_keys) self.assertTrue(TeamRobotsQuery('frc604').cache_key in cache_keys) def test_team_updated(self): affected_refs = { 'key': {ndb.Key(Team, 'frc254'), ndb.Key(Team, 'frc604')}, } cache_keys = [q.cache_key for q in get_affected_queries.team_updated(affected_refs)] self.assertEqual(len(cache_keys), 13) self.assertTrue(TeamQuery('frc254').cache_key in cache_keys) self.assertTrue(TeamQuery('frc604').cache_key in cache_keys) self.assertTrue(TeamListQuery(0).cache_key in cache_keys) self.assertTrue(TeamListQuery(1).cache_key in cache_keys) self.assertTrue(TeamListYearQuery(2015, 0).cache_key in cache_keys) self.assertTrue(TeamListYearQuery(2015, 1).cache_key in cache_keys) self.assertTrue(TeamListYearQuery(2010, 1).cache_key in cache_keys) self.assertTrue(DistrictTeamsQuery('2015fim').cache_key in cache_keys) self.assertTrue(DistrictTeamsQuery('2015mar').cache_key in cache_keys) self.assertTrue(DistrictTeamsQuery('2016ne').cache_key in cache_keys) self.assertTrue(EventTeamsQuery('2015casj').cache_key in cache_keys) self.assertTrue(EventTeamsQuery('2015cama').cache_key in cache_keys) self.assertTrue(EventTeamsQuery('2010cama').cache_key in cache_keys) def test_eventteam_updated(self): affected_refs = { 'event': {ndb.Key(Event, '2015casj'), ndb.Key(Event, '2015cama')}, 'team': {ndb.Key(Team, 'frc254'), ndb.Key(Team, 'frc604')}, 'year': {2014, 2015} } cache_keys = [q.cache_key for q in get_affected_queries.eventteam_updated(affected_refs)] self.assertEqual(len(cache_keys), 18) self.assertTrue(TeamEventsQuery('frc254').cache_key in cache_keys) self.assertTrue(TeamEventsQuery('frc604').cache_key in cache_keys) self.assertTrue(TeamParticipationQuery('frc254').cache_key in cache_keys) self.assertTrue(TeamParticipationQuery('frc604').cache_key in cache_keys) self.assertTrue(TeamYearEventsQuery('frc254', 2014).cache_key in cache_keys) self.assertTrue(TeamYearEventsQuery('frc254', 2015).cache_key in cache_keys) self.assertTrue(TeamYearEventsQuery('frc604', 2014).cache_key in cache_keys) self.assertTrue(TeamYearEventsQuery('frc604', 2015).cache_key in cache_keys) self.assertTrue(TeamListYearQuery(2014, 0).cache_key in cache_keys) self.assertTrue(TeamListYearQuery(2014, 1).cache_key in cache_keys) self.assertTrue(TeamListYearQuery(2015, 0).cache_key in cache_keys) self.assertTrue(TeamListYearQuery(2015, 1).cache_key in cache_keys) self.assertTrue(EventTeamsQuery('2015casj').cache_key in cache_keys) self.assertTrue(EventTeamsQuery('2015cama').cache_key in cache_keys) self.assertTrue(EventTeamsMediasQuery('2015cama').cache_key in cache_keys) self.assertTrue(EventTeamsMediasQuery('2015casj').cache_key in cache_keys) self.assertTrue(EventTeamsPreferredMediasQuery('2015cama').cache_key in cache_keys) self.assertTrue(EventTeamsPreferredMediasQuery('2015casj').cache_key in cache_keys) def test_districtteam_updated(self): affected_refs = { 'district_key': {ndb.Key(District, '2015fim'), ndb.Key(District, '2015mar')}, 'team': {ndb.Key(Team, 'frc254'), ndb.Key(Team, 'frc604')} } cache_keys = [q.cache_key for q in get_affected_queries.districtteam_updated(affected_refs)] self.assertEqual(len(cache_keys), 4) self.assertTrue(DistrictTeamsQuery('2015fim').cache_key in cache_keys) self.assertTrue(DistrictTeamsQuery('2015mar').cache_key in cache_keys) self.assertTrue(TeamDistrictsQuery('frc254').cache_key in cache_keys) self.assertTrue(TeamDistrictsQuery('frc604').cache_key in cache_keys) def test_district_updated(self): affected_refs = { 'key': {ndb.Key(District, '2016ne')}, 'year': {2015, 2016}, 'abbreviation': {'ne', 'chs'} } cache_keys = [q.cache_key for q in get_affected_queries.district_updated(affected_refs)] self.assertEqual(len(cache_keys), 11) self.assertTrue(DistrictsInYearQuery(2015).cache_key in cache_keys) self.assertTrue(DistrictsInYearQuery(2016).cache_key in cache_keys) self.assertTrue(DistrictHistoryQuery('ne').cache_key in cache_keys) self.assertTrue(DistrictHistoryQuery('chs').cache_key in cache_keys) self.assertTrue(DistrictQuery('2016ne').cache_key in cache_keys) self.assertTrue(TeamDistrictsQuery('frc604').cache_key in cache_keys) # Necessary because APIv3 Event models include the District model self.assertTrue(EventQuery('2016necmp').cache_key in cache_keys) self.assertTrue(EventListQuery(2016).cache_key in cache_keys) self.assertTrue(DistrictEventsQuery('2016ne').cache_key in cache_keys) self.assertTrue(TeamEventsQuery('frc125').cache_key in cache_keys) self.assertTrue(TeamYearEventsQuery('frc125', 2016).cache_key in cache_keys)
def validate_request(cls, handler): kwargs = handler.request.route_kwargs error_dict = {'Errors': []} valid = True team_future = None event_future = None match_future = None district_future = None # Check key formats if 'team_key' in kwargs: team_key = kwargs['team_key'] results = cls.team_id_validator(team_key) if results: error_dict['Errors'].append(results) valid = False else: team_future = Team.get_by_id_async(team_key) if 'event_key' in kwargs: event_key = kwargs['event_key'] results = cls.event_id_validator(event_key) if results: error_dict['Errors'].append(results) valid = False else: event_future = Event.get_by_id_async(event_key) if 'match_key' in kwargs: match_key = kwargs['match_key'] results = cls.match_id_validator(match_key) if results: error_dict['Errors'].append(results) valid = False else: match_future = Match.get_by_id_async(match_key) if 'district_key' in kwargs: district_key = kwargs['district_key'] results = cls.district_id_validator(district_key) if results: error_dict['Errors'].append(results) valid = False else: district_future = District.get_by_id_async(district_key) if 'year' in kwargs: year = int(kwargs['year']) if year > tba_config.MAX_YEAR or year < 1992: error_dict['Errors'].append({ 'year': 'Invalid year: {}. Must be between 1992 and {} inclusive.'. format(year, tba_config.MAX_YEAR) }) valid = False # Check if keys exist if team_future and team_future.get_result() is None: error_dict['Errors'].append( {'team_id': 'team id {} does not exist'.format(team_key)}) valid = False if event_future and event_future.get_result() is None: error_dict['Errors'].append( {'event_id': 'event id {} does not exist'.format(event_key)}) valid = False if match_future and match_future.get_result() is None: error_dict['Errors'].append( {'match_id': 'match id {} does not exist'.format(match_key)}) valid = False if district_future and district_future.get_result() is None: error_dict['Errors'].append({ 'district_id': 'district id {} does not exist'.format(district_key) }) valid = False if not valid: return error_dict
class TestDistrictTeamsApiController(unittest2.TestCase): def setUp(self): app = webapp2.WSGIApplication([webapp2.Route(r'/<district_abbrev:>/<year:([0-9]*)>', ApiDistrictTeamsController, methods=['GET'])], debug=True) self.testapp = webtest.TestApp(app) self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_urlfetch_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.team = Team( id="frc281", name="Michelin / Caterpillar / Greenville Technical College /\ jcpenney / Baldor / ASME / Gastroenterology Associates /\ Laserflex South & Greenville County Schools & Greenville\ Technical Charter High School", team_number=281, nickname="EnTech GreenVillians", city="Greenville", state_prov="SC", country="USA", website="www.entech.org", motto="Infiltrating Young Minds One Robot at a Time" ) self.district = District( id='2015ne', year=2015, abbreviation='ne' ) self.district_team = DistrictTeam( id="2015ne_frc281", team=self.team.key, year=2015, district_key=ndb.Key(District, '2015ne') ) self.team.put() self.district.put() self.district_team.put() def tearDown(self): self.testbed.deactivate() def assertTeamJson(self, team): team = team[0] self.assertEqual(team["key"], self.team.key_name) self.assertEqual(team["team_number"], self.team.team_number) self.assertEqual(team["nickname"], self.team.nickname) self.assertEqual(team["location"], self.team.location) self.assertEqual(team["locality"], "Greenville") self.assertEqual(team["country_name"], "USA") self.assertEqual(team["region"], "SC") self.assertEqual(team["website"], self.team.website) self.assertEqual(team["motto"], None) def test_districts_api(self): response = self.testapp.get('/ne/2015', headers={"X-TBA-App-Id": "tba-tests:team-districts-controller-test:v01"}) teams = json.loads(response.body) self.assertTeamJson(teams)
def _query_async(self): year = self._query_args[0] district_keys = yield District.query(District.year == year).fetch_async(keys_only=True) districts = yield ndb.get_multi_async(district_keys) raise ndb.Return(districts)
def post(self, type): self._require_registration('/account/') event_key = self.request.get('event_key') match_key = self.request.get('match_key') district_key = self.request.get('district_key') user_id = self.user_bundle.account.key.id() logging.info("Sending for {}".format(type)) try: type = int(type) except ValueError: # Not passed a valid int, just stop here logging.info("Invalid number passed") return event = None if type != NotificationType.DISTRICT_POINTS_UPDATED: if event_key == "": logging.info("No event key") self.response.out.write("No event key specified!") return event = Event.get_by_id(event_key) if event is None: logging.info("Invalid event key passed") self.response.out.write("Invalid event key!") return if type == NotificationType.UPCOMING_MATCH: if match_key == "": logging.info("No match key") self.response.out.write("No match key specified!") return match = Match.get_by_id(match_key) if match is None: logging.info("Invalid match key passed") self.response.out.write("Invalid match key!") return notification = UpcomingMatchNotification(match, event) elif type == NotificationType.MATCH_SCORE: if match_key == "": logging.info("No match key") self.response.out.write("No match key specified!") return match = Match.get_by_id(match_key) if match is None: logging.info("Invalid match key passed") self.response.out.write("Invalid match key!") return notification = MatchScoreNotification(match) elif type == NotificationType.LEVEL_STARTING: if match_key == "": logging.info("No match key") self.response.out.write("No match key specified!") return match = Match.get_by_id(match_key) if match is None: logging.info("Invalid match key passed") self.response.out.write("Invalid match key!") return notification = CompLevelStartingNotification(match, event) elif type == NotificationType.ALLIANCE_SELECTION: notification = AllianceSelectionNotification(event) elif type == NotificationType.AWARDS: notification = AwardsUpdatedNotification(event) elif type == NotificationType.MEDIA_POSTED: # Not implemented yet pass elif type == NotificationType.DISTRICT_POINTS_UPDATED: if district_key == "": logging.info("No district key") self.response.out.write("No district key specified!") return district = District.get_by_id(district_key) if district is None: logging.info("Invalid district key passed") self.response.out.write("Invalid district key!") return notification = DistrictPointsUpdatedNotification(district) elif type == NotificationType.SCHEDULE_UPDATED: if match_key == "": logging.info("No match key") self.response.out.write("No match key specified!") return match = Match.get_by_id(match_key) if match is None: logging.info("Invalid match key passed") self.response.out.write("Invalid match key!") return notification = ScheduleUpdatedNotification(event, match) elif type == NotificationType.FINAL_RESULTS: # Not implemented yet pass elif type == NotificationType.MATCH_VIDEO: if match_key == "": logging.info("No match key") self.response.out.write("No match key specified!") return match = Match.get_by_id(match_key) if match is None: logging.info("Invalid match key passed") self.response.out.write("Invalid match key!") return notification = MatchVideoNotification(match) elif type == NotificationType.EVENT_MATCH_VIDEO: if match_key == "": logging.info("No match key") self.response.out.write("No match key specified!") return match = Match.get_by_id(match_key) if match is None: logging.info("Invalid match key passed") self.response.out.write("Invalid match key!") return notification = EventMatchVideoNotification(match) else: # Not passed a valid int, return return keys = PushHelper.get_client_ids_for_users([user_id]) logging.info("Keys: {}".format(keys)) if notification: # This page should not push notifications to the firebase queue # Nor should its notifications be tracked in analytics notification.send(keys, push_firebase=False, track_call=False) self.response.out.write("ok")
def is_valid_model_key(cls, key): return (Team.validate_key_name(key) or Event.validate_key_name(key) or Match.validate_key_name(key) or District.validate_key_name(key))
def _query_async(self): abbreviation = self._query_args[0] district_keys = yield District.query(District.abbreviation.IN(get_equivalent_codes(abbreviation))).fetch_async(keys_only=True) districts = yield ndb.get_multi_async(district_keys) raise ndb.Return(districts)
def parse(self, response): events = [] districts = {} cmp_hack_sitevar = Sitevar.get_or_insert('cmp_registration_hacks') divisions_to_skip = cmp_hack_sitevar.contents.get('divisions_to_skip', []) \ if cmp_hack_sitevar else [] event_name_override = cmp_hack_sitevar.contents.get('event_name_override', []) \ if cmp_hack_sitevar else [] events_to_change_dates = cmp_hack_sitevar.contents.get('set_start_to_last_day', []) \ if cmp_hack_sitevar else [] for event in response['Events']: code = event['code'].lower() event_type = EventType.PRESEASON if code == 'week0' else self.EVENT_TYPES.get(event['type'].lower(), None) if event_type is None: logging.warn("Event type '{}' not recognized!".format(event['type'])) continue name = event['name'] short_name = EventHelper.getShortName(name) district_enum = EventHelper.parseDistrictName(event['districtCode'].lower()) if event['districtCode'] else DistrictType.NO_DISTRICT district_key = District.renderKeyName(self.season, event['districtCode'].lower()) if event['districtCode'] else None venue = event['venue'] city = event['city'] state_prov = event['stateprov'] country = event['country'] start = datetime.datetime.strptime(event['dateStart'], self.DATE_FORMAT_STR) end = datetime.datetime.strptime(event['dateEnd'], self.DATE_FORMAT_STR) website = event.get('website') # TODO read timezone from API # Special cases for district championship divisions if event_type == EventType.DISTRICT_CMP_DIVISION: split_name = name.split('-') short_name = '{} - {}'.format( ''.join(item[0].upper() for item in split_name[0].split()), split_name[-1].replace('Division', '').strip()) # Special cases for champs if code in self.EVENT_CODE_EXCEPTIONS: code, short_name = self.EVENT_CODE_EXCEPTIONS[code] # FIRST indicates CMP registration before divisions are assigned by adding all teams # to Einstein. We will hack around that by not storing divisions and renaming # Einstein to simply "Championship" when certain sitevar flags are set if code in self.EINSTEIN_CODES: override = [item for item in event_name_override if item['event'] == "{}{}".format(self.season, code)] if override: name = short_name.format(override[0]['name']) short_name = short_name.format(override[0]['short_name']) else: # Divisions name = '{} Division'.format(short_name) event_key = "{}{}".format(self.season, code) if event_key in divisions_to_skip: continue # Allow an overriding the start date to be the beginning of the last day if event_key in events_to_change_dates: start = end.replace(hour=0, minute=0, second=0, microsecond=0) events.append(Event( id=event_key, name=name, short_name=short_name, event_short=code, event_type_enum=event_type, official=True, start_date=start, end_date=end, venue=venue, city=city, state_prov=state_prov, country=country, venue_address=None, # Even though FRC API provides address, ElasticSearch is more detailed year=self.season, event_district_enum=district_enum, district_key=ndb.Key(District, district_key) if district_key else None, website=website, )) # Build District Model if district_key and district_key not in districts: districts[district_key] = District( id=district_key, year=self.season, abbreviation=event['districtCode'].lower(), ) return events, list(districts.values())
class TestDistrictTeamsApiController(unittest2.TestCase): def setUp(self): app = webapp2.WSGIApplication([ webapp2.Route(r'/<district_abbrev:>/<year:([0-9]*)>', ApiDistrictTeamsController, methods=['GET']) ], debug=True) self.testapp = webtest.TestApp(app) self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_urlfetch_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.team = Team( id="frc281", name="Michelin / Caterpillar / Greenville Technical College /\ jcpenney / Baldor / ASME / Gastroenterology Associates /\ Laserflex South & Greenville County Schools & Greenville\ Technical Charter High School", team_number=281, nickname="EnTech GreenVillians", city="Greenville", state_prov="SC", country="USA", website="www.entech.org", motto="Infiltrating Young Minds One Robot at a Time") self.district = District(id='2015ne', year=2015, abbreviation='ne') self.district_team = DistrictTeam(id="2015ne_frc281", team=self.team.key, year=2015, district_key=ndb.Key( District, '2015ne')) self.team.put() self.district.put() self.district_team.put() def tearDown(self): self.testbed.deactivate() def assertTeamJson(self, team): team = team[0] self.assertEqual(team["key"], self.team.key_name) self.assertEqual(team["team_number"], self.team.team_number) self.assertEqual(team["nickname"], self.team.nickname) self.assertEqual(team["location"], self.team.location) self.assertEqual(team["locality"], "Greenville") self.assertEqual(team["country_name"], "USA") self.assertEqual(team["region"], "SC") self.assertEqual(team["website"], self.team.website) self.assertEqual(team["motto"], None) def test_districts_api(self): response = self.testapp.get( '/ne/2015', headers={ "X-TBA-App-Id": "tba-tests:team-districts-controller-test:v01" }) teams = json.loads(response.body) self.assertTeamJson(teams)
def district_id_validator(cls, value): error_message = "{} is not a valid district abbreviation".format(value) district_key_error = {"district_abbrev": error_message} if District.validate_key_name(value) is False: return district_key_error