django-reploc / reploc / utils.py

from django.db.models.signals import post_save
from django.conf import settings
from reploc.models import Location
from datetime import datetime, timedelta
from geopy import geocoders


def get_coordinates(location=None, address=None):
    if not location and not address:
        raise ValueError('You must specify either a Location \
                object or a string address!')
    elif location:
        addy = location.string_address
    elif address:
        addy = address

    try:
        g = geocoders.Google(settings.GOOGLE_MAPS_KEY)
    except AttributeError:
        return

    # retrieve the coordinates from Google Maps
    results = g.geocode(addy, exactly_one=False)
    place, coord = results[0]

    return coord


def update_coordinates(sender, instance, created, *args, **kwargs):
    """
    Retrieves the latitude and longitude coordinates of an address for a dealer
    location object.  This makes it so the application does not have to
    constantly be requesting the same information each time the dealer locator
    page is displayed.
    """

    now = datetime.now()

    # bail out if there has been an error getting the coordinates; avoids
    # infinite recursion
    if instance.coordinate_error:
        return

    # if the last check was within the last 5 minutes, skip the coord update
    # since we call the instance.save() method in this function, we would be
    # put in an infinite loop without something like this.
    if not instance.get_coordinates or \
        (instance.last_coord_check and \
        instance.last_coord_check > now - timedelta(minutes=5)):
        return

    try:
        # retrieve the coordinates from Google Maps
        coords = get_coordinates(instance)
    except:
        # if we run into any problems, just set the error and leave
        instance.coordinate_error = True
        instance.save()
    else:
        # otherwise, save the coordinates
        instance.update_coordinates(coords)

# connect the callback to the signal
post_save.connect(update_coordinates, sender=Location)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.