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")),
            event_district_enum=EventHelper.parseDistrictName(self.request.get("event_district_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)

        MemcacheWebcastFlusher.flushEvent(event.key_name)

        self.redirect("/admin/event/" + event.key_name)
    def parse(self, response):
        events = []
        districts = {}
        for event in response['Events']:
            code = event['code'].lower()
            event_type = EventType.PRESEASON if code == 'week0' else self.EVENT_TYPES.get(event['type'].lower(), None)
            if event_type is None:
                logging.warn("Event type '{}' not recognized!".format(event['type']))
                continue
            name = event['name']
            short_name = EventHelper.getShortName(name)
            district_enum = EventHelper.parseDistrictName(event['districtCode'].lower()) if event['districtCode'] else DistrictType.NO_DISTRICT
            district_key = District.renderKeyName(self.season, event['districtCode'].lower()) if event['districtCode'] else None
            venue = event['venue']
            city = event['city']
            state_prov = event['stateprov']
            country = event['country']
            start = datetime.datetime.strptime(event['dateStart'], self.DATE_FORMAT_STR)
            end = datetime.datetime.strptime(event['dateEnd'], self.DATE_FORMAT_STR)
            website = event.get('website')

            # TODO read timezone from API

            # Special cases for champs
            if code in self.EVENT_CODE_EXCEPTIONS:
                code, short_name = self.EVENT_CODE_EXCEPTIONS[code]
                if code in self.EINSTEIN_CODES:
                    name = '{} Field'.format(short_name)
                    start = end.replace(hour=0, minute=0, second=0, microsecond=0)  # Set to beginning of last day
                else:  # Divisions
                    name = '{} Division'.format(short_name)

            events.append(Event(
                id="{}{}".format(self.season, code),
                name=name,
                short_name=short_name,
                event_short=code,
                event_type_enum=event_type,
                official=True,
                start_date=start,
                end_date=end,
                venue=venue,
                city=city,
                state_prov=state_prov,
                country=country,
                venue_address=None,  # Even though FRC API provides address, ElasticSearch is more detailed
                year=self.season,
                event_district_enum=district_enum,
                district_key=ndb.Key(District, district_key) if district_key else None,
                website=website,
            ))

            # Build District Model
            if district_key and district_key not in districts:
                districts[district_key] = District(
                    id=district_key,
                    year=self.season,
                    abbreviation=event['districtCode'].lower(),
                )
        return events, list(districts.values())
 def test_event_parse_district_name(self):
     """
     A bunch of tests from various years
     """
     self.assertEqual(EventHelper.parseDistrictName('FIRST in Michigan'), DistrictType.MICHIGAN)
     self.assertEqual(EventHelper.parseDistrictName('Mid-Atlantic Robotics'), DistrictType.MID_ATLANTIC)
     self.assertEqual(EventHelper.parseDistrictName('New England'), DistrictType.NEW_ENGLAND)
     self.assertEqual(EventHelper.parseDistrictName('Pacific Northwest'), DistrictType.PACIFIC_NORTHWEST)
     self.assertEqual(EventHelper.parseDistrictName('IndianaFIRST'), DistrictType.INDIANA)
     self.assertEqual(EventHelper.parseDistrictName('Not a valid district'), DistrictType.NO_DISTRICT)
     self.assertEqual(EventHelper.parseDistrictName('California'), DistrictType.NO_DISTRICT)
     self.assertEqual(EventHelper.parseDistrictName(None), DistrictType.NO_DISTRICT)
     self.assertEqual(EventHelper.parseDistrictName(''), DistrictType.NO_DISTRICT)
    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")),
            event_district_enum=EventHelper.parseDistrictName(
                self.request.get("event_district_str")),
            venue=self.request.get("venue"),
            venue_address=self.request.get("venue_address"),
            city=self.request.get("city"),
            state_prov=self.request.get("state_prov"),
            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 parse(self, response):
        events = []
        for event in response["Events"]:
            code = event["code"].lower()
            event_type = self.EVENT_TYPES.get(event["type"].lower(), None)
            if event_type is None:
                logging.warn("Event type '{}' not recognized!".format(event["type"]))
                continue
            name = event["name"]
            short_name = EventHelper.getShortName(name)
            district_enum = (
                EventHelper.parseDistrictName(event["districtCode"].lower())
                if event["districtCode"]
                else DistrictType.NO_DISTRICT
            )
            venue = event["venue"]
            city = event["city"]
            state_prov = event["stateprov"]
            country = event["country"]
            start = datetime.datetime.strptime(event["dateStart"], self.DATE_FORMAT_STR)
            end = datetime.datetime.strptime(event["dateEnd"], self.DATE_FORMAT_STR)

            # TODO read timezone from API

            # Special cases for champs
            if code in self.EVENT_CODE_EXCEPTIONS:
                code, short_name = self.EVENT_CODE_EXCEPTIONS[code]
                if code == "cmp":  # Einstein
                    name = "{} Field".format(short_name)
                    start = end.replace(hour=0, minute=0, second=0, microsecond=0)  # Set to beginning of last day
                else:  # Divisions
                    name = "{} Division".format(short_name)

            events.append(
                Event(
                    id="{}{}".format(self.season, code),
                    name=name,
                    short_name=short_name,
                    event_short=code,
                    event_type_enum=event_type,
                    official=True,
                    start_date=start,
                    end_date=end,
                    venue=venue,
                    city=city,
                    state_prov=state_prov,
                    country=country,
                    venue_address=None,  # FIRST API doesn't provide detailed venue address
                    year=self.season,
                    event_district_enum=district_enum,
                )
            )
        return events
    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")),
            event_district_enum=EventHelper.parseDistrictName(self.request.get("event_district_str")),
            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)
Exemple #7
0
    def parse(self, html):
        """
        Parse the list of events from USFIRST. This provides us with basic
        information about events and is how we first discover them.
        """
        events = list()
        soup = BeautifulSoup(html, convertEntities=BeautifulSoup.HTML_ENTITIES)

        for tr in soup.findAll('tr'):  # Events are in table rows
            event = dict()
            try:
                tds = tr.findAll('td')
                if tds[0].string is None:
                    # this may happen if this is a district event, in which case we can also extract the district name
                    event_type_str = unicode(
                        tds[0].findAll(text=True)[2].string)

                    district_name_str = unicode(tds[0].findAll('em')[0].string)
                else:
                    event_type_str = unicode(tds[0].string)
                    district_name_str = None
                event["event_type_enum"] = EventHelper.parseEventType(
                    event_type_str)
                event["event_district_enum"] = EventHelper.parseDistrictName(
                    district_name_str)
                url_get_params = urlparse.parse_qs(
                    urlparse.urlparse(tds[1].a["href"]).query)
                event["first_eid"] = url_get_params["eid"][0]

                event["name"] = ''.join(tds[1].a.findAll(
                    text=True)).strip()  # <em>s in event names fix
                #event.venue = unicode(tds[2].string)
                #event.location = unicode(tds[3].string)

                # try:
                #    event_dates = str(tds[4].string).strip()
                #    event.start_date, event.stop_date = self.parseEventDates(event_dates)
                #    event.year = int(event_dates[-4:])
                # except Exception, detail:
                #    logging.error('Date Parse Failed: ' + str(detail))

                if event.get("event_type_enum",
                             None) in EventType.NON_CMP_EVENT_TYPES:
                    events.append(event)

            except Exception, detail:
                logging.info('Event parsing failed: ' + str(detail))
    def parse(self, response):
        events = []
        for event in response['Events']:
            code = event['code'].lower()
            event_type = self.EVENT_TYPES.get(event['type'].lower(), None)
            if event_type is None:
                logging.warn("Event type '{}' not recognized!".format(event['type']))
                continue
            name = event['name']
            short_name = EventHelper.getShortName(name)
            district_enum = EventHelper.parseDistrictName(event['districtCode'].lower()) if event['districtCode'] else DistrictType.NO_DISTRICT
            venue = event['venue']
            city = event['city']
            state_prov = event['stateprov']
            country = event['country']
            start = datetime.datetime.strptime(event['dateStart'], self.DATE_FORMAT_STR)
            end = datetime.datetime.strptime(event['dateEnd'], self.DATE_FORMAT_STR)

            # TODO read timezone from API

            # Special cases for champs
            if code in self.EVENT_CODE_EXCEPTIONS:
                code, short_name = self.EVENT_CODE_EXCEPTIONS[code]
                if code in self.EINSTEIN_CODES:
                    name = '{} Field'.format(short_name)
                    start = end.replace(hour=0, minute=0, second=0, microsecond=0)  # Set to beginning of last day
                else:  # Divisions
                    name = '{} Division'.format(short_name)

            events.append(Event(
                id="{}{}".format(self.season, code),
                name=name,
                short_name=short_name,
                event_short=code,
                event_type_enum=event_type,
                official=True,
                start_date=start,
                end_date=end,
                venue=venue,
                city=city,
                state_prov=state_prov,
                country=country,
                venue_address=None,  # FIRST API doesn't provide detailed venue address
                year=self.season,
                event_district_enum=district_enum
            ))
        return events
Exemple #9
0
    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")),
            event_district_enum=EventHelper.parseDistrictName(
                self.request.get("event_district_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)

        MemcacheWebcastFlusher.flushEvent(event.key_name)

        self.redirect("/admin/event/" + event.key_name)
    def parse(self, response):
        events = []
        for event in response['Events']:
            code = event['code'].lower()
            event_type = self.EVENT_TYPES.get(event['type'].lower(), None)
            if event_type is None:
                logging.warn("Event type '{}' not recognized!".format(event['type']))
                continue
            name = event['name']
            short_name = EventHelper.getShortName(name)
            district_enum = EventHelper.parseDistrictName(event['districtCode'].lower()) if event['districtCode'] else DistrictType.NO_DISTRICT
            venue = event['venue']
            location = "{}, {}, {}".format(event['city'], event['stateprov'], event['country'])
            start = datetime.datetime.strptime(event['dateStart'], self.DATE_FORMAT_STR)
            end = datetime.datetime.strptime(event['dateEnd'], self.DATE_FORMAT_STR)

            # TODO read timezone from API

            # Special cases for champs
            if code in self.EVENT_CODE_EXCEPTIONS:
                code, short_name = self.EVENT_CODE_EXCEPTIONS[code]
                if code == 'cmp':  # Einstein
                    name = '{} Field'.format(short_name)
                    start = end.replace(hour=0, minute=0, second=0, microsecond=0)  # Set to beginning of last day
                else:  # Divisions
                    name = '{} Division'.format(short_name)

            events.append(Event(
                id="{}{}".format(self.season, code),
                name=name,
                short_name=short_name,
                event_short=code,
                event_type_enum=event_type,
                official=True,
                start_date=start,
                end_date=end,
                venue=venue,
                location=location,
                venue_address=None,  # FIRST API doesn't provide detailed venue address
                year=self.season,
                event_district_enum=district_enum
            ))
        return events
    def parse(self, html):
        """
        Parse the list of events from USFIRST. This provides us with basic
        information about events and is how we first discover them.
        """
        events = list()
        soup = BeautifulSoup(html,
                             convertEntities=BeautifulSoup.HTML_ENTITIES)

        for tr in soup.findAll('tr'):  # Events are in table rows
            event = dict()
            try:
                tds = tr.findAll('td')
                if tds[0].string is None:
                    # this may happen if this is a district event, in which case we can also extract the district name
                    event_type_str = unicode(tds[0].findAll(text=True)[2].string)

                    district_name_str = unicode(tds[0].findAll('em')[0].string)
                else:
                    event_type_str = unicode(tds[0].string)
                    district_name_str = None
                event["event_type_enum"] = EventHelper.parseEventType(event_type_str)
                event["event_district_enum"] = EventHelper.parseDistrictName(district_name_str)
                url_get_params = urlparse.parse_qs(urlparse.urlparse(tds[1].a["href"]).query)
                event["first_eid"] = url_get_params["eid"][0]

                event["name"] = ''.join(tds[1].a.findAll(text=True)).strip()  # <em>s in event names fix
                #event.venue = unicode(tds[2].string)
                #event.location = unicode(tds[3].string)

                # try:
                #    event_dates = str(tds[4].string).strip()
                #    event.start_date, event.stop_date = self.parseEventDates(event_dates)
                #    event.year = int(event_dates[-4:])
                # except Exception, detail:
                #    logging.error('Date Parse Failed: ' + str(detail))

                if event.get("event_type_enum", None) in EventType.NON_CMP_EVENT_TYPES:
                    events.append(event)

            except Exception, detail:
                logging.info('Event parsing failed: ' + str(detail))
    def parse(self, response):
        events = []
        for event in response['Events']:
            code = event['code'].lower()
            key = "{}{}".format(self.season, code)
            name = event['name']
            short_name = EventHelper.getShortName(name)
            event_type = EventHelper.parseEventType(event['type'])
            district_enum = EventHelper.parseDistrictName(
                event['districtCode'].lower(
                )) if event['districtCode'] else DistrictType.NO_DISTRICT
            venue = event['venue']
            location = "{}, {}, {}".format(event['city'], event['stateprov'],
                                           event['country'])
            start = datetime.datetime.strptime(event['dateStart'],
                                               self.DATE_FORMAT_STR)
            end = datetime.datetime.strptime(event['dateEnd'],
                                             self.DATE_FORMAT_STR)

            # TODO read timezone from API

            # Do not read in CMP divisions, we'll add those manually
            if event_type in EventType.CMP_EVENT_TYPES:
                continue

            events.append(
                Event(
                    id=key,
                    name=name,
                    short_name=short_name,
                    event_short=code,
                    event_type_enum=event_type,
                    official=True,
                    start_date=start,
                    end_date=end,
                    venue=venue,
                    location=location,
                    venue_address=
                    None,  # FIRST API doesn't provide detailed venue address
                    year=self.season,
                    event_district_enum=district_enum))
        return events
    def parse(self, response):
        events = []
        for event in response['Events']:
            code = event['code'].lower()
            key = "{}{}".format(self.season, code)
            name = event['name']
            short_name = EventHelper.getShortName(name)
            event_type = EventHelper.parseEventType(event['type'])
            district_enum = EventHelper.parseDistrictName(event['districtCode'].lower()) if event['districtCode'] else DistrictType.NO_DISTRICT
            venue = event['venue']
            location = "{}, {}, {}".format(event['city'], event['stateprov'], event['country'])
            start = datetime.datetime.strptime(event['dateStart'], self.DATE_FORMAT_STR)
            end = datetime.datetime.strptime(event['dateEnd'], self.DATE_FORMAT_STR)

            # TODO read timezone from API

            # Do not read in CMP divisions, we'll add those manually
            if event_type in EventType.CMP_EVENT_TYPES:
                continue

            events.append(Event(
                id=key,
                name=name,
                short_name=short_name,
                event_short=code,
                event_type_enum=event_type,
                official=True,
                start_date=start,
                end_date=end,
                venue=venue,
                location=location,
                venue_address="{}, {}".format(venue, location),
                year=self.season,
                event_district_enum=district_enum
            ))
        return events
Exemple #14
0
    def parse(self, response):
        events = []
        districts = {}
        for event in response['Events']:
            code = event['code'].lower()
            event_type = EventType.PRESEASON if code == 'week0' else self.EVENT_TYPES.get(
                event['type'].lower(), None)
            if event_type is None:
                logging.warn("Event type '{}' not recognized!".format(
                    event['type']))
                continue
            name = event['name']
            short_name = EventHelper.getShortName(name)
            district_enum = EventHelper.parseDistrictName(
                event['districtCode'].lower(
                )) if event['districtCode'] else DistrictType.NO_DISTRICT
            district_key = District.renderKeyName(
                self.season, event['districtCode'].lower()
            ) if event['districtCode'] else None
            venue = event['venue']
            city = event['city']
            state_prov = event['stateprov']
            country = event['country']
            start = datetime.datetime.strptime(event['dateStart'],
                                               self.DATE_FORMAT_STR)
            end = datetime.datetime.strptime(event['dateEnd'],
                                             self.DATE_FORMAT_STR)
            website = event.get('website')

            # TODO read timezone from API

            # Special cases for champs
            if code in self.EVENT_CODE_EXCEPTIONS:
                code, short_name = self.EVENT_CODE_EXCEPTIONS[code]
                if code in self.EINSTEIN_CODES:
                    name = '{} Field'.format(short_name)
                    start = end.replace(
                        hour=0, minute=0, second=0,
                        microsecond=0)  # Set to beginning of last day
                else:  # Divisions
                    name = '{} Division'.format(short_name)

            events.append(
                Event(
                    id="{}{}".format(self.season, code),
                    name=name,
                    short_name=short_name,
                    event_short=code,
                    event_type_enum=event_type,
                    official=True,
                    start_date=start,
                    end_date=end,
                    venue=venue,
                    city=city,
                    state_prov=state_prov,
                    country=country,
                    venue_address=
                    None,  # Even though FRC API provides address, ElasticSearch is more detailed
                    year=self.season,
                    event_district_enum=district_enum,
                    district_key=ndb.Key(District, district_key)
                    if district_key else None,
                    website=website,
                ))

            # Build District Model
            if district_key and district_key not in districts:
                districts[district_key] = District(
                    id=district_key,
                    year=self.season,
                    abbreviation=event['districtCode'].lower(),
                )
        return events, list(districts.values())
Exemple #15
0
    def parse(self, response):
        events = []
        districts = {}

        cmp_hack_sitevar = Sitevar.get_or_insert('cmp_registration_hacks')
        divisions_to_skip = cmp_hack_sitevar.contents.get('divisions_to_skip', []) \
            if cmp_hack_sitevar else []
        event_name_override = cmp_hack_sitevar.contents.get('event_name_override', []) \
            if cmp_hack_sitevar else []
        events_to_change_dates = cmp_hack_sitevar.contents.get('set_start_to_last_day', []) \
            if cmp_hack_sitevar else []

        for event in response['Events']:
            code = event['code'].lower()

            api_event_type = event['type'].lower()
            event_type = EventType.PRESEASON if code == 'week0' else self.EVENT_TYPES.get(api_event_type, None)
            if event_type is None and not self.event_short:
                logging.warn("Event type '{}' not recognized!".format(api_event_type))
                continue

            # Some event types should be marked as unofficial, so sync is disabled
            official = True
            if api_event_type in self.NON_OFFICIAL_EVENT_TYPES:
                official = False

            name = event['name']
            short_name = EventHelper.getShortName(name, district_code=event['districtCode'])
            district_enum = EventHelper.parseDistrictName(event['districtCode'].lower()) if event['districtCode'] else DistrictType.NO_DISTRICT
            district_key = District.renderKeyName(self.season, event['districtCode'].lower()) if event['districtCode'] else None
            address = event.get('address')
            venue = event['venue']
            city = event['city']
            state_prov = event['stateprov']
            country = event['country']
            start = datetime.datetime.strptime(event['dateStart'], self.DATE_FORMAT_STR)
            end = datetime.datetime.strptime(event['dateEnd'], self.DATE_FORMAT_STR)
            website = event.get('website')
            webcasts = [WebcastParser.webcast_dict_from_url(url) for url in event.get('webcasts', [])]

            # TODO read timezone from API

            # Special cases for district championship divisions
            if event_type == EventType.DISTRICT_CMP_DIVISION:
                split_name = name.split('-')
                short_name = '{} - {}'.format(
                    ''.join(item[0].upper() for item in split_name[0].split()),
                    split_name[-1].replace('Division', '').strip())

            # Special cases for champs
            if code in self.EVENT_CODE_EXCEPTIONS:
                code, short_name = self.EVENT_CODE_EXCEPTIONS[code]

                # FIRST indicates CMP registration before divisions are assigned by adding all teams
                # to Einstein. We will hack around that by not storing divisions and renaming
                # Einstein to simply "Championship" when certain sitevar flags are set

                if code in self.EINSTEIN_CODES:
                    override = [item for item in event_name_override if item['event'] == "{}{}".format(self.season, code)]
                    if override:
                        name = short_name.format(override[0]['name'])
                        short_name = short_name.format(override[0]['short_name'])
                else:  # Divisions
                    name = '{} Division'.format(short_name)
            elif self.event_short:
                code = self.event_short

            event_key = "{}{}".format(self.season, code)
            if event_key in divisions_to_skip:
                continue

            # Allow an overriding the start date to be the beginning of the last day
            if event_key in events_to_change_dates:
                start = end.replace(hour=0, minute=0, second=0, microsecond=0)

            events.append(Event(
                id=event_key,
                name=name,
                short_name=short_name,
                event_short=code,
                event_type_enum=event_type,
                official=official,
                start_date=start,
                end_date=end,
                venue=venue,
                city=city,
                state_prov=state_prov,
                country=country,
                venue_address=address,
                year=self.season,
                event_district_enum=district_enum,
                district_key=ndb.Key(District, district_key) if district_key else None,
                website=website,
                webcast_json=json.dumps(webcasts) if webcasts else None,
            ))

            # Build District Model
            if district_key and district_key not in districts:
                districts[district_key] = District(
                    id=district_key,
                    year=self.season,
                    abbreviation=event['districtCode'].lower(),
                )

        # Prep for division <-> parent associations
        district_champs_by_district = {}
        champ_events = []
        for event in events:
            if event.event_type_enum == EventType.DISTRICT_CMP:
                district_champs_by_district[event.district_key] = event
            elif event.event_type_enum == EventType.CMP_FINALS:
                champ_events.append(event)

        # Build district cmp division <-> parent associations based on district
        # Build cmp division <-> parent associations based on date
        for event in events:
            parent_event = None
            if event.event_type_enum == EventType.DISTRICT_CMP_DIVISION:
                parent_event = district_champs_by_district.get(event.district_key)
            elif event.event_type_enum == EventType.CMP_DIVISION:
                for parent_event in champ_events:
                    if abs(parent_event.end_date - event.end_date) < datetime.timedelta(days=1):
                        break
                else:
                    parent_event = None
            else:
                continue

            if parent_event is None:
                continue

            parent_event.divisions = sorted(parent_event.divisions + [event.key])
            event.parent_event = parent_event.key

        return events, list(districts.values())
    def parse(self, response):
        events = []
        districts = {}

        cmp_hack_sitevar = Sitevar.get_or_insert('cmp_registration_hacks')
        divisions_to_skip = cmp_hack_sitevar.contents.get('divisions_to_skip', []) \
            if cmp_hack_sitevar else []
        event_name_override = cmp_hack_sitevar.contents.get('event_name_override', []) \
            if cmp_hack_sitevar else []
        events_to_change_dates = cmp_hack_sitevar.contents.get('set_start_to_last_day', []) \
            if cmp_hack_sitevar else []

        for event in response['Events']:
            code = event['code'].lower()
            event_type = EventType.PRESEASON if code == 'week0' else self.EVENT_TYPES.get(event['type'].lower(), None)
            if event_type is None:
                logging.warn("Event type '{}' not recognized!".format(event['type']))
                continue
            name = event['name']
            short_name = EventHelper.getShortName(name)
            district_enum = EventHelper.parseDistrictName(event['districtCode'].lower()) if event['districtCode'] else DistrictType.NO_DISTRICT
            district_key = District.renderKeyName(self.season, event['districtCode'].lower()) if event['districtCode'] else None
            venue = event['venue']
            city = event['city']
            state_prov = event['stateprov']
            country = event['country']
            start = datetime.datetime.strptime(event['dateStart'], self.DATE_FORMAT_STR)
            end = datetime.datetime.strptime(event['dateEnd'], self.DATE_FORMAT_STR)
            website = event.get('website')

            # TODO read timezone from API

            # Special cases for district championship divisions
            if event_type == EventType.DISTRICT_CMP_DIVISION:
                split_name = name.split('-')
                short_name = '{} - {}'.format(
                    ''.join(item[0].upper() for item in split_name[0].split()),
                    split_name[-1].replace('Division', '').strip())

            # Special cases for champs
            if code in self.EVENT_CODE_EXCEPTIONS:
                code, short_name = self.EVENT_CODE_EXCEPTIONS[code]

                # FIRST indicates CMP registration before divisions are assigned by adding all teams
                # to Einstein. We will hack around that by not storing divisions and renaming
                # Einstein to simply "Championship" when certain sitevar flags are set

                if code in self.EINSTEIN_CODES:
                    override = [item for item in event_name_override if item['event'] == "{}{}".format(self.season, code)]
                    if override:
                        name = short_name.format(override[0]['name'])
                        short_name = short_name.format(override[0]['short_name'])
                else:  # Divisions
                    name = '{} Division'.format(short_name)

            event_key = "{}{}".format(self.season, code)
            if event_key in divisions_to_skip:
                continue

            # Allow an overriding the start date to be the beginning of the last day
            if event_key in events_to_change_dates:
                start = end.replace(hour=0, minute=0, second=0, microsecond=0)

            events.append(Event(
                id=event_key,
                name=name,
                short_name=short_name,
                event_short=code,
                event_type_enum=event_type,
                official=True,
                start_date=start,
                end_date=end,
                venue=venue,
                city=city,
                state_prov=state_prov,
                country=country,
                venue_address=None,  # Even though FRC API provides address, ElasticSearch is more detailed
                year=self.season,
                event_district_enum=district_enum,
                district_key=ndb.Key(District, district_key) if district_key else None,
                website=website,
            ))

            # Build District Model
            if district_key and district_key not in districts:
                districts[district_key] = District(
                    id=district_key,
                    year=self.season,
                    abbreviation=event['districtCode'].lower(),
                )
        return events, list(districts.values())
Exemple #17
0
    def parse(self, response):
        events = []
        districts = {}

        cmp_hack_sitevar = Sitevar.get_or_insert('cmp_registration_hacks')
        store_cmp_division = cmp_hack_sitevar.contents.get('should_store_divisions', True) \
            if cmp_hack_sitevar else True
        einstein_name = cmp_hack_sitevar.contents.get('einstein_name', self.EINSTEIN_NAME_DEFAULT) \
            if cmp_hack_sitevar else self.EINSTEIN_NAME_DEFAULT
        einstein_short_name = cmp_hack_sitevar.contents.get('einstein_short_name', self.EINSTEIN_SHORT_NAME_DEFAULT) \
            if cmp_hack_sitevar else self.EINSTEIN_SHORT_NAME_DEFAULT
        change_einstein_dates = cmp_hack_sitevar.contents.get('should_change_einstein_dates', False) \
            if cmp_hack_sitevar else False

        for event in response['Events']:
            code = event['code'].lower()
            event_type = EventType.PRESEASON if code == 'week0' else self.EVENT_TYPES.get(event['type'].lower(), None)
            if event_type is None:
                logging.warn("Event type '{}' not recognized!".format(event['type']))
                continue
            name = event['name']
            short_name = EventHelper.getShortName(name)
            district_enum = EventHelper.parseDistrictName(event['districtCode'].lower()) if event['districtCode'] else DistrictType.NO_DISTRICT
            district_key = District.renderKeyName(self.season, event['districtCode'].lower()) if event['districtCode'] else None
            venue = event['venue']
            city = event['city']
            state_prov = event['stateprov']
            country = event['country']
            start = datetime.datetime.strptime(event['dateStart'], self.DATE_FORMAT_STR)
            end = datetime.datetime.strptime(event['dateEnd'], self.DATE_FORMAT_STR)
            website = event.get('website')

            # TODO read timezone from API

            # Special cases for champs
            if code in self.EVENT_CODE_EXCEPTIONS:
                code, short_name = self.EVENT_CODE_EXCEPTIONS[code]

                # FIRST indicates CMP registration before divisions are assigned by adding all teams
                # to Einstein. We will hack around that by not storing divisions and renaming
                # Einstein to simply "Championship" when certain sitevar flags are set

                if code in self.EINSTEIN_CODES:
                    name = short_name.format(einstein_name)
                    short_name = short_name.format(einstein_short_name)
                    if change_einstein_dates:
                        # Set to beginning of last day
                        start = end.replace(hour=0, minute=0, second=0, microsecond=0)
                else:  # Divisions
                    name = '{} Division'.format(short_name)

                    # Allow skipping storing CMP divisions before they're announced
                    if not store_cmp_division:
                        continue

            events.append(Event(
                id="{}{}".format(self.season, code),
                name=name,
                short_name=short_name,
                event_short=code,
                event_type_enum=event_type,
                official=True,
                start_date=start,
                end_date=end,
                venue=venue,
                city=city,
                state_prov=state_prov,
                country=country,
                venue_address=None,  # Even though FRC API provides address, ElasticSearch is more detailed
                year=self.season,
                event_district_enum=district_enum,
                district_key=ndb.Key(District, district_key) if district_key else None,
                website=website,
            ))

            # Build District Model
            if district_key and district_key not in districts:
                districts[district_key] = District(
                    id=district_key,
                    year=self.season,
                    abbreviation=event['districtCode'].lower(),
                )
        return events, list(districts.values())
    def parse(self, response):
        events = []
        districts = {}

        cmp_hack_sitevar = Sitevar.get_or_insert('cmp_registration_hacks')
        divisions_to_skip = cmp_hack_sitevar.contents.get('divisions_to_skip', []) \
            if cmp_hack_sitevar else []
        event_name_override = cmp_hack_sitevar.contents.get('event_name_override', []) \
            if cmp_hack_sitevar else []
        events_to_change_dates = cmp_hack_sitevar.contents.get('set_start_to_last_day', []) \
            if cmp_hack_sitevar else []

        for event in response['Events']:
            code = event['code'].lower()
            event_type = EventType.PRESEASON if code == 'week0' else self.EVENT_TYPES.get(event['type'].lower(), None)
            if event_type is None and not self.event_short:
                logging.warn("Event type '{}' not recognized!".format(event['type']))
                continue
            name = event['name']
            short_name = EventHelper.getShortName(name, district_code=event['districtCode'])
            district_enum = EventHelper.parseDistrictName(event['districtCode'].lower()) if event['districtCode'] else DistrictType.NO_DISTRICT
            district_key = District.renderKeyName(self.season, event['districtCode'].lower()) if event['districtCode'] else None
            venue = event['venue']
            city = event['city']
            state_prov = event['stateprov']
            country = event['country']
            start = datetime.datetime.strptime(event['dateStart'], self.DATE_FORMAT_STR)
            end = datetime.datetime.strptime(event['dateEnd'], self.DATE_FORMAT_STR)
            website = event.get('website')

            # TODO read timezone from API

            # Special cases for district championship divisions
            if event_type == EventType.DISTRICT_CMP_DIVISION:
                split_name = name.split('-')
                short_name = '{} - {}'.format(
                    ''.join(item[0].upper() for item in split_name[0].split()),
                    split_name[-1].replace('Division', '').strip())

            # Special cases for champs
            if code in self.EVENT_CODE_EXCEPTIONS:
                code, short_name = self.EVENT_CODE_EXCEPTIONS[code]

                # FIRST indicates CMP registration before divisions are assigned by adding all teams
                # to Einstein. We will hack around that by not storing divisions and renaming
                # Einstein to simply "Championship" when certain sitevar flags are set

                if code in self.EINSTEIN_CODES:
                    override = [item for item in event_name_override if item['event'] == "{}{}".format(self.season, code)]
                    if override:
                        name = short_name.format(override[0]['name'])
                        short_name = short_name.format(override[0]['short_name'])
                else:  # Divisions
                    name = '{} Division'.format(short_name)
            elif self.event_short:
                code = self.event_short

            event_key = "{}{}".format(self.season, code)
            if event_key in divisions_to_skip:
                continue

            # Allow an overriding the start date to be the beginning of the last day
            if event_key in events_to_change_dates:
                start = end.replace(hour=0, minute=0, second=0, microsecond=0)

            events.append(Event(
                id=event_key,
                name=name,
                short_name=short_name,
                event_short=code,
                event_type_enum=event_type,
                official=True,
                start_date=start,
                end_date=end,
                venue=venue,
                city=city,
                state_prov=state_prov,
                country=country,
                venue_address=None,  # Even though FRC API provides address, ElasticSearch is more detailed
                year=self.season,
                event_district_enum=district_enum,
                district_key=ndb.Key(District, district_key) if district_key else None,
                website=website,
            ))

            # Build District Model
            if district_key and district_key not in districts:
                districts[district_key] = District(
                    id=district_key,
                    year=self.season,
                    abbreviation=event['districtCode'].lower(),
                )
        return events, list(districts.values())