full access token should work now
This commit is contained in:
parent
e6255c8ecd
commit
b856a0168a
13 changed files with 113 additions and 96 deletions
|
@ -1,5 +1,6 @@
|
|||
from django.conf import settings
|
||||
|
||||
from c3nav.mapdata.inclusion import get_maybe_invisible_areas_names
|
||||
from c3nav.mapdata.utils.cache import get_packages_cached
|
||||
|
||||
|
||||
|
@ -29,3 +30,9 @@ def can_access_package(request, package):
|
|||
|
||||
def filter_queryset_by_package_access(request, queryset):
|
||||
return queryset if request.c3nav_full_access else queryset.filter(package__in=get_unlocked_packages(request))
|
||||
|
||||
|
||||
def get_visible_areas(request):
|
||||
areas = [':full' if request.c3nav_full_access else ':base']
|
||||
areas += [name for name in get_maybe_invisible_areas_names() if name in request.c3nav_access_list]
|
||||
return areas
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import re
|
||||
from datetime import timedelta
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import transaction
|
||||
from django.db.models import Q
|
||||
from django.utils import timezone
|
||||
|
@ -17,8 +18,8 @@ class AccessTokenMiddleware:
|
|||
request.c3nav_access = None
|
||||
request.c3nav_new_access = False
|
||||
|
||||
request.c3nav_full_access = False
|
||||
request.c3nav_access_list = None
|
||||
request.c3nav_full_access = settings.DEBUG
|
||||
request.c3nav_access_list = ()
|
||||
|
||||
access_cookie = request.COOKIES.get('c3nav_access')
|
||||
if access_cookie and re.match(r'^[0-9]+:[a-zA-Z0-9]+$', access_cookie):
|
||||
|
|
|
@ -12,7 +12,7 @@ from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet
|
|||
from c3nav.access.apply import filter_queryset_by_package_access, get_unlocked_packages_names
|
||||
from c3nav.mapdata.models import GEOMETRY_MAPITEM_TYPES, AreaLocation, Level, LocationGroup, Package, Source
|
||||
from c3nav.mapdata.models.geometry import DirectedLineGeometryMapItemWithLevel
|
||||
from c3nav.mapdata.models.locations import get_location
|
||||
from c3nav.mapdata.search import get_location
|
||||
from c3nav.mapdata.serializers.main import LevelSerializer, PackageSerializer, SourceSerializer
|
||||
from c3nav.mapdata.utils.cache import (CachedReadOnlyViewSetMixin, cache_mapdata_api_response, get_levels_cached,
|
||||
get_packages_cached)
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
from collections import OrderedDict
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from c3nav.access.apply import can_access_package
|
||||
from c3nav.mapdata.models import AreaLocation, LocationGroup
|
||||
|
||||
|
||||
|
@ -29,20 +27,21 @@ def get_includables_avoidables(request):
|
|||
locations = list(AreaLocation.objects.exclude(routing_inclusion='default'))
|
||||
locations += list(LocationGroup.objects.exclude(routing_inclusion='default'))
|
||||
|
||||
if settings.DEBUG:
|
||||
if request.c3nav_full_access:
|
||||
includables.append((':nonpublic', _('non-public areas')))
|
||||
avoidables.append((':public', _('public areas')))
|
||||
|
||||
from c3nav.access.apply import can_access_package
|
||||
|
||||
for location in locations:
|
||||
item = (location.location_id, location.title)
|
||||
|
||||
# Todo: allow by access token
|
||||
if not can_access_package(request, location.package):
|
||||
continue
|
||||
|
||||
# Todo: allow by access token
|
||||
if location.routing_inclusion == 'needs_permission' and not settings.DEBUG:
|
||||
continue
|
||||
if location.routing_inclusion == 'needs_permission':
|
||||
if not request.c3nav_full_access and location.location_id not in request.c3nav_access_list:
|
||||
continue
|
||||
|
||||
if location.routing_inclusion == 'allow_avoid':
|
||||
avoidables.append(item)
|
||||
|
@ -52,6 +51,14 @@ def get_includables_avoidables(request):
|
|||
return OrderedDict(includables), OrderedDict(avoidables)
|
||||
|
||||
|
||||
def get_maybe_invisible_areas():
|
||||
return AreaLocation.objects.exclude(routing_inclusion='default')
|
||||
|
||||
|
||||
def get_maybe_invisible_areas_names():
|
||||
return tuple(area.name for area in get_maybe_invisible_areas())
|
||||
|
||||
|
||||
def parse_include_avoid(request, include_input, avoid_input):
|
||||
includable, avoidable = get_includables_avoidables(request)
|
||||
include_input = set(include_input) & set(includable)
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
import re
|
||||
from collections import OrderedDict
|
||||
|
||||
import numpy as np
|
||||
from django.core.cache import cache
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from c3nav.access.apply import filter_queryset_by_package_access
|
||||
from c3nav.mapdata.fields import JSONField
|
||||
from c3nav.mapdata.lastupdate import get_last_mapdata_update
|
||||
from c3nav.mapdata.models import Level
|
||||
from c3nav.mapdata.models.base import MapItem
|
||||
from c3nav.mapdata.models.geometry import GeometryMapItemWithLevel
|
||||
from c3nav.mapdata.utils.cache import get_levels_cached
|
||||
|
||||
|
||||
class Location:
|
||||
|
@ -238,49 +234,6 @@ class AreaLocation(LocationModelMixin, GeometryMapItemWithLevel):
|
|||
return self.title
|
||||
|
||||
|
||||
def get_location(request, name):
|
||||
match = re.match('^c:(?P<level>[a-z0-9-_]+):(?P<x>[0-9]+):(?P<y>[0-9]+)$', name)
|
||||
if match:
|
||||
levels = get_levels_cached()
|
||||
level = levels.get(match.group('level'))
|
||||
if level is None:
|
||||
return None
|
||||
return PointLocation(level=level, x=int(match.group('x'))/100, y=int(match.group('y'))/100)
|
||||
|
||||
if name.startswith('g:'):
|
||||
return filter_queryset_by_package_access(request, LocationGroup.objects.filter(name=name[2:])).first()
|
||||
|
||||
return filter_queryset_by_package_access(request, AreaLocation.objects.filter(name=name)).first()
|
||||
|
||||
|
||||
def filter_words(queryset, words):
|
||||
for word in words:
|
||||
queryset = queryset.filter(Q(name__icontains=word) | Q(titles__icontains=word))
|
||||
return queryset
|
||||
|
||||
|
||||
def search_location(request, search):
|
||||
results = []
|
||||
location = get_location(request, search)
|
||||
if location:
|
||||
results.append(location)
|
||||
|
||||
words = search.split(' ')[:10]
|
||||
|
||||
queryset = AreaLocation.objects.all()
|
||||
if isinstance(location, AreaLocation):
|
||||
queryset.exclude(name=location.name)
|
||||
results += sorted(filter_words(filter_queryset_by_package_access(request, queryset), words),
|
||||
key=AreaLocation.get_sort_key, reverse=True)
|
||||
|
||||
queryset = LocationGroup.objects.all()
|
||||
if isinstance(location, LocationGroup):
|
||||
queryset.exclude(name=location.name)
|
||||
results += list(filter_words(filter_queryset_by_package_access(request, queryset), words)[:10])
|
||||
|
||||
return results
|
||||
|
||||
|
||||
class PointLocation(Location):
|
||||
def __init__(self, level: Level, x: int, y: int):
|
||||
self.level = level
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
import mimetypes
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.files import File
|
||||
from django.http import HttpResponse
|
||||
|
||||
from c3nav.mapdata.utils.misc import get_render_path
|
||||
|
||||
|
||||
class LevelComposer:
|
||||
def get_level_image(self, request, level):
|
||||
if settings.DIRECT_EDITING:
|
||||
img = get_render_path('png', level.name, 'full', True)
|
||||
else:
|
||||
img = get_render_path('png', level.name, 'full', False)
|
||||
|
||||
response = HttpResponse(content_type=mimetypes.guess_type(img)[0])
|
||||
for chunk in File(open(img, 'rb')).chunks():
|
||||
response.write(chunk)
|
||||
return response
|
||||
|
||||
|
||||
composer = LevelComposer()
|
51
src/c3nav/mapdata/search.py
Normal file
51
src/c3nav/mapdata/search.py
Normal file
|
@ -0,0 +1,51 @@
|
|||
import re
|
||||
|
||||
from django.db.models import Q
|
||||
|
||||
from c3nav.access.apply import filter_queryset_by_package_access
|
||||
from c3nav.mapdata.models import AreaLocation, LocationGroup
|
||||
from c3nav.mapdata.models.locations import PointLocation
|
||||
from c3nav.mapdata.utils.cache import get_levels_cached
|
||||
|
||||
|
||||
def get_location(request, name):
|
||||
match = re.match('^c:(?P<level>[a-z0-9-_]+):(?P<x>[0-9]+):(?P<y>[0-9]+)$', name)
|
||||
if match:
|
||||
levels = get_levels_cached()
|
||||
level = levels.get(match.group('level'))
|
||||
if level is None:
|
||||
return None
|
||||
return PointLocation(level=level, x=int(match.group('x'))/100, y=int(match.group('y'))/100)
|
||||
|
||||
if name.startswith('g:'):
|
||||
return filter_queryset_by_package_access(request, LocationGroup.objects.filter(name=name[2:])).first()
|
||||
|
||||
return filter_queryset_by_package_access(request, AreaLocation.objects.filter(name=name)).first()
|
||||
|
||||
|
||||
def filter_words(queryset, words):
|
||||
for word in words:
|
||||
queryset = queryset.filter(Q(name__icontains=word) | Q(titles__icontains=word))
|
||||
return queryset
|
||||
|
||||
|
||||
def search_location(request, search):
|
||||
results = []
|
||||
location = get_location(request, search)
|
||||
if location:
|
||||
results.append(location)
|
||||
|
||||
words = search.split(' ')[:10]
|
||||
|
||||
queryset = AreaLocation.objects.all()
|
||||
if isinstance(location, AreaLocation):
|
||||
queryset.exclude(name=location.name)
|
||||
results += sorted(filter_words(filter_queryset_by_package_access(request, queryset), words),
|
||||
key=AreaLocation.get_sort_key, reverse=True)
|
||||
|
||||
queryset = LocationGroup.objects.all()
|
||||
if isinstance(location, LocationGroup):
|
||||
queryset.exclude(name=location.name)
|
||||
results += list(filter_words(filter_queryset_by_package_access(request, queryset), words)[:10])
|
||||
|
||||
return results
|
|
@ -86,7 +86,7 @@ body, .btn {
|
|||
.locationselect-map .scroll-hint {
|
||||
color:#FFFFFF;
|
||||
position:absolute;
|
||||
top:150px;
|
||||
top:250px;
|
||||
left:16px;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ c3nav = {
|
|||
|
||||
c3nav.svg_width = parseInt(c3nav.main_view.attr('data-svg-width'));
|
||||
c3nav.svg_height = parseInt(c3nav.main_view.attr('data-svg-height'));
|
||||
c3nav.visible_areas = c3nav.main_view.attr('data-visible-areas').split(';');
|
||||
|
||||
c3nav._typeahead_locations = new Bloodhound({
|
||||
datumTokenizer: function(data) {
|
||||
|
@ -77,11 +78,13 @@ c3nav = {
|
|||
$(this).siblings().removeClass('active');
|
||||
$(this).addClass('active');
|
||||
map_container.find('img').remove();
|
||||
map_container.append($('<img>').attr({
|
||||
'src': '/map/'+level+'.png',
|
||||
'width': c3nav.svg_width,
|
||||
'height': c3nav.svg_height
|
||||
}));
|
||||
for (var i=0;i<c3nav.visible_areas.length;i++) {
|
||||
map_container.append($('<img>').attr({
|
||||
'src': '/map/'+level+'/'+c3nav.visible_areas[i]+'.png',
|
||||
'width': c3nav.svg_width,
|
||||
'height': c3nav.svg_height
|
||||
}));
|
||||
}
|
||||
map_container.attr('data-level', level);
|
||||
},
|
||||
_locationselect_click_image: function(e) {
|
||||
|
|
|
@ -31,8 +31,10 @@
|
|||
<div class="map-container">
|
||||
<div class="dummy" style="width:{{ svg_width }}px;height:{{ svg_height }}px;"></div>
|
||||
{% if map_level %}
|
||||
<input type="image" src="/map/{{ map_level }}.png" width="{{ svg_width }}" height="{{ svg_height }}">
|
||||
<p class="scroll-hint">{% trans 'You have Javascript deactivated. Please scroll in this direction ⇘' %}</p>
|
||||
{% for area in visible_areas %}
|
||||
<input type="image" src="{% url 'site.level_image' level=map_level area=area %}" width="{{ svg_width }}" height="{{ svg_height }}">
|
||||
{% endfor %}
|
||||
<p class="scroll-hint">{% trans 'Javascript is disabled. Please scroll in this direction ⇘' %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="map-buttons">
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post" class="main-view mode-{{ mode }}{% if origin and destination %} can-route{% endif %}" data-svg-width="{{ svg_width }}" data-svg-height="{{ svg_height }}">
|
||||
<form method="post" class="main-view mode-{{ mode }}{% if origin and destination %} can-route{% endif %}"
|
||||
data-svg-width="{{ svg_width }}" data-svg-height="{{ svg_height }}" data-visible-areas="{{ visible_areas | join:';' }}"
|
||||
{% csrf_token %}
|
||||
<div class="row locations">
|
||||
{% trans "Location" as heading %}
|
||||
|
|
|
@ -3,7 +3,7 @@ from django.conf.urls import url
|
|||
from c3nav.site.views import level_image, main
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^map/(?P<level>[a-z0-9-_:]+).png$', level_image, name='site.level_image'),
|
||||
url(r'^map/(?P<level>[a-z0-9-_:]+)/(?P<area>[a-z0-9-_:]+).png$', level_image, name='site.level_image'),
|
||||
url(r'^l/(?P<location>[a-z0-9-_:]+)/$', main, name='site.location'),
|
||||
url(r'^o/(?P<origin>[a-z0-9-_:]+)/$', main, name='site.origin'),
|
||||
url(r'^d/(?P<destination>[a-z0-9-_:]+)/$', main, name='site.destination'),
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import mimetypes
|
||||
from datetime import timedelta
|
||||
|
||||
from django.http import Http404
|
||||
from django.core.files import File
|
||||
from django.http import Http404, HttpResponse
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
|
||||
from c3nav.access.apply import get_visible_areas
|
||||
from c3nav.mapdata.inclusion import get_includables_avoidables, parse_include_avoid
|
||||
from c3nav.mapdata.models import Level
|
||||
from c3nav.mapdata.models.locations import get_location, search_location
|
||||
from c3nav.mapdata.render.compose import composer
|
||||
from c3nav.mapdata.search import get_location, search_location
|
||||
from c3nav.mapdata.utils.cache import get_levels_cached
|
||||
from c3nav.mapdata.utils.misc import get_dimensions
|
||||
from c3nav.mapdata.utils.misc import get_dimensions, get_render_path
|
||||
from c3nav.routing.exceptions import AlreadyThere, NoRouteFound, NotYetRoutable
|
||||
from c3nav.routing.graph import Graph
|
||||
|
||||
|
@ -68,6 +70,7 @@ def main(request, location=None, origin=None, destination=None):
|
|||
|
||||
'full_access': request.c3nav_full_access,
|
||||
'access_list': request.c3nav_access_list,
|
||||
'visible_areas': get_visible_areas(request),
|
||||
}
|
||||
|
||||
width, height = get_dimensions()
|
||||
|
@ -209,6 +212,18 @@ def main(request, location=None, origin=None, destination=None):
|
|||
return response
|
||||
|
||||
|
||||
def level_image(request, level):
|
||||
def level_image(request, area, level):
|
||||
level = get_object_or_404(Level, name=level, intermediate=False)
|
||||
return composer.get_level_image(request, level)
|
||||
if area == ':base':
|
||||
img = get_render_path('png', level.name, 'full', True)
|
||||
elif area == ':full':
|
||||
if not request.c3nav_full_access:
|
||||
raise Http404
|
||||
img = get_render_path('png', level.name, 'full', False)
|
||||
else:
|
||||
raise Http404
|
||||
|
||||
response = HttpResponse(content_type=mimetypes.guess_type(img)[0])
|
||||
for chunk in File(open(img, 'rb')).chunks():
|
||||
response.write(chunk)
|
||||
return response
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue