annotate membermap/views.py @ 762:840f2579ef1c

Added a test for the forgotten password cycle. This was broken when I upgraded to Django 1.6. Ensure we catch it next time.
author Brian Neal <bgneal@gmail.com>
date Sun, 19 Jan 2014 00:19:44 -0600
parents 89b240fe9297
children 9e803323a0d0
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@266 60 entries = MapEntry.objects.all().select_related().order_by('user__username')
bgneal@266 61 users = []
bgneal@266 62 user_ids = []
bgneal@266 63 recent = []
bgneal@266 64 for entry in entries.iterator():
bgneal@266 65 users.append(dict(name=entry.user.username,
bgneal@266 66 lat=entry.lat,
bgneal@266 67 lon=entry.lon,
bgneal@266 68 message=entry.html,
bgneal@266 69 ))
bgneal@266 70 user_ids.append(entry.user.id)
bgneal@266 71 recent.append((entry.date_updated, entry.user.username))
bgneal@266 72
bgneal@266 73 # Get avatars for all users
bgneal@266 74 profiles = UserProfile.objects.filter(user__in=user_ids).select_related()
bgneal@266 75 avatars = {}
bgneal@266 76 for profile in profiles.iterator():
bgneal@266 77 if profile.avatar and profile.avatar.url:
bgneal@266 78 avatars[profile.user.username] = profile.avatar.url
bgneal@266 79
bgneal@266 80 # Render the messages that go in the balloons
bgneal@266 81 for user in users:
bgneal@266 82 user['message'] = render_to_string('membermap/balloon.html',
bgneal@266 83 dict(user=user, avatar_url=avatars.get(user['name'])))
bgneal@266 84
bgneal@266 85 # Produce the list of recent updates
bgneal@266 86 recent.sort(reverse=True)
bgneal@266 87 del recent[10:]
bgneal@266 88 recent = [entry[1] for entry in recent]
bgneal@266 89
bgneal@266 90 # Create the JSON for the map
bgneal@266 91 result = dict(users=users, recent=recent)
bgneal@266 92 s = json.dumps(result, ensure_ascii=False)
bgneal@266 93
bgneal@266 94 cache.set(CACHE_KEY, s, CACHE_TIMEOUT)
bgneal@266 95 return HttpResponse(s, content_type='application/json')
gremmie@1 96
gremmie@1 97
gremmie@1 98 @require_POST
gremmie@1 99 def add(request):
gremmie@1 100 """
gremmie@1 101 This view is called by AJAX to add/update the user to the map.
gremmie@1 102 It returns the new JSON representation of the user.
gremmie@1 103 """
gremmie@1 104 if not request.user.is_authenticated():
gremmie@1 105 return HttpResponseForbidden('You must be logged in.')
gremmie@1 106
gremmie@1 107 loc = request.POST.get('loc', None)
gremmie@1 108 lat = request.POST.get('lat', None)
gremmie@1 109 lon = request.POST.get('lon', None)
gremmie@1 110 msg = request.POST.get('msg', '')
gremmie@1 111
gremmie@1 112 if loc is None or lat is None or lon is None:
gremmie@1 113 return HttpResponseBadRequest('Missing parameters')
gremmie@1 114
gremmie@1 115 try:
gremmie@1 116 lat = float(lat)
gremmie@1 117 lon = float(lon)
gremmie@1 118 except ValueError:
gremmie@1 119 return HttpResponseBadRequest('Invalid lat/lon')
gremmie@1 120
gremmie@1 121 try:
gremmie@1 122 entry = MapEntry.objects.get(user=request.user)
gremmie@1 123 except MapEntry.DoesNotExist:
gremmie@1 124 entry = MapEntry(user=request.user)
gremmie@1 125
gremmie@1 126 entry.location = loc
gremmie@1 127 entry.lat = lat
gremmie@1 128 entry.lon = lon
gremmie@1 129 entry.message = msg
gremmie@1 130 entry.save()
gremmie@1 131
bgneal@266 132 cache.delete(CACHE_KEY)
bgneal@266 133
bgneal@266 134 avatar_url = None
bgneal@266 135 profile = entry.user.get_profile()
bgneal@266 136 if profile.avatar and profile.avatar.url:
bgneal@266 137 avatar_url = profile.avatar.url
bgneal@266 138
bgneal@266 139 u = dict(name=entry.user.username,
bgneal@266 140 lat=entry.lat,
bgneal@266 141 lon=entry.lon,
bgneal@266 142 message=entry.html)
bgneal@266 143
bgneal@266 144 u['message'] = render_to_string('membermap/balloon.html',
bgneal@266 145 dict(user=u, avatar_url=avatar_url))
bgneal@266 146
bgneal@266 147 result = json.dumps(u, ensure_ascii=False)
bgneal@266 148 return HttpResponse(result, content_type='application/json')
gremmie@1 149
gremmie@1 150
gremmie@1 151 @require_POST
gremmie@1 152 def delete(request):
gremmie@1 153 """
gremmie@1 154 This view is called by AJAX to delete the user from the map.
gremmie@1 155 """
gremmie@1 156 if not request.user.is_authenticated():
gremmie@1 157 return HttpResponseForbidden('You must be logged in.')
gremmie@1 158
gremmie@1 159 try:
gremmie@1 160 entry = MapEntry.objects.get(user=request.user)
gremmie@1 161 except MapEntry.DoesNotExist:
gremmie@1 162 pass
gremmie@1 163 else:
gremmie@1 164 entry.delete()
bgneal@266 165 cache.delete(CACHE_KEY)
gremmie@1 166
gremmie@1 167 return HttpResponse('')