api-drf-1/api/views.py

219 lines
No EOL
7.7 KiB
Python

from rest_framework import status, generics, permissions
from rest_framework.response import Response
from rest_framework.views import APIView
from django.utils import timezone
from .models import Prediction, User, UserPrediction
from .serializers import PredictionSerializer, PredictionRequestSerializer, PredictionListSerializer, PredictionDetailSerializer
from rest_framework.permissions import IsAuthenticated
import requests
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from rest_framework.permissions import AllowAny
from .services.tawhiri import TawhiriClient
from django.contrib.auth import get_user_model
from .models import Satellite, TelemetryPacket
from .serializers import TelemetryPacketSerializer
from .permissions import ReadOnlyOrAuthenticated
import time
from django.http import JsonResponse
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from django.contrib.auth import authenticate, login, logout
import json
from django.middleware.csrf import get_token
User = get_user_model()
def get_prediction_from_tawhiri(params):
base_url = "https://fly.stratonautica.ru/api/v2"
response = requests.get(base_url, params=params)
if response.status_code == 200:
return response.json() # получаем результат предсказания
else:
raise Exception(f"Tawhiri error: {response.status_code} {response.text}")
class PredictionCreateView(APIView):
permission_classes = [IsAuthenticated]
def post(self, request):
print("DEBUG: request.user =", request.user)
print("DEBUG: request.user.id =", request.user.id)
serializer = PredictionRequestSerializer(data=request.data)
if not serializer.is_valid():
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
validated_data = serializer.validated_data
try:
prediction_result = TawhiriClient.get_prediction(validated_data)
print(prediction_result)
except requests.RequestException as e:
print("Tawhiri error:", str(e), e.response.text if e.response else "no response")
return Response({"error": f"Tawhiri error: {str(e)}"}, status=status.HTTP_502_BAD_GATEWAY)
prediction = Prediction.objects.create(result=prediction_result)
UserPrediction.objects.create(user=request.user, prediction=prediction, created_at=timezone.now())
return Response({
"id": prediction.id,
"created_at": prediction.created_at,
"result": prediction_result
}, status=status.HTTP_201_CREATED)
class PredictionListView(APIView):
def get(self, request):
user_id = request.query_params.get('user_id')
created_from = request.query_params.get('created_from')
created_till = request.query_params.get('created_till')
predictions = Prediction.objects.filter(
id__in=UserPrediction.objects.filter(user_id=user_id).values_list('prediction_id'),
created_at__gte=created_from,
created_at__lte=created_till,
deleted_at__isnull=True
)
return Response(PredictionSerializer(predictions, many=True).data)
class PredictionHistoryListView(generics.ListAPIView):
permission_classes = [permissions.IsAuthenticated]
serializer_class = PredictionListSerializer
def get_queryset(self):
return Prediction.objects.filter(
id__in=UserPrediction.objects.filter(user=self.request.user).values_list('prediction_id', flat=True),
deleted_at__isnull=True
)
class PredictionHistoryDetailView(generics.RetrieveAPIView):
permission_classes = [permissions.IsAuthenticated]
serializer_class = PredictionDetailSerializer
def get_queryset(self):
return Prediction.objects.filter(
id__in=UserPrediction.objects.filter(user=self.request.user).values_list('prediction_id', flat=True),
deleted_at__isnull=True
)
class PredictionHistoryDeleteView(generics.DestroyAPIView):
permission_classes = [permissions.IsAuthenticated]
def get_queryset(self):
return Prediction.objects.filter(
id__in=UserPrediction.objects.filter(user=self.request.user).values_list('prediction_id', flat=True),
deleted_at__isnull=True
)
def perform_destroy(self, instance):
instance.deleted_at = timezone.now()
instance.save()
class TelemetryListCreateView(generics.ListCreateAPIView):
serializer_class = TelemetryPacketSerializer
permission_classes = [permissions.AllowAny]
def get_queryset(self):
qs = TelemetryPacket.objects.filter(satellite_id=self.kwargs["pk"])
from_ts = self.request.query_params.get("from")
till_ts = self.request.query_params.get("till")
if from_ts:
qs = qs.filter(timestamp__gte=int(from_ts))
if till_ts:
qs = qs.filter(timestamp__lte=int(till_ts))
return qs.order_by("-timestamp")
def post(self, request, pk):
serializer = TelemetryPacketSerializer(data=request.data)
if not serializer.is_valid():
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
validated_data = serializer.validated_data
TelemetryPacket.objects.create(timestamp = time.time(),
satellite=Satellite.objects.get(id=pk),
lat=validated_data["lat"],
lon=validated_data["lon"],
alt=validated_data["alt"],
payload=validated_data['payload'],
)
return Response(serializer.errors, status=status.HTTP_201_CREATED)
class SessionView(APIView):
authentication_classes = [SessionAuthentication, BasicAuthentication]
permission_classes = [IsAuthenticated]
@staticmethod
def get(request, format=None):
return JsonResponse({'isAuthenticated': True})
class WhoAmIView(APIView):
authentication_classes = [SessionAuthentication, BasicAuthentication]
permission_classes = [IsAuthenticated]
@staticmethod
def get(request, format=None):
return JsonResponse({'username': request.user.username})
def get_csrf(request):
response = JsonResponse({'detail': 'CSRF cookie set'})
response['X-CSRFToken'] = get_token(request)
return response
def login_view(request):
data = json.loads(request.body)
username = data.get('username')
password = data.get('password')
if username is None or password is None:
return JsonResponse({'detail': 'Please provide username and password.'}, status=400)
user = authenticate(username=username, password=password)
if user is None:
return JsonResponse({'detail': 'Invalid credentials.'}, status=400)
login(request, user)
return JsonResponse({'detail': 'Successfully logged in.'})
def logout_view(request):
if not request.user.is_authenticated:
return JsonResponse({'detail': 'You\'re not logged in.'}, status=400)
logout(request)
return JsonResponse({'detail': 'Successfully logged out.'})
#class PredictionCreateView(APIView):
#permission_classes = [IsAuthenticated]
# class TelemetryPacket(models.Model):
# id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
# satellite = models.ForeignKey(Satellite, on_delete=models.CASCADE, related_name="telemetry")
# timestamp = models.BigIntegerField() # unix time
# lat = models.FloatField()
# lon = models.FloatField()
# alt = models.FloatField()
# payload = models.JSONField(null=True, blank=True)
# created_at = models.DateTimeField(auto_now_add=True)
# fields = ['id', 'timestamp', 'lat', 'lon', 'alt', 'payload']