From e98c38e5fbd09f493b60e9ec27db8268fff6d214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Tue, 31 Oct 2017 16:08:20 +0100 Subject: [PATCH] represent level in state url as short_label, not its id --- src/c3nav/mapdata/models/level.py | 2 +- src/c3nav/site/static/site/js/c3nav.js | 13 +++++--- src/c3nav/site/urls.py | 2 +- src/c3nav/site/views.py | 41 +++++++++++++++++++++----- 4 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/c3nav/mapdata/models/level.py b/src/c3nav/mapdata/models/level.py index eff57387..aebaac95 100644 --- a/src/c3nav/mapdata/models/level.py +++ b/src/c3nav/mapdata/models/level.py @@ -30,7 +30,7 @@ class Level(SpecificLocation, models.Model): default_height = models.DecimalField(_('default space height'), max_digits=6, decimal_places=2, default=3.0) on_top_of = models.ForeignKey('mapdata.Level', null=True, on_delete=models.CASCADE, related_name='levels_on_top', verbose_name=_('on top of')) - short_label = models.CharField(max_length=20, verbose_name=_('short label'), unique=True) + short_label = models.SlugField(max_length=20, verbose_name=_('short label'), unique=True) render_data = models.BinaryField(null=True) diff --git a/src/c3nav/site/static/site/js/c3nav.js b/src/c3nav/site/static/site/js/c3nav.js index efb1178f..2eb5fca1 100644 --- a/src/c3nav/site/static/site/js/c3nav.js +++ b/src/c3nav/site/static/site/js/c3nav.js @@ -63,7 +63,7 @@ c3nav = { }, update_map_state: function (replace, level, center, zoom) { var new_state = { - level: center ? level : c3nav._levelControl.currentLevel, + level: c3nav.level_labels_by_id[center ? level : c3nav._levelControl.currentLevel], center: L.GeoJSON.latLngToCoords(center ? center : c3nav.map.getCenter(), 2), zoom: Math.round((center ? zoom : c3nav.map.getZoom()) * 100) / 100 }; @@ -399,10 +399,15 @@ c3nav = { // map init_map: function () { - var $map = $('#map'); + var $map = $('#map'), i; c3nav.bounds = JSON.parse($map.attr('data-bounds')); c3nav.levels = JSON.parse($map.attr('data-levels')); + c3nav.level_labels_by_id = {}; + for (i = 0; i < c3nav.levels.length; i ++) { + c3nav.level_labels_by_id[c3nav.levels[i][0]] = c3nav.levels[i][1]; + } + // create leaflet map c3nav.map = L.map('map', { renderer: L.svg({padding: 2}), @@ -432,9 +437,9 @@ c3nav = { c3nav._locationLayers = {}; c3nav._locationLayerBounds = {}; c3nav._routeLayers = {}; - for (var i = c3nav.levels.length - 1; i >= 0; i--) { + for (i = c3nav.levels.length - 1; i >= 0; i--) { var level = c3nav.levels[i]; - var layerGroup = c3nav._levelControl.addLevel(level[0], level[1]); + var layerGroup = c3nav._levelControl.addLevel(level[0], level[2]); c3nav._locationLayers[level[0]] = L.layerGroup().addTo(layerGroup); c3nav._routeLayers[level[0]] = L.layerGroup().addTo(layerGroup); } diff --git a/src/c3nav/site/urls.py b/src/c3nav/site/urls.py index 548764f9..eb419b62 100644 --- a/src/c3nav/site/urls.py +++ b/src/c3nav/site/urls.py @@ -2,7 +2,7 @@ from django.conf.urls import url from c3nav.site.views import map_index -pos = r'(@(?P\d+),(?P\d+(\.\d+)?),(?P\d+(\.\d+)?),(?P\d+(\.\d+)?))?' +pos = r'(@(?P[a-z0-9-_:]+),(?P\d+(\.\d+)?),(?P\d+(\.\d+)?),(?P\d+(\.\d+)?))?' urlpatterns = [ url(r'^r/(?P([a-z0-9-_:]+)?)/(?P([a-z0-9-_:]+)?)/%s$' % pos, map_index, name='site.index'), diff --git a/src/c3nav/site/views.py b/src/c3nav/site/views.py index f781991a..6cf13e85 100644 --- a/src/c3nav/site/views.py +++ b/src/c3nav/site/views.py @@ -1,16 +1,18 @@ # flake8: noqa import json +from collections import OrderedDict from datetime import timedelta -from typing import Optional +from typing import Mapping, Optional import qrcode -from django.core.files import File -from django.http import Http404, HttpResponse, HttpResponseNotModified, JsonResponse -from django.shortcuts import get_object_or_404, redirect, render +from django.core.cache import cache +from django.http import Http404, HttpResponse, JsonResponse +from django.shortcuts import redirect, render from django.urls import reverse from django.utils import timezone -from c3nav.mapdata.models import Location, LocationSlug, Source +from c3nav.mapdata.models import Location, Source +from c3nav.mapdata.models.access import AccessPermission from c3nav.mapdata.models.level import Level from c3nav.mapdata.models.locations import LocationRedirect, SpecificLocation from c3nav.mapdata.render.base import set_tile_access_cookie @@ -83,6 +85,20 @@ def check_location(location: Optional[str], request) -> Optional[SpecificLocatio return location +def get_levels(request) -> Mapping[int, Level]: + cache_key = 'mapdata:levels:%s' % AccessPermission.cache_key_for_request(request) + levels = cache.get(cache_key, None) + if levels is not None: + return levels + + levels = OrderedDict( + (level.slug, (level.pk, level.slug, level.short_label)) + for level in Level.qs_for_request(request).order_by('base_altitude') + ) + cache.set(cache_key, levels, 300) + return levels + + def map_index(request, origin=None, destination=None, level=None, x=None, y=None, zoom=None): levels = Level.qs_for_request(request).filter(on_top_of_id__isnull=True) @@ -99,16 +115,27 @@ def map_index(request, origin=None, destination=None, level=None, x=None, y=None if destination else None), 'sidebar': destination_slug is not None, } + + levels_cache_key = 'mapdata:levels:%s' % AccessPermission.cache_key_for_request(request) + levels = cache.get(levels_cache_key, None) + if levels is None: + levels = OrderedDict( + (level.slug, (level.pk, level.slug, level.short_label)) + for level in Level.qs_for_request(request).order_by('base_altitude') + ) + cache.set(levels_cache_key, levels, 300) + + level = levels.get(level, None) if level else None if level is not None: state.update({ - 'level': int(level), + 'level': level[0], 'center': (float(x), float(y)), 'zoom': float(zoom), }) ctx = { 'bounds': json.dumps(Source.max_bounds(), separators=(',', ':')), - 'levels': json.dumps(tuple((level.pk, level.short_label) for level in levels), separators=(',', ':')), + 'levels': json.dumps(tuple(levels.values()), separators=(',', ':')), 'state': json.dumps(state, separators=(',', ':')), } response = render(request, 'site/map.html', ctx)