add editor API stubs
This commit is contained in:
parent
9738ea23ba
commit
bf2dd3b33b
6 changed files with 231 additions and 0 deletions
|
@ -54,6 +54,10 @@ ninja_api = c3navAPI(
|
|||
"name": "mapdata",
|
||||
"description": "Access the raw map data",
|
||||
},
|
||||
{
|
||||
"name": "editor",
|
||||
"description": "Endpoints for the editor and to interface with the editor",
|
||||
},
|
||||
{
|
||||
"name": "mesh",
|
||||
"description": "Manage the location node mesh network",
|
||||
|
|
|
@ -36,6 +36,16 @@ class LineStringSchema(Schema):
|
|||
)
|
||||
|
||||
|
||||
class LineSchema(Schema):
|
||||
"""
|
||||
A GeoJSON LineString with only two points
|
||||
"""
|
||||
type: Literal["LineString"]
|
||||
coordinates: tuple[tuple[float, float], tuple[float, float]] = APIField(
|
||||
example=[[1.5, 1.5], [5, 8.7]]
|
||||
)
|
||||
|
||||
|
||||
class PointSchema(Schema):
|
||||
"""
|
||||
A GeoJSON Point
|
||||
|
|
|
@ -12,6 +12,7 @@ from c3nav.api.api import SessionViewSet
|
|||
from c3nav.api.newapi import auth_api_router
|
||||
from c3nav.api.ninja import ninja_api
|
||||
from c3nav.editor.api import ChangeSetViewSet, EditorViewSet
|
||||
from c3nav.editor.newapi.endpoints import editor_api_router
|
||||
from c3nav.mapdata.api import (AccessRestrictionGroupViewSet, AccessRestrictionViewSet, AreaViewSet, BuildingViewSet,
|
||||
ColumnViewSet, CrossDescriptionViewSet, DoorViewSet, DynamicLocationPositionViewSet,
|
||||
HoleViewSet, LeaveDescriptionViewSet, LevelViewSet, LineObstacleViewSet,
|
||||
|
@ -34,6 +35,7 @@ ninja_api.add_router("/map/", map_api_router)
|
|||
ninja_api.add_router("/routing/", routing_api_router)
|
||||
ninja_api.add_router("/positioning/", positioning_api_router)
|
||||
ninja_api.add_router("/mapdata/", mapdata_api_router)
|
||||
ninja_api.add_router("/editor/", editor_api_router)
|
||||
ninja_api.add_router("/mesh/", mesh_api_router)
|
||||
|
||||
|
||||
|
|
0
src/c3nav/editor/newapi/__init__.py
Normal file
0
src/c3nav/editor/newapi/__init__.py
Normal file
111
src/c3nav/editor/newapi/endpoints.py
Normal file
111
src/c3nav/editor/newapi/endpoints.py
Normal file
|
@ -0,0 +1,111 @@
|
|||
from datetime import datetime
|
||||
from typing import Annotated, Optional, Literal, Union
|
||||
|
||||
from django.db import IntegrityError, transaction
|
||||
from ninja import Field as APIField
|
||||
from ninja import Query
|
||||
from ninja import Router as APIRouter
|
||||
from ninja import Schema, UploadedFile
|
||||
from ninja.pagination import paginate
|
||||
from pydantic import PositiveInt, field_validator
|
||||
|
||||
from c3nav.api.exceptions import API404, APIConflict, APIRequestValidationFailed
|
||||
from c3nav.api.newauth import APITokenAuth, auth_permission_responses, auth_responses, validate_responses
|
||||
from c3nav.api.schema import GeometrySchema, LineSchema
|
||||
from c3nav.api.utils import NonEmptyStr
|
||||
from c3nav.editor.newapi.schemas import GeometryStylesSchema, EditorID, EditorSpaceGeometriesElemSchema, \
|
||||
EditorLevelGeometriesElemSchema, UpdateCacheKey
|
||||
from c3nav.mapdata.models import Source
|
||||
from c3nav.mapdata.newapi.base import newapi_etag
|
||||
from c3nav.mapdata.schemas.responses import BoundsSchema
|
||||
from c3nav.mesh.dataformats import BoardType, ChipType, FirmwareImage
|
||||
from c3nav.mesh.messages import MeshMessageType
|
||||
from c3nav.mesh.models import FirmwareBuild, FirmwareVersion, NodeMessage
|
||||
|
||||
editor_api_router = APIRouter(tags=["editor"], auth=APITokenAuth(permissions={"editor_access"}))
|
||||
|
||||
|
||||
@editor_api_router.get('/bounds/', summary="Get editor map boundaries",
|
||||
response={200: BoundsSchema, **auth_permission_responses})
|
||||
@newapi_etag()
|
||||
def bounds(request):
|
||||
return {
|
||||
"bounds": Source.max_bounds(),
|
||||
}
|
||||
|
||||
|
||||
@editor_api_router.get('/geometrystyles/', summary="get the default colors for each geometry type",
|
||||
response={200: GeometryStylesSchema, **auth_permission_responses})
|
||||
@newapi_etag(permissions=False)
|
||||
def geometrystyles():
|
||||
return {
|
||||
'building': '#aaaaaa',
|
||||
'space': '#eeeeee',
|
||||
'hole': 'rgba(255, 0, 0, 0.3)',
|
||||
'door': '#ffffff',
|
||||
'area': '#55aaff',
|
||||
'stair': '#a000a0',
|
||||
'ramp': 'rgba(160, 0, 160, 0.2)',
|
||||
'obstacle': '#999999',
|
||||
'lineobstacle': '#999999',
|
||||
'column': 'rgba(0, 0, 50, 0.3)',
|
||||
'poi': '#4488cc',
|
||||
'shadow': '#000000',
|
||||
'graphnode': '#009900',
|
||||
'graphedge': '#00CC00',
|
||||
'altitudemarker': '#0000FF',
|
||||
'wifimeasurement': '#DDDD00',
|
||||
'rangingbeacon': '#CC00CC',
|
||||
}
|
||||
|
||||
|
||||
@editor_api_router.get('/geometries/space/{space_id}/', summary="get the geometries to display for a space",
|
||||
response={200: list[EditorSpaceGeometriesElemSchema], **API404.dict(),
|
||||
**auth_permission_responses})
|
||||
@newapi_etag() # todo: correct?
|
||||
def space_geometries(space_id: EditorID, update_cache_key: UpdateCacheKey = None):
|
||||
"""
|
||||
look. this is a complex mess. there will hopefully be more documentation soon. or a better endpoint.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
@editor_api_router.get('/geometries/level/{level_id}/', summary="get the geometries to display for a level",
|
||||
response={200: list[EditorLevelGeometriesElemSchema], **API404.dict(),
|
||||
**auth_permission_responses})
|
||||
@newapi_etag() # todo: correct?
|
||||
def level_geometries(level_id: EditorID, update_cache_key: UpdateCacheKey = None):
|
||||
"""
|
||||
look. this is a complex mess. there will hopefully be more documentation soon. or a better endpoint.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
# todo: need a way to pass the changeset if it's not a session API key
|
||||
|
||||
|
||||
@editor_api_router.get('/{path:path}/', summary="access the editor UI programmatically",
|
||||
response={200: dict, **API404.dict(), **auth_permission_responses})
|
||||
@newapi_etag() # todo: correct?
|
||||
def view_as_api(path: str):
|
||||
"""
|
||||
get editor views rendered as JSON instead of HTML.
|
||||
`path` is the path after /editor/.
|
||||
this is a mess. good luck. if you actually want to use this, poke us so we might add better documentation.
|
||||
"""
|
||||
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
@editor_api_router.post('/{path:path}/', summary="access the editor UI programmatically",
|
||||
response={200: dict, **API404.dict(), **auth_permission_responses})
|
||||
@newapi_etag() # todo: correct?
|
||||
def view_as_api(path: str):
|
||||
"""
|
||||
get editor views rendered as JSON instead of HTML.
|
||||
`path` is the path after /editor/.
|
||||
this is a mess. good luck. if you actually want to use this, poke us so we might add better documentation.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
104
src/c3nav/editor/newapi/schemas.py
Normal file
104
src/c3nav/editor/newapi/schemas.py
Normal file
|
@ -0,0 +1,104 @@
|
|||
from typing import Annotated, Union, Literal, Optional
|
||||
|
||||
from ninja import Schema
|
||||
from pydantic import Field as APIField, PositiveInt
|
||||
|
||||
from c3nav.api.schema import LineSchema, GeometrySchema
|
||||
from c3nav.api.utils import NonEmptyStr
|
||||
|
||||
GeometryStylesSchema = Annotated[
|
||||
dict[
|
||||
Annotated[str, APIField(title="feature type")],
|
||||
Annotated[str, APIField(title="color")]
|
||||
],
|
||||
APIField(description="mapping with a color for each feature type")
|
||||
]
|
||||
EditorID = Union[
|
||||
Annotated[PositiveInt, APIField(title="an existing object that might have been modified in this changeset")],
|
||||
Annotated[str, APIField(pattern="^c:[0-9]+$", title="an object that was created in this changeset")],
|
||||
]
|
||||
EditorGeometriesUpdateCacheKeyElem = Annotated[
|
||||
tuple[
|
||||
Literal["update_cache_key"],
|
||||
Annotated[NonEmptyStr, APIField(title="the new cache key")],
|
||||
],
|
||||
APIField(
|
||||
title="new cache key", # todo better explanation
|
||||
description="the first element of the list, it informs you of the cache key to store these geometries under"
|
||||
)
|
||||
]
|
||||
EditorGeometriesCacheReferenceElem = Annotated[
|
||||
tuple[
|
||||
Annotated[NonEmptyStr, APIField(title="geometry type")],
|
||||
Annotated[EditorID, APIField(title="geometry id")], # this could be an editor id, right?
|
||||
],
|
||||
APIField(
|
||||
title="reference to a cached geometry", # todo better explanation
|
||||
description="replaces an element that has not changed from the cache key you supplied. get it from your cache."
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
class BaseEditorGeometriesPropertiesSchema(Schema):
|
||||
id: EditorID
|
||||
type: NonEmptyStr
|
||||
bounds: bool = False
|
||||
color: Optional[str] = None
|
||||
opacity: Optional[float] = None # todo: range
|
||||
|
||||
|
||||
class EditorGeometriesGraphEdgePropertiesSchema(Schema):
|
||||
id: EditorID
|
||||
type: Literal["graphedge"]
|
||||
from_node: EditorID
|
||||
to_node: EditorID
|
||||
|
||||
|
||||
class EditorSpaceGeometriesPropertiesSchema(BaseEditorGeometriesPropertiesSchema):
|
||||
space: EditorID
|
||||
|
||||
|
||||
class EditorLevelGeometriesPropertiesSchema(BaseEditorGeometriesPropertiesSchema):
|
||||
level: EditorID
|
||||
|
||||
|
||||
class EditorGeometriesGraphEdgeElemSchema(Schema):
|
||||
type: Literal["Feature"]
|
||||
properties: EditorGeometriesGraphEdgePropertiesSchema
|
||||
geometry: LineSchema
|
||||
|
||||
|
||||
class BaseEditorGeometriesGeometryElemSchema(Schema):
|
||||
type: Literal["Feature"]
|
||||
geometry: GeometrySchema = APIField(description="geometry, potentially modified for displaying")
|
||||
original_geometry: Optional[GeometrySchema] = APIField(
|
||||
default=None,
|
||||
description="original unchanged geometry, not modified, original(??)", # todo: more precise
|
||||
)
|
||||
|
||||
|
||||
class EditorSpaceGeometriesGeometryElemSchema(BaseEditorGeometriesGeometryElemSchema):
|
||||
properties: EditorSpaceGeometriesPropertiesSchema
|
||||
|
||||
|
||||
class EditorLevelGeometriesGeometryElemSchema(BaseEditorGeometriesGeometryElemSchema):
|
||||
properties: EditorLevelGeometriesPropertiesSchema
|
||||
|
||||
|
||||
EditorSpaceGeometriesElemSchema = Union[
|
||||
EditorGeometriesUpdateCacheKeyElem,
|
||||
Annotated[EditorSpaceGeometriesGeometryElemSchema, APIField(title="a geometry object")],
|
||||
Annotated[EditorGeometriesGraphEdgeElemSchema, APIField(title="a graph edge")],
|
||||
EditorGeometriesCacheReferenceElem,
|
||||
]
|
||||
EditorLevelGeometriesElemSchema = Union[
|
||||
EditorGeometriesUpdateCacheKeyElem,
|
||||
Annotated[EditorLevelGeometriesGeometryElemSchema, APIField(title="a geometry object")],
|
||||
Annotated[EditorGeometriesGraphEdgeElemSchema, APIField(title="a graph edge")],
|
||||
EditorGeometriesCacheReferenceElem,
|
||||
]
|
||||
|
||||
UpdateCacheKey = Annotated[
|
||||
Optional[NonEmptyStr],
|
||||
APIField(default=None, pattern="^c:[0-9]+$", title="the cache key under which you have cached objects"),
|
||||
]
|
Loading…
Add table
Add a link
Reference in a new issue