def get(self, year):
        year = int(year)
        team_districts = defaultdict(list)
        logging.info("Fetching events in {}".format(year))
        year_events = Event.query(
            year == Event.year,
            Event.event_district_enum != DistrictType.NO_DISTRICT,
            Event.event_district_enum != None).fetch()
        for event in year_events:
            logging.info("Fetching EventTeams for {}".format(event.key_name))
            event_teams = EventTeam.query(EventTeam.event == event.key).fetch()
            for event_team in event_teams:
                team_districts[event_team.team.id()].append(
                    event.event_district_enum)

        new_district_teams = []
        for team_key, districts in team_districts.iteritems():
            most_frequent_district = max(set(districts), key=districts.count)
            logging.info("Assuming team {} belongs to {}".format(
                team_key, DistrictType.type_names[most_frequent_district]))
            dt_key = DistrictTeam.renderKeyName(year, most_frequent_district,
                                                team_key)
            new_district_teams.append(
                DistrictTeam(id=dt_key,
                             year=year,
                             team=ndb.Key(Team, team_key),
                             district=most_frequent_district))

        logging.info("Finishing updating old district teams from event teams")
        DistrictTeamManipulator.createOrUpdate(new_district_teams)
        self.response.out.write(
            "Finished creating district teams for {}".format(year))
예제 #2
0
    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 get(self, key_name):
        fms_df = DatafeedFMSAPI('v2.0')
        fms_details = fms_df.getTeamDetails(date.today().year, key_name)

        if fms_details:
            team, district_team, robot = fms_details
        else:
            fms_team = None
            district_team = None
            robot = None

        if team:
            team = TeamManipulator.createorUpdate(team)

        if district_team:
            district_team = DistrictTeamManipulator.createOrUpdate(
                district_team)

        if robot:
            robot = RobotManipulator.createOrUpdate(robot)

        template_values = {
            'key_name': key_name,
            'team': team,
            'success': success,
            'district': district_team,
            'robot': robot,
        }

        path = os.path.join(
            os.path.dirname(__file__),
            '../templates/datafeeds/usfirst_team_details_get.html')
        self.response.out.write(template.render(path, template_values))
    def get(self, key_name):
        fms_df = DatafeedFMSAPI('v2.0')
        fms_details = fms_df.getTeamDetails(date.today().year, key_name)

        if fms_details:
            team, district_team, robot = fms_details
        else:
            fms_team = None
            district_team = None
            robot = None

        if team:
            team = TeamManipulator.createorUpdate(team)

        if district_team:
            district_team = DistrictTeamManipulator.createOrUpdate(district_team)

        if robot:
            robot = RobotManipulator.createOrUpdate(robot)

        template_values = {
            'key_name': key_name,
            'team': team,
            'success': success,
            'district': district_team,
            'robot': robot,
        }

        path = os.path.join(os.path.dirname(__file__), '../templates/datafeeds/usfirst_team_details_get.html')
        self.response.out.write(template.render(path, template_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 get(self, event_key):
        df = DatafeedFMSAPI('v2.0')
        event = Event.get_by_id(event_key)

        models = df.getEventTeams(event_key)
        teams = []
        district_teams = []
        robots = []
        for group in models:
            # models is a list of tuples (team, districtTeam, robot)
            if isinstance(group[0], Team):
                teams.append(group[0])
            if isinstance(group[1], DistrictTeam):
                district_teams.append(group[1])
            if isinstance(group[2], Robot):
                robots.append(group[2])

        # Write new models
        teams = TeamManipulator.createOrUpdate(teams)
        district_teams = DistrictTeamManipulator.createOrUpdate(district_teams)
        robots = RobotManipulator.createOrUpdate(robots)

        if not teams:
            # No teams found registered for this event
            teams = []

        # Build EventTeams
        event_teams = [
            EventTeam(id=event.key_name + "_" + team.key_name,
                      event=event.key,
                      team=team.key,
                      year=event.year) for team in teams
        ]

        # Delete eventteams of teams that are no longer registered
        if event.future:
            existing_event_team_keys = set(
                EventTeam.query(EventTeam.event == event.key).fetch(
                    1000, keys_only=True))
            event_team_keys = set([et.key for et in event_teams])
            et_keys_to_delete = existing_event_team_keys.difference(
                event_team_keys)
            EventTeamManipulator.delete_keys(et_keys_to_delete)

        event_teams = EventTeamManipulator.createOrUpdate(event_teams)
        if type(event_teams) is not list:
            event_teams = [event_teams]

        template_values = {
            'event': event,
            'event_teams': event_teams,
        }

        path = os.path.join(
            os.path.dirname(__file__),
            '../templates/datafeeds/usfirst_event_details_get.html')
        self.response.out.write(template.render(path, template_values))
    def get(self, key_name):
        # Combines data from three datafeeds with priorities:
        # 1) DatafeedFMSAPI
        # 2) DatafeedUsfirst (missing rookie year)
        # 3) DatafeedUsfirstLegacy (has all info)

        legacy_df = DatafeedUsfirstLegacy()
        usfirst_df = DatafeedUsfirst()
        fms_df = DatafeedFMSAPI('v2.0')

        # Start with lowest priority
        legacy_team = legacy_df.getTeamDetails(Team.get_by_id(key_name))
        usfirst_team = usfirst_df.getTeamDetails(Team.get_by_id(key_name))
        fms_details = fms_df.getTeamDetails(tba_config.MAX_YEAR, key_name)

        # Separate out the multiple models returned from FMSAPI call
        # Since we're only hitting one team at a time, the response won't
        # ever be paginated so we can ignore the possibility
        if fms_details and fms_details[0]:
            models, more_pages = fms_details
            fms_team, district_team, robot = models[0]
        else:
            fms_team = None
            district_team = None
            robot = None

        team = None
        if usfirst_team:
            team = TeamManipulator.updateMergeBase(usfirst_team, legacy_team)
        if fms_team:
            team = TeamManipulator.updateMergeBase(fms_team, team)

        if district_team:
            district_team = DistrictTeamManipulator.createOrUpdate(
                district_team)
        if robot:
            robot = RobotManipulator.createOrUpdate(robot)
        if team:
            team = TeamManipulator.createOrUpdate(team)
            success = True
        else:
            success = False
            logging.warning(
                "getTeamDetails failed for team: {}".format(key_name))

        template_values = {
            'key_name': key_name,
            'team': team,
            'success': success,
            'district': district_team,
            'robot': robot,
        }

        path = os.path.join(
            os.path.dirname(__file__),
            '../templates/datafeeds/usfirst_team_details_get.html')
        self.response.out.write(template.render(path, template_values))
예제 #8
0
    def get(self, key_name):
        existing_team = Team.get_by_id(key_name)

        fms_df = DatafeedFMSAPI('v2.0')
        df2 = DatafeedFIRSTElasticSearch()
        year = datetime.date.today().year
        fms_details = fms_df.getTeamDetails(year, key_name)

        if fms_details:
            team, district_team, robot = fms_details[0]
        else:
            team = None
            district_team = None
            robot = None

        if team:
            team = TeamManipulator.mergeModels(
                team, df2.getTeamDetails(existing_team))
        else:
            team = df2.getTeamDetails(existing_team)

        if team:
            team = TeamManipulator.createOrUpdate(team)

        # Clean up junk district teams
        # https://www.facebook.com/groups/moardata/permalink/1310068625680096/
        dt_keys = DistrictTeam.query(
            DistrictTeam.team == existing_team.key,
            DistrictTeam.year == year).fetch(keys_only=True)
        keys_to_delete = set()
        for dt_key in dt_keys:
            if not district_team or dt_key.id() != district_team.key.id():
                keys_to_delete.add(dt_key)
        DistrictTeamManipulator.delete_keys(keys_to_delete)

        if district_team:
            district_team = DistrictTeamManipulator.createOrUpdate(
                district_team)

        if robot:
            robot = RobotManipulator.createOrUpdate(robot)

        template_values = {
            'key_name': key_name,
            'team': team,
            'success': team is not None,
            'district': district_team,
            'robot': robot,
        }

        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_team_details_get.html')
            self.response.out.write(template.render(path, template_values))
    def get(self, year):
        year = int(year)
        team_districts = defaultdict(list)
        logging.info("Fetching events in {}".format(year))
        year_events = Event.query(year == Event.year, Event.district_key == None, Event.event_district_enum != None).fetch()
        for event in year_events:
            logging.info("Fetching EventTeams for {}".format(event.key_name))
            event_teams = EventTeam.query(EventTeam.event == event.key).fetch()
            for event_team in event_teams:
                team_districts[event_team.team.id()].append(event.district_key.id())

        new_district_teams = []
        for team_key, districts in team_districts.iteritems():
            most_frequent_district_key = max(set(districts), key=districts.count)
            logging.info("Assuming team {} belongs to {}".format(team_key, most_frequent_district_key))
            dt_key = DistrictTeam.renderKeyName(most_frequent_district_key, team_key)
            new_district_teams.append(DistrictTeam(id=dt_key, year=year, team=ndb.Key(Team, team_key), district_key=ndb.Key(District, most_frequent_district_key)))

        logging.info("Finishing updating old district teams from event teams")
        DistrictTeamManipulator.createOrUpdate(new_district_teams)
        self.response.out.write("Finished creating district teams for {}".format(year))
    def get(self, key_name):
        # Combines data from three datafeeds with priorities:
        # 1) DatafeedFMSAPI
        # 2) DatafeedUsfirst (missing rookie year)
        # 3) DatafeedUsfirstLegacy (has all info)

        legacy_df = DatafeedUsfirstLegacy()
        usfirst_df = DatafeedUsfirst()
        fms_df = DatafeedFMSAPI('v2.0')

        # Start with lowest priority
        legacy_team = legacy_df.getTeamDetails(Team.get_by_id(key_name))
        usfirst_team = usfirst_df.getTeamDetails(Team.get_by_id(key_name))
        fms_details = fms_df.getTeamDetails(tba_config.MAX_YEAR, key_name)

        # Separate out the multiple models returned from FMSAPI call
        # Since we're only hitting one team at a time, the response won't
        # ever be paginated so we can ignore the possibility
        if fms_details and fms_details[0]:
            models, more_pages = fms_details
            fms_team, district_team, robot = models[0]
        else:
            fms_team = None
            district_team = None
            robot = None

        team = None
        if usfirst_team:
            team = TeamManipulator.updateMergeBase(usfirst_team, legacy_team)
        if fms_team:
            team = TeamManipulator.updateMergeBase(fms_team, team)

        if district_team:
            district_team = DistrictTeamManipulator.createOrUpdate(district_team)
        if robot:
            robot = RobotManipulator.createOrUpdate(robot)
        if team:
            team = TeamManipulator.createOrUpdate(team)
            success = True
        else:
            success = False
            logging.warning("getTeamDetails failed for team: {}".format(key_name))

        template_values = {
            'key_name': key_name,
            'team': team,
            'success': success,
            'district': district_team,
            'robot': robot,
        }

        path = os.path.join(os.path.dirname(__file__), '../templates/datafeeds/usfirst_team_details_get.html')
        self.response.out.write(template.render(path, template_values))
    def get(self, event_key):
        df = DatafeedFMSAPI('v2.0')
        event = Event.get_by_id(event_key)

        models = df.getEventTeams(event_key)
        teams = []
        district_teams = []
        robots = []
        for group in models:
            # models is a list of tuples (team, districtTeam, robot)
            if isinstance(group[0], Team):
                teams.append(group[0])
            if isinstance(group[1], DistrictTeam):
                district_teams.append(group[1])
            if isinstance(group[2], Robot):
                robots.append(group[2])

        # Write new models
        teams = TeamManipulator.createOrUpdate(teams)
        district_teams = DistrictTeamManipulator.createOrUpdate(district_teams)
        robots = RobotManipulator.createOrUpdate(robots)

        if not teams:
            # No teams found registered for this event
            teams = []

        # Build EventTeams
        event_teams = [EventTeam(
            id=event.key_name + "_" + team.key_name,
            event=event.key,
            team=team.key,
            year=event.year)
            for team in teams]

        # Delete eventteams of teams that are no longer registered
        if event.future:
            existing_event_team_keys = set(EventTeam.query(EventTeam.event == event.key).fetch(1000, keys_only=True))
            event_team_keys = set([et.key for et in event_teams])
            et_keys_to_delete = existing_event_team_keys.difference(event_team_keys)
            EventTeamManipulator.delete_keys(et_keys_to_delete)

        event_teams = EventTeamManipulator.createOrUpdate(event_teams)
        if type(event_teams) is not list:
            event_teams = [event_teams]

        template_values = {
            'event': event,
            'event_teams': event_teams,
        }

        path = os.path.join(os.path.dirname(__file__), '../templates/datafeeds/usfirst_event_details_get.html')
        self.response.out.write(template.render(path, template_values))
예제 #12
0
    def get(self, key_name):
        existing_team = Team.get_by_id(key_name)

        fms_df = DatafeedFMSAPI('v2.0')
        df2 = DatafeedFIRSTElasticSearch()
        year = datetime.date.today().year
        fms_details = fms_df.getTeamDetails(year, key_name)

        if fms_details:
            team, district_team, robot = fms_details[0]
        else:
            team = None
            district_team = None
            robot = None

        if team:
            team = TeamManipulator.mergeModels(team, df2.getTeamDetails(existing_team))
        else:
            team = df2.getTeamDetails(existing_team)

        if team:
            team = TeamManipulator.createOrUpdate(team)

        # Clean up junk district teams
        # https://www.facebook.com/groups/moardata/permalink/1310068625680096/
        dt_keys = DistrictTeam.query(
            DistrictTeam.team == existing_team.key,
            DistrictTeam.year == year).fetch(keys_only=True)
        keys_to_delete = set()
        for dt_key in dt_keys:
            if not district_team or dt_key.id() != district_team.key.id():
                keys_to_delete.add(dt_key)
        DistrictTeamManipulator.delete_keys(keys_to_delete)

        if district_team:
            district_team = DistrictTeamManipulator.createOrUpdate(district_team)

        if robot:
            robot = RobotManipulator.createOrUpdate(robot)

        template_values = {
            'key_name': key_name,
            'team': team,
            'success': team is not None,
            'district': district_team,
            'robot': robot,
        }

        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_team_details_get.html')
            self.response.out.write(template.render(path, template_values))
예제 #13
0
    def get(self, key_name):
        # Combines data from three datafeeds with priorities:
        # 1) DatafeedFMSAPI (missing website)
        # 2) DatafeedUsfirst (missing rookie year)
        # 3) DatafeedUsfirstLegacy (has all info)

        legacy_df = DatafeedUsfirstLegacy()
        usfirst_df = DatafeedUsfirst()
        fms_df = DatafeedFMSAPI('v2.0')

        # Start with lowest priority
        legacy_team = legacy_df.getTeamDetails(Team.get_by_id(key_name))
        usfirst_team = usfirst_df.getTeamDetails(Team.get_by_id(key_name))
        fms_details = fms_df.getTeamDetails(date.today().year, key_name)

        if fms_details:
            fms_team, district_team, robot = fms_details
        else:
            fms_team = None
            district_team = None
            robot = None

        team = None
        if usfirst_team:
            team = TeamManipulator.updateMergeBase(usfirst_team, legacy_team)
        if fms_team:
            team = TeamManipulator.updateMergeBase(fms_team, team)

        if district_team:
            district_team = DistrictTeamManipulator.createOrUpdate(district_team)
        if robot:
            robot = RobotManipulator.createOrUpdate(robot)
        if team:
            team = TeamManipulator.createOrUpdate(team)
            success = True
        else:
            success = False
            logging.warning("getTeamDetails failed for team: {}".format(key_name))

        template_values = {
            'key_name': key_name,
            'team': team,
            'success': success,
            'district': district_team,
            'robot': robot,
        }

        path = os.path.join(os.path.dirname(__file__), '../templates/datafeeds/usfirst_team_details_get.html')
        self.response.out.write(template.render(path, template_values))
예제 #14
0
    def get(self, key_name):
        existing_team = Team.get_by_id(key_name)

        fms_df = DatafeedFMSAPI('v2.0')
        df2 = DatafeedFIRSTElasticSearch()
        fms_details = fms_df.getTeamDetails(datetime.date.today().year,
                                            key_name)

        if fms_details:
            team, district_team, robot = fms_details[0]
        else:
            team = None
            district_team = None
            robot = None

        if team:
            team = TeamManipulator.mergeModels(
                team, df2.getTeamDetails(existing_team))
        else:
            team = df2.getTeamDetails(existing_team)

        if team:
            team = TeamManipulator.createOrUpdate(team)

        if district_team:
            district_team = DistrictTeamManipulator.createOrUpdate(
                district_team)

        if robot:
            robot = RobotManipulator.createOrUpdate(robot)

        template_values = {
            'key_name': key_name,
            'team': team,
            'success': team is not None,
            'district': district_team,
            'robot': robot,
        }

        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_team_details_get.html')
            self.response.out.write(template.render(path, template_values))
    def get(self, key_name):
        existing_team = Team.get_by_id(key_name)

        fms_df = DatafeedFMSAPI('v2.0')
        df2 = DatafeedFIRSTElasticSearch()
        fms_details = fms_df.getTeamDetails(datetime.date.today().year, key_name)

        if fms_details:
            team, district_team, robot = fms_details[0]
        else:
            team = None
            district_team = None
            robot = None

        if team:
            team = TeamManipulator.mergeModels(team, df2.getTeamDetails(existing_team))
        else:
            team = df2.getTeamDetails(existing_team)

        if team:
            team = TeamManipulator.createOrUpdate(team)

        if district_team:
            district_team = DistrictTeamManipulator.createOrUpdate(district_team)

        if robot:
            robot = RobotManipulator.createOrUpdate(robot)

        template_values = {
            'key_name': key_name,
            'team': team,
            'success': team is not None,
            'district': district_team,
            'robot': robot,
        }

        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_team_details_get.html')
            self.response.out.write(template.render(path, template_values))
예제 #16
0
    def get(self, event_key):
        df = DatafeedFMSAPI('v2.0')
        df2 = DatafeedFIRSTElasticSearch()

        event = Event.get_by_id(event_key)

        # Update event
        fmsapi_events, fmsapi_districts = df.getEventDetails(event_key)
        elasticsearch_events = df2.getEventDetails(event)
        updated_event = EventManipulator.mergeModels(fmsapi_events,
                                                     elasticsearch_events)
        if updated_event:
            event = EventManipulator.createOrUpdate(updated_event)
        DistrictManipulator.createOrUpdate(fmsapi_districts)

        models = df.getEventTeams(event_key)
        teams = []
        district_teams = []
        robots = []
        for group in models:
            # models is a list of tuples (team, districtTeam, robot)
            if isinstance(group[0], Team):
                teams.append(group[0])
            if isinstance(group[1], DistrictTeam):
                district_teams.append(group[1])
            if isinstance(group[2], Robot):
                robots.append(group[2])

        # Merge teams
        teams = TeamManipulator.mergeModels(teams, df2.getEventTeams(event))

        # Write new models
        if teams and event.year == tba_config.MAX_YEAR:  # Only update from latest year
            teams = TeamManipulator.createOrUpdate(teams)
        district_teams = DistrictTeamManipulator.createOrUpdate(district_teams)
        robots = RobotManipulator.createOrUpdate(robots)

        if not teams:
            # No teams found registered for this event
            teams = []
        if type(teams) is not list:
            teams = [teams]

        # Build EventTeams
        cmp_hack_sitevar = Sitevar.get_or_insert('cmp_registration_hacks')
        events_without_eventteams = cmp_hack_sitevar.contents.get('skip_eventteams', []) \
            if cmp_hack_sitevar else []
        skip_eventteams = event_key in events_without_eventteams
        event_teams = [
            EventTeam(id=event.key_name + "_" + team.key_name,
                      event=event.key,
                      team=team.key,
                      year=event.year) for team in teams
        ] if not skip_eventteams else []

        # Delete eventteams of teams that are no longer registered
        if event_teams and not skip_eventteams:
            existing_event_team_keys = set(
                EventTeam.query(EventTeam.event == event.key).fetch(
                    1000, keys_only=True))
            event_team_keys = set([et.key for et in event_teams])
            et_keys_to_delete = existing_event_team_keys.difference(
                event_team_keys)
            EventTeamManipulator.delete_keys(et_keys_to_delete)

            event_teams = EventTeamManipulator.createOrUpdate(event_teams)
        if type(event_teams) is not list:
            event_teams = [event_teams]

        if event.year in {2018, 2019, 2020}:
            avatars, keys_to_delete = df.getEventTeamAvatars(event.key_name)
            if avatars:
                MediaManipulator.createOrUpdate(avatars)
            MediaManipulator.delete_keys(keys_to_delete)

        template_values = {
            'event': event,
            'event_teams': event_teams,
        }

        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_details_get.html')
            self.response.out.write(template.render(path, template_values))
    def get(self, event_key):
        df = DatafeedFMSAPI('v2.0')
        df2 = DatafeedFIRSTElasticSearch()

        event = Event.get_by_id(event_key)

        # Update event
        fmsapi_events, fmsapi_districts = df.getEventDetails(event_key)
        elasticsearch_events = df2.getEventDetails(event)
        updated_event = EventManipulator.mergeModels(
            fmsapi_events,
            elasticsearch_events)
        if updated_event:
            event = EventManipulator.createOrUpdate(updated_event)
        DistrictManipulator.createOrUpdate(fmsapi_districts)

        models = df.getEventTeams(event_key)
        teams = []
        district_teams = []
        robots = []
        for group in models:
            # models is a list of tuples (team, districtTeam, robot)
            if isinstance(group[0], Team):
                teams.append(group[0])
            if isinstance(group[1], DistrictTeam):
                district_teams.append(group[1])
            if isinstance(group[2], Robot):
                robots.append(group[2])

        # Merge teams
        teams = TeamManipulator.mergeModels(teams, df2.getEventTeams(event))

        # Write new models
        if teams:
            teams = TeamManipulator.createOrUpdate(teams)
        district_teams = DistrictTeamManipulator.createOrUpdate(district_teams)
        robots = RobotManipulator.createOrUpdate(robots)

        if not teams:
            # No teams found registered for this event
            teams = []
        if type(teams) is not list:
            teams = [teams]

        # Build EventTeams
        cmp_hack_sitevar = Sitevar.get_or_insert('cmp_registration_hacks')
        events_without_eventteams = cmp_hack_sitevar.contents.get('skip_eventteams', []) \
            if cmp_hack_sitevar else []
        skip_eventteams = event_key in events_without_eventteams
        event_teams = [EventTeam(
            id=event.key_name + "_" + team.key_name,
            event=event.key,
            team=team.key,
            year=event.year)
            for team in teams] if not skip_eventteams else []

        # Delete eventteams of teams that are no longer registered
        if event_teams != [] or skip_eventteams:
            existing_event_team_keys = set(EventTeam.query(EventTeam.event == event.key).fetch(1000, keys_only=True))
            event_team_keys = set([et.key for et in event_teams])
            et_keys_to_delete = existing_event_team_keys.difference(event_team_keys)
            EventTeamManipulator.delete_keys(et_keys_to_delete)

            event_teams = EventTeamManipulator.createOrUpdate(event_teams)
        if type(event_teams) is not list:
            event_teams = [event_teams]

        template_values = {
            'event': event,
            'event_teams': event_teams,
        }

        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_details_get.html')
            self.response.out.write(template.render(path, template_values))