""" Data entry view for satellite points. """ import json import re from datetime import datetime from django.contrib.auth.mixins import LoginRequiredMixin from django.db.models import Q from django.http import JsonResponse from django.shortcuts import render from django.views import View from ..models import ObjItem, Satellite class DataEntryView(LoginRequiredMixin, View): """ View for data entry form with Tabulator table. """ def get(self, request): # Get satellites that have points satellites = Satellite.objects.filter( parameters__objitem__isnull=False ).distinct().order_by('name') context = { 'satellites': satellites, "full_width_page": True } return render(request, 'mainapp/data_entry.html', context) class SearchObjItemAPIView(LoginRequiredMixin, View): """ API endpoint for searching ObjItem by name and coordinates. Returns closest matching ObjItem with all required data. """ def get(self, request): from django.contrib.gis.geos import Point from django.contrib.gis.db.models.functions import Distance name = request.GET.get('name', '').strip() satellite_id = request.GET.get('satellite_id', '').strip() latitude = request.GET.get('latitude', '').strip() longitude = request.GET.get('longitude', '').strip() if not name: return JsonResponse({'error': 'Name parameter is required'}, status=400) # Build query query = Q(name__iexact=name) # Add satellite filter if provided if satellite_id: try: sat_id = int(satellite_id) query &= Q(parameter_obj__id_satellite_id=sat_id) except (ValueError, TypeError): pass # Filter ObjItems with geo data query &= Q(geo_obj__coords__isnull=False) # Get queryset objitems = ObjItem.objects.filter(query).select_related( 'parameter_obj', 'parameter_obj__id_satellite', 'parameter_obj__polarization', 'parameter_obj__modulation', 'parameter_obj__standard', 'geo_obj' ).prefetch_related( 'geo_obj__mirrors' ) # If coordinates provided, find closest point if latitude and longitude: try: lat = float(latitude.replace(',', '.')) lon = float(longitude.replace(',', '.')) point = Point(lon, lat, srid=4326) # Order by distance and get closest objitem = objitems.annotate( distance=Distance('geo_obj__coords', point) ).order_by('distance').first() except (ValueError, TypeError): # If coordinate parsing fails, just get first match objitem = objitems.first() else: # No coordinates provided, get first match objitem = objitems.first() if not objitem: return JsonResponse({'found': False}) # Prepare response data data = { 'found': True, 'frequency': None, 'freq_range': None, 'bod_velocity': None, 'modulation': None, 'snr': None, 'mirrors': None, } # Get parameter data if hasattr(objitem, 'parameter_obj') and objitem.parameter_obj: param = objitem.parameter_obj data['frequency'] = param.frequency if param.frequency else None data['freq_range'] = param.freq_range if param.freq_range else None data['bod_velocity'] = param.bod_velocity if param.bod_velocity else None data['modulation'] = param.modulation.name if param.modulation else None data['snr'] = param.snr if param.snr else None # Get mirrors data if hasattr(objitem, 'geo_obj') and objitem.geo_obj: mirrors = objitem.geo_obj.mirrors.all() if mirrors: data['mirrors'] = ', '.join([m.name for m in mirrors]) return JsonResponse(data)