diff --git a/db/api/filters.py b/db/api/filters.py index 0c16fcd..e52e229 100644 --- a/db/api/filters.py +++ b/db/api/filters.py @@ -1,5 +1,6 @@ """SatNOGS DB django rest framework Filters class""" import django_filters +from django_filters import Filter from django_filters import rest_framework as filters from django_filters.rest_framework import FilterSet @@ -7,6 +8,18 @@ from db.base.models import SATELLITE_STATUS, Artifact, DemodData, LatestTleSet, Transmitter +class ListFilter(Filter): + """Custom Filter to use list""" + def filter(self, qs, value): + """Returns a QuerySet using list of values as input""" + if value: + value_list = value.replace(' ', '').split(u',') + kwargs = {'{0}__in'.format(self.field_name): value_list} + return qs.filter(**kwargs) + + return qs + + class TransmitterViewFilter(FilterSet): """SatNOGS DB Transmitter API View Filter""" alive = filters.BooleanFilter(field_name='status', label='Alive', method='filter_status') @@ -27,6 +40,39 @@ class TransmitterViewFilter(FilterSet): satellite__norad_cat_id = filters.NumberFilter( field_name='satellite__satellite_entry__norad_cat_id', label='Satellite NORAD ID' ) + sat_id = django_filters.CharFilter( + method='get_current_sat_transmitter_from_sat_id', label='Satellite ID' + ) + + # pylint: disable=W0613,R0201 + def get_current_sat_transmitter_from_sat_id(self, queryset, field_name, value): + """Return the transmitter from the parent satellite in case a merged + + satellite id is searched + """ + if value: + id_list = value.replace(' ', '').split(u',') + parent_id_list = [] + + qs = Satellite.objects.select_related('associated_satellite').filter( + satellite_entry__approved=True, satellite_identifier__sat_id__in=id_list + ) + + try: + sats = qs.all() + for sat in sats: + if sat.associated_satellite is None: + parent_id_list.append(sat.id) + else: + parent_id_list.append(sat.associated_satellite.id) + except Satellite.DoesNotExist: + return qs + + return Transmitter.objects.select_related('satellite__associated_satellite').filter( + satellite__satellite_entry__approved=True, satellite__id__in=parent_id_list + ) + + return queryset class Meta: model = Transmitter @@ -52,6 +98,31 @@ class SatelliteViewFilter(FilterSet): norad_cat_id = filters.NumberFilter( field_name='satellite_entry__norad_cat_id', label='Satellite NORAD ID' ) + sat_id = django_filters.CharFilter(method='get_current_sat_from_sat_id', label='Satellite ID') + + # pylint: disable=W0613,R0201 + def get_current_sat_from_sat_id(self, queryset, field_name, value): + """Return the parent Satellite in case a merged + + satellite id is searched + """ + if value: + qs = Satellite.objects.select_related('associated_satellite').filter( + satellite_entry__approved=True, satellite_identifier__sat_id=value + ) + try: + sat = qs.get() + if sat.associated_satellite is None: + return qs + + qs = Satellite.objects.filter( + satellite_entry__approved=True, id=sat.associated_satellite.id + ) + return qs + except Satellite.DoesNotExist: + return qs + + return queryset class Meta: model = Satellite @@ -65,6 +136,7 @@ class TelemetryViewFilter(FilterSet): lookup_expr='exact', label='Satellite NORAD ID' ) + sat_id = ListFilter(field_name='satellite__satellite_identifier__sat_id', label='Satellite ID') start = django_filters.IsoDateTimeFilter(field_name='timestamp', lookup_expr='gte') end = django_filters.IsoDateTimeFilter(field_name='timestamp', lookup_expr='lte') @@ -80,6 +152,7 @@ class LatestTleSetViewFilter(FilterSet): lookup_expr='exact', label='Satellite NORAD ID' ) + sat_id = ListFilter(field_name='satellite__satellite_identifier__sat_id', label='Satellite ID') class Meta: model = LatestTleSet diff --git a/db/api/views.py b/db/api/views.py index 584ec22..9ed8654 100644 --- a/db/api/views.py +++ b/db/api/views.py @@ -278,7 +278,7 @@ class TransmitterViewSet( # pylint: disable=R0901 ] parser_classes = [JSONLDParser] queryset = Transmitter.objects.filter( - satellite__associated_satellite__isnull=True, satellite__satellite_entry__approved=True + satellite__satellite_entry__approved=True, satellite__associated_satellite__isnull=True ).exclude(status='invalid') serializer_class = serializers.TransmitterSerializer filterset_class = filters.TransmitterViewFilter