2018-09-19 19:08:47 +02:00
|
|
|
import inspect
|
2016-10-11 17:29:02 +02:00
|
|
|
import re
|
|
|
|
from collections import OrderedDict
|
|
|
|
|
2022-04-03 16:33:43 +02:00
|
|
|
from django.urls import include, path, re_path
|
2018-09-16 20:08:01 +02:00
|
|
|
from django.utils.functional import cached_property
|
2023-11-11 03:01:15 +01:00
|
|
|
from ninja import NinjaAPI
|
2016-10-11 17:29:02 +02:00
|
|
|
from rest_framework.generics import GenericAPIView
|
|
|
|
from rest_framework.response import Response
|
|
|
|
from rest_framework.routers import SimpleRouter
|
2016-09-11 21:39:01 +02:00
|
|
|
|
2018-11-23 22:28:04 +01:00
|
|
|
from c3nav.api.api import SessionViewSet
|
2023-11-14 18:29:21 +01:00
|
|
|
from c3nav.api.exceptions import CustomAPIException
|
2023-11-14 17:54:56 +01:00
|
|
|
from c3nav.api.newapi import auth_api_router
|
2023-11-14 18:29:21 +01:00
|
|
|
from c3nav.api.newauth import BearerAuth
|
2017-07-06 13:07:05 +02:00
|
|
|
from c3nav.editor.api import ChangeSetViewSet, EditorViewSet
|
2017-12-20 22:53:57 +01:00
|
|
|
from c3nav.mapdata.api import (AccessRestrictionGroupViewSet, AccessRestrictionViewSet, AreaViewSet, BuildingViewSet,
|
2019-12-27 20:02:58 +01:00
|
|
|
ColumnViewSet, CrossDescriptionViewSet, DoorViewSet, DynamicLocationPositionViewSet,
|
|
|
|
HoleViewSet, LeaveDescriptionViewSet, LevelViewSet, LineObstacleViewSet,
|
|
|
|
LocationBySlugViewSet, LocationGroupCategoryViewSet, LocationGroupViewSet,
|
|
|
|
LocationViewSet, MapViewSet, ObstacleViewSet, POIViewSet, RampViewSet, SourceViewSet,
|
|
|
|
SpaceViewSet, StairViewSet, UpdatesViewSet)
|
2018-09-19 19:08:47 +02:00
|
|
|
from c3nav.mapdata.utils.user import can_access_editor
|
2023-11-05 18:47:20 +01:00
|
|
|
from c3nav.mesh.api import FirmwareViewSet
|
2023-11-11 03:01:15 +01:00
|
|
|
from c3nav.mesh.newapi import api_router as mesh_api_router
|
2023-11-14 18:29:21 +01:00
|
|
|
from c3nav.mapdata.newapi import api_router as mapdata_api_router
|
2017-11-27 16:40:15 +01:00
|
|
|
from c3nav.routing.api import RoutingViewSet
|
2016-09-11 21:39:01 +02:00
|
|
|
|
2023-11-11 03:01:15 +01:00
|
|
|
ninja_api = NinjaAPI(
|
|
|
|
title="c3nav API",
|
|
|
|
version="v2",
|
|
|
|
docs_url="/",
|
2023-11-14 18:29:21 +01:00
|
|
|
auth=BearerAuth(),
|
2023-11-11 03:01:15 +01:00
|
|
|
)
|
2023-11-14 18:29:21 +01:00
|
|
|
|
|
|
|
|
|
|
|
@ninja_api.exception_handler(CustomAPIException)
|
|
|
|
def on_invalid_token(request, exc):
|
|
|
|
return ninja_api.create_response(request, {"detail": exc.detail}, status=exc.status_code)
|
|
|
|
|
|
|
|
|
2023-11-14 17:54:56 +01:00
|
|
|
ninja_api.add_router("/auth/", auth_api_router)
|
2023-11-11 03:01:15 +01:00
|
|
|
ninja_api.add_router("/mesh/", mesh_api_router)
|
|
|
|
|
2016-10-11 17:29:02 +02:00
|
|
|
router = SimpleRouter()
|
2022-04-03 16:33:43 +02:00
|
|
|
router.register(r'map', MapViewSet, basename='map')
|
2017-06-11 14:43:14 +02:00
|
|
|
router.register(r'levels', LevelViewSet)
|
2017-05-11 19:36:49 +02:00
|
|
|
router.register(r'buildings', BuildingViewSet)
|
|
|
|
router.register(r'spaces', SpaceViewSet)
|
|
|
|
router.register(r'doors', DoorViewSet)
|
|
|
|
router.register(r'holes', HoleViewSet)
|
|
|
|
router.register(r'areas', AreaViewSet)
|
|
|
|
router.register(r'stairs', StairViewSet)
|
2017-11-17 20:31:29 +01:00
|
|
|
router.register(r'ramps', RampViewSet)
|
2017-05-11 19:36:49 +02:00
|
|
|
router.register(r'obstacles', ObstacleViewSet)
|
|
|
|
router.register(r'lineobstacles', LineObstacleViewSet)
|
2017-06-09 15:22:30 +02:00
|
|
|
router.register(r'columns', ColumnViewSet)
|
2017-07-08 16:29:12 +02:00
|
|
|
router.register(r'pois', POIViewSet)
|
2017-12-20 22:53:57 +01:00
|
|
|
router.register(r'leavedescriptions', LeaveDescriptionViewSet)
|
|
|
|
router.register(r'crossdescriptions', CrossDescriptionViewSet)
|
2016-09-27 16:18:18 +02:00
|
|
|
router.register(r'sources', SourceViewSet)
|
2017-07-13 19:01:47 +02:00
|
|
|
router.register(r'accessrestrictions', AccessRestrictionViewSet)
|
2017-12-20 22:53:57 +01:00
|
|
|
router.register(r'accessrestrictiongroups', AccessRestrictionGroupViewSet)
|
2016-10-13 13:55:02 +02:00
|
|
|
|
2017-05-11 19:36:49 +02:00
|
|
|
router.register(r'locations', LocationViewSet)
|
2022-04-03 16:33:43 +02:00
|
|
|
router.register(r'locations/by_slug', LocationBySlugViewSet, basename='location-by-slug')
|
|
|
|
router.register(r'locations/dynamic', DynamicLocationPositionViewSet, basename='dynamic-location')
|
2017-07-10 13:54:33 +02:00
|
|
|
router.register(r'locationgroupcategories', LocationGroupCategoryViewSet)
|
2017-05-11 19:36:49 +02:00
|
|
|
router.register(r'locationgroups', LocationGroupViewSet)
|
2016-12-15 13:18:46 +01:00
|
|
|
|
2022-04-03 16:33:43 +02:00
|
|
|
router.register(r'updates', UpdatesViewSet, basename='updates')
|
2017-12-04 16:11:42 +01:00
|
|
|
|
2022-04-03 16:33:43 +02:00
|
|
|
router.register(r'routing', RoutingViewSet, basename='routing')
|
2017-11-27 16:40:15 +01:00
|
|
|
|
2022-04-03 16:33:43 +02:00
|
|
|
router.register(r'editor', EditorViewSet, basename='editor')
|
2017-07-06 13:07:05 +02:00
|
|
|
router.register(r'changesets', ChangeSetViewSet)
|
2022-04-03 16:33:43 +02:00
|
|
|
router.register(r'session', SessionViewSet, basename='session')
|
2017-05-21 23:39:26 +02:00
|
|
|
|
2023-11-05 18:47:20 +01:00
|
|
|
router.register(r'firmwares', FirmwareViewSet, basename='firmware')
|
|
|
|
|
2016-10-11 17:29:02 +02:00
|
|
|
|
|
|
|
class APIRoot(GenericAPIView):
|
|
|
|
"""
|
|
|
|
Welcome to the c3nav RESTful API.
|
2017-11-29 11:27:50 +01:00
|
|
|
The HTML preview is only shown because your Browser sent text/html in its Accept header.
|
2017-11-29 11:13:13 +01:00
|
|
|
If you want to use this API on a large scale, please use a client that supports E-Tags.
|
2017-11-29 11:27:50 +01:00
|
|
|
For more information on a specific API endpoint, access it with a browser.
|
2023-11-11 03:01:15 +01:00
|
|
|
|
|
|
|
This is the old API which is slowly being phased out in favor of the new API at /api/v2/.
|
2016-10-11 17:29:02 +02:00
|
|
|
"""
|
|
|
|
|
|
|
|
def _format_pattern(self, pattern):
|
|
|
|
return re.sub(r'\(\?P<([^>]*[^>_])_?>[^)]+\)', r'{\1}', pattern)[1:-1]
|
|
|
|
|
|
|
|
@cached_property
|
|
|
|
def urls(self):
|
2018-09-19 19:08:47 +02:00
|
|
|
include_editor = can_access_editor(self.request)
|
2022-04-03 20:19:41 +02:00
|
|
|
urls: dict[str, dict[str, str] | str] = OrderedDict()
|
2016-10-11 17:29:02 +02:00
|
|
|
for urlpattern in router.urls:
|
2018-09-19 19:08:47 +02:00
|
|
|
if not include_editor and inspect.getmodule(urlpattern.callback).__name__.startswith('c3nav.editor.'):
|
|
|
|
continue
|
2016-10-11 17:29:02 +02:00
|
|
|
name = urlpattern.name
|
2018-09-19 17:31:36 +02:00
|
|
|
url = self._format_pattern(str(urlpattern.pattern)).replace('{pk}', '{id}')
|
2016-10-11 17:29:02 +02:00
|
|
|
base = url.split('/', 1)[0]
|
2018-11-21 01:38:57 +01:00
|
|
|
if base == 'editor':
|
|
|
|
if name == 'editor-list':
|
|
|
|
continue
|
|
|
|
if name == 'editor-detail':
|
|
|
|
name = 'editor-api'
|
2018-11-23 22:28:04 +01:00
|
|
|
elif base == 'session':
|
|
|
|
if name == 'session-list':
|
|
|
|
name = 'session-info'
|
2016-10-11 17:29:02 +02:00
|
|
|
if '-' in name:
|
|
|
|
urls.setdefault(base, OrderedDict())[name.split('-', 1)[1]] = url
|
|
|
|
else:
|
|
|
|
urls[name] = url
|
|
|
|
return urls
|
|
|
|
|
|
|
|
def get(self, request):
|
|
|
|
return Response(self.urls)
|
|
|
|
|
|
|
|
|
|
|
|
urlpatterns = [
|
2022-04-03 16:33:43 +02:00
|
|
|
# todo: does this work? can it be better?
|
|
|
|
re_path(r'^$', APIRoot.as_view()),
|
|
|
|
path('', include(router.urls)),
|
2016-10-11 17:29:02 +02:00
|
|
|
]
|