diff bandmap/admin.py @ 826:d7e4c08b2e8b

Bandmap WIP: added admin action to update lat/lon.
author Brian Neal <bgneal@gmail.com>
date Sat, 27 Sep 2014 15:14:47 -0500
parents 5892c05886a9
children 5103edd3acc4
line wrap: on
line diff
--- a/bandmap/admin.py	Thu Sep 25 21:15:22 2014 -0500
+++ b/bandmap/admin.py	Sat Sep 27 15:14:47 2014 -0500
@@ -2,8 +2,12 @@
 
 """
 import datetime
+import json
+import urllib
+import urllib2
 
 from django.contrib import admin
+import django.contrib.messages as messages
 
 from bandmap.models import BandEntry
 import bio.badges
@@ -17,7 +21,7 @@
     readonly_fields = ['lat', 'lon']
     search_fields = ['name', 'location', 'note']
     raw_id_fields = ['user']
-    actions = ['approve_bands']
+    actions = ['approve_bands', 'update_location']
 
     def approve_bands(self, request, qs):
         """This admin action awards a map pin to the user who added the band.
@@ -36,5 +40,45 @@
 
     approve_bands.short_description = "Approve selected band map entries"
 
+    def update_location(self, request, qs):
+        """Admin action to refresh the lat/lon fields after updating the
+        location field. Queries the Google Maps HTTP server-side API for the
+        data.
+
+        """
+        base_url = "http://maps.googleapis.com/maps/api/geocode/json?address=%s"
+        ok_cnt = 0
+        for band in qs:
+            url = base_url % urllib.quote_plus(band.location)
+            try:
+                response = urllib2.urlopen(url)
+            except urllib2.URLError as ex:
+                self.message_user(request, 'Error processing {}: {}'.format(
+                    band.name, ex), level=messages.ERROR)
+                continue
+
+            code = response.getcode()
+            if code == 200:
+                result = json.loads(response.read())
+                try:
+                    loc = result['results'][0]['geometry']['location']
+                    band.lat = loc['lat']
+                    band.lon = loc['lng']
+                except (KeyError, IndexError) as ex:
+                    self.message_user(request, 'Unexpected response for {}'.format(
+                        band.name), level=messages.ERROR)
+                else:
+                    band.save()
+                    ok_cnt += 1
+            else:
+                msg = "Error response ({}) for band {}".format(code, band.name)
+                self.message_user(request, msg, level=messages.ERROR)
+
+        if ok_cnt > 0:
+            msg = '{} band location(s) successfully updated'.format(ok_cnt)
+            self.message_user(request, msg)
+
+    update_location.short_description = "Update lat/lon for selected band map entries"
+
 
 admin.site.register(BandEntry, BandEntryAdmin)