annotate membermap/views.py @ 629:f4c043cf55ac

Wiki integration. Requests don't always have sessions. In particular this occurs when a request is made without a trailing slash. The Common middleware redirects when this happens, and the middleware process_request() processing stops before a session can get added. So just set an attribute on the request object for each operation. This seemed weird to me at first, but there are plenty of examples of this in the Django code base already.
author Brian Neal <bgneal@gmail.com>
date Tue, 13 Nov 2012 13:50:06 -0600
parents ee87ea74d46b
children 89b240fe9297
rev   line source
gremmie@1 1 """
gremmie@1 2 Views for the membermap application.
gremmie@1 3 """
gremmie@1 4 from django.shortcuts import render_to_response
bgneal@266 5 from django.template.loader import render_to_string
gremmie@1 6 from django.template import RequestContext
gremmie@1 7 from django.http import HttpResponse
gremmie@1 8 from django.http import HttpResponseBadRequest
gremmie@1 9 from django.http import HttpResponseForbidden
gremmie@1 10 from django.views.decorators.http import require_POST
bgneal@266 11 import django.utils.simplejson as json
bgneal@266 12 from django.core.cache import cache
gremmie@1 13
gremmie@1 14 from membermap.models import MapEntry
gremmie@1 15 from membermap.forms import MapEntryForm
bgneal@266 16 from bio.models import UserProfile
bgneal@266 17
bgneal@266 18 CACHE_KEY = 'membermap_json'
bgneal@266 19 CACHE_TIMEOUT = 5 * 60
gremmie@1 20
gremmie@1 21
gremmie@1 22 def index(request):
gremmie@1 23 entry = None
gremmie@1 24 if request.user.is_authenticated():
gremmie@1 25 try:
gremmie@1 26 entry = MapEntry.objects.get(user=request.user)
gremmie@1 27 except MapEntry.DoesNotExist:
gremmie@1 28 pass
gremmie@1 29 if entry is not None:
gremmie@1 30 form = MapEntryForm(initial={
gremmie@1 31 'location': entry.location,
gremmie@1 32 'message': entry.message})
gremmie@1 33 else:
gremmie@1 34 form = MapEntryForm()
gremmie@1 35
gremmie@1 36 return render_to_response('membermap/index.html', {
gremmie@1 37 'form': form,
gremmie@1 38 },
gremmie@1 39 context_instance = RequestContext(request))
gremmie@1 40
gremmie@1 41
gremmie@1 42 def query(request):
gremmie@1 43 """
gremmie@1 44 This view is called by AJAX. If the user is logged in, return
gremmie@1 45 a JSON object that consists of:
gremmie@1 46 "users" : array of user objects
gremmie@1 47 "recent" : array of usernames recently modified
gremmie@1 48 """
bgneal@266 49 if not request.user.is_authenticated():
bgneal@266 50 return HttpResponseForbidden('You must be logged in.')
gremmie@1 51
bgneal@266 52 # Do we have all the JSON cached?
bgneal@266 53 s = cache.get(CACHE_KEY)
bgneal@266 54 if s:
gremmie@1 55 return HttpResponse(s, content_type='application/json')
gremmie@1 56
bgneal@266 57 # Compute JSON for the map
bgneal@266 58 entries = MapEntry.objects.all().select_related().order_by('user__username')
bgneal@266 59 users = []
bgneal@266 60 user_ids = []
bgneal@266 61 recent = []
bgneal@266 62 for entry in entries.iterator():
bgneal@266 63 users.append(dict(name=entry.user.username,
bgneal@266 64 lat=entry.lat,
bgneal@266 65 lon=entry.lon,
bgneal@266 66 message=entry.html,
bgneal@266 67 ))
bgneal@266 68 user_ids.append(entry.user.id)
bgneal@266 69 recent.append((entry.date_updated, entry.user.username))
bgneal@266 70
bgneal@266 71 # Get avatars for all users
bgneal@266 72 profiles = UserProfile.objects.filter(user__in=user_ids).select_related()
bgneal@266 73 avatars = {}
bgneal@266 74 for profile in profiles.iterator():
bgneal@266 75 if profile.avatar and profile.avatar.url:
bgneal@266 76 avatars[profile.user.username] = profile.avatar.url
bgneal@266 77
bgneal@266 78 # Render the messages that go in the balloons
bgneal@266 79 for user in users:
bgneal@266 80 user['message'] = render_to_string('membermap/balloon.html',
bgneal@266 81 dict(user=user, avatar_url=avatars.get(user['name'])))
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@266 133 profile = entry.user.get_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('')