Mercurial > public > sg101
changeset 827:5103edd3acc4
Bandmap: initial version complete.
Javascript queries server for band data.
View created to handle query.
Test created for view.
Link added to map in sidebar.
Template tweaks.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sat, 27 Sep 2014 19:41:41 -0500 |
parents | d7e4c08b2e8b |
children | d02e8d7a0bcd |
files | bandmap/admin.py bandmap/static/css/bandmap.css bandmap/static/js/bandmap.js bandmap/tests/test_views.py bandmap/urls.py bandmap/views.py sg101/templates/bandmap/add.html sg101/templates/bandmap/balloon.html sg101/templates/bandmap/map.html sg101/templates/base.html |
diffstat | 10 files changed, 208 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/bandmap/admin.py Sat Sep 27 15:14:47 2014 -0500 +++ b/bandmap/admin.py Sat Sep 27 19:41:41 2014 -0500 @@ -21,7 +21,7 @@ readonly_fields = ['lat', 'lon'] search_fields = ['name', 'location', 'note'] raw_id_fields = ['user'] - actions = ['approve_bands', 'update_location'] + actions = ['update_location', 'approve_bands'] def approve_bands(self, request, qs): """This admin action awards a map pin to the user who added the band. @@ -31,10 +31,12 @@ count = qs.count() now = datetime.datetime.now() for band in qs: - bio.badges.award_badge(bio.badges.MAP_PIN, band.user) - band.date_approved = now - band.is_approved = True - band.save() + if not band.is_approved: + if band.date_approved is None: + bio.badges.award_badge(bio.badges.MAP_PIN, band.user) + band.date_approved = now + band.is_approved = True + band.save() self.message_user(request, "%d band(s) approved." % count)
--- a/bandmap/static/css/bandmap.css Sat Sep 27 15:14:47 2014 -0500 +++ b/bandmap/static/css/bandmap.css Sat Sep 27 19:41:41 2014 -0500 @@ -4,3 +4,6 @@ border: 1px solid black; margin: 0 auto; } +#map-info { + margin-top: 2em; +}
--- a/bandmap/static/js/bandmap.js Sat Sep 27 15:14:47 2014 -0500 +++ b/bandmap/static/js/bandmap.js Sat Sep 27 19:41:41 2014 -0500 @@ -1,5 +1,11 @@ var bandmap = null; var geocoder = null; +var surfbands = []; +var map_options = { + center: {lat: 15.0, lng: -30.0}, + zoom: 2 +}; +var info_win = null; function addBandOnSubmit(event) { var location = $('#id_location').val(); @@ -26,14 +32,54 @@ return false; } + +function refreshMap() { + bandmap.setOptions(map_options); + $.each(surfbands, function(i, band) { + band.marker.setMap(null); + }); + surfbands.length = 0; + var band_sel = $('#map-bands'); + band_sel[0].length = 0; + band_sel.append($('<option>', {value: -1}).html('(select)')); + var count_span = $('#map-band-count'); + count_span.html('0'); + var filter = $('#map-filter option:selected').val(); + + $.getJSON('/bandmap/query/', {show: filter}, + function(data) { + $.each(data, function(i, band) { + band_sel.append($('<option>', {value: i, text: band.name})); + var marker = new google.maps.Marker({ + position: {lat: band.lat, lng: band.lon}, + title: band.name, + map: bandmap + }); + google.maps.event.addListener(marker, 'click', function() { + info_win.setContent(band.note); + info_win.open(bandmap, marker); + }); + surfbands[i] = band; + surfbands[i].marker = marker; + }); + count_span.html(data.length); + }); +} + $(document).ready(function() { var map_div = $('#map-canvas'); if (map_div.length) { - var map_options = { - center: {lat: 15.0, lng: -30.0}, - zoom: 2 - }; bandmap = new google.maps.Map(map_div[0], map_options); + info_win = new google.maps.InfoWindow(); + $('#map-filter-go').click(refreshMap); + $('#map-bands').change(function() { + var n = $('option:selected', this).val(); + if (n != -1) { + info_win.setContent(surfbands[n].note); + info_win.open(bandmap, surfbands[n].marker); + } + }); + refreshMap(); } var add_form = $('#bandmap-add-form');
--- a/bandmap/tests/test_views.py Sat Sep 27 15:14:47 2014 -0500 +++ b/bandmap/tests/test_views.py Sat Sep 27 19:41:41 2014 -0500 @@ -3,6 +3,7 @@ """ import datetime +import json from django.test import TestCase from django.core.urlresolvers import reverse @@ -81,3 +82,74 @@ self.assertEqual(entry.note, post_data['note']) self.assertTrue(entry.is_active) self.assertFalse(entry.is_approved) + +class QueryTestCase(TestCase): + """Testing the query view function which returns JSON.""" + + def setUp(self): + self.user = User.objects.create_user( + username='pj', email='pj@example.com', password='top_secret') + + now = datetime.datetime.now() + + kwargs = { + 'name': 'Test Band 1', + 'user': self.user, + 'date_submitted': now, + 'date_approved': now, + 'url': 'http://example.com', + 'location': 'Somewhere', + 'lat': 42.0, + 'lon': -30.0, + 'note': 'Some text here', + 'is_active': True, + 'is_approved': True, + } + BandEntry.objects.create(**kwargs) + + kwargs['name'] = 'Test Band 2' + kwargs['is_active'] = False + BandEntry.objects.create(**kwargs) + + kwargs['name'] = 'Test Band 3' + kwargs['is_active'] = True + kwargs['is_approved'] = False + BandEntry.objects.create(**kwargs) + + def test_query(self): + url = reverse('bandmap-query') + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result), 2) + self.assertEqual(result[0]['name'], 'Test Band 1') + self.assertEqual(result[1]['name'], 'Test Band 2') + + def test_query_all(self): + url = reverse('bandmap-query') + response = self.client.get(url, {'show': 'all'}) + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result), 2) + self.assertEqual(result[0]['name'], 'Test Band 1') + self.assertEqual(result[1]['name'], 'Test Band 2') + + def test_query_active(self): + url = reverse('bandmap-query') + response = self.client.get(url, {'show': 'active'}) + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result), 1) + self.assertEqual(result[0]['name'], 'Test Band 1') + + def test_query_inactive(self): + url = reverse('bandmap-query') + response = self.client.get(url, {'show': 'inactive'}) + self.assertEqual(response.status_code, 200) + + result = json.loads(response.content) + self.assertEqual(len(result), 1) + self.assertEqual(result[0]['name'], 'Test Band 2')
--- a/bandmap/urls.py Sat Sep 27 15:14:47 2014 -0500 +++ b/bandmap/urls.py Sat Sep 27 19:41:41 2014 -0500 @@ -8,4 +8,7 @@ url(r'^add/$', 'bandmap.views.add_band', name='bandmap-add'), + url(r'^query/$', + 'bandmap.views.query', + name='bandmap-query'), )
--- a/bandmap/views.py Sat Sep 27 15:14:47 2014 -0500 +++ b/bandmap/views.py Sat Sep 27 19:41:41 2014 -0500 @@ -1,11 +1,17 @@ """Views for the bandmap application. """ +import json + from django.contrib.auth.decorators import login_required from django.shortcuts import redirect, render from django.contrib import messages as django_messages +from django.http import HttpResponse +from django.template.loader import render_to_string +from django.core.cache import cache from bandmap.forms import BandForm +from bandmap.models import BandEntry SUCCESS = "Successfully submitted {} for admin review. Thanks!" @@ -35,3 +41,41 @@ return render(request, 'bandmap/add.html', { 'form': form, }) + + +def query(request): + """Retrieves the band map entries and returns them as JSON. + + """ + show_param = request.GET.get('show', 'all') + if show_param not in ['all', 'active', 'inactive']: + show_param = 'all' + + # Do we have the results cached already? + cache_key = 'bandmap-results-{}'.format(show_param) + results = cache.get(cache_key) + if results: + return HttpResponse(results, content_type='application/json') + + # Generate results + qs = BandEntry.objects.filter(is_approved=True) + if show_param == 'active': + qs = qs.filter(is_active=True) + elif show_param == 'inactive': + qs = qs.filter(is_active=False) + + bands = [] + for band in qs.iterator(): + bands.append({ + 'name': band.name, + 'url': band.url, + 'lat': band.lat, + 'lon': band.lon, + 'note': render_to_string('bandmap/balloon.html', {'band': band}), + }) + results = json.dumps(bands) + + # Store in cache + cache.set(cache_key, results, 300) + + return HttpResponse(results, content_type='application/json')
--- a/sg101/templates/bandmap/add.html Sat Sep 27 15:14:47 2014 -0500 +++ b/sg101/templates/bandmap/add.html Sat Sep 27 19:41:41 2014 -0500 @@ -40,4 +40,5 @@ </tr> </table> </form> +<p>Back to the <a href="{% url 'bandmap-map' %}">surf band map</a>.</p> {% endblock %}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sg101/templates/bandmap/balloon.html Sat Sep 27 19:41:41 2014 -0500 @@ -0,0 +1,15 @@ +<div class="band-balloon"> +{% if band.url %} +<strong><a href="{{ band.url }}">{{ band.name }}</a></strong> +{% else %} +<strong>{{ band.name }}</strong> +{% endif %} +<em> +{% if band.is_active %} +(Active) +{% else %} +(Inactive) +{% endif %} +</em><br /> +{{ band.note }} +</div>
--- a/sg101/templates/bandmap/map.html Sat Sep 27 15:14:47 2014 -0500 +++ b/sg101/templates/bandmap/map.html Sat Sep 27 19:41:41 2014 -0500 @@ -3,5 +3,16 @@ <p>Welcome to our surf band map! This map is updated by our users and displays the locations of both active and inactive surf bands from around the world.</p> <div id="map-canvas"></div> -<p><a href="{% url 'bandmap-add' %}">Add a band to the map</a>. +<div id="map-info"> + <ul> + <li>Number of bands: <span id="map-band-count">0</span></li> + <li>Bands: <select id="map-bands"></select></li> + <li>Show: <select id="map-filter"> + <option value="all">all bands</option> + <option value="active">active bands</option> + <option value="inactive">inactive bands</option> + </select> <button id="map-filter-go">Go</button></li> + <li><a href="{% url 'bandmap-add' %}">Add a band to the map</a></li> + </ul> +</div> {% endblock %}
--- a/sg101/templates/base.html Sat Sep 27 15:14:47 2014 -0500 +++ b/sg101/templates/base.html Sat Sep 27 19:41:41 2014 -0500 @@ -60,6 +60,7 @@ <li><a href="{% url 'weblinks-main' %}">Links</a></li> <li><a href="{% url 'haystack_search' %}">Search</a></li> <li><a href="/store/">Store</a></li> + <li><a href="{% url 'bandmap-map' %}">Surf Band Map</a></li> <li><a href="http://wiki.surfguitar101.com">Wiki</a></li> <li><a href="{% url 'ygroup-thread_index' %}">Yahoo Group</a></li> </ul>