annotate membermap/views.py @ 821:71db8076dc3d

Bandmap WIP: geocoding integrated with add form. Add form works. Before submitting the form, client side JS makes a geocode request to Google and populates hidden lat/lon fields with the result. Successfully created a model instance on the server side. Still need to update admin dashboard, admin approval, and give out badges for adding bands to the map. Once that is done, then work on displaying the map with filtering.
author Brian Neal <bgneal@gmail.com>
date Tue, 23 Sep 2014 20:40:31 -0500
parents 0ca691cccf8d
children 21c592cac71c
rev   line source
gremmie@1 1 """
gremmie@1 2 Views for the membermap application.
bgneal@679 3
gremmie@1 4 """
bgneal@679 5 import json
bgneal@679 6
gremmie@1 7 from django.shortcuts import render_to_response
bgneal@266 8 from django.template.loader import render_to_string
gremmie@1 9 from django.template import RequestContext
gremmie@1 10 from django.http import HttpResponse
gremmie@1 11 from django.http import HttpResponseBadRequest
gremmie@1 12 from django.http import HttpResponseForbidden
gremmie@1 13 from django.views.decorators.http import require_POST
bgneal@266 14 from django.core.cache import cache
gremmie@1 15
gremmie@1 16 from membermap.models import MapEntry
gremmie@1 17 from membermap.forms import MapEntryForm
bgneal@266 18 from bio.models import UserProfile
bgneal@266 19
bgneal@266 20 CACHE_KEY = 'membermap_json'
bgneal@266 21 CACHE_TIMEOUT = 5 * 60
gremmie@1 22
gremmie@1 23
gremmie@1 24 def index(request):
gremmie@1 25 entry = None
gremmie@1 26 if request.user.is_authenticated():
gremmie@1 27 try:
gremmie@1 28 entry = MapEntry.objects.get(user=request.user)
gremmie@1 29 except MapEntry.DoesNotExist:
gremmie@1 30 pass
gremmie@1 31 if entry is not None:
gremmie@1 32 form = MapEntryForm(initial={
gremmie@1 33 'location': entry.location,
gremmie@1 34 'message': entry.message})
gremmie@1 35 else:
gremmie@1 36 form = MapEntryForm()
gremmie@1 37
gremmie@1 38 return render_to_response('membermap/index.html', {
gremmie@1 39 'form': form,
gremmie@1 40 },
gremmie@1 41 context_instance = RequestContext(request))
gremmie@1 42
gremmie@1 43
gremmie@1 44 def query(request):
gremmie@1 45 """
gremmie@1 46 This view is called by AJAX. If the user is logged in, return
gremmie@1 47 a JSON object that consists of:
gremmie@1 48 "users" : array of user objects
gremmie@1 49 "recent" : array of usernames recently modified
gremmie@1 50 """
bgneal@266 51 if not request.user.is_authenticated():
bgneal@266 52 return HttpResponseForbidden('You must be logged in.')
gremmie@1 53
bgneal@266 54 # Do we have all the JSON cached?
bgneal@266 55 s = cache.get(CACHE_KEY)
bgneal@266 56 if s:
gremmie@1 57 return HttpResponse(s, content_type='application/json')
gremmie@1 58
bgneal@266 59 # Compute JSON for the map
bgneal@791 60 entries = MapEntry.objects.select_related('user', 'user__profile').\
bgneal@791 61 order_by('user__username')
bgneal@266 62 users = []
bgneal@791 63 avatar_urls = []
bgneal@266 64 recent = []
bgneal@266 65 for entry in entries.iterator():
bgneal@266 66 users.append(dict(name=entry.user.username,
bgneal@266 67 lat=entry.lat,
bgneal@266 68 lon=entry.lon,
bgneal@266 69 message=entry.html,
bgneal@266 70 ))
bgneal@791 71 avatar = entry.user.profile.avatar
bgneal@791 72 if avatar and avatar.url:
bgneal@791 73 avatar_urls.append(avatar.url)
bgneal@791 74 else:
bgneal@791 75 avatar_urls.append(None)
bgneal@266 76 recent.append((entry.date_updated, entry.user.username))
bgneal@266 77
bgneal@266 78 # Render the messages that go in the balloons
bgneal@791 79 for user, avatar_url in zip(users, avatar_urls):
bgneal@266 80 user['message'] = render_to_string('membermap/balloon.html',
bgneal@791 81 dict(user=user, avatar_url=avatar_url))
bgneal@266 82
bgneal@266 83 # Produce the list of recent updates
bgneal@266 84 recent.sort(reverse=True)
bgneal@266 85 del recent[10:]
bgneal@266 86 recent = [entry[1] for entry in recent]
bgneal@266 87
bgneal@266 88 # Create the JSON for the map
bgneal@266 89 result = dict(users=users, recent=recent)
bgneal@266 90 s = json.dumps(result, ensure_ascii=False)
bgneal@266 91
bgneal@266 92 cache.set(CACHE_KEY, s, CACHE_TIMEOUT)
bgneal@266 93 return HttpResponse(s, content_type='application/json')
gremmie@1 94
gremmie@1 95
gremmie@1 96 @require_POST
gremmie@1 97 def add(request):
gremmie@1 98 """
gremmie@1 99 This view is called by AJAX to add/update the user to the map.
gremmie@1 100 It returns the new JSON representation of the user.
gremmie@1 101 """
gremmie@1 102 if not request.user.is_authenticated():
gremmie@1 103 return HttpResponseForbidden('You must be logged in.')
gremmie@1 104
gremmie@1 105 loc = request.POST.get('loc', None)
gremmie@1 106 lat = request.POST.get('lat', None)
gremmie@1 107 lon = request.POST.get('lon', None)
gremmie@1 108 msg = request.POST.get('msg', '')
gremmie@1 109
gremmie@1 110 if loc is None or lat is None or lon is None:
gremmie@1 111 return HttpResponseBadRequest('Missing parameters')
gremmie@1 112
gremmie@1 113 try:
gremmie@1 114 lat = float(lat)
gremmie@1 115 lon = float(lon)
gremmie@1 116 except ValueError:
gremmie@1 117 return HttpResponseBadRequest('Invalid lat/lon')
gremmie@1 118
gremmie@1 119 try:
gremmie@1 120 entry = MapEntry.objects.get(user=request.user)
gremmie@1 121 except MapEntry.DoesNotExist:
gremmie@1 122 entry = MapEntry(user=request.user)
gremmie@1 123
gremmie@1 124 entry.location = loc
gremmie@1 125 entry.lat = lat
gremmie@1 126 entry.lon = lon
gremmie@1 127 entry.message = msg
gremmie@1 128 entry.save()
gremmie@1 129
bgneal@266 130 cache.delete(CACHE_KEY)
bgneal@266 131
bgneal@266 132 avatar_url = None
bgneal@789 133 profile = entry.user.profile
bgneal@266 134 if profile.avatar and profile.avatar.url:
bgneal@266 135 avatar_url = profile.avatar.url
bgneal@266 136
bgneal@266 137 u = dict(name=entry.user.username,
bgneal@266 138 lat=entry.lat,
bgneal@266 139 lon=entry.lon,
bgneal@266 140 message=entry.html)
bgneal@266 141
bgneal@266 142 u['message'] = render_to_string('membermap/balloon.html',
bgneal@266 143 dict(user=u, avatar_url=avatar_url))
bgneal@266 144
bgneal@266 145 result = json.dumps(u, ensure_ascii=False)
bgneal@266 146 return HttpResponse(result, content_type='application/json')
gremmie@1 147
gremmie@1 148
gremmie@1 149 @require_POST
gremmie@1 150 def delete(request):
gremmie@1 151 """
gremmie@1 152 This view is called by AJAX to delete the user from the map.
gremmie@1 153 """
gremmie@1 154 if not request.user.is_authenticated():
gremmie@1 155 return HttpResponseForbidden('You must be logged in.')
gremmie@1 156
gremmie@1 157 try:
gremmie@1 158 entry = MapEntry.objects.get(user=request.user)
gremmie@1 159 except MapEntry.DoesNotExist:
gremmie@1 160 pass
gremmie@1 161 else:
gremmie@1 162 entry.delete()
bgneal@266 163 cache.delete(CACHE_KEY)
gremmie@1 164
gremmie@1 165 return HttpResponse('')