2024-07-08 11:44:39 -04:00
from django . shortcuts import render
from . models import Country , Region , VisitedRegion
from . serializers import CountrySerializer , RegionSerializer , VisitedRegionSerializer
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 )
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 :
print ( f " Adventure { adventure . id } : lat= { adventure . latitude } , lon= { adventure . longitude } " )
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 )
2024-07-27 12:46:50 -04:00
return Response ( serializer . data , status = status . HTTP_201_CREATED , headers = headers )
2024-08-06 12:35:30 -04:00
2024-07-27 12:46:50 -04:00
class GeoJSONView ( viewsets . ViewSet ) :
"""
Combine all GeoJSON data from . json files in static / data into a single GeoJSON object .
"""
def list ( self , request ) :
combined_geojson = {
" type " : " FeatureCollection " ,
" features " : [ ]
}
# Use Django's static file finder to locate the 'data' directory
data_dir = finders . find ( ' data ' )
if not data_dir or not os . path . isdir ( data_dir ) :
return Response ( { " error " : " Data directory does not exist. " } , status = 404 )
for filename in os . listdir ( data_dir ) :
if filename . endswith ( ' .json ' ) :
file_path = os . path . join ( data_dir , filename )
try :
with open ( file_path , ' r ' ) as f :
json_data = json . load ( f )
# Check if the JSON data is GeoJSON
if isinstance ( json_data , dict ) and " type " in json_data :
if json_data [ " type " ] == " FeatureCollection " :
combined_geojson [ " features " ] . extend ( json_data . get ( " features " , [ ] ) )
elif json_data [ " type " ] == " Feature " :
combined_geojson [ " features " ] . append ( json_data )
# You can add more conditions here for other GeoJSON types if needed
except ( IOError , json . JSONDecodeError ) as e :
return Response ( { " error " : f " Error reading file { filename } : { str ( e ) } " } , status = 500 )
return Response ( combined_geojson )