class TestListDistrictsController(unittest2.TestCase): def setUp(self): app = webapp2.WSGIApplication([webapp2.Route(r'/<year:>', ApiDistrictListController, 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() self.testbed.init_taskqueue_stub(root_path=".") self.event = Event( id="2010sc", name="Palmetto Regional", event_type_enum=EventType.DISTRICT_CMP, event_district_enum=DistrictType.NEW_ENGLAND, 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 tearDown(self): self.testbed.deactivate() def assertDistrictKeys(self, district): self.assertEqual(district["key"], DistrictType.type_abbrevs[DistrictType.NEW_ENGLAND]) self.assertEqual(district["name"], DistrictType.type_names[DistrictType.NEW_ENGLAND]) def testDistrictApi(self): response = self.testapp.get('/{}'.format(self.event.year), headers={"X-TBA-App-Id": "tba-tests:disstrict-controller-test:v01"}) districts = json.loads(response.body) self.assertDistrictKeys(districts[0])
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 setUp(self): app = webapp2.WSGIApplication([webapp2.Route(r'/<event_key:>', ApiEventRankingsController, 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() self.testbed.init_taskqueue_stub(root_path=".") self.rankings = [ ["Rank", "Team", "QS", "ASSIST", "AUTO", "T&C", "TELEOP", "Record (W-L-T)", "DQ", "PLAYED"], ["1", "1126", "20.00", "240.00", "480.00", "230.00", "478.00", "10-2-0", "0", "12"], ["2", "5030", "20.00", "200.00", "290.00", "220.00", "592.00", "10-2-0", "0", "12"], ["3", "250", "20.00", "70.00", "415.00", "220.00", "352.00", "10-2-0", "0", "12"] ] self.event = Event( id="2010sc", name="Palmetto Regional", event_type_enum=EventType.REGIONAL, short_name="Palmetto", event_short="sc", year=2010, end_date=datetime(2010, 03, 27), official=True, city="Clemson", state_prov="SC", country="USA", start_date=datetime(2010, 03, 24) ) self.event.put() self.event_details = EventDetails( id=self.event.key.id(), rankings=self.rankings ) self.event_details.put() self.eventNoRanks = Event( id="2010ct", name="Palmetto Regional", event_type_enum=EventType.REGIONAL, short_name="Palmetto", event_short="ct", year=2010, end_date=datetime(2010, 03, 27), official=True, city="Clemson", state_prov="SC", country="USA", start_date=datetime(2010, 03, 24), ) self.eventNoRanks.put()
def _process_request(self, request, event_key): rankings = JSONRankingsParser.parse(request.body) event_details = EventDetails(id=event_key, rankings=rankings) if event_details.year >= 2017: # TODO: Temporary fix. Should directly parse request into rankings2 event_details.rankings2 = RankingsHelper.convert_rankings( event_details) EventDetailsManipulator.createOrUpdate(event_details) self.response.out.write( json.dumps({'Success': "Rankings successfully updated"}))
def setUp(self): app = webapp2.WSGIApplication([ webapp2.Route( r'/<event_key:>', ApiEventStatsController, 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.matchstats = { "dprs": { "971": 10.52178695299036, "114": 23.7313645955704, "115": 29.559784481082044 }, "oprs": { "971": 91.42946669932006, "114": 59.27751047482864, "115": 13.285278757495144 }, "ccwms": { "971": 80.90767974632955, "114": 35.54614587925829, "115": -16.27450572358693 }, } self.event = Event(id="2010sc", name="Palmetto Regional", event_type_enum=EventType.REGIONAL, short_name="Palmetto", event_short="sc", year=2010, end_date=datetime(2010, 03, 27), official=True, city="Clemson", state_prov="SC", country="USA", start_date=datetime(2010, 03, 24)) self.event.put() self.event_details = EventDetails(id=self.event.key.id(), matchstats=self.matchstats) self.event_details.put()
def _process_request(self, request, event_key): rankings = JSONRankingsParser.parse(request.body) event_details = EventDetails( id=event_key, rankings=rankings ) if event_details.year >= 2017: # TODO: Temporary fix. Should directly parse request into rankings2 event_details.rankings2 = RankingsHelper.convert_rankings(event_details) EventDetailsManipulator.createOrUpdate(event_details) self.response.out.write(json.dumps({'Success': "Rankings successfully updated"}))
def post(self): self._require_admin() event_key = self.request.get("event_key").strip() event = Event.get_by_id(event_key) if not event: self.redirect("/admin/event/" + event.key_name) return if event.playoff_type != PlayoffType.ROUND_ROBIN_6_TEAM: logging.warning("Can't set advancement for non-round robin events") self.redirect("/admin/event/" + event.key_name) return advancement_csv = self.request.get("advancement_csv") comp_level = self.request.get("comp_level") matches_per_team = int(self.request.get("num_matches")) if comp_level not in Match.ELIM_LEVELS: logging.warning("Bad comp level: {}".format(comp_level)) self.redirect("/admin/event/" + event.key_name) return parsed_advancement = CSVAdvancementParser.parse( advancement_csv, matches_per_team) advancement = PlayoffAdvancementHelper.generatePlayoffAdvancementFromCSV( event, parsed_advancement, comp_level) cleaned_matches = MatchHelper.deleteInvalidMatches( event.matches, event) matches = MatchHelper.organizeMatches(cleaned_matches) bracket_table = PlayoffAdvancementHelper.generateBracket( matches, event, event.alliance_selections) comp_levels = bracket_table.keys() for comp_level in comp_levels: if comp_level != 'f': del bracket_table[comp_level] existing_details = EventDetails.get_by_id(event.key_name) new_advancement = existing_details.playoff_advancement if existing_details and existing_details.playoff_advancement else {} new_advancement.update(advancement) event_details = EventDetails( id=event.key_name, playoff_advancement={ 'advancement': new_advancement, 'bracket': bracket_table, }, ) EventDetailsManipulator.createOrUpdate(event_details) self.redirect("/admin/event/" + event.key_name) return
def setUp(self): self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_taskqueue_stub(root_path=".") self.testbed.init_memcache_stub() ndb.get_context().clear_cache() # Prevent data from leaking between tests self.maxDiff = None with open('test_data/usfirst_html/usfirst_event_rankings_2012ct.html', 'r') as f: good_rankings, _ = UsfirstEventRankingsParser.parse(f.read()) with open('test_data/usfirst_html/usfirst_event_rankings_2012ct_bad.html', 'r') as f: bad_rankings, _ = UsfirstEventRankingsParser.parse(f.read()) self.old_alliance_selections = { '1': {'picks': ['frc254', 'frc469', 'frc2848', 'frc74'], 'declines': []}, '2': {'picks': ['frc1718', 'frc2451', 'frc573', 'frc2016'], 'declines': []}, '3': {'picks': ['frc2928', 'frc2013', 'frc1311', 'frc842'], 'declines': []}, '4': {'picks': ['frc180', 'frc125', 'frc1323', 'frc2468'], 'declines': []}, '5': {'picks': ['frc118', 'frc359', 'frc4334', 'frc865'], 'declines': []}, '6': {'picks': ['frc135', 'frc1241', 'frc11', 'frc68'], 'declines': []}, '7': {'picks': ['frc3478', 'frc177', 'frc294', 'frc230'], 'declines': []}, '8': {'picks': ['frc624', 'frc987', 'frc3476', 'frc123'], 'declines': []}, } self.new_alliance_selections = { '1': {'picks': ['frc254', 'frc469', 'frc2848', 'frc74'], 'declines': []}, '2': {'picks': ['frc1718', 'frc2451', 'frc573', 'frc2016'], 'declines': []}, '3': {'picks': ['frc2928', 'frc2013', 'frc1311', 'frc842'], 'declines': []}, '4': {'picks': ['frc180', 'frc125', 'frc1323', 'frc2468'], 'declines': []}, '5': {'picks': ['frc118', 'frc359', 'frc4334', 'frc865'], 'declines': []}, '6': {'picks': ['frc135', 'frc1241', 'frc11', 'frc68'], 'declines': []}, '7': {'picks': ['frc3478', 'frc177', 'frc294', 'frc230'], 'declines': []}, '8': {'picks': ['frc624', 'frc987', 'frc3476', 'frc3015'], 'declines': []}, } self.old_event_details = EventDetails( id='2011ct', rankings=good_rankings, alliance_selections=self.old_alliance_selections, ) self.new_event_details = EventDetails( id='2011ct', rankings=bad_rankings, alliance_selections=self.new_alliance_selections, matchstats={'oprs': {'4255': 7.4877151786460301, '2643': 27.285682906835952, '852': 10.452538750544525, '4159': 25.820137009871139, '581': 18.513816255143144}} )
class TestEventStatsApiController(unittest2.TestCase): def setUp(self): app = webapp2.WSGIApplication([webapp2.Route(r'/<event_key:>', ApiEventStatsController, 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.matchstats = { "dprs": {"971": 10.52178695299036, "114": 23.7313645955704, "115": 29.559784481082044}, "oprs": {"971": 91.42946669932006, "114": 59.27751047482864, "115": 13.285278757495144}, "ccwms": {"971": 80.90767974632955, "114": 35.54614587925829, "115": -16.27450572358693}, } self.event = Event( id="2010sc", name="Palmetto Regional", event_type_enum=EventType.REGIONAL, short_name="Palmetto", event_short="sc", year=2010, end_date=datetime(2010, 03, 27), official=True, city="Clemson", state_prov="SC", country="USA", start_date=datetime(2010, 03, 24) ) self.event.put() self.event_details = EventDetails( id=self.event.key.id(), matchstats=self.matchstats ) self.event_details.put() def tearDown(self): self.testbed.deactivate() def testEventStatsApi(self): response = self.testapp.get('/2010sc', headers={"X-TBA-App-Id": "tba-tests:event-controller-test:v01"}) matchstats = json.loads(response.body) self.assertEqual(self.matchstats, matchstats)
class TestEventStatsApiController(unittest2.TestCase): def setUp(self): app = webapp2.WSGIApplication([webapp2.Route(r'/<event_key:>', ApiEventStatsController, 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() self.testbed.init_taskqueue_stub(root_path=".") self.matchstats = { "dprs": {"971": 10.52178695299036, "114": 23.7313645955704, "115": 29.559784481082044}, "oprs": {"971": 91.42946669932006, "114": 59.27751047482864, "115": 13.285278757495144}, "ccwms": {"971": 80.90767974632955, "114": 35.54614587925829, "115": -16.27450572358693}, } self.event = Event( id="2010sc", name="Palmetto Regional", event_type_enum=EventType.REGIONAL, short_name="Palmetto", event_short="sc", year=2010, end_date=datetime(2010, 03, 27), official=True, city="Clemson", state_prov="SC", country="USA", start_date=datetime(2010, 03, 24) ) self.event.put() self.event_details = EventDetails( id=self.event.key.id(), matchstats=self.matchstats ) self.event_details.put() def tearDown(self): self.testbed.deactivate() def testEventStatsApi(self): response = self.testapp.get('/2010sc', headers={"X-TBA-App-Id": "tba-tests:event-controller-test:v01"}) matchstats = json.loads(response.body) self.assertEqual(self.matchstats, matchstats)
def get(self, event_key): event = Event.get_by_id(event_key) matchstats_dict = MatchstatsHelper.calculate_matchstats(event.matches, event.year) if any([v != {} for v in matchstats_dict.values()]): pass else: logging.warn("Matchstat calculation for {} failed!".format(event_key)) matchstats_dict = None predictions_dict = None if event.year == 2016: organized_matches = MatchHelper.organizeMatches(event.matches) match_predictions, match_prediction_stats = PredictionHelper.get_match_predictions(organized_matches['qm']) ranking_predictions, ranking_prediction_stats = PredictionHelper.get_ranking_predictions(organized_matches['qm'], match_predictions) predictions_dict = { 'match_predictions': match_predictions, 'match_prediction_stats': match_prediction_stats, 'ranking_predictions': ranking_predictions, 'ranking_prediction_stats': ranking_prediction_stats } event_details = EventDetails( id=event_key, matchstats=matchstats_dict, predictions=predictions_dict ) EventDetailsManipulator.createOrUpdate(event_details) template_values = { 'matchstats_dict': matchstats_dict, } path = os.path.join(os.path.dirname(__file__), '../templates/math/event_matchstats_do.html') self.response.out.write(template.render(path, template_values))
def post(self, event_key): self._require_admin() # Note, we don't actually use event_key. start_date = None if self.request.get("start_date"): start_date = datetime.strptime(self.request.get("start_date"), "%Y-%m-%d") end_date = None if self.request.get("end_date"): end_date = datetime.strptime(self.request.get("end_date"), "%Y-%m-%d") district_key = self.request.get("event_district_key", None) event = Event( id=str(self.request.get("year")) + str.lower(str(self.request.get("event_short"))), end_date=end_date, event_short=self.request.get("event_short"), event_type_enum=EventHelper.parseEventType( self.request.get("event_type_str")), district_key=ndb.Key(District, self.request.get("event_district_key")) if district_key and district_key != 'None' else None, venue=self.request.get("venue"), venue_address=self.request.get("venue_address"), city=self.request.get("city"), state_prov=self.request.get("state_prov"), postalcode=self.request.get("postalcode"), country=self.request.get("country"), name=self.request.get("name"), short_name=self.request.get("short_name"), start_date=start_date, website=self.request.get("website"), year=int(self.request.get("year")), official={ "true": True, "false": False }.get(self.request.get("official").lower()), facebook_eid=self.request.get("facebook_eid"), custom_hashtag=self.request.get("custom_hashtag"), webcast_json=self.request.get("webcast_json"), ) event = EventManipulator.createOrUpdate(event) if self.request.get("alliance_selections_json") or self.request.get( "rankings_json"): event_details = EventDetails( id=event_key, alliance_selections=json.loads( self.request.get("alliance_selections_json")), rankings=json.loads(self.request.get("rankings_json"))) EventDetailsManipulator.createOrUpdate(event_details) MemcacheWebcastFlusher.flushEvent(event.key_name) self.redirect("/admin/event/" + event.key_name)
def get(self, event_key): event = Event.get_by_id(event_key) if event.event_type_enum not in EventType.SEASON_EVENT_TYPES and not self.request.get( 'allow-offseason', None): if 'X-Appengine-Taskname' not in self.request.headers: self.response.out.write( "Can't calculate district points for a non-season event {}!" .format(event.key_name)) return district_points = DistrictHelper.calculate_event_points(event) event_details = EventDetails(id=event_key, district_points=district_points) EventDetailsManipulator.createOrUpdate(event_details) if 'X-Appengine-Taskname' not in self.request.headers: # Only write out if not in taskqueue self.response.out.write(event.district_points) # Enqueue task to update rankings if event.district_key: taskqueue.add( url='/tasks/math/do/district_rankings_calc/{}'.format( event.district_key.id()), method='GET')
def get(self, event_key): event = Event.get_by_id(event_key) if not event: self.abort(404) event_future = EventQuery(event_key).fetch_async(return_updated=True) matches_future = EventMatchesQuery(event_key).fetch_async( return_updated=True) event, _ = event_future.get_result() matches, _ = matches_future.get_result() cleaned_matches = MatchHelper.deleteInvalidMatches(matches, event) matches = MatchHelper.organizeMatches(cleaned_matches) bracket_table, playoff_advancement, _, _ = PlayoffAdvancementHelper.generatePlayoffAdvancement( event, matches) event_details = EventDetails( id=event.key_name, playoff_advancement={ 'advancement': playoff_advancement, 'bracket': bracket_table, }, ) EventDetailsManipulator.createOrUpdate(event_details) self.response.out.write("New playoff advancement for {}\n{}".format( event.key_name, json.dumps(event_details.playoff_advancement, indent=2, sort_keys=True)))
def get(self, event_key): df = DatafeedFMSAPI('v2.0', save_response=True) event = Event.get_by_id(event_key) rankings, rankings2 = df.getEventRankings(event_key) if event and event.remap_teams: EventHelper.remapteams_rankings(rankings, event.remap_teams) EventHelper.remapteams_rankings2(rankings2, event.remap_teams) event_details = EventDetails(id=event_key, rankings=rankings, rankings2=rankings2) EventDetailsManipulator.createOrUpdate(event_details) template_values = { 'rankings': rankings, 'event_name': event_details.key.id() } if 'X-Appengine-Taskname' not in self.request.headers: # Only write out if not in taskqueue path = os.path.join( os.path.dirname(__file__), '../templates/datafeeds/usfirst_event_rankings_get.html') self.response.out.write(template.render(path, template_values))
def setUp(self): app = webapp2.WSGIApplication([webapp2.Route(r'/<event_key:>', ApiEventController, 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() self.testbed.init_taskqueue_stub(root_path=".") self.event = Event( id="2010sc", name="Palmetto Regional", event_type_enum=EventType.REGIONAL, event_district_enum=DistrictType.NO_DISTRICT, 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", timezone_id="America/New_York", 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 setUp(self): app = webapp2.WSGIApplication([webapp2.Route(r'/<event_key:>', ApiEventRankingsController, 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.rankings = [ ["Rank", "Team", "QS", "ASSIST", "AUTO", "T&C", "TELEOP", "Record (W-L-T)", "DQ", "PLAYED"], ["1", "1126", "20.00", "240.00", "480.00", "230.00", "478.00", "10-2-0", "0", "12"], ["2", "5030", "20.00", "200.00", "290.00", "220.00", "592.00", "10-2-0", "0", "12"], ["3", "250", "20.00", "70.00", "415.00", "220.00", "352.00", "10-2-0", "0", "12"] ] self.event = Event( id="2010sc", name="Palmetto Regional", event_type_enum=EventType.REGIONAL, short_name="Palmetto", event_short="sc", year=2010, end_date=datetime(2010, 03, 27), official=True, city="Clemson", state_prov="SC", country="USA", start_date=datetime(2010, 03, 24) ) self.event.put() self.event_details = EventDetails( id=self.event.key.id(), rankings=self.rankings ) self.event_details.put() self.eventNoRanks = Event( id="2010ct", name="Palmetto Regional", event_type_enum=EventType.REGIONAL, short_name="Palmetto", event_short="ct", year=2010, end_date=datetime(2010, 03, 27), official=True, city="Clemson", state_prov="SC", country="USA", start_date=datetime(2010, 03, 24), ) self.eventNoRanks.put()
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 _process_request(self, request, event_key): rankings = JSONRankingsParser.parse(request.body) event = Event.get_by_id(event_key) event_details = EventDetails(id=event_key, rankings=rankings) EventDetailsManipulator.createOrUpdate(event_details) self.response.out.write( json.dumps({'Success': "Rankings successfully updated"}))
def create_event_details(event_key): event = Event.get_by_id(event_key) if event.alliance_selections or event.district_points or event.matchstats or event.rankings: event_details = EventDetails( id=event_key, alliance_selections=event.alliance_selections, district_points=event.district_points, matchstats=event.matchstats, rankings=event.rankings) EventDetailsManipulator.createOrUpdate(event_details)
def generateTeamAtEventStatusAsync(cls, team_key, event): """ Generate Team@Event status items :return: a tuple future <long summary string, qual record, qual ranking, playoff status> """ team_number = team_key[3:] matches, event_details = yield TeamEventMatchesQuery( team_key, event.key.id()).fetch_async(), EventDetails.get_by_id_async( event.key.id()) matches = MatchHelper.organizeMatches(matches) # Compute alliances alliance_number = cls._get_alliance_number(team_key, event_details) # Playoff Status status, short_playoff_status = cls._get_playoff_status( team_key, matches, alliance_number) # Still in quals or team did not make it to elims # Compute qual W-L-T wins, losses, ties, unplayed_qual = cls._get_qual_wlt( team_key, matches) if wins == 0 and losses == 0 and ties == 0: # No matches played yet status = "Team {} has not played any matches yet.".format( team_number) if not status else status # Compute rank & num_teams # Gets record from ranking data to account for surrogate matches rank, ranking_points, record, num_teams = cls._get_rank( team_number, event_details) rank_str = "Rank {} with {} RP".format(rank, ranking_points) # Compute final long status for nightbot, if one isn't already there if unplayed_qual > 0 and not status: if rank is not None: status = "Team {} is currently rank {}/{} with a record of {} and {} ranking points.".format( team_number, rank, num_teams, record, ranking_points) else: status = "Team {} currently has a record of {}.".format( team_number, record) elif not status: if alliance_number is None: status = "Team {} ended qualification matches at rank {}/{} with a record of {}.".format( team_number, rank, num_teams, record) elif alliance_number == 0: status = "Team {} ended qualification matches at rank {}/{} with a record of {} and was not picked for playoff matches.".format( team_number, rank, num_teams, record) else: status = "Team {} will be competing in the playoff matches on alliance #{}.".format( team_number, alliance_number) raise ndb.Return(status, record, rank_str, short_playoff_status)
def _process_request(self, request, event_key): alliance_selections = JSONAllianceSelectionsParser.parse(request.body) event = Event.get_by_id(event_key) event_details = EventDetails(id=event_key, alliance_selections=alliance_selections) EventDetailsManipulator.createOrUpdate(event_details) self.response.out.write( json.dumps({'Success': "Alliance selections successfully updated"}))
def _process_request(self, request, event_key): alliance_selections = JSONAllianceSelectionsParser.parse(request.body) event_details = EventDetails( id=event_key, alliance_selections=alliance_selections ) if self.event.remap_teams: EventHelper.remapteams_alliances(event_details.alliance_selections, self.event.remap_teams) EventDetailsManipulator.createOrUpdate(event_details) self.response.out.write(json.dumps({'Success': "Alliance selections successfully updated"}))
def post(self, event_key_id): self._require_admin() event = Event.get_by_id(event_key_id) alliance_selections_csv = self.request.get('alliance_selections_csv') alliance_selections = CSVAllianceSelectionsParser.parse( alliance_selections_csv) event_details = EventDetails(id=event_key_id, alliance_selections=alliance_selections) EventDetailsManipulator.createOrUpdate(event_details) self.redirect("/admin/event/" + event.key_name)
def setUp(self): self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_taskqueue_stub(root_path=".") self.testbed.init_memcache_stub() ndb.get_context().clear_cache() # Prevent data from leaking between tests self.maxDiff = None with open('test_data/usfirst_html/usfirst_event_rankings_2012ct.html', 'r') as f: good_rankings, _ = UsfirstEventRankingsParser.parse(f.read()) with open('test_data/usfirst_html/usfirst_event_rankings_2012ct_bad.html', 'r') as f: bad_rankings, _ = UsfirstEventRankingsParser.parse(f.read()) self.old_alliance_selections = { '1': {'picks': ['frc254', 'frc469', 'frc2848', 'frc74'], 'declines':[] }, '2': {'picks': ['frc1718', 'frc2451', 'frc573', 'frc2016'], 'declines':[] }, '3': {'picks': ['frc2928', 'frc2013', 'frc1311', 'frc842'], 'declines':[] }, '4': {'picks': ['frc180', 'frc125', 'frc1323', 'frc2468'], 'declines':[] }, '5': {'picks': ['frc118', 'frc359', 'frc4334', 'frc865'], 'declines':[] }, '6': {'picks': ['frc135', 'frc1241', 'frc11', 'frc68'], 'declines':[] }, '7': {'picks': ['frc3478', 'frc177', 'frc294', 'frc230'], 'declines':[] }, '8': {'picks': ['frc624', 'frc987', 'frc3476', 'frc123'], 'declines':[] }, } self.new_alliance_selections = { '1': {'picks': ['frc254', 'frc469', 'frc2848', 'frc74'], 'declines':[] }, '2': {'picks': ['frc1718', 'frc2451', 'frc573', 'frc2016'], 'declines':[] }, '3': {'picks': ['frc2928', 'frc2013', 'frc1311', 'frc842'], 'declines':[] }, '4': {'picks': ['frc180', 'frc125', 'frc1323', 'frc2468'], 'declines':[] }, '5': {'picks': ['frc118', 'frc359', 'frc4334', 'frc865'], 'declines':[] }, '6': {'picks': ['frc135', 'frc1241', 'frc11', 'frc68'], 'declines':[] }, '7': {'picks': ['frc3478', 'frc177', 'frc294', 'frc230'], 'declines':[] }, '8': {'picks': ['frc624', 'frc987', 'frc3476', 'frc3015'], 'declines':[] }, } self.old_event_details = EventDetails( id='2011ct', rankings=good_rankings, alliance_selections=self.old_alliance_selections, ) self.new_event_details = EventDetails( id='2011ct', rankings=bad_rankings, alliance_selections=self.new_alliance_selections, matchstats={'oprs': {'4255': 7.4877151786460301, '2643': 27.285682906835952, '852': 10.452538750544525, '4159': 25.820137009871139, '581': 18.513816255143144}} )
def _update_rankings(self): """ Generates and saves fake rankings """ event = Event.get_by_id('2016nytr') team_wins = defaultdict(int) team_losses = defaultdict(int) team_ties = defaultdict(int) teams = set() for match in event.matches: if match.comp_level == 'qm': for alliance in ['red', 'blue']: for team in match.alliances[alliance]['teams']: teams.add(team) if match.has_been_played: if alliance == match.winning_alliance: team_wins[team] += 1 elif match.winning_alliance == '': team_ties[team] += 1 else: team_losses[team] += 1 rankings = [] for team in sorted(teams): wins = team_wins[team] losses = team_losses[team] ties = team_ties[team] rankings.append({ 'team_key': team, 'record': { 'wins': wins, 'losses': losses, 'ties': ties, }, 'matches_played': wins + losses + ties, 'dq': 0, 'sort_orders': [2 * wins + ties, 0, 0, 0, 0], 'qual_average': None, }) rankings = sorted(rankings, key=lambda r: -r['sort_orders'][0]) for i, ranking in enumerate(rankings): ranking['rank'] = i + 1 EventDetailsManipulator.createOrUpdate( EventDetails( id='2016nytr', rankings2=rankings, ))
def get(self, event_key): event = Event.get_by_id(event_key) if event.event_district_enum == DistrictType.NO_DISTRICT: self.response.out.write("Can't calculate district points for a non-district event!") return district_points = DistrictHelper.calculate_event_points(event) event_details = EventDetails( id=event_key, district_points=district_points ) EventDetailsManipulator.createOrUpdate(event_details) self.response.out.write(event.district_points)
def post(self, event_key): self._require_admin() event = Event.get_by_id(event_key) if not event: self.redirect("/admin/event/" + event.key_name) return details = EventDetails.get_by_id(event.key_name) if details: details.playoff_advancement = {} EventDetailsManipulator.createOrUpdate(details) self.redirect("/admin/event/" + event.key_name) return
def get(self, event_key): event = Event.get_by_id(event_key) matchstats_dict = MatchstatsHelper.calculate_matchstats( event.matches, event.year) if any([v != {} for v in matchstats_dict.values()]): pass else: logging.warn( "Matchstat calculation for {} failed!".format(event_key)) matchstats_dict = None predictions_dict = None if event.year in { 2016, 2017, 2018, 2019, 2020 } and event.event_type_enum in EventType.SEASON_EVENT_TYPES or event.enable_predictions: sorted_matches = MatchHelper.play_order_sort_matches(event.matches) match_predictions, match_prediction_stats, stat_mean_vars = PredictionHelper.get_match_predictions( sorted_matches) ranking_predictions, ranking_prediction_stats = PredictionHelper.get_ranking_predictions( sorted_matches, match_predictions) predictions_dict = { 'match_predictions': match_predictions, 'match_prediction_stats': match_prediction_stats, 'stat_mean_vars': stat_mean_vars, 'ranking_predictions': ranking_predictions, 'ranking_prediction_stats': ranking_prediction_stats } event_insights = EventInsightsHelper.calculate_event_insights( event.matches, event.year) event_details = EventDetails( id=event_key, matchstats=matchstats_dict, predictions=predictions_dict, insights=event_insights, ) EventDetailsManipulator.createOrUpdate(event_details) template_values = { 'matchstats_dict': matchstats_dict, } if 'X-Appengine-Taskname' not in self.request.headers: # Only write out if not in taskqueue path = os.path.join(os.path.dirname(__file__), '../templates/math/event_matchstats_do.html') self.response.out.write(template.render(path, template_values))
def test_fcm_notification_team_four(self): team = Team.get_by_id('frc1') # Setup alliance selection information EventDetails(id=self.event.key_name, alliance_selections=[{ "declines": [], "picks": ["frc2", "frc1", "frc3", "frc4"] }]).put() notification = AllianceSelectionNotification(self.event, team) self.assertIsNotNone(notification.fcm_notification) self.assertEqual(notification.fcm_notification.title, 'TESTPRESENT Alliances Updated') self.assertEqual( notification.fcm_notification.body, 'Present Test Event alliances have been updated. Team 1 is on Alliance 1 with Team 2, Team 3 and Team 4.' )
def get(self, event_key): df = DatafeedFMSAPI('v2.0') event = Event.get_by_id(event_key) alliance_selections = df.getEventAlliances(event_key) event_details = EventDetails( id=event_key, alliance_selections=alliance_selections ) EventDetailsManipulator.createOrUpdate(event_details) template_values = {'alliance_selections': alliance_selections, 'event_name': event_details.key.id()} if 'X-Appengine-Taskname' not in self.request.headers: # Only write out if not in taskqueue path = os.path.join(os.path.dirname(__file__), '../templates/datafeeds/usfirst_event_alliances_get.html') self.response.out.write(template.render(path, template_values))
def setUp(self): app = webapp2.WSGIApplication([webapp2.Route(r'/<event_key:>', ApiEventStatsController, 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() self.testbed.init_taskqueue_stub(root_path=".") self.matchstats = { "dprs": {"971": 10.52178695299036, "114": 23.7313645955704, "115": 29.559784481082044}, "oprs": {"971": 91.42946669932006, "114": 59.27751047482864, "115": 13.285278757495144}, "ccwms": {"971": 80.90767974632955, "114": 35.54614587925829, "115": -16.27450572358693}, } self.event = Event( id="2010sc", name="Palmetto Regional", event_type_enum=EventType.REGIONAL, short_name="Palmetto", event_short="sc", year=2010, end_date=datetime(2010, 03, 27), official=True, city="Clemson", state_prov="SC", country="USA", start_date=datetime(2010, 03, 24) ) self.event.put() self.event_details = EventDetails( id=self.event.key.id(), matchstats=self.matchstats ) self.event_details.put()
class TestEventApiController(unittest2.TestCase): def setUp(self): app = webapp2.WSGIApplication([webapp2.Route(r'/<event_key:>', ApiEventController, 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.event = Event( id="2010sc", name="Palmetto Regional", event_type_enum=EventType.REGIONAL, district_key=None, 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", timezone_id="America/New_York", 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 tearDown(self): self.testbed.deactivate() def assertEventJson(self, event): self.assertEqual(event["key"], self.event.key_name) self.assertEqual(event["name"], self.event.name) self.assertEqual(event["short_name"], self.event.short_name) self.assertEqual(event["official"], self.event.official) self.assertEqual(event["event_type_string"], self.event.event_type_str) self.assertEqual(event["event_type"], self.event.event_type_enum) self.assertEqual(event["event_district_string"], self.event.event_district_str) self.assertEqual(event["event_district"], self.event.event_district_enum) self.assertEqual(event["start_date"], self.event.start_date.date().isoformat()) self.assertEqual(event["end_date"], self.event.end_date.date().isoformat()) self.assertEqual(event["location"], self.event.location) self.assertEqual(event["venue_address"], self.event.venue_address.replace('\r\n', '\n')) self.assertEqual(event["webcast"], json.loads(self.event.webcast_json)) self.assertEqual(event["alliances"], self.event.alliance_selections) self.assertEqual(event["website"], self.event.website) self.assertEqual(event["timezone"], self.event.timezone_id) def testEventApi(self): response = self.testapp.get('/2010sc', headers={"X-TBA-App-Id": "tba-tests:event-controller-test:v01"}) event_dict = json.loads(response.body) self.assertEventJson(event_dict)
def generateTeamAtEventStatusAsync(cls, team_key, event): """ Generate Team@Event status items :return: a tuple future <long summary string, qual record, qual ranking, playoff status> """ team_number = team_key[3:] matches, event_details = yield TeamEventMatchesQuery(team_key, event.key.id()).fetch_async(), EventDetails.get_by_id_async(event.key.id()) matches = MatchHelper.organizeMatches(matches) # Compute alliances alliance_number = cls._get_alliance_number(team_key, event_details) # Playoff Status status, short_playoff_status = cls._get_playoff_status(team_key, matches, alliance_number) # Still in quals or team did not make it to elims # Compute qual W-L-T wins, losses, ties, unplayed_qual = cls._get_qual_wlt(team_key, matches) if wins == 0 and losses == 0 and ties == 0: # No matches played yet status = "Team {} has not played any matches yet.".format(team_number) if not status else status # Compute rank & num_teams # Gets record from ranking data to account for surrogate matches rank, ranking_points, record, num_teams = cls._get_rank(team_number, event_details) rank_str = "Rank {} with {} RP".format(rank, ranking_points) # Compute final long status for nightbot, if one isn't already there if unplayed_qual > 0 and not status: if rank is not None: status = "Team {} is currently rank {}/{} with a record of {} and {} ranking points.".format(team_number, rank, num_teams, record, ranking_points) else: status = "Team {} currently has a record of {}.".format(team_number, record) elif not status: if alliance_number is None: status = "Team {} ended qualification matches at rank {}/{} with a record of {}.".format(team_number, rank, num_teams, record) elif alliance_number == 0: status = "Team {} ended qualification matches at rank {}/{} with a record of {} and was not picked for playoff matches.".format(team_number, rank, num_teams, record) else: status = "Team {} will be competing in the playoff matches on alliance #{}.".format(team_number, alliance_number) raise ndb.Return(status, record, rank_str, short_playoff_status)
def _query_async(self): event_key = self._query_args[0] event_details = yield EventDetails.get_by_id_async(event_key) raise ndb.Return(event_details)
def generateTeamAtEventStatusAsync(cls, team_key, event): """ Generate Team@Event status items :return: a tuple future <long summary string, qual record, qual ranking, playoff status> """ team_number = team_key[3:] # We need all the event's playoff matches here to properly account for backup teams matches, event_details = yield EventMatchesQuery(event.key.id()).fetch_async(), EventDetails.get_by_id_async(event.key.id()) qual_match_count = 0 playoff_match_count = 0 playoff_matches = [] for match in matches: if match.comp_level in Match.ELIM_LEVELS: playoff_match_count += 1 playoff_matches.append(match) else: qual_match_count += 1 matches = MatchHelper.organizeMatches(playoff_matches) team_status = cls.generate_team_at_event_status(team_key, event, matches) rank_status = team_status.get('rank', None) alliance_status = team_status.get('alliance', None) playoff_status = team_status.get('playoff', None) # Playoff Status status, short_playoff_status = cls._get_playoff_status_string(team_key, alliance_status, playoff_status) # Still in quals or team did not make it to elims if not rank_status or rank_status.get('played', 0) == 0: # No matches played yet status = "Team {} has not played any matches yet.".format(team_number) if not status else status record = '?' rank_str = '?' else: # Compute rank & num_teams # Gets record from ranking data to account for surrogate matches rank = rank_status.get('rank', '?') ranking_points = rank_status.get('first_sort', '?') record = rank_status.get('record', '?') num_teams = rank_status.get('total', '?') rank_str = "Rank {} with {} RP".format(rank, ranking_points) alliance_name = alliance_status.get('name', '?') if alliance_status else '?' # Compute final long status for nightbot, if one isn't already there matches_per_team = qual_match_count // rank_status.get('total', 1) if rank_status.get('played', 0) - matches_per_team > 0 and not status: if rank is not None: status = "Team {} is currently rank {}/{} with a record of {} and {} ranking points.".format(team_number, rank, num_teams, record, ranking_points) else: status = "Team {} currently has a record of {}.".format(team_number, record) elif not status: if alliance_status is None and playoff_match_count == 0: status = "Team {} ended qualification matches at rank {}/{} with a record of {}.".format(team_number, rank, num_teams, record) elif alliance_status is None and playoff_match_count > 0: status = "Team {} ended qualification matches at rank {}/{} with a record of {} and was not picked for playoff matches.".format(team_number, rank, num_teams, record) else: status = "Team {} will be competing in the playoff matches on {}.".format(team_number, alliance_name) raise ndb.Return(status, record, rank_str, short_playoff_status)
def details(self): if self._details is None: self._details = EventDetails.get_by_id(self.key.id()) elif type(self._details) == Future: self._details = self._details.get_result() return self._details
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 store_eventdetail(event, type, data): detail = EventDetails(id=event.key_name) setattr(detail, type, data) return EventDetailsManipulator.createOrUpdate(detail)
class TestEventDetailsManipulator(unittest2.TestCase): def setUp(self): self.testbed = testbed.Testbed() self.testbed.activate() self.testbed.init_datastore_v3_stub() self.testbed.init_taskqueue_stub(root_path=".") self.testbed.init_memcache_stub() self.maxDiff = None with open('test_data/usfirst_html/usfirst_event_rankings_2012ct.html', 'r') as f: good_rankings, _ = UsfirstEventRankingsParser.parse(f.read()) with open('test_data/usfirst_html/usfirst_event_rankings_2012ct_bad.html', 'r') as f: bad_rankings, _ = UsfirstEventRankingsParser.parse(f.read()) self.old_alliance_selections = { '1': {'picks': ['frc254', 'frc469', 'frc2848', 'frc74'], 'declines':[] }, '2': {'picks': ['frc1718', 'frc2451', 'frc573', 'frc2016'], 'declines':[] }, '3': {'picks': ['frc2928', 'frc2013', 'frc1311', 'frc842'], 'declines':[] }, '4': {'picks': ['frc180', 'frc125', 'frc1323', 'frc2468'], 'declines':[] }, '5': {'picks': ['frc118', 'frc359', 'frc4334', 'frc865'], 'declines':[] }, '6': {'picks': ['frc135', 'frc1241', 'frc11', 'frc68'], 'declines':[] }, '7': {'picks': ['frc3478', 'frc177', 'frc294', 'frc230'], 'declines':[] }, '8': {'picks': ['frc624', 'frc987', 'frc3476', 'frc123'], 'declines':[] }, } self.new_alliance_selections = { '1': {'picks': ['frc254', 'frc469', 'frc2848', 'frc74'], 'declines':[] }, '2': {'picks': ['frc1718', 'frc2451', 'frc573', 'frc2016'], 'declines':[] }, '3': {'picks': ['frc2928', 'frc2013', 'frc1311', 'frc842'], 'declines':[] }, '4': {'picks': ['frc180', 'frc125', 'frc1323', 'frc2468'], 'declines':[] }, '5': {'picks': ['frc118', 'frc359', 'frc4334', 'frc865'], 'declines':[] }, '6': {'picks': ['frc135', 'frc1241', 'frc11', 'frc68'], 'declines':[] }, '7': {'picks': ['frc3478', 'frc177', 'frc294', 'frc230'], 'declines':[] }, '8': {'picks': ['frc624', 'frc987', 'frc3476', 'frc3015'], 'declines':[] }, } self.old_event_details = EventDetails( id='2011ct', rankings=good_rankings, alliance_selections=self.old_alliance_selections, ) self.new_event_details = EventDetails( id='2011ct', rankings=bad_rankings, alliance_selections=self.new_alliance_selections, matchstats={'oprs': {'4255': 7.4877151786460301, '2643': 27.285682906835952, '852': 10.452538750544525, '4159': 25.820137009871139, '581': 18.513816255143144}} ) def tearDown(self): self.testbed.deactivate() def assertMergedEventDetails(self, event_details): self.assertOldEventDetails(event_details) self.assertEqual(event_details.matchstats, {'oprs': {'4255': 7.4877151786460301, '2643': 27.285682906835952, '852': 10.452538750544525, '4159': 25.820137009871139, '581': 18.513816255143144}}) self.assertEqual(event_details.rankings, [['Rank', 'Team', 'QS', 'HP', 'BP', 'TP', 'CP', 'Record (W-L-T)', 'DQ', 'Played'], ['1', '2168', '32.00', '147.00', '60.00', '208.00', '14', '9-1-0', '0', '10'], ['2', '118', '31.00', '168.00', '90.00', '231.00', '17', '7-3-0', '0', '10'], ['3', '177', '30.00', '177.00', '120.00', '151.00', '14', '8-2-0', '0', '10'], ['4', '195', '29.00', '116.00', '70.00', '190.00', '16', '6-3-1', '0', '10'], ['5', '237', '28.00', '120.00', '60.00', '123.00', '14', '7-3-0', '0', '10'], ['6', '1071', '28.00', '115.00', '120.00', '142.00', '10', '9-1-0', '0', '10'], ['7', '173', '28.00', '114.00', '110.00', '108.00', '14', '7-3-0', '0', '10'], ['8', '1073', '28.00', '110.00', '100.00', '152.00', '11', '8-1-1', '0', '10'], ['9', '694', '28.00', '78.00', '100.00', '140.00', '14', '7-3-0', '0', '10'], ['10', '558', '27.00', '152.00', '100.00', '145.00', '13', '7-3-0', '0', '10'], ['11', '175', '27.00', '141.00', '160.00', '117.00', '13', '7-3-0', '0', '10'], ['12', '181', '26.00', '151.00', '70.00', '95.00', '14', '6-4-0', '0', '10'], ['13', '176', '26.00', '120.00', '60.00', '90.00', '18', '4-6-0', '0', '10'], ['14', '1511', '26.00', '111.00', '80.00', '164.00', '14', '6-4-0', '0', '10'], ['15', '126', '26.00', '108.00', '70.00', '165.00', '14', '6-4-0', '0', '10'], ['16', '4122', '26.00', '92.00', '100.00', '78.00', '14', '6-4-0', '0', '10'], ['17', '869', '25.00', '68.00', '130.00', '75.00', '12', '6-3-1', '0', '10'], ['18', '3464', '24.00', '135.00', '80.00', '109.00', '14', '5-5-0', '0', '10'], ['19', '3467', '24.00', '101.00', '80.00', '123.00', '10', '7-3-0', '0', '10'], ['20', '3718', '24.00', '100.00', '60.00', '106.00', '12', '6-4-0', '0', '10'], ['21', '3461', '24.00', '79.00', '30.00', '94.00', '14', '5-5-0', '0', '10'], ['22', '4055', '24.00', '78.00', '80.00', '79.00', '16', '4-6-0', '0', '10'], ['23', '1922', '23.00', '114.00', '110.00', '151.00', '10', '6-3-1', '0', '10'], ['24', '95', '22.00', '120.00', '70.00', '123.00', '14', '4-6-0', '0', '10'], ['25', '1991', '22.00', '113.00', '100.00', '58.00', '12', '5-5-0', '0', '10'], ['26', '839', '22.00', '96.00', '110.00', '136.00', '10', '6-4-0', '0', '10'], ['27', '1099', '21.00', '126.00', '110.00', '97.00', '8', '6-3-1', '0', '10'], ['28', '230', '20.00', '143.00', '80.00', '104.00', '8', '6-4-0', '0', '10'], ['29', '3017', '20.00', '134.00', '50.00', '88.00', '12', '4-6-0', '0', '10'], ['30', '2067', '20.00', '128.00', '80.00', '122.00', '10', '5-5-0', '0', '10'], ['31', '250', '20.00', '118.00', '40.00', '99.00', '10', '5-5-0', '0', '10'], ['32', '155', '20.00', '100.00', '50.00', '74.00', '12', '4-6-0', '0', '10'], ['33', '236', '20.00', '99.00', '20.00', '126.00', '10', '5-5-0', '0', '10'], ['34', '1124', '20.00', '92.00', '80.00', '109.00', '8', '6-4-0', '0', '10'], ['35', '3146', '20.00', '81.00', '110.00', '81.00', '6', '7-3-0', '0', '10'], ['36', '663', '20.00', '71.00', '90.00', '90.00', '12', '4-6-0', '0', '10'], ['37', '1699', '20.00', '70.00', '80.00', '139.00', '12', '4-6-0', '0', '10'], ['38', '1027', '20.00', '53.00', '70.00', '97.00', '12', '4-6-0', '0', '10'], ['39', '20', '19.00', '79.00', '70.00', '106.00', '9', '5-5-0', '0', '10'], ['40', '3182', '18.00', '108.00', '60.00', '147.00', '8', '5-5-0', '0', '10'], ['41', '229', '18.00', '97.00', '40.00', '153.00', '10', '4-6-0', '0', '10'], ['42', '1665', '18.00', '95.00', '120.00', '106.00', '10', '4-6-0', '0', '10'], ['43', '228', '18.00', '81.00', '60.00', '163.00', '10', '4-6-0', '0', '10'], ['44', '178', '18.00', '81.00', '50.00', '58.00', '12', '3-7-0', '0', '10'], ['45', '1740', '18.00', '62.00', '20.00', '99.00', '8', '5-5-0', '0', '10'], ['46', '3634', '18.00', '54.00', '30.00', '105.00', '10', '4-6-0', '0', '10'], ['47', '2791', '18.00', '53.00', '100.00', '108.00', '10', '4-6-0', '0', '10'], ['48', '571', '18.00', '53.00', '70.00', '109.00', '10', '4-6-0', '0', '10'], ['49', '2170', '17.00', '89.00', '60.00', '103.00', '9', '4-5-0', '1', '10'], ['50', '1493', '16.00', '150.00', '60.00', '132.00', '6', '5-5-0', '0', '10'], ['51', '549', '16.00', '129.00', '100.00', '91.00', '6', '5-5-0', '0', '10'], ['52', '743', '16.00', '70.00', '30.00', '67.00', '10', '3-7-0', '0', '10'], ['53', '2836', '16.00', '64.00', '80.00', '126.00', '8', '4-6-0', '0', '10'], ['54', '999', '14.00', '114.00', '20.00', '79.00', '10', '2-8-0', '0', '10'], ['55', '3525', '14.00', '109.00', '40.00', '66.00', '6', '4-6-0', '0', '10'], ['56', '3104', '14.00', '92.00', '20.00', '80.00', '6', '4-6-0', '0', '10'], ['57', '3555', '14.00', '68.00', '60.00', '68.00', '8', '3-7-0', '0', '10'], ['58', '4134', '13.00', '96.00', '30.00', '80.00', '6', '3-6-1', '0', '10'], ['59', '1559', '12.00', '110.00', '10.00', '94.00', '8', '2-8-0', '0', '10'], ['60', '3719', '12.00', '97.00', '60.00', '95.00', '6', '3-7-0', '0', '10'], ['61', '3654', '12.00', '59.00', '20.00', '57.00', '8', '2-8-0', '0', '10'], ['62', '2785', '12.00', '41.00', '70.00', '96.00', '8', '2-8-0', '0', '10'], ['63', '1880', '10.00', '57.00', '40.00', '86.00', '6', '2-8-0', '0', '10'], ['64', '1784', '10.00', '44.00', '40.00', '60.00', '6', '2-7-0', '1', '10']]) self.assertEqual(event_details.alliance_selections, self.new_alliance_selections) def assertOldEventDetails(self, event_details): self.assertEqual(event_details.key.id(), "2011ct") def test_createOrUpdate(self): EventDetailsManipulator.createOrUpdate(self.old_event_details) self.assertOldEventDetails(EventDetails.get_by_id('2011ct')) EventDetailsManipulator.createOrUpdate(self.new_event_details) self.assertMergedEventDetails(EventDetails.get_by_id('2011ct')) def test_findOrSpawn(self): self.old_event_details.put() self.assertMergedEventDetails(EventDetailsManipulator.findOrSpawn(self.new_event_details)) def test_updateMerge(self): self.assertMergedEventDetails(EventDetailsManipulator.updateMerge(self.new_event_details, self.old_event_details))
def details(self): if self._details is None: self._details = EventDetails.get_by_id(self.key.id()) return self._details
class TestEventApiController(unittest2.TestCase): def setUp(self): app = webapp2.WSGIApplication([webapp2.Route(r'/<event_key:>', ApiEventController, 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() self.testbed.init_taskqueue_stub(root_path=".") self.event = Event( id="2010sc", name="Palmetto Regional", event_type_enum=EventType.REGIONAL, event_district_enum=DistrictType.NO_DISTRICT, 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", timezone_id="America/New_York", 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 tearDown(self): self.testbed.deactivate() def assertEventJson(self, event): self.assertEqual(event["key"], self.event.key_name) self.assertEqual(event["name"], self.event.name) self.assertEqual(event["short_name"], self.event.short_name) self.assertEqual(event["official"], self.event.official) self.assertEqual(event["event_type_string"], self.event.event_type_str) self.assertEqual(event["event_type"], self.event.event_type_enum) self.assertEqual(event["event_district_string"], self.event.event_district_str) self.assertEqual(event["event_district"], self.event.event_district_enum) self.assertEqual(event["start_date"], self.event.start_date.date().isoformat()) self.assertEqual(event["end_date"], self.event.end_date.date().isoformat()) self.assertEqual(event["location"], self.event.location) self.assertEqual(event["venue_address"], self.event.venue_address.replace('\r\n', '\n')) self.assertEqual(event["webcast"], json.loads(self.event.webcast_json)) self.assertEqual(event["alliances"], self.event.alliance_selections) self.assertEqual(event["website"], self.event.website) self.assertEqual(event["timezone"], self.event.timezone_id) def testEventApi(self): response = self.testapp.get('/2010sc', headers={"X-TBA-App-Id": "tba-tests:event-controller-test:v01"}) event_dict = json.loads(response.body) self.assertEventJson(event_dict)
class TestEventController(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 app = webapp2.WSGIApplication([ RedirectRoute(r'/event/<event_key>', EventDetail, 'event-detail'), RedirectRoute(r'/event/<event_key>/insights', EventInsights, 'event-insights'), RedirectRoute(r'/events/<year:[0-9]+>', EventList, 'event-list-year'), RedirectRoute(r'/events', EventList, 'event-list'), ]) self.testapp = webtest.TestApp(app) self.event1 = Event( id="2016necmp", name="New England District Championship", event_type_enum=EventType.DISTRICT_CMP, event_district_enum=DistrictType.NEW_ENGLAND, short_name="New England", event_short="necmp", year=2016, end_date=datetime(2016, 03, 27), official=True, city='Hartford', state_prov='CT', country='USA', venue="Some Venue", venue_address="Some Venue, Hartford, CT, USA", timezone_id="America/New_York", start_date=datetime(2016, 03, 24), webcast_json="[{\"type\": \"twitch\", \"channel\": \"frcgamesense\"}]", website="http://www.firstsv.org", ) self.event1.put() # To test that /events defaults to current year this_year = datetime.now().year self.event2 = Event( id="{}necmp".format(this_year), name="New England District Championship", event_type_enum=EventType.DISTRICT_CMP, event_district_enum=DistrictType.NEW_ENGLAND, short_name="New England", event_short="necmp", year=this_year, end_date=datetime(this_year, 03, 27), official=True, city='Hartford', state_prov='CT', country='USA', venue="Some Venue", venue_address="Some Venue, Hartford, CT, USA", timezone_id="America/New_York", start_date=datetime(this_year, 03, 24), webcast_json="[{\"type\": \"twitch\", \"channel\": \"frcgamesense\"}]", website="http://www.firstsv.org", ) self.event2.put() self.event1_details = EventDetails( id=self.event1.key.id(), predictions={"ranking_prediction_stats": None, "match_predictions": None, "ranking_predictions": None, "match_prediction_stats": None} ) self.event1_details.put() self.event2_details = EventDetails( id=self.event2.key.id(), predictions={"ranking_prediction_stats": None, "match_predictions": None, "ranking_predictions": None, "match_prediction_stats": None} ) self.event2_details.put() def tearDown(self): self.testbed.deactivate() def testEventListDefaultYear(self): response = self.testapp.get("/events") self.assertEqual(response.status_int, 200) def testEventListExplicitYear(self): response = self.testapp.get("/events/2015") self.assertEqual(response.status_int, 200) def testEventListNoEvents(self): response = self.testapp.get("/events/2014") self.assertEqual(response.status_int, 200) def testEventDetails(self): response = self.testapp.get("/event/2016necmp") self.assertEqual(response.status_int, 200) def testEventDetailsNotFound(self): response = self.testapp.get("/event/2016meow", status=404) self.assertEqual(response.status_int, 404) def testEventInsights(self): response = self.testapp.get("/event/2016necmp/insights") self.assertEqual(response.status_int, 200) def testEventInsightsNotFound(self): response = self.testapp.get("/event/2016meow/insights", status=404) self.assertEqual(response.status_int, 404)
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 app = webapp2.WSGIApplication([ RedirectRoute(r'/event/<event_key>', EventDetail, 'event-detail'), RedirectRoute(r'/event/<event_key>/insights', EventInsights, 'event-insights'), RedirectRoute(r'/events/<year:[0-9]+>', EventList, 'event-list-year'), RedirectRoute(r'/events', EventList, 'event-list'), ]) self.testapp = webtest.TestApp(app) self.event1 = Event( id="2016necmp", name="New England District Championship", event_type_enum=EventType.DISTRICT_CMP, event_district_enum=DistrictType.NEW_ENGLAND, short_name="New England", event_short="necmp", year=2016, end_date=datetime(2016, 03, 27), official=True, city='Hartford', state_prov='CT', country='USA', venue="Some Venue", venue_address="Some Venue, Hartford, CT, USA", timezone_id="America/New_York", start_date=datetime(2016, 03, 24), webcast_json="[{\"type\": \"twitch\", \"channel\": \"frcgamesense\"}]", website="http://www.firstsv.org", ) this_year = datetime.now().year self.event2 = Event( id="2016necmp", name="New England District Championship", event_type_enum=EventType.DISTRICT_CMP, event_district_enum=DistrictType.NEW_ENGLAND, short_name="New England", event_short="necmp", year=this_year, end_date=datetime(this_year, 03, 27), official=True, city='Hartford', state_prov='CT', country='USA', venue="Some Venue", venue_address="Some Venue, Hartford, CT, USA", timezone_id="America/New_York", start_date=datetime(this_year, 03, 24), webcast_json="[{\"type\": \"twitch\", \"channel\": \"frcgamesense\"}]", website="http://www.firstsv.org", ) self.event1.put() self.event2.put() self.event1_details = EventDetails( id=self.event1.key.id(), predictions={"ranking_prediction_stats": None, "match_predictions": None, "ranking_predictions": None, "match_prediction_stats": None} ) self.event1_details.put() self.event2_details = EventDetails( id=self.event2.key.id(), predictions={"ranking_prediction_stats": None, "match_predictions": None, "ranking_predictions": None, "match_prediction_stats": None} ) self.event2_details.put()
class TestEventRankingsApiController(unittest2.TestCase): def setUp(self): app = webapp2.WSGIApplication([webapp2.Route(r'/<event_key:>', ApiEventRankingsController, 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() self.testbed.init_taskqueue_stub(root_path=".") self.rankings = [ ["Rank", "Team", "QS", "ASSIST", "AUTO", "T&C", "TELEOP", "Record (W-L-T)", "DQ", "PLAYED"], ["1", "1126", "20.00", "240.00", "480.00", "230.00", "478.00", "10-2-0", "0", "12"], ["2", "5030", "20.00", "200.00", "290.00", "220.00", "592.00", "10-2-0", "0", "12"], ["3", "250", "20.00", "70.00", "415.00", "220.00", "352.00", "10-2-0", "0", "12"] ] self.event = Event( id="2010sc", name="Palmetto Regional", event_type_enum=EventType.REGIONAL, short_name="Palmetto", event_short="sc", year=2010, end_date=datetime(2010, 03, 27), official=True, city="Clemson", state_prov="SC", country="USA", start_date=datetime(2010, 03, 24) ) self.event.put() self.event_details = EventDetails( id=self.event.key.id(), rankings=self.rankings ) self.event_details.put() self.eventNoRanks = Event( id="2010ct", name="Palmetto Regional", event_type_enum=EventType.REGIONAL, short_name="Palmetto", event_short="ct", year=2010, end_date=datetime(2010, 03, 27), official=True, city="Clemson", state_prov="SC", country="USA", start_date=datetime(2010, 03, 24), ) self.eventNoRanks.put() def tearDown(self): self.testbed.deactivate() def testEventRankingsApi(self): response = self.testapp.get('/2010sc', headers={"X-TBA-App-Id": "tba-tests:event-controller-test:v01"}) rankings = json.loads(response.body) self.assertEqual(self.rankings, rankings) def testEventNoRankingsApi(self): response = self.testapp.get('/2010ct', headers={"X-TBA-App-Id": "tba-tests:event-controller-test:v01"}) self.assertEqual("[]", response.body)
def test_createOrUpdate(self): EventDetailsManipulator.createOrUpdate(self.old_event_details) self.assertOldEventDetails(EventDetails.get_by_id('2011ct')) EventDetailsManipulator.createOrUpdate(self.new_event_details) self.assertMergedEventDetails(EventDetails.get_by_id('2011ct'))