1
0
Fork 0
satnogs-network/network/base/utils.py

141 lines
4.7 KiB
Python

"""Miscellaneous functions for SatNOGS Network"""
from __future__ import absolute_import, division
import csv
from builtins import str
from datetime import datetime
import requests # pylint: disable=C0412
from django.conf import settings
from django.contrib.admin.helpers import label_for_field
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.utils.text import slugify
from requests.exceptions import RequestException
from network.base.models import DemodData
def export_as_csv(modeladmin, request, queryset):
"""Exports admin panel table in csv format"""
if not request.user.is_staff:
raise PermissionDenied
field_names = modeladmin.list_display
if 'action_checkbox' in field_names:
field_names.remove('action_checkbox')
response = HttpResponse(content_type="text/csv")
response['Content-Disposition'] = 'attachment; filename={}.csv'.format(
str(modeladmin.model._meta).replace('.', '_')
)
writer = csv.writer(response)
headers = []
for field_name in list(field_names):
label = label_for_field(field_name, modeladmin.model, modeladmin)
if label.islower():
label = label.title()
headers.append(label)
writer.writerow(headers)
for row in queryset:
values = []
for field in field_names:
try:
value = (getattr(row, field))
except AttributeError:
value = (getattr(modeladmin, field))
if callable(value):
try:
# get value from model
value = value()
except TypeError:
# get value from modeladmin e.g: admin_method_1
value = value(row)
if value is None:
value = ''
values.append(str(value))
writer.writerow(values)
return response
def export_station_status(self, request, queryset):
"""Exports status of selected stations in csv format"""
meta = self.model._meta
field_names = ["id", "status"]
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta)
writer = csv.writer(response)
writer.writerow(field_names)
for obj in queryset:
writer.writerow([getattr(obj, field) for field in field_names])
return response
def sync_demoddata_to_db(frame_id):
"""
Task to send a frame from SatNOGS Network to SatNOGS DB
Raises requests.exceptions.RequestException if sync fails."""
frame = DemodData.objects.get(id=frame_id)
obs = frame.observation
sat = obs.satellite
ground_station = obs.ground_station
# need to abstract the timestamp from the filename. hacky..
file_datetime = frame.payload_demod.name.split('/')[2].split('_')[2]
frame_datetime = datetime.strptime(file_datetime, '%Y-%m-%dT%H-%M-%S')
submit_datetime = datetime.strftime(frame_datetime, '%Y-%m-%dT%H:%M:%S.000Z')
# SiDS parameters
params = {
'noradID': sat.norad_cat_id,
'source': ground_station.name,
'timestamp': submit_datetime,
'locator': 'longLat',
'longitude': ground_station.lng,
'latitude': ground_station.lat,
'frame': frame.display_payload_hex().replace(' ', ''),
'satnogs_network': 'True' # NOT a part of SiDS
}
telemetry_url = "{}telemetry/".format(settings.DB_API_ENDPOINT)
response = requests.post(telemetry_url, data=params, timeout=settings.DB_API_TIMEOUT)
response.raise_for_status()
frame.copied_to_db = True
frame.save()
def community_get_discussion_details(
observation_id, satellite_name, norad_cat_id, observation_url
):
"""
Return the details of a discussion of the observation (if existent) in the
satnogs community (discourse)
"""
discussion_url = ('https://community.libre.space/new-topic?title=Observation {0}: {1}'
' ({2})&body=Regarding [Observation {0}]({3}) ...'
'&category=observations') \
.format(observation_id, satellite_name, norad_cat_id, observation_url)
discussion_slug = 'https://community.libre.space/t/observation-{0}-{1}-{2}' \
.format(observation_id, slugify(satellite_name),
norad_cat_id)
try:
response = requests.get(
'{}.json'.format(discussion_slug), timeout=settings.COMMUNITY_TIMEOUT
)
response.raise_for_status()
has_comments = (response.status_code == 200)
except RequestException:
# Community is unreachable
has_comments = False
return {'url': discussion_url, 'slug': discussion_slug, 'has_comments': has_comments}