annotate membermap/views.py @ 1200:b9514abc2a67

Initial commit of ssg101.
author Brian Neal <bgneal@gmail.com>
date Sat, 24 Jun 2023 16:06:51 -0500
parents 26f2b83e7468
children
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
bgneal@1031 7 from django.shortcuts import render
bgneal@266 8 from django.template.loader import render_to_string
gremmie@1 9 from django.http import HttpResponse
gremmie@1 10 from django.http import HttpResponseBadRequest
gremmie@1 11 from django.http import HttpResponseForbidden
gremmie@1 12 from django.views.decorators.http import require_POST
bgneal@266 13 from django.core.cache import cache
gremmie@1 14
bgneal@1024 15 from core.html import ImageCheckError
bgneal@1024 16 from core.html import image_check
bgneal@1024 17 from core.markup import site_markup
gremmie@1 18 from membermap.models import MapEntry
gremmie@1 19 from membermap.forms import MapEntryForm
bgneal@266 20
bgneal@266 21 CACHE_KEY = 'membermap_json'
bgneal@266 22 CACHE_TIMEOUT = 5 * 60
gremmie@1 23
gremmie@1 24
gremmie@1 25 def index(request):
gremmie@1 26 entry = None
gremmie@1 27 if request.user.is_authenticated():
gremmie@1 28 try:
gremmie@1 29 entry = MapEntry.objects.get(user=request.user)
gremmie@1 30 except MapEntry.DoesNotExist:
gremmie@1 31 pass
gremmie@1 32 if entry is not None:
gremmie@1 33 form = MapEntryForm(initial={
gremmie@1 34 'location': entry.location,
gremmie@1 35 'message': entry.message})
gremmie@1 36 else:
gremmie@1 37 form = MapEntryForm()
gremmie@1 38
bgneal@1031 39 return render(request, 'membermap/index.html', {
gremmie@1 40 'form': form,
bgneal@1077 41 'V3_DESIGN': True,
bgneal@1031 42 })
gremmie@1 43
gremmie@1 44
gremmie@1 45 def query(request):
gremmie@1 46 """
gremmie@1 47 This view is called by AJAX. If the user is logged in, return
gremmie@1 48 a JSON object that consists of:
gremmie@1 49 "users" : array of user objects
gremmie@1 50 "recent" : array of usernames recently modified
gremmie@1 51 """
bgneal@266 52 if not request.user.is_authenticated():
bgneal@266 53 return HttpResponseForbidden('You must be logged in.')
gremmie@1 54
bgneal@266 55 # Do we have all the JSON cached?
bgneal@266 56 s = cache.get(CACHE_KEY)
bgneal@266 57 if s:
gremmie@1 58 return HttpResponse(s, content_type='application/json')
gremmie@1 59
bgneal@266 60 # Compute JSON for the map
bgneal@791 61 entries = MapEntry.objects.select_related('user', 'user__profile').\
bgneal@791 62 order_by('user__username')
bgneal@266 63 users = []
bgneal@791 64 avatar_urls = []
bgneal@266 65 recent = []
bgneal@266 66 for entry in entries.iterator():
bgneal@266 67 users.append(dict(name=entry.user.username,
bgneal@266 68 lat=entry.lat,
bgneal@266 69 lon=entry.lon,
bgneal@266 70 message=entry.html,
bgneal@266 71 ))
bgneal@791 72 avatar = entry.user.profile.avatar
bgneal@791 73 if avatar and avatar.url:
bgneal@791 74 avatar_urls.append(avatar.url)
bgneal@791 75 else:
bgneal@791 76 avatar_urls.append(None)
bgneal@266 77 recent.append((entry.date_updated, entry.user.username))
bgneal@266 78
bgneal@266 79 # Render the messages that go in the balloons
bgneal@791 80 for user, avatar_url in zip(users, avatar_urls):
bgneal@266 81 user['message'] = render_to_string('membermap/balloon.html',
bgneal@791 82 dict(user=user, avatar_url=avatar_url))
bgneal@266 83
bgneal@266 84 # Produce the list of recent updates
bgneal@266 85 recent.sort(reverse=True)
bgneal@266 86 del recent[10:]
bgneal@266 87 recent = [entry[1] for entry in recent]
bgneal@266 88
bgneal@266 89 # Create the JSON for the map
bgneal@266 90 result = dict(users=users, recent=recent)
bgneal@266 91 s = json.dumps(result, ensure_ascii=False)
bgneal@266 92
bgneal@266 93 cache.set(CACHE_KEY, s, CACHE_TIMEOUT)
bgneal@266 94 return HttpResponse(s, content_type='application/json')
gremmie@1 95
gremmie@1 96
gremmie@1 97 @require_POST
gremmie@1 98 def add(request):
gremmie@1 99 """
gremmie@1 100 This view is called by AJAX to add/update the user to the map.
gremmie@1 101 It returns the new JSON representation of the user.
gremmie@1 102 """
gremmie@1 103 if not request.user.is_authenticated():
gremmie@1 104 return HttpResponseForbidden('You must be logged in.')
gremmie@1 105
gremmie@1 106 loc = request.POST.get('loc', None)
gremmie@1 107 lat = request.POST.get('lat', None)
gremmie@1 108 lon = request.POST.get('lon', None)
bgneal@1024 109 msg = request.POST.get('msg', '').strip()
gremmie@1 110
gremmie@1 111 if loc is None or lat is None or lon is None:
gremmie@1 112 return HttpResponseBadRequest('Missing parameters')
gremmie@1 113
gremmie@1 114 try:
gremmie@1 115 lat = float(lat)
gremmie@1 116 lon = float(lon)
gremmie@1 117 except ValueError:
gremmie@1 118 return HttpResponseBadRequest('Invalid lat/lon')
gremmie@1 119
bgneal@1024 120 html = ''
bgneal@1024 121 if msg:
bgneal@1024 122 html = site_markup(msg)
bgneal@1024 123 try:
bgneal@1024 124 image_check(html)
bgneal@1024 125 except ImageCheckError as ex:
bgneal@1024 126 return HttpResponseBadRequest(str(ex))
bgneal@1024 127
gremmie@1 128 try:
gremmie@1 129 entry = MapEntry.objects.get(user=request.user)
gremmie@1 130 except MapEntry.DoesNotExist:
gremmie@1 131 entry = MapEntry(user=request.user)
gremmie@1 132
gremmie@1 133 entry.location = loc
gremmie@1 134 entry.lat = lat
gremmie@1 135 entry.lon = lon
gremmie@1 136 entry.message = msg
bgneal@1024 137 entry.save(html=html)
gremmie@1 138
bgneal@266 139 cache.delete(CACHE_KEY)
bgneal@266 140
bgneal@266 141 avatar_url = None
bgneal@789 142 profile = entry.user.profile
bgneal@266 143 if profile.avatar and profile.avatar.url:
bgneal@266 144 avatar_url = profile.avatar.url
bgneal@266 145
bgneal@266 146 u = dict(name=entry.user.username,
bgneal@266 147 lat=entry.lat,
bgneal@266 148 lon=entry.lon,
bgneal@266 149 message=entry.html)
bgneal@266 150
bgneal@266 151 u['message'] = render_to_string('membermap/balloon.html',
bgneal@266 152 dict(user=u, avatar_url=avatar_url))
bgneal@266 153
bgneal@266 154 result = json.dumps(u, ensure_ascii=False)
bgneal@266 155 return HttpResponse(result, content_type='application/json')
gremmie@1 156
gremmie@1 157
gremmie@1 158 @require_POST
gremmie@1 159 def delete(request):
gremmie@1 160 """
gremmie@1 161 This view is called by AJAX to delete the user from the map.
gremmie@1 162 """
gremmie@1 163 if not request.user.is_authenticated():
gremmie@1 164 return HttpResponseForbidden('You must be logged in.')
gremmie@1 165
gremmie@1 166 try:
gremmie@1 167 entry = MapEntry.objects.get(user=request.user)
gremmie@1 168 except MapEntry.DoesNotExist:
gremmie@1 169 pass
gremmie@1 170 else:
gremmie@1 171 entry.delete()
bgneal@266 172 cache.delete(CACHE_KEY)
gremmie@1 173
gremmie@1 174 return HttpResponse('')