def apply_sorting(self, obj_list, options=None): # TODO: geopy based distance calculations result = list(super(ModelResource, self).apply_sorting(obj_list, options)) ref_location = Location(latitude=options.get("lat"), longitude=options.get("lng")) if ref_location.is_geocoded(): distance = ( lambda p: ref_location.distance_from(p.location, fast=True) if p.location and p.location.is_geocoded() else float("inf") ) result.sort(key=distance) return result
def insert_row(row, idx): logging.info(u"Importing row %d (%s)" % (int(idx), row["name"])) try: lat = decimal.Decimal(row.get("lat")) except (TypeError, decimal.InvalidOperation): lat = None try: lng = decimal.Decimal(row.get("lng")) except (TypeError, decimal.InvalidOperation): lng = None address = row.get("street", "") location = Location(address=address, postcode="15213", latitude=lat, longitude=lng) # want to resolve location if we have an address worht normalizing and/or we don't have geocoded values if location.address or location.latitude is None or location.longitude is None: logging.info('Resolving location "%s"' % unicode(location)) resolved = resolve_location(location) if resolved: # hack to get around Google Geocoding appending unviersity names onto many addresses if "university" in resolved.address.lower() and "university" not in row.get("street", "").lower(): resolved.address = ",".join(resolved.address.split(",")[1:]) resolved.address = resolved.address.strip() try: # if exact match exists, use it instead of the newly found one location = Location.objects.get(address=resolved.address, postcode=location.postcode) except Location.DoesNotExist: location = resolved location.save() else: logging.warning("Geocoding failed") has_corporate_fb = row.get("fb_id", "").startswith("corporate") place, created = Place.objects.get_or_create( name=row["name"], location=location, url=row.get("url", "")[:200], phone=row.get("phone", "")[:200], fb_id=row.get("fb_id", "").split(":")[-1], description=row.get("description", ""), listed=bool(int(row.get("listed", "0"))), ) for t in row.get("tags", "").split(";"): tag, _ = Tag.objects.get_or_create(name=slugify(t.lower())) place.tags.add(tag) place.save() image_path = row.get("image_url", "") if re.match("https?\:", image_path): if re.match("https?\:\/\/profile.ak.fbcdn.net", image_path): logging.info("Skipping Facebook cdn image") else: logging.info("Pulling live image from web") try: place.image = utils.imagefile_from_url(image_path) except IOError: logging.error("Failed pulling image") pass elif image_path != "": logging.info("Using local image file") f = open(os.path.join(DATA_DIR, "images", image_path)) place.image = File(f) place.save() if place.image: place.image.close() if place.fb_id: logging.info("Supplementing info from Facebook...") try: places_fb_import.commit_place(place, corporate=has_corporate_fb) except places_fb_import.FacebookAPIError as e: logging.error("Facebook API error (fb id %s): %s" % (str(place.fb_id), unicode(e))) except IOError as e: logging.error(unicode(e)) logging.info("Finished import: %s" % unicode(place)) logging.info("")