API for querying positions

This commit is contained in:
Laura Klünder 2023-11-24 01:05:38 +01:00
parent 9c6d7989c0
commit 715d6c2f11
5 changed files with 202 additions and 30 deletions

View file

@ -3,6 +3,7 @@ from typing import Annotated, Union
from django.core.cache import cache
from django.core.serializers.json import DjangoJSONEncoder
from django.http import Http404
from django.shortcuts import redirect
from ninja import Query
from ninja import Router as APIRouter
@ -15,10 +16,11 @@ from c3nav.api.newauth import auth_responses, validate_responses
from c3nav.api.utils import NonEmptyStr
from c3nav.mapdata.models import Source
from c3nav.mapdata.models.access import AccessPermission
from c3nav.mapdata.models.locations import LocationRedirect
from c3nav.mapdata.models.locations import DynamicLocation, LocationRedirect, Position
from c3nav.mapdata.schemas.filters import BySearchableFilter, RemoveGeometryFilter
from c3nav.mapdata.schemas.model_base import LocationID
from c3nav.mapdata.schemas.models import FullLocationSchema, LocationDisplay, SlimLocationSchema
from c3nav.mapdata.schemas.model_base import AnyLocationID, AnyPositionID
from c3nav.mapdata.schemas.models import (AnyPositionStatusSchema, FullListableLocationSchema, FullLocationSchema,
LocationDisplay, SlimListableLocationSchema, SlimLocationSchema)
from c3nav.mapdata.schemas.responses import BoundsSchema
from c3nav.mapdata.utils.locations import (get_location_by_id_for_request, get_location_by_slug_for_request,
searchable_locations_for_request, visible_locations_for_request)
@ -74,14 +76,14 @@ def _location_list(request, detailed: bool, filters: LocationListFilters):
@map_api_router.get('/locations/',
response={200: list[SlimLocationSchema], **validate_responses, **auth_responses},
response={200: list[SlimListableLocationSchema], **validate_responses, **auth_responses},
summary="Get locations (with most important attributes)")
def location_list(request, filters: Query[LocationListFilters]):
return _location_list(request, detailed=False, filters=filters)
@map_api_router.get('/locations/full/',
response={200: list[FullLocationSchema], **validate_responses, **auth_responses},
response={200: list[FullListableLocationSchema], **validate_responses, **auth_responses},
summary="Get locations (with all attributes)")
def location_list_full(request, filters: Query[LocationListFilters]):
return _location_list(request, detailed=True, filters=filters)
@ -134,7 +136,7 @@ class ShowRedirects(Schema):
response={200: SlimLocationSchema, **API404.dict(), **validate_responses, **auth_responses},
summary="Get location by ID (with most important attributes)",
description="a numeric ID for a map location or a string ID for generated locations can be used")
def location_by_id(request, location_id: LocationID, filters: Query[RemoveGeometryFilter],
def location_by_id(request, location_id: AnyLocationID, filters: Query[RemoveGeometryFilter],
redirects: Query[ShowRedirects]):
return _location_retrieve(
request,
@ -147,7 +149,7 @@ def location_by_id(request, location_id: LocationID, filters: Query[RemoveGeomet
response={200: FullLocationSchema, **API404.dict(), **validate_responses, **auth_responses},
summary="Get location by ID (with all attributes)",
description="a numeric ID for a map location or a string ID for generated locations can be used")
def location_by_id_full(request, location_id: LocationID, filters: Query[RemoveGeometryFilter],
def location_by_id_full(request, location_id: AnyLocationID, filters: Query[RemoveGeometryFilter],
redirects: Query[ShowRedirects]):
return _location_retrieve(
request,
@ -160,14 +162,13 @@ def location_by_id_full(request, location_id: LocationID, filters: Query[RemoveG
response={200: LocationDisplay, **API404.dict(), **auth_responses},
summary="Get location display data by ID",
description="a numeric ID for a map location or a string ID for generated locations can be used")
def location_by_id_display(request, location_id: LocationID):
def location_by_id_display(request, location_id: AnyLocationID):
return _location_display(
request,
get_location_by_id_for_request(location_id, request),
)
@map_api_router.get('/locations/by-slug/{location_slug}/',
response={200: SlimLocationSchema, **API404.dict(), **validate_responses, **auth_responses},
summary="Get location by slug (with most important attributes)")
@ -200,3 +201,20 @@ def location_by_slug_display(request, location_slug: NonEmptyStr):
request,
get_location_by_slug_for_request(location_slug, request),
)
@map_api_router.get('/get_position/{position_id}/',
response={200: AnyPositionStatusSchema, **API404.dict(), **auth_responses},
summary="a numeric ID for a dynamic location or a string ID for the position secret can be used")
def get_current_position_by_id(request, position_id: AnyPositionID):
location = None
if isinstance(position_id, int) or position_id.isdigit():
location = get_location_by_id_for_request(position_id, request)
if not isinstance(location, DynamicLocation):
raise Http404
if location is None and position_id.startswith('p:'):
try:
location = Position.objects.get(secret=position_id[2:])
except Position.DoesNotExist:
raise Http404
return location.serialize_position()