Compare commits
2 commits
b49adc60f5
...
efcfe06198
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
efcfe06198 | ||
|
|
8f61eb0834 |
8 changed files with 212 additions and 32 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,6 +1,8 @@
|
||||||
# Python
|
# Python
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
**/__pycache__/**
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
|
*pyc
|
||||||
*.pyo
|
*.pyo
|
||||||
*.pyd
|
*.pyd
|
||||||
*.so
|
*.so
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from .models import User, Prediction, UserPrediction, Satellite, TelemetryPacket
|
from .models import User, Prediction, Satellite, TelemetryPacket
|
||||||
|
|
||||||
admin.site.register(User)
|
admin.site.register(User)
|
||||||
admin.site.register(Prediction)
|
admin.site.register(Prediction)
|
||||||
admin.site.register(UserPrediction)
|
|
||||||
admin.site.register(Satellite)
|
admin.site.register(Satellite)
|
||||||
admin.site.register(TelemetryPacket)
|
admin.site.register(TelemetryPacket)
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
# Generated by Django 4.2.23 on 2025-06-25 11:17
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('api', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='PreditctionTemplate',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=100)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('template_data', models.JSONField(blank=True, default=dict)),
|
||||||
|
('is_default', models.BooleanField(default=False)),
|
||||||
|
('user', models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'unique_together': {('user', 'name')},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='SavedPoint',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=100)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('lat', models.FloatField(default=0.0)),
|
||||||
|
('lon', models.FloatField(default=0.0)),
|
||||||
|
('alt', models.FloatField(default=0.0)),
|
||||||
|
('is_default', models.BooleanField(default=False)),
|
||||||
|
('user', models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'unique_together': {('user', 'name')},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='SavedRateProfile',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=100)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('rate_profile_data', models.JSONField(blank=True, default=dict)),
|
||||||
|
('is_default', models.BooleanField(default=False)),
|
||||||
|
('user', models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'unique_together': {('user', 'name')},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='prediction',
|
||||||
|
name='deleted_at',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='prediction',
|
||||||
|
name='request',
|
||||||
|
field=models.JSONField(default=dict),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='prediction',
|
||||||
|
name='user',
|
||||||
|
field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, related_name='predictions', to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='satellite',
|
||||||
|
name='created_at',
|
||||||
|
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='satellite',
|
||||||
|
name='image',
|
||||||
|
field=models.ImageField(blank=True, null=True, upload_to='satellite_images/'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='satellite',
|
||||||
|
name='metadata',
|
||||||
|
field=models.JSONField(blank=True, default=dict),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='satellite',
|
||||||
|
name='user',
|
||||||
|
field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='telemetrypacket',
|
||||||
|
name='raw_data',
|
||||||
|
field=models.JSONField(blank=True, default=dict),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='telemetrypacket',
|
||||||
|
name='user',
|
||||||
|
field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='prediction',
|
||||||
|
name='result',
|
||||||
|
field=models.JSONField(default=dict),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='telemetrypacket',
|
||||||
|
name='alt',
|
||||||
|
field=models.FloatField(default=0.0),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='telemetrypacket',
|
||||||
|
name='lat',
|
||||||
|
field=models.FloatField(default=0.0),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='telemetrypacket',
|
||||||
|
name='lon',
|
||||||
|
field=models.FloatField(default=0.0),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='telemetrypacket',
|
||||||
|
name='payload',
|
||||||
|
field=models.JSONField(blank=True, default=dict),
|
||||||
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='UserPrediction',
|
||||||
|
),
|
||||||
|
]
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -1,36 +1,87 @@
|
||||||
import uuid
|
import uuid
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth.models import AbstractUser
|
from django.contrib.auth.models import AbstractUser, AnonymousUser
|
||||||
|
|
||||||
|
|
||||||
class User(AbstractUser):
|
class User(AbstractUser):
|
||||||
satellites = models.ManyToManyField("Satellite", related_name="users")
|
satellites = models.ManyToManyField("Satellite", related_name="users")
|
||||||
|
|
||||||
|
|
||||||
class Prediction(models.Model):
|
class Prediction(models.Model):
|
||||||
satellite = models.ForeignKey('Satellite', on_delete=models.CASCADE, related_name='predictions', null=True)
|
user = models.ForeignKey(get_user_model(
|
||||||
|
), on_delete=models.CASCADE, default=0, related_name='predictions')
|
||||||
|
satellite = models.ForeignKey(
|
||||||
|
'Satellite', on_delete=models.CASCADE, related_name='predictions', null=True)
|
||||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
result = models.JSONField()
|
request = models.JSONField(default=dict)
|
||||||
deleted_at = models.DateTimeField(null=True, blank=True)
|
result = models.JSONField(default=dict)
|
||||||
|
|
||||||
|
|
||||||
class UserPrediction(models.Model):
|
|
||||||
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
|
|
||||||
prediction = models.ForeignKey("Prediction", on_delete=models.CASCADE)
|
|
||||||
created_at = models.DateTimeField()
|
|
||||||
|
|
||||||
class Satellite(models.Model):
|
class Satellite(models.Model):
|
||||||
|
user = models.ForeignKey(
|
||||||
|
get_user_model(), on_delete=models.CASCADE, default=0)
|
||||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||||
name = models.CharField(max_length=100)
|
name = models.CharField(max_length=100)
|
||||||
|
metadata = models.JSONField(blank=True, default=dict)
|
||||||
|
image = models.ImageField(
|
||||||
|
upload_to='satellite_images/', blank=True, null=True)
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
|
||||||
class TelemetryPacket(models.Model):
|
class TelemetryPacket(models.Model):
|
||||||
|
user = models.ForeignKey(
|
||||||
|
get_user_model(), on_delete=models.CASCADE, default=0)
|
||||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||||
satellite = models.ForeignKey(Satellite, on_delete=models.CASCADE, related_name="telemetry")
|
satellite = models.ForeignKey(
|
||||||
|
Satellite, on_delete=models.CASCADE, related_name="telemetry")
|
||||||
timestamp = models.BigIntegerField() # unix time
|
timestamp = models.BigIntegerField() # unix time
|
||||||
lat = models.FloatField()
|
lat = models.FloatField(default=0.0)
|
||||||
lon = models.FloatField()
|
lon = models.FloatField(default=0.0)
|
||||||
alt = models.FloatField()
|
alt = models.FloatField(default=0.0)
|
||||||
payload = models.JSONField(null=True, blank=True)
|
payload = models.JSONField(blank=True, default=dict)
|
||||||
|
raw_data = models.JSONField(blank=True, default=dict)
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
|
||||||
|
class PreditctionTemplate(models.Model):
|
||||||
|
user = models.ForeignKey(
|
||||||
|
get_user_model(), on_delete=models.CASCADE, default=0)
|
||||||
|
name = models.CharField(max_length=100)
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
template_data = models.JSONField(blank=True, default=dict)
|
||||||
|
is_default = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = ('user', 'name')
|
||||||
|
|
||||||
|
|
||||||
|
class SavedPoint(models.Model):
|
||||||
|
user = models.ForeignKey(
|
||||||
|
get_user_model(), on_delete=models.CASCADE, default=0)
|
||||||
|
name = models.CharField(max_length=100)
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
lat = models.FloatField(default=0.0)
|
||||||
|
lon = models.FloatField(default=0.0)
|
||||||
|
alt = models.FloatField(default=0.0)
|
||||||
|
is_default = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = ('user', 'name')
|
||||||
|
|
||||||
|
|
||||||
|
class SavedRateProfile(models.Model):
|
||||||
|
user = models.ForeignKey(
|
||||||
|
get_user_model(), on_delete=models.CASCADE, default=0)
|
||||||
|
name = models.CharField(max_length=100)
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
rate_profile_data = models.JSONField(blank=True, default=dict)
|
||||||
|
is_default = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = ('user', 'name')
|
||||||
21
api/views.py
21
api/views.py
|
|
@ -2,7 +2,7 @@ from rest_framework import status, generics, permissions
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from .models import Prediction, User, UserPrediction
|
from .models import Prediction, User
|
||||||
from .serializers import PredictionSerializer, PredictionRequestSerializer, PredictionListSerializer, PredictionDetailSerializer
|
from .serializers import PredictionSerializer, PredictionRequestSerializer, PredictionListSerializer, PredictionDetailSerializer
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
import requests
|
import requests
|
||||||
|
|
@ -57,8 +57,7 @@ class PredictionCreateView(APIView):
|
||||||
print("Tawhiri error:", str(e), e.response.text if e.response else "no response")
|
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)
|
return Response({"error": f"Tawhiri error: {str(e)}"}, status=status.HTTP_502_BAD_GATEWAY)
|
||||||
|
|
||||||
prediction = Prediction.objects.create(result=prediction_result)
|
prediction = Prediction.objects.create(result=prediction_result, user=request.user, request=validated_data)
|
||||||
UserPrediction.objects.create(user=request.user, prediction=prediction, created_at=timezone.now())
|
|
||||||
return Response({
|
return Response({
|
||||||
"id": prediction.id,
|
"id": prediction.id,
|
||||||
"created_at": prediction.created_at,
|
"created_at": prediction.created_at,
|
||||||
|
|
@ -80,7 +79,7 @@ class PredictionListView(APIView):
|
||||||
return Response({'detail': 'Access to this satellite is forbidden.'}, status=403)
|
return Response({'detail': 'Access to this satellite is forbidden.'}, status=403)
|
||||||
|
|
||||||
filters = {
|
filters = {
|
||||||
'id__in': UserPrediction.objects.filter(user=user).values_list('prediction_id', flat=True),
|
'id__in': Prediction.objects.filter(user=user).values_list('prediction_id', flat=True),
|
||||||
'deleted_at__isnull': True
|
'deleted_at__isnull': True
|
||||||
}
|
}
|
||||||
print(filters)
|
print(filters)
|
||||||
|
|
@ -103,8 +102,7 @@ class PredictionHistoryListView(generics.ListAPIView):
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return Prediction.objects.filter(
|
return Prediction.objects.filter(
|
||||||
id__in=UserPrediction.objects.filter(user=self.request.user).values_list('prediction_id', flat=True),
|
user=self.request.user,
|
||||||
deleted_at__isnull=True
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -115,8 +113,7 @@ class PredictionHistoryDetailView(generics.RetrieveAPIView):
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return Prediction.objects.filter(
|
return Prediction.objects.filter(
|
||||||
id__in=UserPrediction.objects.filter(user=self.request.user).values_list('prediction_id', flat=True),
|
user=self.request.user,
|
||||||
deleted_at__isnull=True
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -126,15 +123,9 @@ class PredictionHistoryDeleteView(generics.DestroyAPIView):
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return Prediction.objects.filter(
|
return Prediction.objects.filter(
|
||||||
id__in=UserPrediction.objects.filter(user=self.request.user).values_list('prediction_id', flat=True),
|
user=self.request.user,
|
||||||
deleted_at__isnull=True
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def perform_destroy(self, instance):
|
|
||||||
instance.deleted_at = timezone.now()
|
|
||||||
instance.save()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TelemetryListCreateView(generics.ListCreateAPIView):
|
class TelemetryListCreateView(generics.ListCreateAPIView):
|
||||||
serializer_class = TelemetryPacketSerializer
|
serializer_class = TelemetryPacketSerializer
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,5 @@ psycopg2-binary
|
||||||
drf-spectacular
|
drf-spectacular
|
||||||
requests
|
requests
|
||||||
django-cors-headers
|
django-cors-headers
|
||||||
|
Pillow
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue