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