2024-07-08 11:44:39 -04:00
from django . shortcuts import render
2025-01-09 12:38:29 -05:00
from . models import Country , Region , VisitedRegion , City , VisitedCity
from . serializers import CitySerializer , CountrySerializer , RegionSerializer , VisitedRegionSerializer , VisitedCitySerializer
2024-07-23 12:09:24 -04:00
from rest_framework import viewsets , status
2024-07-08 11:44:39 -04:00
from rest_framework . permissions import IsAuthenticated
from django . shortcuts import get_object_or_404
from rest_framework . response import Response
from rest_framework . decorators import api_view , permission_classes
2024-07-27 12:46:50 -04:00
import os
import json
2024-08-23 13:56:27 -04:00
from django . http import JsonResponse
from django . contrib . gis . geos import Point
2024-07-27 12:46:50 -04:00
from django . conf import settings
2024-08-23 13:56:27 -04:00
from rest_framework . decorators import action
2024-07-27 12:46:50 -04:00
from django . contrib . staticfiles import finders
2024-08-23 18:34:11 -04:00
from adventures . models import Adventure
2024-07-08 11:44:39 -04:00
@api_view ( [ ' GET ' ] )
@permission_classes ( [ IsAuthenticated ] )
def regions_by_country ( request , country_code ) :
# require authentication
country = get_object_or_404 ( Country , country_code = country_code )
2024-08-05 14:17:41 -04:00
regions = Region . objects . filter ( country = country ) . order_by ( ' name ' )
2024-07-08 11:44:39 -04:00
serializer = RegionSerializer ( regions , many = True )
return Response ( serializer . data )
@api_view ( [ ' GET ' ] )
@permission_classes ( [ IsAuthenticated ] )
def visits_by_country ( request , country_code ) :
country = get_object_or_404 ( Country , country_code = country_code )
2024-07-23 12:00:15 -04:00
visits = VisitedRegion . objects . filter ( region__country = country , user_id = request . user . id )
2024-07-08 11:44:39 -04:00
serializer = VisitedRegionSerializer ( visits , many = True )
return Response ( serializer . data )
2025-01-09 11:11:02 -05:00
@api_view ( [ ' GET ' ] )
@permission_classes ( [ IsAuthenticated ] )
def cities_by_region ( request , region_id ) :
region = get_object_or_404 ( Region , id = region_id )
cities = City . objects . filter ( region = region ) . order_by ( ' name ' )
serializer = CitySerializer ( cities , many = True )
return Response ( serializer . data )
2025-01-09 12:38:29 -05:00
@api_view ( [ ' GET ' ] )
@permission_classes ( [ IsAuthenticated ] )
def visits_by_region ( request , region_id ) :
region = get_object_or_404 ( Region , id = region_id )
visits = VisitedCity . objects . filter ( city__region = region , user_id = request . user . id )
serializer = VisitedCitySerializer ( visits , many = True )
return Response ( serializer . data )
2024-07-08 11:44:39 -04:00
class CountryViewSet ( viewsets . ReadOnlyModelViewSet ) :
2024-09-13 20:33:44 -04:00
queryset = Country . objects . all ( ) . order_by ( ' name ' )
2024-07-08 11:44:39 -04:00
serializer_class = CountrySerializer
permission_classes = [ IsAuthenticated ]
2024-08-23 13:56:27 -04:00
@action ( detail = False , methods = [ ' get ' ] )
def check_point_in_region ( self , request ) :
lat = float ( request . query_params . get ( ' lat ' ) )
lon = float ( request . query_params . get ( ' lon ' ) )
point = Point ( lon , lat , srid = 4326 )
region = Region . objects . filter ( geometry__contains = point ) . first ( )
if region :
2024-08-23 14:08:04 -04:00
return Response ( { ' in_region ' : True , ' region_name ' : region . name , ' region_id ' : region . id } )
2024-08-23 13:56:27 -04:00
else :
return Response ( { ' in_region ' : False } )
2024-08-23 18:34:11 -04:00
# make a post action that will get all of the users adventures and check if the point is in any of the regions if so make a visited region object for that user if it does not already exist
@action ( detail = False , methods = [ ' post ' ] )
def region_check_all_adventures ( self , request ) :
2024-08-23 18:41:59 -04:00
adventures = Adventure . objects . filter ( user_id = request . user . id , type = ' visited ' )
2024-08-23 18:34:11 -04:00
count = 0
for adventure in adventures :
if adventure . latitude is not None and adventure . longitude is not None :
try :
point = Point ( float ( adventure . longitude ) , float ( adventure . latitude ) , srid = 4326 )
region = Region . objects . filter ( geometry__contains = point ) . first ( )
if region :
if not VisitedRegion . objects . filter ( user_id = request . user . id , region = region ) . exists ( ) :
VisitedRegion . objects . create ( user_id = request . user , region = region )
count + = 1
except Exception as e :
print ( f " Error processing adventure { adventure . id } : { e } " )
continue
return Response ( { ' regions_visited ' : count } )
2024-08-23 13:56:27 -04:00
2024-07-08 11:44:39 -04:00
class RegionViewSet ( viewsets . ReadOnlyModelViewSet ) :
queryset = Region . objects . all ( )
serializer_class = RegionSerializer
permission_classes = [ IsAuthenticated ]
class VisitedRegionViewSet ( viewsets . ModelViewSet ) :
serializer_class = VisitedRegionSerializer
2024-07-23 11:56:33 -04:00
permission_classes = [ IsAuthenticated ]
def get_queryset ( self ) :
2024-07-23 12:09:24 -04:00
return VisitedRegion . objects . filter ( user_id = self . request . user . id )
2024-08-06 12:35:30 -04:00
def perform_create ( self , serializer ) :
serializer . save ( user_id = self . request . user )
2024-07-23 12:09:24 -04:00
def create ( self , request , * args , * * kwargs ) :
2024-08-06 12:35:30 -04:00
request . data [ ' user_id ' ] = request . user
2024-08-17 08:07:50 -04:00
if VisitedRegion . objects . filter ( user_id = request . user . id , region = request . data [ ' region ' ] ) . exists ( ) :
return Response ( { " error " : " Region already visited by user. " } , status = 400 )
2024-07-23 12:09:24 -04:00
serializer = self . get_serializer ( data = request . data )
serializer . is_valid ( raise_exception = True )
self . perform_create ( serializer )
headers = self . get_success_headers ( serializer . data )
2025-01-09 12:38:29 -05:00
return Response ( serializer . data , status = status . HTTP_201_CREATED , headers = headers )
def destroy ( self , request , * * kwargs ) :
# delete by region id
region = get_object_or_404 ( Region , id = kwargs [ ' pk ' ] )
visited_region = VisitedRegion . objects . filter ( user_id = request . user . id , region = region )
if visited_region . exists ( ) :
visited_region . delete ( )
return Response ( status = status . HTTP_204_NO_CONTENT )
else :
return Response ( { " error " : " Visited region not found. " } , status = status . HTTP_404_NOT_FOUND )
class VisitedCityViewSet ( viewsets . ModelViewSet ) :
serializer_class = VisitedCitySerializer
permission_classes = [ IsAuthenticated ]
def get_queryset ( self ) :
return VisitedCity . objects . filter ( user_id = self . request . user . id )
def perform_create ( self , serializer ) :
serializer . save ( user_id = self . request . user )
def create ( self , request , * args , * * kwargs ) :
request . data [ ' user_id ' ] = request . user
serializer = self . get_serializer ( data = request . data )
serializer . is_valid ( raise_exception = True )
self . perform_create ( serializer )
2025-01-09 19:40:23 -05:00
# if the region is not visited, visit it
region = serializer . validated_data [ ' city ' ] . region
if not VisitedRegion . objects . filter ( user_id = request . user . id , region = region ) . exists ( ) :
VisitedRegion . objects . create ( user_id = request . user , region = region )
2025-01-09 12:38:29 -05:00
headers = self . get_success_headers ( serializer . data )
return Response ( serializer . data , status = status . HTTP_201_CREATED , headers = headers )
def destroy ( self , request , * * kwargs ) :
# delete by city id
city = get_object_or_404 ( City , id = kwargs [ ' pk ' ] )
visited_city = VisitedCity . objects . filter ( user_id = request . user . id , city = city )
if visited_city . exists ( ) :
visited_city . delete ( )
return Response ( status = status . HTTP_204_NO_CONTENT )
else :
return Response ( { " error " : " Visited city not found. " } , status = status . HTTP_404_NOT_FOUND )