def _process_request(self, request, event_key):
        alliance_selections = JSONAllianceSelectionsParser.parse(request.body)

        event = Event.get_by_id(event_key)
        event.alliance_selections_json = json.dumps(alliance_selections)
        event.dirty = True  # TODO: hacky
        EventManipulator.createOrUpdate(event)
    def _process_request(self, request, event_key):
        rankings = JSONRankingsParser.parse(request.body)

        event = Event.get_by_id(event_key)
        event.rankings_json = json.dumps(rankings)
        event.dirty = True  # TODO: hacky
        EventManipulator.createOrUpdate(event)
    def get(self, year):
        df = DatafeedFMSAPI('v2.0')
        df2 = DatafeedFIRSTElasticSearch()

        fmsapi_events, fmsapi_districts = df.getEventList(year)
        elasticsearch_events = df2.getEventList(year)
        merged_events = EventManipulator.mergeModels(fmsapi_events, elasticsearch_events)
        events = EventManipulator.createOrUpdate(merged_events)
        districts = DistrictManipulator.createOrUpdate(fmsapi_districts)

        # Fetch event details for each event
        for event in events:
            taskqueue.add(
                queue_name='datafeed',
                target='backend-tasks',
                url='/backend-tasks/get/event_details/'+event.key_name,
                method='GET'
            )

        template_values = {
            "events": events,
            "districts": districts,
        }

        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/fms_event_list_get.html')
            self.response.out.write(template.render(path, template_values))
    def get(self, year):
        self._require_admin()
        year = int(year)
        events = EventListQuery(year).fetch()
        events_by_type = defaultdict(list)
        for event in events:
            if event.event_type_enum in self.TYPE_MAP.keys() or event.event_type_enum in self.TYPE_MAP.values():
                events_by_type[event.event_type_enum].append(event)

        output = ""
        for from_type, to_type in self.TYPE_MAP.iteritems():
            for event in events_by_type[to_type]:
                divisions = []
                for candidate_division in events_by_type[from_type]:
                    if candidate_division.end_date.date() == event.end_date.date() and candidate_division.district_key == event.district_key:
                        candidate_division.parent_event = event.key
                        divisions.append(candidate_division.key)
                        output += "Event {} is the parent of {}<br/>".format(event.key_name, candidate_division.key_name)
                        EventManipulator.createOrUpdate(candidate_division)

                event.divisions = divisions
                if divisions:
                    output += "Divisions {} added to {}<br/>".format(event.division_keys_json, event.key_name)
                EventManipulator.createOrUpdate(event)
        self.response.out.write(output)
    def get(self, event_key):
        event = Event.get_by_id(event_key)
        matchstats_dict = MatchstatsHelper.calculate_matchstats(event.matches, event.year)

        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)

            matchstats_dict['match_predictions'] = match_predictions
            matchstats_dict['match_prediction_stats'] = match_prediction_stats
            matchstats_dict['ranking_predictions'] = ranking_predictions
            matchstats_dict['ranking_prediction_stats'] = ranking_prediction_stats

        if any([v != {} for v in matchstats_dict.values()]):
            event.matchstats_json = json.dumps(matchstats_dict)
            EventManipulator.createOrUpdate(event)
        else:
            logging.warn("Matchstat calculation for {} failed!".format(event_key))

        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_id):
        self._require_admin()

        event = Event.get_by_id(event_key_id)
        if not event:
            self.abort(404)

        place_id = self.request.get('place_id')
        if not place_id:
            self.abort(400)

        # Construct a mostly empty input struct that'll get filled in
        location_input = {
            'place_id': place_id,
            'geometry': {
                'location': {
                    'lat': '',
                    'lng': '',
                },
            },
            'name': '',
            'types': [],
        }

        location_info = LocationHelper.construct_location_info_async(location_input).get_result()
        event.normalized_location = LocationHelper.build_normalized_location(location_info)
        EventManipulator.createOrUpdate(event)
        self.redirect('/admin/event/{}'.format(event_key_id))
    def create_target_model(self, suggestion):
        event_id = self.request.get("event_short", None)
        event_key = str(self.request.get("year")) + str.lower(str(self.request.get("event_short")))
        if not event_id:
            # Need to supply a key :(
            return 'missing_key', None
        if not Event.validate_key_name(event_key):
            # Bad event key generated
            return 'bad_key', None

        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")

        existing_event = Event.get_by_id(event_key)
        if existing_event:
            return 'duplicate_key', None

        first_code = self.request.get("first_code", '')
        event = Event(
            id=event_key,
            end_date=end_date,
            event_short=self.request.get("event_short"),
            event_type_enum=EventType.OFFSEASON,
            district_key=None,
            venue=self.request.get("venue"),
            venue_address=self.request.get("venue_address"),
            city=self.request.get("city"),
            state_prov=self.request.get("state"),
            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")),
            first_code=first_code,
            official=(not first_code == ''),
        )
        EventManipulator.createOrUpdate(event)

        author = suggestion.author.get()
        OutgoingNotificationHelper.send_suggestion_result_email(
            to=author.email,
            subject="[TBA] Offseason Event Suggestion: {}".format(event.name),
            email_body="""Dear {},

Thank you for suggesting an offseason event to The Blue Alliance. Your suggestion has been approved and you can find the event at https://thebluealliance.com/event/{}

If you are the event's organizer and would like to upload teams attending, match videos, or real-time match results to TBA before or during the event, you can do so using the TBA EventWizard - request auth keys here: https://www.thebluealliance.com/request/apiwrite

Thanks for helping make TBA better,
The Blue Alliance Admins
            """.format(author.nickname, event_key)
        )

        return 'success', event_key
    def get(self, event_key):
        event = Event.get_by_id(event_key)
        event.short_name = EventHelper.getShortName(event.name)
        EventManipulator.createOrUpdate(event)

        template_values = {'event': event}
        path = os.path.join(os.path.dirname(__file__), '../templates/math/event_short_name_calc_do.html')
        self.response.out.write(template.render(path, template_values))
    def _process_request(self, request, event_key):
        rankings = JSONRankingsParser.parse(request.body)

        event = Event.get_by_id(event_key)
        event.rankings_json = json.dumps(rankings)
        event.dirty = True  # TODO: hacky
        EventManipulator.createOrUpdate(event)

        self.response.out.write(json.dumps({'Success': "Rankings successfully updated"}))
    def _process_request(self, request, event_key):
        alliance_selections = JSONAllianceSelectionsParser.parse(request.body)

        event = Event.get_by_id(event_key)
        event.alliance_selections_json = json.dumps(alliance_selections)
        event.dirty = True  # TODO: hacky
        EventManipulator.createOrUpdate(event)

        self.response.out.write(json.dumps({'Success': "Alliance selections successfully updated"}))
    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.district_points_json = json.dumps(district_points)
        EventManipulator.createOrUpdate(event)

        self.response.out.write(event.district_points)
 def get(self, year):
     self._require_admin()
     year = int(year)
     events = EventListQuery(year).fetch()
     for event in events:
         if not event.playoff_type:
             if event.year == 2015 and event.key_name not in self.EXCEPTIONS_2015:
                 event.playoff_type = PlayoffType.AVG_SCORE_8_TEAM
             else:
                 event.playoff_type = PlayoffType.BRACKET_8_TEAM
         EventManipulator.createOrUpdate(event)
     self.response.out.write("Update {} events".format(len(events)))
    def remove_webcast(cls, event, index, type, channel, file):
        webcasts = event.webcast
        if not webcasts or index >= len(webcasts):
            return

        webcast = webcasts[index]
        if type != webcast.get("type") or channel != webcast.get("channel") or file != webcast.get("file"):
            return

        webcasts.pop(index)
        event.webcast_json = json.dumps(webcasts)
        EventManipulator.createOrUpdate(event, auto_union=False)
        MemcacheWebcastFlusher.flushEvent(event.key_name)
    def get(self, event_key):
        event = Event.get_by_id(event_key)
        matchstats_dict = MatchstatsHelper.calculate_matchstats(event.matches)
        if matchstats_dict != {}:
            event.matchstats_json = json.dumps(matchstats_dict)
            event.dirty = True  # TODO: hacky
            EventManipulator.createOrUpdate(event)
        else:
            logging.warn("Matchstat calculation for {} failed!".format(event_key))

        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_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)

        if alliance_selections and event.alliance_selections != alliance_selections:
            event.alliance_selections_json = json.dumps(alliance_selections)
            event._alliance_selections = None
            event.dirty = True

        EventManipulator.createOrUpdate(event)

        self.redirect("/admin/event/" + event.key_name)
    def get(self, event_key):
        event = Event.get_by_id(event_key)
        matchstats_dict = MatchstatsHelper.calculate_matchstats(event.matches)
        if any([v != {} for v in matchstats_dict.values()]):
            event.matchstats_json = json.dumps(matchstats_dict)
            EventManipulator.createOrUpdate(event)
        else:
            logging.warn("Matchstat calculation for {} failed!".format(event_key))

        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):
        self.verify_permissions()
        suggestion = Suggestion.get_by_id(int(self.request.get("suggestion_id")))
        verdict = self.request.get("verdict")
        if verdict == "accept":
            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")

            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=EventType.OFFSEASON,
                event_district_enum=DistrictType.NO_DISTRICT,
                venue=self.request.get("venue"),
                venue_address=self.request.get("venue_address"),
                location=self.request.get("location"),
                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=False,
            )
            EventManipulator.createOrUpdate(event)

            suggestion.review_state = Suggestion.REVIEW_ACCEPTED
            suggestion.reviewer = self.user_bundle.account.key
            suggestion.reviewed_at = datetime.now()
            suggestion.put()

            self.redirect("/suggest/offseason/review?success=accept&event_key=%s" % event.key.id())
            return
        elif verdict == "reject":
            suggestion.review_state = Suggestion.REVIEW_REJECTED
            suggestion.reviewer = self.user_bundle.account.key
            suggestion.reviewed_at = datetime.now()
            suggestion.put()

            self.redirect("/suggest/offseason/review?success=reject")
            return

        self.redirect("/suggest/offseason/review")
    def get(self, year, first_eid):
        datafeed = DatafeedUsfirst()

        event = datafeed.getEventDetails(int(year), first_eid)
        event = EventManipulator.createOrUpdate(event)
        
        teams = datafeed.getEventTeams(int(year), first_eid)
        teams = TeamManipulator.createOrUpdate(teams)

        if teams:
            event_teams = [EventTeam(
                id = event.key.id() + "_" + team.key.id(),
                event = event.key,
                team = team.key,
                year = event.year)
                for team in teams]
            event_teams = EventTeamManipulator.createOrUpdate(event_teams)
        else:
            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, event_key):
        df = DatafeedUsfirst()

        event = Event.get_by_id(event_key)
        rankings = df.getEventRankings(event)
        if event.rankings_json != json.dumps(rankings):
            event.rankings_json = json.dumps(rankings)
            event.dirty = True

        EventManipulator.createOrUpdate(event)

        template_values = {'rankings': rankings,
                           'event_name': event.key_name}

        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 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")

        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")),
            location=self.request.get("location"),
            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"),
            webcast_json=self.request.get("webcast_json"),
            rankings_json=self.request.get("rankings_json"),
        )
        event = EventManipulator.createOrUpdate(event)

        self.redirect("/admin/event/" + event.key_name)
    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
        if event.year < 2014:
            self.response.out.write("Can't calculate district points for events before 2014!")  # TODO: implement correct points for pre-2014 districts
            return

        district_points = DistrictHelper.calculate_event_points(event)

        event.district_points_json = json.dumps(district_points)
        event.dirty = True  # This is so hacky. -fangeugene 2014-05-08
        EventManipulator.createOrUpdate(event)

        self.response.out.write(event.district_points)
    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 add_webcast(cls, event, webcast):
        """Takes a webcast dictionary and adds it to an event"""

        if event.webcast:
            webcasts = event.webcast
            if webcast in webcasts:
                return event
            else:
                webcasts.append(webcast)
                event.webcast_json = json.dumps(webcasts)
        else:
            event.webcast_json = json.dumps([webcast])
        event.dirty = True
        EventManipulator.createOrUpdate(event)
        MemcacheWebcastFlusher.flushEvent(event.key_name)

        return event
    def post(self, event_key_id):
        logging.warning("Deleting %s at the request of %s / %s" % (
            event_key_id,
            users.get_current_user().user_id(),
            users.get_current_user().email()))

        event = Event.get_by_id(event_key_id)
        
        matches = Match.query(Match.event == event.key).fetch(5000)
        MatchManipulator.delete(matches)

        event_teams = EventTeam.query(EventTeam.event == event.key).fetch(5000)
        EventTeamManipulator.delete(event_teams)

        EventManipulator.delete(event)

        self.redirect("/admin/events?deleted=%s" % event_key_id)
    def post(self, event_key_id):
        self._require_admin()
        event = Event.get_by_id(event_key_id)

        remap_teams = {}
        for key, value in json.loads(self.request.get('remap_teams')).items():
            remap_teams['frc{}'.format(key)] = 'frc{}'.format(value)

        event.remap_teams = remap_teams
        EventManipulator.createOrUpdate(event)

        taskqueue.add(
            url='/tasks/do/remap_teams/{}'.format(event.key_name),
            method='GET',
            queue_name='admin',
        )

        self.redirect("/admin/event/" + event.key_name)
    def get(self, event_key):
        df = DatafeedFMSAPI('v2.0')

        rankings = df.getEventRankings(event_key)

        event = Event.get_by_id(event_key)
        if rankings and event.rankings_json != json.dumps(rankings):
            event.rankings_json = json.dumps(rankings)
            event.dirty = True

        EventManipulator.createOrUpdate(event)

        template_values = {'rankings': rankings,
                           'event_name': event.key_name}

        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 post(self):
        self._require_admin()

        if self.request.get("submit") == "duplicate":
            old_event = Event.get_by_id(self.request.get("duplicate_event_key"))
            old_event.first_eid = self.request.get("event_first_eid")
            old_event.dirty = True  # TODO: hacky
            EventManipulator.createOrUpdate(old_event)

            self.redirect("/admin/offseasons?success=duplicate&event_key=%s" % self.request.get("duplicate_event_key"))
            return

        if self.request.get("submit") == "create":

            start_date = None
            if self.request.get("event_start_date"):
                start_date = datetime.datetime.strptime(self.request.get("event_start_date"), "%Y-%m-%d")

            end_date = None
            if self.request.get("event_end_date"):
                end_date = datetime.datetime.strptime(self.request.get("event_end_date"), "%Y-%m-%d")

            event_key = str(self.request.get("event_year")) + str.lower(str(self.request.get("event_short")))

            event = Event(
                id=event_key,
                event_type_enum=int(self.request.get("event_type_enum")),
                event_short=self.request.get("event_short"),
                first_eid=self.request.get("event_first_eid"),
                name=self.request.get("event_name"),
                year=int(self.request.get("event_year")),
                start_date=start_date,
                end_date=end_date,
                city=self.request.get("city"),
                state_prov=self.request.get("state_prov"),
                country=self.request.get("country"),
                )
            event = EventManipulator.createOrUpdate(event)

            self.redirect("/admin/offseasons?success=create&event_key=%s" % event_key)
            return

        self.redirect("/admin/offseasons")
    def get(self, event_key):
        df = DatafeedFMSAPI('v2.0')

        event = Event.get_by_id(event_key)

        alliance_selections = df.getEventAlliances(event_key)
        if alliance_selections and event.alliance_selections != alliance_selections:
            event.alliance_selections_json = json.dumps(alliance_selections)
            event._alliance_selections = None
            event.dirty = True

        EventManipulator.createOrUpdate(event)

        template_values = {'alliance_selections': alliance_selections,
                           'event_name': event.key_name}

        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 get(self, year):
        df = DatafeedFMSAPI('v2.0')
        first_events, _ = df.getSyncEnabledOffseasonEvents(year)
        linked_events, maybed_linked_events, new_events = \
            OffseasonEventHelper.categorize_offseasons(int(year), first_events)

        events_to_update = []
        events_to_put = []

        # for all events with a first_code linked, ensure official=True
        logging.info("Found {} already linked events".format(len(linked_events)))
        for tba, first in linked_events:
            if tba.first_code != first.event_short or not tba.official:
                tba.first_code = first.event_short
                tba.official = True
                events_to_put.append(tba)
            events_to_update.append(tba)

        # for all events that we can maybe link, also do that
        logging.info("Auto-linking {} probably events".format(len(maybed_linked_events)))
        for tba, first in maybed_linked_events:
            tba.first_code = first.event_short
            tba.official = True
            events_to_put.append(tba)
            events_to_update.append(tba)

        logging.info("Found {} events to put".format(len(events_to_put)))
        if events_to_put:
            EventManipulator.createOrUpdate(events_to_put)

        # Enqueue details updates for these events
        logging.info("Found {} events to update".format(len(events_to_update)))
        for event in events_to_update:
            taskqueue.add(
                queue_name='datafeed',
                target='backend-tasks',
                url='/backend-tasks/get/event_details/'+event.key_name,
                method='GET'
            )

        # Event we don't have anything for... Create suggestions
        logging.info("Found {} new events to link".format(len(new_events)))
        SuggestionCreator.createDummyOffseasonSuggestions(new_events)
    def get(self, year, first_eid):
        df = DatafeedUsfirst()
        df_legacy = DatafeedUsfirstLegacy()

        event = df.getEventDetails(first_eid)
        if not event:
            logging.warning("getEventDetails with DatafeedUsfirst for event id {} failed. Retrying with DatafeedUsfirstLegacy.".format(first_eid))
            event = df_legacy.getEventDetails(int(year), first_eid)

        if self.request.get('event_district_enum'):
            event.event_district_enum = int(self.request.get('event_district_enum'))
        event = EventManipulator.createOrUpdate(event)

        teams = df.getEventTeams(int(year), first_eid)
        if not teams:
            logging.warning("getEventTeams with DatafeedUsfirst for event id {} failed. Retrying with DatafeedUsfirstLegacy.".format(first_eid))
            teams = df_legacy.getEventTeams(int(year), first_eid)
            if not teams:
                logging.warning("getEventTeams with DatafeedUsfirstLegacy for event id {} failed.".format(first_eid))
                teams = []

        teams = TeamManipulator.createOrUpdate(teams)

        if teams:
            if type(teams) is not list:
                teams = [teams]

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

            # Delete eventteams of teams that unregister from an event
            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]
        else:
            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))