team-3/src/c3nav/mapdata/views.py

114 lines
3.3 KiB
Python
Raw Normal View History

2017-10-20 16:47:53 +02:00
import os
from django.conf import settings
2017-10-24 13:59:42 +02:00
from django.core.exceptions import PermissionDenied
2017-10-20 16:21:25 +02:00
from django.http import Http404, HttpResponse, HttpResponseNotModified
2017-10-24 13:59:42 +02:00
from django.shortcuts import get_object_or_404
2017-10-10 14:39:11 +02:00
from shapely.geometry import box
2017-10-24 13:59:42 +02:00
from c3nav.mapdata.cache import MapHistory
2017-10-20 16:21:25 +02:00
from c3nav.mapdata.models import Level, MapUpdate, Source
from c3nav.mapdata.render.svg import SVGRenderer
2017-10-10 14:39:11 +02:00
def tile(request, level, zoom, x, y, format):
import cProfile
import pstats
pr = cProfile.Profile()
pr.enable()
2017-10-10 14:39:11 +02:00
zoom = int(zoom)
if not (0 <= zoom <= 10):
raise Http404
bounds = Source.max_bounds()
x, y = int(x), int(y)
size = 256/2**zoom
minx = size * x
miny = size * (-y-1)
2017-10-10 14:39:11 +02:00
maxx = minx + size
maxy = miny + size
if not box(bounds[0][1], bounds[0][0], bounds[1][1], bounds[1][0]).intersects(box(minx, miny, maxx, maxy)):
raise Http404
renderer = SVGRenderer(level, miny, minx, maxy, maxx, scale=2**zoom, user=request.user)
2017-10-23 22:49:45 +02:00
update_cache_key = MapUpdate.current_cache_key()
2017-10-20 16:21:25 +02:00
access_cache_key = renderer.access_cache_key
etag = update_cache_key+'_'+access_cache_key
if_none_match = request.META.get('HTTP_IF_NONE_MATCH')
if if_none_match == etag:
return HttpResponseNotModified()
2017-10-20 16:47:53 +02:00
f = None
if settings.CACHE_TILES:
dirname = os.path.sep.join((settings.TILES_ROOT, update_cache_key, level, str(zoom), str(x), str(y)))
filename = os.path.sep.join((dirname, access_cache_key+'.'+format))
try:
f = open(filename, 'rb')
except FileNotFoundError:
pass
content_type = 'image/svg+xml' if format == 'svg' else 'image/png'
if not settings.CACHE_TILES or f is None:
try:
renderer.check_level()
except Level.DoesNotExist:
raise Http404
2017-10-10 14:39:11 +02:00
2017-10-20 16:47:53 +02:00
svg = renderer.render()
if format == 'svg':
data = svg.get_xml()
filemode = 'w'
elif format == 'png':
data = svg.get_png()
filemode = 'wb'
else:
raise ValueError
2017-10-20 16:47:53 +02:00
if settings.CACHE_TILES:
# noinspection PyUnboundLocalVariable
os.makedirs(dirname, exist_ok=True)
# noinspection PyUnboundLocalVariable
with open(filename, filemode) as f:
f.write(data)
2017-10-10 14:39:11 +02:00
else:
2017-10-20 16:47:53 +02:00
data = f.read()
2017-10-10 14:39:11 +02:00
pr.disable()
s = open('/tmp/profiled', 'w')
sortby = 'cumulative'
ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
ps.print_stats()
2017-10-20 16:47:53 +02:00
response = HttpResponse(data, content_type)
2017-10-20 16:21:25 +02:00
response['ETag'] = etag
response['Cache-Control'] = 'no-cache'
2017-10-10 14:39:11 +02:00
return response
2017-10-24 13:59:42 +02:00
def history(request, level, mode, format):
if not request.user.is_superuser:
raise PermissionDenied
level = get_object_or_404(Level, pk=level)
if mode == 'render' and level.on_top_of_id is None:
raise Http404
history = MapHistory.open(os.path.join(settings.CACHE_ROOT, 'level_%s_%d' % (mode, level.pk)))
if format == 'png':
response = HttpResponse(content_type='image/png')
history.to_image().save(response, format='PNG')
elif format == 'data':
response = HttpResponse(content_type='application/octet-stream')
history.write(response)
else:
raise ValueError
return response