コード例 #1
0
def store_fbpage_place(page_info, create_owner=True):
    '''
    Takes a dict of properties retreived from a Facebook Graph API call for
    a page and stores a Place from the information. The following 
    fields in the dict are used:
    - id          (required)
    - type        (required with value 'page' or a TypeError will be thrown)
    - location    (required or TypeError will be thrown)
    - description
    - url
    - phone
    - hours
    - picture

    No new Place will be returned if either an identical one already
    exists in the db, or an ExternalPlaceSource already exists for 
    the given Facebook id. An INFO message is logged to note the attempt 
    to store an existing page as a Place.

    If create_owner is True a new Organization will be created from the same
    page information if one does not already exist.
    '''
    pid = page_info['id']

    try:
        place = ExternalPlaceSource.objects.get(service='fb', uid=pid).place
        outsourcing_log.info('Existing fb page Place found for fbid %s' %
                             unicode(pid))
        return place
    except ExternalPlaceSource.DoesNotExist:
        pass

    if page_info.get('type') != 'page':
        raise TypeError("Cannot store object without 'page' type as a Place.")
    elif 'location' not in page_info:
        raise TypeError("Cannot store object without location key as a Place.")

    pname = page_info['name'].strip()

    ### Figure out the new Place's location field
    fbloc = page_info['location']
    if 'id' in fbloc:
        # TODO: need to ensure fbloc_to_loc can handle ids in location if this ever happens
        outsourcing_log.info('Facebook page %s has id in location (%s)' %
                             (pid, fbloc['id']))
    location = fbloc_to_loc(fbloc)

    # if there's no address or geocoding, we'll need to talk to outside services
    if not location.address:
        seed_place = Place(name=pname, location=location)
        resolved_place = resolve_place(seed_place)
        if resolved_place:
            location = resolved_place.location

    # really want geolocation, go to Google Geocoding for it if we need it
    if location.longitude is None or location.latitude is None:
        seed_loc = copy.deepcopy(location)
        resolved_location = resolve_location(seed_loc, allow_numberless=False)
        if resolved_location:
            location = resolved_location

    # if there's no specific address information, make the error radius around the
    # lat/lng super tight. Don't want to create whirlpools.
    cl_opts = dict(lat_error=1e-5,
                   lng_error=1e-5) if not location.address else {}

    location, created = Location.close_manager.get_close_or_create(
        address=location.address,
        postcode=location.postcode,
        town=location.town,
        state=location.state,
        country=location.country,
        neighborhood=location.neighborhood,
        latitude=location.latitude,
        longitude=location.longitude,
        _close_options=cl_opts)
    if created:
        outsourcing_log.debug('Saved new location "%s"' % location.full_string)
    else:
        outsourcing_log.debug('Retrieved existing location "%s"' %
                              location.full_string)

    try:
        owner = FacebookOrgRecord.objects.get(fb_id=pid).organization
    except FacebookOrgRecord.DoesNotExist:
        if create_owner:
            outsourcing_log.info(
                'Creating new Organization as byproduct of creating Place from Facebook page %s'
                % unicode(pid))
            owner = store_fbpage_organization(page_info)
        else:
            owner = None

    place, created = Place.objects.get_or_create(name=pname[:200],
                                                 description=page_info.get(
                                                     'description',
                                                     '').strip(),
                                                 location=location,
                                                 owner=owner)

    # add place meta info that exists
    _store_fbpage_placemeta(page_info, place)

    # create a new link to an external id
    ExternalPlaceSource.objects.create(service='fb', uid=pid, place=place)
    return place
コード例 #2
0
ファイル: fbevents.py プロジェクト: gregarious/onlyinpgh
def _process_place(event_info):
    '''
    Attempts to tease a Place out of the given event_info. 

    May return either an already stored Place or a non-stored one (check 
    the pk value to tell the difference).

    Important! If Place is not yet stored, the Location inside it is not
    guaranteed to be stored either. Ensure the inner Location is saved 
    before saving the Place!
    '''
    venue = event_info.get('venue',{})
    place_name = event_info.get('location','').strip()
    if venue.get('id'):
        # best case is that our venue is identified by an existing Facebook ID
        try:
            return ExternalPlaceSource.facebook.get(uid=venue.get('id')).place
        except ExternalPlaceSource.DoesNotExist:
            pass

    # we couldn't get a nice id-based Place, so we're going to try to figure one 
    # out manually if there's vanue or place_name fields 
    if venue or place_name:
        # do something semi-intelligent to get a good Location out of the venue
        if venue:
            location = fbpages.fbloc_to_loc(venue)
            # if there's no address or geocoding, we'll need to talk to outside services
            if not location.address:
                # try to build a seed to resolve with
                seed_loc = copy.deepcopy(location)
                
                # in the absense of city/state info, assume location is in same city/state as owner
                if not seed_loc.town or not seed_loc.state:
                    fbowner = event_info.get('owner',{})
                    if fbowner.get('id'):
                        try:
                            owner_place = ExternalPlaceSource.facebook.get(uid=fbowner.get('id')).place
                        except ExternalPlaceSource.DoesNotExist:
                            owner_place = None
                        if owner_place:
                            if not seed_loc.town:
                                seed_loc.town = owner_place.location.town
                            if not seed_loc.state:
                                seed_loc.state = owner_place.location.state

                seed_place = Place(name=place_name,location=seed_loc)
                resolved_place = resolve_place(seed_place)
                if resolved_place:
                    # throw awy everything but the location
                    location = resolved_place.location
            
            # really want geolocation, go to Google Geocoding for it if we need it
            if location.longitude is None or location.latitude is None:
                seed_loc = copy.deepcopy(location)
                resolved_location = resolve_location(seed_loc)
                if resolved_location: 
                    location = resolved_location
            
            # if there's a "close enough" location in the db already, find and use it
            # only want to include "not-null" arguments into the get_close call. find these here
            # if still no geocoding info, 
            has_geocoding = location.latitude is not None and location.longitude is not None
            if has_geocoding:
                # since we've got geocoding info, this location is specific. therefore, null entries 
                # just signify a lack of info, not a planned null field for a vague address: omit them 
                # for the get query
                kwargs = _location_to_kwargs(location,True)  
                try:
                    location = Location.close_manager.get_close(**kwargs)
                except Location.DoesNotExist:   # if none found, no biggie, just return
                    pass
            else:
                # if we don't have geocoding, we want to find an exact match in the db, null fields and all
                kwargs = _location_to_kwargs(location,False) 
                try:
                    location = Location.objects.get(**kwargs)
                except Location.DoesNotExist:   
                    # if none found, no biggie, just return
                    pass
                except Location.MultipleObjectsReturned:
                    # if more than one found, its a sign there's some dups in the db. just return the first one.
                    outsourcing_log.warning('Multiple objects returned with Location query of %s' % unicode(kwargs))
                    return Location.objects.filter(**kwargs)[0]
        else:
            location = None

        return Place(name=place_name,location=location)
            
    # worst case: we assume the event is happening at the location specified by the
    #   owners fbid (assuming this fbid is already linked to a place)
    fbowner_id = event_info.get('owner',{}).get('id')
    if fbowner_id:
        # TODO: try harder to resolve owner place? isolated event creation will always fail here
        try:
            return ExternalPlaceSource.facebook.get(uid=fbowner_id).place
        except ExternalPlaceSource.DoesNotExist:
            pass
    
    return None
コード例 #3
0
ファイル: fbpages.py プロジェクト: gregarious/onlyinpgh
def store_fbpage_place(page_info,create_owner=True):
    '''
    Takes a dict of properties retreived from a Facebook Graph API call for
    a page and stores a Place from the information. The following 
    fields in the dict are used:
    - id          (required)
    - type        (required with value 'page' or a TypeError will be thrown)
    - location    (required or TypeError will be thrown)
    - description
    - url
    - phone
    - hours
    - picture

    No new Place will be returned if either an identical one already
    exists in the db, or an ExternalPlaceSource already exists for 
    the given Facebook id. An INFO message is logged to note the attempt 
    to store an existing page as a Place.

    If create_owner is True a new Organization will be created from the same
    page information if one does not already exist.
    '''
    pid = page_info['id']
    
    try:
        place = ExternalPlaceSource.objects.get(service='fb',uid=pid).place
        outsourcing_log.info('Existing fb page Place found for fbid %s' % unicode(pid))
        return place
    except ExternalPlaceSource.DoesNotExist:
        pass

    if page_info.get('type') != 'page':
        raise TypeError("Cannot store object without 'page' type as a Place.")
    elif 'location' not in page_info:
        raise TypeError("Cannot store object without location key as a Place.")
    
    pname = page_info['name'].strip()

    ### Figure out the new Place's location field
    fbloc = page_info['location']
    if 'id' in fbloc:
        # TODO: need to ensure fbloc_to_loc can handle ids in location if this ever happens
        outsourcing_log.info('Facebook page %s has id in location (%s)' % (pid,fbloc['id']))
    location = fbloc_to_loc(fbloc)

    # if there's no address or geocoding, we'll need to talk to outside services
    if not location.address:
        seed_place = Place(name=pname,location=location)
        resolved_place = resolve_place(seed_place)
        if resolved_place:
            location = resolved_place.location
    
    # really want geolocation, go to Google Geocoding for it if we need it
    if location.longitude is None or location.latitude is None:
        seed_loc = copy.deepcopy(location)
        resolved_location = resolve_location(seed_loc,allow_numberless=False)
        if resolved_location: 
            location = resolved_location

    # if there's no specific address information, make the error radius around the
    # lat/lng super tight. Don't want to create whirlpools. 
    cl_opts = dict(lat_error=1e-5,lng_error=1e-5) if not location.address else {}
    
    location, created = Location.close_manager.get_close_or_create(
                    address=location.address,
                    postcode=location.postcode,
                    town=location.town,
                    state=location.state,
                    country=location.country,
                    neighborhood=location.neighborhood,
                    latitude=location.latitude,
                    longitude=location.longitude,
                    _close_options=cl_opts)
    if created:
        outsourcing_log.debug('Saved new location "%s"' % location.full_string)
    else:
        outsourcing_log.debug('Retrieved existing location "%s"' % location.full_string)

    try:
        owner = FacebookOrgRecord.objects.get(fb_id=pid).organization
    except FacebookOrgRecord.DoesNotExist:
        if create_owner:
            outsourcing_log.info('Creating new Organization as byproduct of creating Place from Facebook page %s' % unicode(pid))
            owner = store_fbpage_organization(page_info)
        else:
            owner = None

    place, created = Place.objects.get_or_create(name=pname[:200],
                        description=page_info.get('description','').strip(),
                        location=location,
                        owner=owner)

    # add place meta info that exists      
    _store_fbpage_placemeta(page_info,place)

    # create a new link to an external id
    ExternalPlaceSource.objects.create(service='fb',uid=pid,
                                        place=place)
    return place
コード例 #4
0
def _process_place(event_info):
    '''
    Attempts to tease a Place out of the given event_info. 

    May return either an already stored Place or a non-stored one (check 
    the pk value to tell the difference).

    Important! If Place is not yet stored, the Location inside it is not
    guaranteed to be stored either. Ensure the inner Location is saved 
    before saving the Place!
    '''
    venue = event_info.get('venue', {})
    place_name = event_info.get('location', '').strip()
    if venue.get('id'):
        # best case is that our venue is identified by an existing Facebook ID
        try:
            return ExternalPlaceSource.facebook.get(uid=venue.get('id')).place
        except ExternalPlaceSource.DoesNotExist:
            pass

    # we couldn't get a nice id-based Place, so we're going to try to figure one
    # out manually if there's vanue or place_name fields
    if venue or place_name:
        # do something semi-intelligent to get a good Location out of the venue
        if venue:
            location = fbpages.fbloc_to_loc(venue)
            # if there's no address or geocoding, we'll need to talk to outside services
            if not location.address:
                # try to build a seed to resolve with
                seed_loc = copy.deepcopy(location)

                # in the absense of city/state info, assume location is in same city/state as owner
                if not seed_loc.town or not seed_loc.state:
                    fbowner = event_info.get('owner', {})
                    if fbowner.get('id'):
                        try:
                            owner_place = ExternalPlaceSource.facebook.get(
                                uid=fbowner.get('id')).place
                        except ExternalPlaceSource.DoesNotExist:
                            owner_place = None
                        if owner_place:
                            if not seed_loc.town:
                                seed_loc.town = owner_place.location.town
                            if not seed_loc.state:
                                seed_loc.state = owner_place.location.state

                seed_place = Place(name=place_name, location=seed_loc)
                resolved_place = resolve_place(seed_place)
                if resolved_place:
                    # throw awy everything but the location
                    location = resolved_place.location

            # really want geolocation, go to Google Geocoding for it if we need it
            if location.longitude is None or location.latitude is None:
                seed_loc = copy.deepcopy(location)
                resolved_location = resolve_location(seed_loc)
                if resolved_location:
                    location = resolved_location

            # if there's a "close enough" location in the db already, find and use it
            # only want to include "not-null" arguments into the get_close call. find these here
            # if still no geocoding info,
            has_geocoding = location.latitude is not None and location.longitude is not None
            if has_geocoding:
                # since we've got geocoding info, this location is specific. therefore, null entries
                # just signify a lack of info, not a planned null field for a vague address: omit them
                # for the get query
                kwargs = _location_to_kwargs(location, True)
                try:
                    location = Location.close_manager.get_close(**kwargs)
                except Location.DoesNotExist:  # if none found, no biggie, just return
                    pass
            else:
                # if we don't have geocoding, we want to find an exact match in the db, null fields and all
                kwargs = _location_to_kwargs(location, False)
                try:
                    location = Location.objects.get(**kwargs)
                except Location.DoesNotExist:
                    # if none found, no biggie, just return
                    pass
                except Location.MultipleObjectsReturned:
                    # if more than one found, its a sign there's some dups in the db. just return the first one.
                    outsourcing_log.warning(
                        'Multiple objects returned with Location query of %s' %
                        unicode(kwargs))
                    return Location.objects.filter(**kwargs)[0]
        else:
            location = None

        return Place(name=place_name, location=location)

    # worst case: we assume the event is happening at the location specified by the
    #   owners fbid (assuming this fbid is already linked to a place)
    fbowner_id = event_info.get('owner', {}).get('id')
    if fbowner_id:
        # TODO: try harder to resolve owner place? isolated event creation will always fail here
        try:
            return ExternalPlaceSource.facebook.get(uid=fbowner_id).place
        except ExternalPlaceSource.DoesNotExist:
            pass

    return None