gremmie@1: """
gremmie@1: Views for the membermap application.
gremmie@1: """
gremmie@1: from django.shortcuts import render_to_response
bgneal@266: from django.template.loader import render_to_string
gremmie@1: from django.template import RequestContext
gremmie@1: from django.http import HttpResponse
gremmie@1: from django.http import HttpResponseBadRequest
gremmie@1: from django.http import HttpResponseForbidden
gremmie@1: from django.views.decorators.http import require_POST
bgneal@266: import django.utils.simplejson as json
bgneal@266: from django.core.cache import cache
gremmie@1: 
gremmie@1: from membermap.models import MapEntry
gremmie@1: from membermap.forms import MapEntryForm
bgneal@266: from bio.models import UserProfile
bgneal@266: 
bgneal@266: CACHE_KEY = 'membermap_json'
bgneal@266: CACHE_TIMEOUT = 5 * 60
gremmie@1: 
gremmie@1: 
gremmie@1: def index(request):
gremmie@1:     entry = None
gremmie@1:     if request.user.is_authenticated():
gremmie@1:         try:
gremmie@1:             entry = MapEntry.objects.get(user=request.user)
gremmie@1:         except MapEntry.DoesNotExist:
gremmie@1:             pass
gremmie@1:     if entry is not None:
gremmie@1:         form = MapEntryForm(initial={
gremmie@1:             'location': entry.location,
gremmie@1:             'message': entry.message})
gremmie@1:     else:
gremmie@1:         form = MapEntryForm()
gremmie@1: 
gremmie@1:     return render_to_response('membermap/index.html', {
gremmie@1:         'form': form,
gremmie@1:         },
gremmie@1:         context_instance = RequestContext(request))
gremmie@1: 
gremmie@1: 
gremmie@1: def query(request):
gremmie@1:     """
gremmie@1:     This view is called by AJAX. If the user is logged in, return
gremmie@1:     a JSON object that consists of:
gremmie@1:         "users" : array of user objects
gremmie@1:         "recent" : array of usernames recently modified
gremmie@1:     """
bgneal@266:     if not request.user.is_authenticated():
bgneal@266:         return HttpResponseForbidden('You must be logged in.')
gremmie@1: 
bgneal@266:     # Do we have all the JSON cached?
bgneal@266:     s = cache.get(CACHE_KEY)
bgneal@266:     if s:
gremmie@1:         return HttpResponse(s, content_type='application/json')
gremmie@1: 
bgneal@266:     # Compute JSON for the map
bgneal@266:     entries = MapEntry.objects.all().select_related().order_by('user__username')
bgneal@266:     users = []
bgneal@266:     user_ids = []
bgneal@266:     recent = []
bgneal@266:     for entry in entries.iterator():
bgneal@266:         users.append(dict(name=entry.user.username,
bgneal@266:             lat=entry.lat,
bgneal@266:             lon=entry.lon,
bgneal@266:             message=entry.html,
bgneal@266:             ))
bgneal@266:         user_ids.append(entry.user.id)
bgneal@266:         recent.append((entry.date_updated, entry.user.username))
bgneal@266: 
bgneal@266:     # Get avatars for all users
bgneal@266:     profiles = UserProfile.objects.filter(user__in=user_ids).select_related()
bgneal@266:     avatars = {}
bgneal@266:     for profile in profiles.iterator():
bgneal@266:         if profile.avatar and profile.avatar.url:
bgneal@266:             avatars[profile.user.username] = profile.avatar.url
bgneal@266: 
bgneal@266:     # Render the messages that go in the balloons
bgneal@266:     for user in users:
bgneal@266:         user['message'] = render_to_string('membermap/balloon.html',
bgneal@266:                 dict(user=user, avatar_url=avatars.get(user['name'])))
bgneal@266: 
bgneal@266:     # Produce the list of recent updates
bgneal@266:     recent.sort(reverse=True)
bgneal@266:     del recent[10:]
bgneal@266:     recent = [entry[1] for entry in recent]
bgneal@266: 
bgneal@266:     # Create the JSON for the map
bgneal@266:     result = dict(users=users, recent=recent)
bgneal@266:     s = json.dumps(result, ensure_ascii=False)
bgneal@266: 
bgneal@266:     cache.set(CACHE_KEY, s, CACHE_TIMEOUT)
bgneal@266:     return HttpResponse(s, content_type='application/json')
gremmie@1: 
gremmie@1: 
gremmie@1: @require_POST
gremmie@1: def add(request):
gremmie@1:     """
gremmie@1:     This view is called by AJAX to add/update the user to the map.
gremmie@1:     It returns the new JSON representation of the user.
gremmie@1:     """
gremmie@1:     if not request.user.is_authenticated():
gremmie@1:         return HttpResponseForbidden('You must be logged in.')
gremmie@1: 
gremmie@1:     loc = request.POST.get('loc', None)
gremmie@1:     lat = request.POST.get('lat', None)
gremmie@1:     lon = request.POST.get('lon', None)
gremmie@1:     msg = request.POST.get('msg', '')
gremmie@1: 
gremmie@1:     if loc is None or lat is None or lon is None:
gremmie@1:         return HttpResponseBadRequest('Missing parameters')
gremmie@1: 
gremmie@1:     try:
gremmie@1:         lat = float(lat)
gremmie@1:         lon = float(lon)
gremmie@1:     except ValueError:
gremmie@1:         return HttpResponseBadRequest('Invalid lat/lon')
gremmie@1: 
gremmie@1:     try:
gremmie@1:         entry = MapEntry.objects.get(user=request.user)
gremmie@1:     except MapEntry.DoesNotExist:
gremmie@1:         entry = MapEntry(user=request.user)
gremmie@1: 
gremmie@1:     entry.location = loc
gremmie@1:     entry.lat = lat
gremmie@1:     entry.lon = lon
gremmie@1:     entry.message = msg
gremmie@1:     entry.save()
gremmie@1: 
bgneal@266:     cache.delete(CACHE_KEY)
bgneal@266: 
bgneal@266:     avatar_url = None
bgneal@266:     profile = entry.user.get_profile()
bgneal@266:     if profile.avatar and profile.avatar.url:
bgneal@266:         avatar_url = profile.avatar.url
bgneal@266: 
bgneal@266:     u = dict(name=entry.user.username,
bgneal@266:             lat=entry.lat,
bgneal@266:             lon=entry.lon,
bgneal@266:             message=entry.html)
bgneal@266: 
bgneal@266:     u['message'] = render_to_string('membermap/balloon.html',
bgneal@266:         dict(user=u, avatar_url=avatar_url))
bgneal@266: 
bgneal@266:     result = json.dumps(u, ensure_ascii=False)
bgneal@266:     return HttpResponse(result, content_type='application/json')
gremmie@1: 
gremmie@1: 
gremmie@1: @require_POST
gremmie@1: def delete(request):
gremmie@1:     """
gremmie@1:     This view is called by AJAX to delete the user from the map.
gremmie@1:     """
gremmie@1:     if not request.user.is_authenticated():
gremmie@1:         return HttpResponseForbidden('You must be logged in.')
gremmie@1: 
gremmie@1:     try:
gremmie@1:         entry = MapEntry.objects.get(user=request.user)
gremmie@1:     except MapEntry.DoesNotExist:
gremmie@1:         pass
gremmie@1:     else:
gremmie@1:         entry.delete()
bgneal@266:         cache.delete(CACHE_KEY)
gremmie@1: 
gremmie@1:     return HttpResponse('')