mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-31 12:07:02 -05:00
feat: Implement MFA authentication, add ride statistics model, and update various services, APIs, and tests across the application.
This commit is contained in:
@@ -9,18 +9,19 @@ This service provides functionality for:
|
||||
- Proper rate limiting and caching
|
||||
"""
|
||||
|
||||
import time
|
||||
import math
|
||||
import logging
|
||||
import requests
|
||||
from typing import Dict, List, Optional, Any
|
||||
import math
|
||||
import time
|
||||
from dataclasses import dataclass
|
||||
from itertools import permutations
|
||||
from typing import Any
|
||||
|
||||
import requests
|
||||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
from django.contrib.gis.geos import Point
|
||||
from django.contrib.gis.measure import Distance
|
||||
from django.core.cache import cache
|
||||
|
||||
from apps.parks.models import Park
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -33,7 +34,7 @@ class Coordinates:
|
||||
latitude: float
|
||||
longitude: float
|
||||
|
||||
def to_list(self) -> List[float]:
|
||||
def to_list(self) -> list[float]:
|
||||
"""Return as [lat, lon] list."""
|
||||
return [self.latitude, self.longitude]
|
||||
|
||||
@@ -48,7 +49,7 @@ class RouteInfo:
|
||||
|
||||
distance_km: float
|
||||
duration_minutes: int
|
||||
geometry: Optional[str] = None # Encoded polyline
|
||||
geometry: str | None = None # Encoded polyline
|
||||
|
||||
@property
|
||||
def formatted_distance(self) -> str:
|
||||
@@ -79,7 +80,7 @@ class TripLeg:
|
||||
route: RouteInfo
|
||||
|
||||
@property
|
||||
def parks_along_route(self) -> List["Park"]:
|
||||
def parks_along_route(self) -> list["Park"]:
|
||||
"""Get parks along this route segment."""
|
||||
# This would be populated by find_parks_along_route
|
||||
return []
|
||||
@@ -89,8 +90,8 @@ class TripLeg:
|
||||
class RoadTrip:
|
||||
"""Complete road trip with multiple parks."""
|
||||
|
||||
parks: List["Park"]
|
||||
legs: List[TripLeg]
|
||||
parks: list["Park"]
|
||||
legs: list[TripLeg]
|
||||
total_distance_km: float
|
||||
total_duration_minutes: int
|
||||
|
||||
@@ -170,7 +171,7 @@ class RoadTripService:
|
||||
}
|
||||
)
|
||||
|
||||
def _make_request(self, url: str, params: Dict[str, Any]) -> Dict[str, Any]:
|
||||
def _make_request(self, url: str, params: dict[str, Any]) -> dict[str, Any]:
|
||||
"""
|
||||
Make HTTP request with rate limiting, retries, and error handling.
|
||||
"""
|
||||
@@ -195,7 +196,7 @@ class RoadTripService:
|
||||
f"Failed to make request after {self.max_retries} attempts: {e}"
|
||||
)
|
||||
|
||||
def geocode_address(self, address: str) -> Optional[Coordinates]:
|
||||
def geocode_address(self, address: str) -> Coordinates | None:
|
||||
"""
|
||||
Convert address to coordinates using Nominatim geocoding service.
|
||||
|
||||
@@ -256,7 +257,7 @@ class RoadTripService:
|
||||
|
||||
def calculate_route(
|
||||
self, start_coords: Coordinates, end_coords: Coordinates
|
||||
) -> Optional[RouteInfo]:
|
||||
) -> RouteInfo | None:
|
||||
"""
|
||||
Calculate route between two coordinate points using OSRM.
|
||||
|
||||
@@ -377,7 +378,7 @@ class RoadTripService:
|
||||
|
||||
def find_parks_along_route(
|
||||
self, start_park: "Park", end_park: "Park", max_detour_km: float = 50
|
||||
) -> List["Park"]:
|
||||
) -> list["Park"]:
|
||||
"""
|
||||
Find parks along a route within specified detour distance.
|
||||
|
||||
@@ -444,7 +445,7 @@ class RoadTripService:
|
||||
|
||||
def _calculate_detour_distance(
|
||||
self, start: Coordinates, end: Coordinates, waypoint: Coordinates
|
||||
) -> Optional[float]:
|
||||
) -> float | None:
|
||||
"""
|
||||
Calculate the detour distance when visiting a waypoint.
|
||||
"""
|
||||
@@ -470,7 +471,7 @@ class RoadTripService:
|
||||
logger.error(f"Failed to calculate detour distance: {e}")
|
||||
return None
|
||||
|
||||
def create_multi_park_trip(self, park_list: List["Park"]) -> Optional[RoadTrip]:
|
||||
def create_multi_park_trip(self, park_list: list["Park"]) -> RoadTrip | None:
|
||||
"""
|
||||
Create optimized multi-park road trip using simple nearest neighbor heuristic.
|
||||
|
||||
@@ -489,7 +490,7 @@ class RoadTripService:
|
||||
else:
|
||||
return self._optimize_trip_nearest_neighbor(park_list)
|
||||
|
||||
def _optimize_trip_exhaustive(self, park_list: List["Park"]) -> Optional[RoadTrip]:
|
||||
def _optimize_trip_exhaustive(self, park_list: list["Park"]) -> RoadTrip | None:
|
||||
"""
|
||||
Find optimal route by testing all permutations (for small lists).
|
||||
"""
|
||||
@@ -508,8 +509,8 @@ class RoadTripService:
|
||||
return best_trip
|
||||
|
||||
def _optimize_trip_nearest_neighbor(
|
||||
self, park_list: List["Park"]
|
||||
) -> Optional[RoadTrip]:
|
||||
self, park_list: list["Park"]
|
||||
) -> RoadTrip | None:
|
||||
"""
|
||||
Optimize trip using nearest neighbor heuristic (for larger lists).
|
||||
"""
|
||||
@@ -553,8 +554,8 @@ class RoadTripService:
|
||||
return self._create_trip_from_order(ordered_parks)
|
||||
|
||||
def _create_trip_from_order(
|
||||
self, ordered_parks: List["Park"]
|
||||
) -> Optional[RoadTrip]:
|
||||
self, ordered_parks: list["Park"]
|
||||
) -> RoadTrip | None:
|
||||
"""
|
||||
Create a RoadTrip object from an ordered list of parks.
|
||||
"""
|
||||
@@ -596,7 +597,7 @@ class RoadTripService:
|
||||
|
||||
def get_park_distances(
|
||||
self, center_park: "Park", radius_km: float = 100
|
||||
) -> List[Dict[str, Any]]:
|
||||
) -> list[dict[str, Any]]:
|
||||
"""
|
||||
Get all parks within radius of a center park with distances.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user