Ejemplo n.º 1
0
    def create_location(self, number):
        """Create location object.

        Args:
            number: Identifier of the location (int).

        Returns:
            Location object.
        """
        location = Location(
            name="Location {}".format(number),
            address="Erskine Building, Science Rd, Ilam, Christchurch",
            geolocation="-43.5225594,172.5811949",
            description="Description for Location {}".format(number),
        )
        location.save()
        return location
Ejemplo n.º 2
0
    def import_events_in_app(self,
                             sport_restrict,
                             geocode=True,
                             limit=0,
                             interactive=False,
                             verbose=False):
        # ignore deprecation warning for better displaying
        nb_created, nb_failed = 0, 0
        event_has_been_cloned = False
        event_re = re.compile('.+(?=\s-\s)')
        address_re = re.compile('(.+)(?=\s-\s\D)')
        locality_re = re.compile('(?<=\s-\s)(.+)(?=\s-\s\w)')
        federation_name = "FFTri"
        edition_no = 1

        restricted_race_list = self.race_list
        if sport_restrict:
            restricted_race_list = [
                x for x in restricted_race_list
                if x['discipline'].lower() == sport_restrict.lower()
            ]

        for race_src in restricted_race_list:
            if verbose: print("--------------------------------------------")
            e, s, c, l, dc, r, o, f = ({} for i in range(8))
            distance_cat, sport, event, contact, location, race, organizer, federation = (
                None for i in range(8))

            race_src_id = race_src.get('id', None)

            f['name'] = federation_name

            e['name'] = event_re.search(race_src.get('nom', None)).group(0)

            tmp_website = race_src.get('site')
            if tmp_website:
                e['website'] = tmp_website if tmp_website[:
                                                          4] == 'http' else 'http://' + tmp_website

            e['edition'] = edition_no
            # event = Event(**e)

            s['name'] = race_src.get('discipline', None)
            # sport = Sport(**s)

            dc['name'] = race_src.get('format', None)
            # distance_cat = DistanceCategory(**dc)

            r['title'] = race_src.get('nom', None)

            d = race_src.get('date')
            r['date'] = datetime.strptime(d, '%d/%m/%Y')
            r['date'] = r['date'].replace(tzinfo=timezone('Europe/Paris'))

            r['price'] = None

            # edition info
            r['created_by'] = "FFTri"
            r['import_source'] = "FFTri"
            r['import_source_id'] = race_src_id

            o['name'] = race_src.get('nom_orga', None)
            c['name'] = race_src.get('nom_orga', None)
            c['email'] = race_src.get('email', None)
            c['phone'] = race_src.get('telephone', None)
            r['description'] = None
            l['raw'] = race_src.get('adresse', None)
            l['postal_code'] = race_src.get('cp', None)
            l['lat'] = race_src.get('latitude', None)
            l['lng'] = race_src.get('longitude', None)

            try:

                # check if the race is already in the db to avoid useless treatment
                has_error = False

                sport = Sport.objects.get(**s)
                if verbose: print("sport found : {0}".format(sport))

                distance_cat = DistanceCategory.objects.get(sport=sport, **dc)
                if verbose: print("distance found : {0}".format(distance_cat))

                organizer, organizer_created = Organizer.objects.get_or_create(
                    **o)
                if verbose and organizer_created:
                    print("new organizer : {0}".format(organizer))
                if verbose and not organizer_created:
                    print("organizer found : {0}".format(organizer))

                # event_ref, event_created = EventReference.objects.get_or_create(organizer=organizer, **eref)
                try:
                    event, event_created = Event.objects.get_or_create(
                        organizer=organizer, **e)
                except MultipleObjectsReturned:
                    # if multiple objects are returned, one is awaiting validation
                    if verbose:
                        print("event found not validated yet (existing): {0}".
                              format(event))
                    e['validated'] = False
                    event = Event.objects.get(**e)
                    event_created = False

                # clon the event if the event found is validated
                if not event_created:
                    if event.validated:
                        old_event_pk = event.pk
                        event = event.clone()
                        event_has_been_cloned = True
                        if verbose:
                            print("event {0} cloned into {1}".format(
                                old_event_pk, event.pk))
                    else:
                        if verbose:
                            print("event found not validated yet (new) : {0}".
                                  format(event))

                if verbose and event_created:
                    print("new event : {0}".format(event))

                contact = Contact.objects.create(**c)
                if verbose: print("contact created : {0}".format(contact))

                federation, federation_created = Federation.objects.get_or_create(
                    **f)
                if verbose and federation_created:
                    print("new federation : {0}".format(federation))
                if verbose and not federation_created:
                    print("federation found : {0}".format(federation))

                location = Location()

                geocoded = False

                # provide initial data if geocode fails
                location.lat = l['lat']
                location.lng = l['lng']
                location.postal_code = l['postal_code']
                address = race_src.get('adresse', None)
                if not address:
                    raise Exception("no address provided")

                if address_re.search(race_src.get('adresse', None)):
                    location.route = address_re.search(address).group(0)
                if locality_re.search(race_src.get('adresse', None)):
                    location.locality = locality_re.search(address).group(0)

                # try geocode
                if geocode:
                    country = 'FR'
                    adm2_short = l['postal_code'][:2]

                    if l['postal_code'][:3] == '971':
                        # guadeloupe
                        country = 'GP'
                        adm2_short = l['postal_code'][:3]
                    elif l['postal_code'][:3] == '972':
                        # martinique
                        country = 'MQ'
                        adm2_short = l['postal_code'][:3]
                    elif l['postal_code'][:3] == '973':
                        # guyane
                        country = 'GF'
                        adm2_short = l['postal_code'][:3]
                    elif l['postal_code'][:3] == '974':
                        # réunion
                        country = 'RE'
                        adm2_short = l['postal_code'][:3]
                    elif l['postal_code'][:3] == '975':
                        # saint pierre et miquelon
                        country = 'PM'
                        adm2_short = l['postal_code'][:3]
                    elif l['postal_code'][:3] == '976':
                        # mayotte
                        country = 'YT'
                        adm2_short = l['postal_code'][:3]
                    elif l['postal_code'][:3] == '984':
                        # terres australes ... on sait jamais
                        country = 'TF'
                        adm2_short = l['postal_code'][:3]
                    elif l['postal_code'][:3] == '986':
                        # wallis et futuna
                        country = 'WF'
                        adm2_short = l['postal_code'][:3]
                    elif l['postal_code'][:3] == '987':
                        # polynesie francaise
                        country = 'PF'
                        adm2_short = l['postal_code'][:3]
                    elif l['postal_code'][:3] == '988':
                        # nouvellae caledonie
                        country = 'NC'
                        adm2_short = l['postal_code'][:3]

                    if verbose:
                        print(
                            "geocoding: country: {0} - postal: {1} - address:{2}"
                            .format(
                                country, location.postal_code,
                                '{0} {1}'.format(location.street_number or '',
                                                 location.route or '')))

                    geocoded = location.geocode(country=country)

                    if verbose and geocoded:
                        print("geocoding succeed: lat:{0} - lng:{1}".format(
                            location.lat, location.lng))
                    if verbose and not geocoded: print("geocoding failed...")

                if not geocoded:
                    while input(
                            'Geocoding failed, try another address (Y/n) :  '
                    ) != 'n':
                        print(
                            'initial address = country: {0} - postal: {1} - address:{2}'
                            .format(country, l['postal_code'], l['raw']))

                        country_retry = input('new country : ')
                        address_retry = input(
                            'new geocode lookup address (complete) : ')
                        geocoded_retry_result = location.geocode_raw_address(
                            raw_address=address_retry, country=country_retry)
                        if geocoded_retry_result:
                            print("found : ")
                            print(geocoded_retry_result)
                            if input('Save this result (Y/n) : ') != 'n':
                                break

                # fix for google geocoder bug for some french departments
                # replace postal code and departement with API value
                location.administrative_area_level_2_short_name = adm2_short

                # check that location is near lat/lng provided
                location.save()

                if verbose: print("location saved")

                race = Race(**r)
                race.event = event

                race.distance_cat = distance_cat
                race.federation = federation
                race.sport = sport
                race.contact = contact
                race.location = location
                race.save()

                doubles = race.get_potential_doubles()
                if doubles:
                    if verbose:
                        print("{0} potential double(s) detected:".format(
                            len(doubles)))
                    for d in doubles:
                        if verbose: print("{0} VS {1}".format(race, d))
                        dbl_input = ''
                        if interactive:
                            dbl_input = input("is double (Y/n) ? : ")
                        if not dbl_input == 'n':
                            raise RaceDoubleException("Double detected")

                if verbose: print("race saved, pk:{0}".format(race.pk))
                nb_created += 1

            except Sport.DoesNotExist:
                has_error = True
                print("[ERR][REF] [{0}] : Sport {1} does not exist".format(
                    race_src_id, s['name']))
            except DistanceCategory.DoesNotExist:
                has_error = True
                print("[ERR][REF] [{0}] : Distance {1} does not exist".format(
                    race_src_id, dc['name']))
            except RaceDoubleException:
                has_error = True
                print("[WAR][DBL] [{0}] : Race already exists in DB".format(
                    race_src_id))

            except Exception as e:
                has_error = True
                exc_type, exc_value, exc_traceback = sys.exc_info()
                lines = traceback.format_exception(exc_type, exc_value,
                                                   exc_traceback)
                print("[ERR][UNK] [{0}] :".format(race_src_id))
                print(''.join('!! ' + line for line in lines))

            finally:
                if has_error:
                    if interactive:
                        input(
                            'due to errors, race will be deleted.... press any key: '
                        )
                    nb_failed += 1
                    if contact:
                        if contact.pk:
                            if verbose:
                                print('contact deleted ({0})'.format(
                                    contact.pk))
                            contact.delete()

                    if location:
                        if location.pk:
                            if verbose:
                                print('location deleted ({0})'.format(
                                    location.pk))
                            location.delete()

                    if race:
                        if race.pk:
                            if verbose:
                                print('race deleted ({0})'.format(race.pk))
                            race.delete()

                    if event:
                        if event.pk:
                            if len(event.get_races()
                                   ) == 0 or event_has_been_cloned:
                                if verbose:
                                    print('event deleted ({0})'.format(
                                        event.pk))
                                event.delete()

                # else:
                # print ("[INF][OK] [{0}] : Race event successfully created".format(race_src_id))
                else:
                    print('race {0} successfully created (total : {1})'.format(
                        race.pk, nb_created))
                    if interactive:
                        input('press enter to continue... '.format(nb_created))

                if limit == 1:
                    break
                limit -= 1

        print("--------------------------------------------")
        print("--------------------------------------------")
        print('finished !  created: {0}, failed: {1}'.format(
            nb_created, nb_failed))
        print("--------------------------------------------")
        print("--------------------------------------------")