gremmie@1: """ gremmie@1: Views for the membermap application. bgneal@679: gremmie@1: """ bgneal@679: import json bgneal@679: 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: from django.core.cache import cache gremmie@1: bgneal@1024: from core.html import ImageCheckError bgneal@1024: from core.html import image_check bgneal@1024: from core.markup import site_markup gremmie@1: from membermap.models import MapEntry gremmie@1: from membermap.forms import MapEntryForm 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@791: entries = MapEntry.objects.select_related('user', 'user__profile').\ bgneal@791: order_by('user__username') bgneal@266: users = [] bgneal@791: avatar_urls = [] 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@791: avatar = entry.user.profile.avatar bgneal@791: if avatar and avatar.url: bgneal@791: avatar_urls.append(avatar.url) bgneal@791: else: bgneal@791: avatar_urls.append(None) bgneal@266: recent.append((entry.date_updated, entry.user.username)) bgneal@266: bgneal@266: # Render the messages that go in the balloons bgneal@791: for user, avatar_url in zip(users, avatar_urls): bgneal@266: user['message'] = render_to_string('membermap/balloon.html', bgneal@791: dict(user=user, avatar_url=avatar_url)) 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) bgneal@1024: msg = request.POST.get('msg', '').strip() 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: bgneal@1024: html = '' bgneal@1024: if msg: bgneal@1024: html = site_markup(msg) bgneal@1024: try: bgneal@1024: image_check(html) bgneal@1024: except ImageCheckError as ex: bgneal@1024: return HttpResponseBadRequest(str(ex)) bgneal@1024: 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 bgneal@1024: entry.save(html=html) gremmie@1: bgneal@266: cache.delete(CACHE_KEY) bgneal@266: bgneal@266: avatar_url = None bgneal@789: profile = entry.user.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('')