first stuff for editor API

This commit is contained in:
Laura Klünder 2018-11-21 01:35:31 +01:00
parent 07941a6126
commit 2a578900cc
2 changed files with 59 additions and 7 deletions

View file

@ -1,8 +1,10 @@
from itertools import chain
from django.db.models import Prefetch, Q
from django.urls import Resolver404, resolve
from django.utils.translation import ugettext_lazy as _
from rest_framework.decorators import detail_route, list_route
from rest_framework.exceptions import PermissionDenied, ValidationError
from rest_framework.exceptions import NotFound, PermissionDenied, ValidationError
from rest_framework.generics import get_object_or_404
from rest_framework.response import Response
from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet
@ -23,6 +25,9 @@ class EditorViewSet(ViewSet):
/geometrystyles/ returns styling information for all geometry types
/bounds/ returns the maximum bounds of the map
"""
lookup_field = 'path'
lookup_value_regex = r'.+'
@staticmethod
def _get_level_geometries(level):
buildings = level.buildings.all()
@ -261,6 +266,33 @@ class EditorViewSet(ViewSet):
'bounds': Source.max_bounds(),
})
def list(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def retrieve(self, request, *args, **kwargs):
if not can_access_editor(request):
return PermissionDenied
resolved = None
path = self.kwargs.get('path', '')
if path:
try:
resolved = resolve('/editor/'+path+'/')
except Resolver404:
pass
if not resolved:
try:
resolved = resolve('/editor/'+path)
except Resolver404:
raise NotFound(_('No matching editor view endpoint found.'))
if not getattr(resolved.func, 'api_hybrid', False):
raise NotFound(_('Matching editor view point does not provide an API.'))
response = resolved.func(request, *resolved.args, **resolved.kwargs)
return Response(str(response))
class ChangeSetViewSet(ReadOnlyModelViewSet):
"""

View file

@ -11,25 +11,34 @@ from c3nav.mapdata.models.access import AccessPermission
from c3nav.mapdata.utils.user import can_access_editor
def sidebar_view(func=None, select_related=None):
def sidebar_view(func=None, select_related=None, api_hybrid=False):
if func is None:
def wrapped(inner_func):
return sidebar_view(inner_func, select_related)
return sidebar_view(inner_func, select_related=select_related, api_hybrid=api_hybrid)
return wrapped
@wraps(func)
def with_ajax_check(request, *args, **kwargs):
def wrapped(request, *args, api=False, **kwargs):
if api and api_hybrid:
raise Exception('API call on a view without api_hybrid!')
if not can_access_editor(request):
raise PermissionDenied
request.changeset = ChangeSet.get_for_request(request, select_related)
ajax = request.is_ajax() or 'ajax' in request.GET
if api:
return call_api_hybrid_view_for_api(func, request, *args, **kwargs)
ajax = request.is_ajax() or 'ajax' in request.GET
if not ajax:
request.META.pop('HTTP_IF_NONE_MATCH', None)
response = func(request, *args, **kwargs)
if api_hybrid:
response = call_api_hybrid_view_for_html(func, request, *args, **kwargs)
else:
response = func(request, *args, **kwargs)
if ajax:
if isinstance(response, HttpResponseRedirect):
return render(request, 'editor/redirect.html', {'target': response['location']})
@ -44,8 +53,19 @@ def sidebar_view(func=None, select_related=None):
response['Cache-Control'] = 'no-cache'
patch_vary_headers(response, ('X-Requested-With', ))
return response
wrapped.api_hybrid = api_hybrid
return with_ajax_check
return wrapped
def call_api_hybrid_view_for_api(func, request, *args, **kwargs):
response = func(request, *args, **kwargs)
return response
def call_api_hybrid_view_for_html(func, request, *args, **kwargs):
response = func(request, *args, **kwargs)
return response
def etag_func(request, *args, **kwargs):