Files
thrillwiki_django_no_react/backend/apps/api/v1/maps/views.py
pacnpal e4e36c7899 Add migrations for ParkPhoto and RidePhoto models with associated events
- Created ParkPhoto and ParkPhotoEvent models in the parks app, including fields for image, caption, alt text, and relationships to the Park model.
- Implemented triggers for insert and update operations on ParkPhoto to log changes in ParkPhotoEvent.
- Created RidePhoto and RidePhotoEvent models in the rides app, with similar structure and functionality as ParkPhoto.
- Added fields for photo type in RidePhoto and implemented corresponding triggers for logging changes.
- Established necessary indexes and unique constraints for both models to ensure data integrity and optimize queries.
2025-08-26 14:40:46 -04:00

354 lines
11 KiB
Python

"""
Centralized map API views.
Migrated from apps.core.views.map_views
"""
import logging
from django.http import HttpRequest
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import AllowAny
from drf_spectacular.utils import extend_schema, extend_schema_view
from drf_spectacular.types import OpenApiTypes
logger = logging.getLogger(__name__)
@extend_schema_view(
get=extend_schema(
summary="Get map locations",
description="Get map locations with optional clustering and filtering.",
parameters=[
{
"name": "north",
"in": "query",
"required": False,
"schema": {"type": "number"},
},
{
"name": "south",
"in": "query",
"required": False,
"schema": {"type": "number"},
},
{
"name": "east",
"in": "query",
"required": False,
"schema": {"type": "number"},
},
{
"name": "west",
"in": "query",
"required": False,
"schema": {"type": "number"},
},
{
"name": "zoom",
"in": "query",
"required": False,
"schema": {"type": "integer"},
},
{
"name": "types",
"in": "query",
"required": False,
"schema": {"type": "string"},
},
{
"name": "cluster",
"in": "query",
"required": False,
"schema": {"type": "boolean"},
},
{
"name": "q",
"in": "query",
"required": False,
"schema": {"type": "string"},
},
],
responses={200: OpenApiTypes.OBJECT},
tags=["Maps"],
),
)
class MapLocationsAPIView(APIView):
"""API endpoint for getting map locations with optional clustering."""
permission_classes = [AllowAny]
def get(self, request: HttpRequest) -> Response:
"""Get map locations with optional clustering and filtering."""
try:
# Simple implementation to fix import error
# TODO: Implement full functionality
return Response(
{
"status": "success",
"message": "Map locations endpoint - implementation needed",
"data": [],
}
)
except Exception as e:
logger.error(f"Error in MapLocationsAPIView: {str(e)}", exc_info=True)
return Response(
{"status": "error", "message": "Failed to retrieve map locations"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
@extend_schema_view(
get=extend_schema(
summary="Get location details",
description="Get detailed information about a specific location.",
parameters=[
{
"name": "location_type",
"in": "path",
"required": True,
"schema": {"type": "string"},
},
{
"name": "location_id",
"in": "path",
"required": True,
"schema": {"type": "integer"},
},
],
responses={200: OpenApiTypes.OBJECT, 404: OpenApiTypes.OBJECT},
tags=["Maps"],
),
)
class MapLocationDetailAPIView(APIView):
"""API endpoint for getting detailed information about a specific location."""
permission_classes = [AllowAny]
def get(
self, request: HttpRequest, location_type: str, location_id: int
) -> Response:
"""Get detailed information for a specific location."""
try:
# Simple implementation to fix import error
return Response(
{
"status": "success",
"message": f"Location detail for {location_type}/{location_id} - implementation needed",
"data": {
"location_type": location_type,
"location_id": location_id,
},
}
)
except Exception as e:
logger.error(f"Error in MapLocationDetailAPIView: {str(e)}", exc_info=True)
return Response(
{"status": "error", "message": "Failed to retrieve location details"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
@extend_schema_view(
get=extend_schema(
summary="Search map locations",
description="Search locations by text query with optional bounds filtering.",
parameters=[
{
"name": "q",
"in": "query",
"required": True,
"schema": {"type": "string"},
},
],
responses={200: OpenApiTypes.OBJECT, 400: OpenApiTypes.OBJECT},
tags=["Maps"],
),
)
class MapSearchAPIView(APIView):
"""API endpoint for searching locations by text query."""
permission_classes = [AllowAny]
def get(self, request: HttpRequest) -> Response:
"""Search locations by text query with pagination."""
try:
query = request.GET.get("q", "").strip()
if not query:
return Response(
{
"status": "error",
"message": "Search query 'q' parameter is required",
},
status=status.HTTP_400_BAD_REQUEST,
)
# Simple implementation to fix import error
return Response(
{
"status": "success",
"message": f"Search for '{query}' - implementation needed",
"data": [],
}
)
except Exception as e:
logger.error(f"Error in MapSearchAPIView: {str(e)}", exc_info=True)
return Response(
{"status": "error", "message": "Search failed due to internal error"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
@extend_schema_view(
get=extend_schema(
summary="Get locations within bounds",
description="Get locations within specific geographic bounds.",
parameters=[
{
"name": "north",
"in": "query",
"required": True,
"schema": {"type": "number"},
},
{
"name": "south",
"in": "query",
"required": True,
"schema": {"type": "number"},
},
{
"name": "east",
"in": "query",
"required": True,
"schema": {"type": "number"},
},
{
"name": "west",
"in": "query",
"required": True,
"schema": {"type": "number"},
},
],
responses={200: OpenApiTypes.OBJECT, 400: OpenApiTypes.OBJECT},
tags=["Maps"],
),
)
class MapBoundsAPIView(APIView):
"""API endpoint for getting locations within specific bounds."""
permission_classes = [AllowAny]
def get(self, request: HttpRequest) -> Response:
"""Get locations within specific geographic bounds."""
try:
# Simple implementation to fix import error
return Response(
{
"status": "success",
"message": "Bounds query - implementation needed",
"data": [],
}
)
except Exception as e:
logger.error(f"Error in MapBoundsAPIView: {str(e)}", exc_info=True)
return Response(
{
"status": "error",
"message": "Failed to retrieve locations within bounds",
},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
@extend_schema_view(
get=extend_schema(
summary="Get map service statistics",
description="Get map service statistics and performance metrics.",
responses={200: OpenApiTypes.OBJECT},
tags=["Maps"],
),
)
class MapStatsAPIView(APIView):
"""API endpoint for getting map service statistics and health information."""
permission_classes = [AllowAny]
def get(self, request: HttpRequest) -> Response:
"""Get map service statistics and performance metrics."""
try:
# Simple implementation to fix import error
return Response(
{
"status": "success",
"data": {"total_locations": 0, "cache_hits": 0, "cache_misses": 0},
}
)
except Exception as e:
return Response(
{"error": f"Internal server error: {str(e)}"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
@extend_schema_view(
delete=extend_schema(
summary="Clear map cache",
description="Clear all map cache (admin only).",
responses={200: OpenApiTypes.OBJECT},
tags=["Maps"],
),
post=extend_schema(
summary="Invalidate specific cache entries",
description="Invalidate specific cache entries.",
responses={200: OpenApiTypes.OBJECT},
tags=["Maps"],
),
)
class MapCacheAPIView(APIView):
"""API endpoint for cache management (admin only)."""
permission_classes = [AllowAny] # TODO: Add admin permission check
def delete(self, request: HttpRequest) -> Response:
"""Clear all map cache (admin only)."""
try:
# Simple implementation to fix import error
return Response(
{"status": "success", "message": "Map cache cleared successfully"}
)
except Exception as e:
return Response(
{"error": f"Internal server error: {str(e)}"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
def post(self, request: HttpRequest) -> Response:
"""Invalidate specific cache entries."""
try:
# Simple implementation to fix import error
return Response(
{"status": "success", "message": "Cache invalidated successfully"}
)
except Exception as e:
return Response(
{"error": f"Internal server error: {str(e)}"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
# Legacy compatibility aliases
MapLocationsView = MapLocationsAPIView
MapLocationDetailView = MapLocationDetailAPIView
MapSearchView = MapSearchAPIView
MapBoundsView = MapBoundsAPIView
MapStatsView = MapStatsAPIView
MapCacheView = MapCacheAPIView