api for setting positions
This commit is contained in:
parent
01befdedb8
commit
399ac98c1c
3 changed files with 54 additions and 3 deletions
|
@ -15,10 +15,11 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.exceptions import NotFound, ValidationError
|
from rest_framework.exceptions import NotFound, ValidationError
|
||||||
from rest_framework.generics import get_object_or_404
|
from rest_framework.generics import get_object_or_404
|
||||||
from rest_framework.mixins import RetrieveModelMixin
|
from rest_framework.mixins import RetrieveModelMixin, UpdateModelMixin
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.viewsets import GenericViewSet, ReadOnlyModelViewSet, ViewSet
|
from rest_framework.viewsets import GenericViewSet, ReadOnlyModelViewSet, ViewSet
|
||||||
|
|
||||||
|
from c3nav.mapdata.forms import PositionAPIUpdateForm
|
||||||
from c3nav.mapdata.models import AccessRestriction, Building, Door, Hole, LocationGroup, MapUpdate, Source, Space
|
from c3nav.mapdata.models import AccessRestriction, Building, Door, Hole, LocationGroup, MapUpdate, Source, Space
|
||||||
from c3nav.mapdata.models.access import AccessPermission, AccessRestrictionGroup
|
from c3nav.mapdata.models.access import AccessPermission, AccessRestrictionGroup
|
||||||
from c3nav.mapdata.models.geometry.base import GeometryMixin
|
from c3nav.mapdata.models.geometry.base import GeometryMixin
|
||||||
|
@ -464,7 +465,7 @@ class LocationBySlugViewSet(LocationViewSetBase):
|
||||||
return get_location_by_slug_for_request(self.kwargs['slug'], self.request)
|
return get_location_by_slug_for_request(self.kwargs['slug'], self.request)
|
||||||
|
|
||||||
|
|
||||||
class DynamicLocationPositionViewSet(RetrieveModelMixin, GenericViewSet):
|
class DynamicLocationPositionViewSet(UpdateModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||||
queryset = LocationSlug.objects.all()
|
queryset = LocationSlug.objects.all()
|
||||||
lookup_field = 'slug'
|
lookup_field = 'slug'
|
||||||
lookup_value_regex = r'[^/]+'
|
lookup_value_regex = r'[^/]+'
|
||||||
|
@ -482,6 +483,20 @@ class DynamicLocationPositionViewSet(RetrieveModelMixin, GenericViewSet):
|
||||||
obj = self.get_object()
|
obj = self.get_object()
|
||||||
return Response(obj.serialize_position())
|
return Response(obj.serialize_position())
|
||||||
|
|
||||||
|
def update(self, request, *args, **kwargs):
|
||||||
|
instance = self.get_object()
|
||||||
|
params = request.data
|
||||||
|
form = PositionAPIUpdateForm(instance=instance, data=params, request=request)
|
||||||
|
|
||||||
|
if not form.is_valid():
|
||||||
|
return Response({
|
||||||
|
'errors': form.errors,
|
||||||
|
}, status=400)
|
||||||
|
|
||||||
|
form.save()
|
||||||
|
|
||||||
|
return Response(form.instance.serialize_position())
|
||||||
|
|
||||||
|
|
||||||
class SourceViewSet(MapdataViewSet):
|
class SourceViewSet(MapdataViewSet):
|
||||||
queryset = Source.objects.all()
|
queryset = Source.objects.all()
|
||||||
|
|
|
@ -8,6 +8,8 @@ from django.utils.translation import get_language_info
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from c3nav.mapdata.fields import I18nField
|
from c3nav.mapdata.fields import I18nField
|
||||||
|
from c3nav.mapdata.models.locations import Position
|
||||||
|
from c3nav.mapdata.utils.locations import get_location_by_id_for_request
|
||||||
|
|
||||||
|
|
||||||
class I18nModelFormMixin(ModelForm):
|
class I18nModelFormMixin(ModelForm):
|
||||||
|
@ -62,3 +64,36 @@ class I18nModelFormMixin(ModelForm):
|
||||||
super().full_clean()
|
super().full_clean()
|
||||||
for field, values in self.i18n_fields:
|
for field, values in self.i18n_fields:
|
||||||
setattr(self.instance, field.attname, {lang: value for lang, value in values.items() if value})
|
setattr(self.instance, field.attname, {lang: value for lang, value in values.items() if value})
|
||||||
|
|
||||||
|
|
||||||
|
class PositionAPIUpdateForm(ModelForm):
|
||||||
|
secret = CharField()
|
||||||
|
|
||||||
|
def __init__(self, *args, request=None, **kwargs):
|
||||||
|
self.request = request
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Position
|
||||||
|
fields = ['coordinates_id', 'timeout']
|
||||||
|
|
||||||
|
def clean_secret(self):
|
||||||
|
# not called api_secret so we don't overwrite it
|
||||||
|
api_secret = self.cleaned_data['secret']
|
||||||
|
if api_secret != self.instance.api_secret:
|
||||||
|
raise ValidationError(_('Wrong API secret.'))
|
||||||
|
return api_secret
|
||||||
|
|
||||||
|
def clean_coordinates_id(self):
|
||||||
|
coordinates_id = self.cleaned_data['coordinates_id']
|
||||||
|
if coordinates_id is None:
|
||||||
|
return coordinates_id
|
||||||
|
|
||||||
|
if not coordinates_id.startswith('c:'):
|
||||||
|
raise ValidationError(_('Invalid coordinates.'))
|
||||||
|
|
||||||
|
coordinates = get_location_by_id_for_request(self.cleaned_data['coordinates_id'], self.request)
|
||||||
|
if coordinates is None:
|
||||||
|
raise ValidationError(_('Invalid coordinates.'))
|
||||||
|
|
||||||
|
return coordinates_id
|
||||||
|
|
|
@ -566,7 +566,8 @@ class Position(CustomLocationProxyMixin, models.Model):
|
||||||
name = models.CharField(_('name'), max_length=32)
|
name = models.CharField(_('name'), max_length=32)
|
||||||
secret = models.CharField(_('secret'), unique=True, max_length=32, default=get_position_secret)
|
secret = models.CharField(_('secret'), unique=True, max_length=32, default=get_position_secret)
|
||||||
last_coordinates_update = models.DateTimeField(_('last coordinates update'), null=True)
|
last_coordinates_update = models.DateTimeField(_('last coordinates update'), null=True)
|
||||||
timeout = models.PositiveSmallIntegerField(_('timeout (in seconds)'), default=0, help_text=_('0 for no timeout'))
|
timeout = models.PositiveSmallIntegerField(_('timeout (in seconds)'), default=0, blank=True,
|
||||||
|
help_text=_('0 for no timeout'))
|
||||||
coordinates_id = models.CharField(_('coordinates'), null=True, max_length=48)
|
coordinates_id = models.CharField(_('coordinates'), null=True, max_length=48)
|
||||||
api_secret = models.CharField(_('api secret'), max_length=64, default=get_position_api_secret)
|
api_secret = models.CharField(_('api secret'), max_length=64, default=get_position_api_secret)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue