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('')