2017-10-10 19:31:51 +02:00
|
|
|
import json
|
2017-11-28 16:17:08 +01:00
|
|
|
from typing import Optional
|
2016-12-15 17:30:55 +01:00
|
|
|
|
2016-12-22 02:40:12 +01:00
|
|
|
import qrcode
|
2017-11-21 04:34:43 +01:00
|
|
|
from django.conf import settings
|
2017-12-07 17:26:51 +01:00
|
|
|
from django.contrib import messages
|
2017-12-07 13:12:56 +01:00
|
|
|
from django.contrib.auth import login, logout
|
|
|
|
from django.contrib.auth.decorators import login_required
|
2017-12-07 17:02:44 +01:00
|
|
|
from django.contrib.auth.forms import AuthenticationForm, PasswordChangeForm, UserCreationForm
|
2017-11-30 13:31:45 +01:00
|
|
|
from django.core.serializers.json import DjangoJSONEncoder
|
2017-12-04 16:11:42 +01:00
|
|
|
from django.http import HttpResponse, HttpResponseBadRequest
|
2017-12-07 13:12:56 +01:00
|
|
|
from django.shortcuts import redirect, render
|
|
|
|
from django.urls import reverse
|
2017-12-07 17:26:51 +01:00
|
|
|
from django.utils.translation import ugettext_lazy as _
|
2017-12-07 13:12:56 +01:00
|
|
|
from django.views.decorators.cache import cache_control, never_cache
|
2017-12-07 00:52:13 +01:00
|
|
|
from django.views.decorators.clickjacking import xframe_options_exempt
|
2017-11-30 18:23:47 +01:00
|
|
|
from django.views.decorators.http import etag
|
2016-12-17 19:25:27 +01:00
|
|
|
|
2017-10-31 16:08:20 +01:00
|
|
|
from c3nav.mapdata.models import Location, Source
|
2017-10-31 15:28:49 +01:00
|
|
|
from c3nav.mapdata.models.locations import LocationRedirect, SpecificLocation
|
2017-11-28 20:24:39 +01:00
|
|
|
from c3nav.mapdata.utils.locations import get_location_by_slug_for_request, levels_by_short_label_for_request
|
2017-12-04 16:11:42 +01:00
|
|
|
from c3nav.mapdata.utils.user import get_user_data
|
2017-11-21 00:15:49 +01:00
|
|
|
from c3nav.mapdata.views import set_tile_access_cookie
|
2016-12-15 17:30:55 +01:00
|
|
|
|
2016-12-22 02:40:12 +01:00
|
|
|
|
2017-10-31 15:28:49 +01:00
|
|
|
def check_location(location: Optional[str], request) -> Optional[SpecificLocation]:
|
|
|
|
if location is None:
|
|
|
|
return None
|
|
|
|
|
|
|
|
location = get_location_by_slug_for_request(location, request)
|
|
|
|
if location is None:
|
2017-10-31 18:35:42 +01:00
|
|
|
return None
|
2017-10-31 15:28:49 +01:00
|
|
|
|
|
|
|
if isinstance(location, LocationRedirect):
|
|
|
|
location: Location = location.target
|
|
|
|
if location is None:
|
|
|
|
return None
|
|
|
|
|
|
|
|
if not location.can_search:
|
|
|
|
location = None
|
|
|
|
|
|
|
|
return location
|
|
|
|
|
|
|
|
|
2017-12-07 00:52:13 +01:00
|
|
|
def map_index(request, mode=None, slug=None, slug2=None, details=None,
|
|
|
|
level=None, x=None, y=None, zoom=None, embed=None):
|
2017-10-31 18:35:42 +01:00
|
|
|
origin = None
|
|
|
|
destination = None
|
|
|
|
routing = False
|
|
|
|
if slug2 is not None:
|
|
|
|
routing = True
|
|
|
|
origin = check_location(slug, request)
|
|
|
|
destination = check_location(slug2, request)
|
|
|
|
else:
|
|
|
|
routing = (mode and mode != 'l')
|
|
|
|
if mode == 'o':
|
|
|
|
origin = check_location(slug, request)
|
|
|
|
else:
|
|
|
|
destination = check_location(slug, request)
|
2017-10-31 15:28:49 +01:00
|
|
|
|
|
|
|
state = {
|
2017-10-31 18:35:42 +01:00
|
|
|
'routing': routing,
|
2017-10-31 15:28:49 +01:00
|
|
|
'origin': (origin.serialize(detailed=False, simple_geometry=True, geometry=False)
|
|
|
|
if origin else None),
|
|
|
|
'destination': (destination.serialize(detailed=False, simple_geometry=True, geometry=False)
|
|
|
|
if destination else None),
|
2017-10-31 18:35:42 +01:00
|
|
|
'sidebar': routing or destination is not None,
|
2017-11-22 18:02:11 +01:00
|
|
|
'details': True if details else False,
|
2017-10-31 15:28:49 +01:00
|
|
|
}
|
2017-10-31 16:08:20 +01:00
|
|
|
|
2017-11-28 20:24:39 +01:00
|
|
|
levels = levels_by_short_label_for_request(request)
|
2017-10-31 16:08:20 +01:00
|
|
|
|
|
|
|
level = levels.get(level, None) if level else None
|
2017-10-31 15:28:49 +01:00
|
|
|
if level is not None:
|
|
|
|
state.update({
|
2017-11-28 20:44:15 +01:00
|
|
|
'level': level.pk,
|
2017-10-31 15:28:49 +01:00
|
|
|
'center': (float(x), float(y)),
|
|
|
|
'zoom': float(zoom),
|
|
|
|
})
|
|
|
|
|
2017-10-10 19:31:51 +02:00
|
|
|
ctx = {
|
2017-10-25 12:15:19 +02:00
|
|
|
'bounds': json.dumps(Source.max_bounds(), separators=(',', ':')),
|
2017-11-28 20:38:37 +01:00
|
|
|
'levels': json.dumps(tuple((level.pk, level.short_label) for level in levels.values()), separators=(',', ':')),
|
2017-11-30 13:31:45 +01:00
|
|
|
'state': json.dumps(state, separators=(',', ':'), cls=DjangoJSONEncoder),
|
2017-11-21 04:34:43 +01:00
|
|
|
'tile_cache_server': settings.TILE_CACHE_SERVER,
|
2017-12-04 16:11:42 +01:00
|
|
|
'user_data': get_user_data(request),
|
2017-12-07 00:52:13 +01:00
|
|
|
'embed': bool(embed),
|
2017-10-10 19:31:51 +02:00
|
|
|
}
|
2017-12-04 17:24:01 +01:00
|
|
|
response = render(request, 'site/map.html', ctx)
|
|
|
|
set_tile_access_cookie(request, response)
|
2017-12-07 00:52:13 +01:00
|
|
|
if embed:
|
|
|
|
xframe_options_exempt(lambda: response)()
|
2017-12-04 17:24:01 +01:00
|
|
|
return response
|
2017-11-30 18:23:47 +01:00
|
|
|
|
|
|
|
|
|
|
|
def qr_code_etag(request, path):
|
|
|
|
return '1'
|
|
|
|
|
|
|
|
|
|
|
|
@etag(qr_code_etag)
|
|
|
|
@cache_control(max_age=3600)
|
|
|
|
def qr_code(request, path):
|
|
|
|
data = (request.build_absolute_uri('/'+path) +
|
|
|
|
('?'+request.META['QUERY_STRING'] if request.META['QUERY_STRING'] else ''))
|
|
|
|
if len(data) > 256:
|
|
|
|
return HttpResponseBadRequest()
|
|
|
|
|
|
|
|
qr = qrcode.QRCode(
|
|
|
|
version=1,
|
|
|
|
error_correction=qrcode.constants.ERROR_CORRECT_L,
|
|
|
|
box_size=10,
|
2017-12-05 16:47:56 +01:00
|
|
|
border=2,
|
2017-11-30 18:23:47 +01:00
|
|
|
)
|
|
|
|
qr.add_data(data)
|
|
|
|
qr.make(fit=True)
|
|
|
|
|
|
|
|
response = HttpResponse(content_type='image/png')
|
|
|
|
qr.make_image().save(response, 'PNG')
|
|
|
|
return response
|
2017-12-07 13:12:56 +01:00
|
|
|
|
|
|
|
|
|
|
|
def close_response(request):
|
|
|
|
ajax = request.is_ajax() or 'ajax' in request.GET
|
|
|
|
if ajax:
|
|
|
|
return HttpResponse(json.dumps(get_user_data(request), cls=DjangoJSONEncoder).encode(),
|
|
|
|
content_type='text/plain')
|
|
|
|
redirect_path = request.GET['next'] if request.GET.get('next', '').startswith('/') else reverse('site.index')
|
|
|
|
return redirect(redirect_path)
|
|
|
|
|
|
|
|
|
|
|
|
@never_cache
|
|
|
|
def login_view(request):
|
|
|
|
if request.user.is_authenticated:
|
|
|
|
return close_response(request)
|
|
|
|
|
|
|
|
if request.method == 'POST':
|
|
|
|
form = AuthenticationForm(request, data=request.POST)
|
|
|
|
if form.is_valid():
|
|
|
|
login(request, form.user_cache)
|
|
|
|
return close_response(request)
|
|
|
|
else:
|
|
|
|
form = AuthenticationForm(request)
|
|
|
|
|
|
|
|
return render(request, 'site/login.html', {'form': form})
|
|
|
|
|
|
|
|
|
|
|
|
@never_cache
|
|
|
|
def logout_view(request):
|
|
|
|
logout(request)
|
|
|
|
return close_response(request)
|
|
|
|
|
|
|
|
|
2017-12-07 16:46:12 +01:00
|
|
|
@never_cache
|
|
|
|
def register_view(request):
|
|
|
|
if request.user.is_authenticated:
|
|
|
|
return close_response(request)
|
|
|
|
|
|
|
|
if request.method == 'POST':
|
|
|
|
form = UserCreationForm(data=request.POST)
|
|
|
|
if form.is_valid():
|
|
|
|
user = form.save()
|
|
|
|
login(request, user)
|
|
|
|
return close_response(request)
|
|
|
|
else:
|
|
|
|
form = UserCreationForm()
|
|
|
|
|
2017-12-07 16:48:19 +01:00
|
|
|
form.fields['username'].max_length = 20
|
2017-12-07 16:46:12 +01:00
|
|
|
for field in form.fields.values():
|
|
|
|
field.help_text = None
|
|
|
|
|
|
|
|
return render(request, 'site/register.html', {'form': form})
|
|
|
|
|
|
|
|
|
2017-12-07 17:02:44 +01:00
|
|
|
@never_cache
|
|
|
|
@login_required(login_url='site.login')
|
|
|
|
def change_password_view(request):
|
|
|
|
if request.method == 'POST':
|
|
|
|
form = PasswordChangeForm(user=request.user, data=request.POST)
|
|
|
|
if form.is_valid():
|
|
|
|
form.save()
|
2017-12-07 17:26:51 +01:00
|
|
|
login(request, request.user)
|
|
|
|
messages.success(request, _('Password successfully changed.'))
|
2017-12-07 17:02:44 +01:00
|
|
|
return redirect('site.account')
|
|
|
|
else:
|
|
|
|
form = PasswordChangeForm(user=request.user)
|
|
|
|
|
|
|
|
for field in form.fields.values():
|
|
|
|
field.help_text = None
|
|
|
|
|
|
|
|
return render(request, 'site/change_password.html', {'form': form})
|
|
|
|
|
|
|
|
|
2017-12-07 13:12:56 +01:00
|
|
|
@never_cache
|
|
|
|
@login_required(login_url='site.login')
|
|
|
|
def account_view(request):
|
2017-12-07 13:19:15 +01:00
|
|
|
return render(request, 'site/account.html', {})
|