From e9733266684cb2d74840735100298647f3de5c99 Mon Sep 17 00:00:00 2001 From: Jorrit Schaap <schaap@astron.nl> Date: Tue, 16 Jan 2024 16:01:15 +0100 Subject: [PATCH] TMSS-2886: added public '/schedule' endpoint to get the current schedule --- SAS/TMSS/backend/src/tmss/tmssapp/views.py | 72 +++++++++++++++++++++- SAS/TMSS/backend/src/tmss/urls.py | 3 +- 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/views.py b/SAS/TMSS/backend/src/tmss/tmssapp/views.py index c529071eaf5..6be8abb8cb6 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/views.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/views.py @@ -7,7 +7,7 @@ from django.http import HttpResponse, JsonResponse, Http404, FileResponse, HttpR from rest_framework.response import Response as RestResponse from rest_framework import status from django.shortcuts import get_object_or_404, render -from lofar.sas.tmss.tmss.tmssapp import models +from lofar.sas.tmss.tmss.tmssapp import models, serializers from lofar.common.json_utils import get_default_json_object_for_schema from lofar.common.util import single_line_with_single_spaces from lofar.sas.tmss.tmss.tmssapp.adapters.parset import convert_to_parset @@ -747,4 +747,72 @@ def failure_report(request): return RestResponse('Error: please specify an isoformat timestamp for stop_time', status=400) result = create_failure_report(start, stop, ignore_time_range_for_histogram) - return JsonResponse(result, status=status.HTTP_200_OK) \ No newline at end of file + return JsonResponse(result, status=status.HTTP_200_OK) + + +@permission_classes([AllowAny]) +@authentication_classes([AllowAny]) +@swagger_auto_schema(responses={200: 'A json list of the current public schedule.'}, + operation_description="Get a json list of the current public schedule.") +def public_schedule(request): + '''return the current and future running and scheduled units in either html table or json depending on the request accept header''' + # get all current and future running and scheduled units + scheduled_or_running_units = models.SchedulingUnitBlueprint.objects.filter(status__value__in=models.SchedulingUnitStatus.ACTIVE_STATUS_VALUES) \ + .filter(obsolete_since__isnull=True) \ + .filter(on_sky_stop_time__gte=datetime.utcnow()) \ + .order_by('on_sky_start_time').all() + + if 'html' in request.headers.get('Accept','').lower(): + base_url = request._current_scheme_host + table_rows = '''<tr><th>Project</th><th>ID</th><th>Status</th><th>Start [UTC]</th><th>End [UTC]</th><th>Duration [min]</th><th>Center [LST]</th><th>Target(s)</th></tr>\n''' + table_rows += '\n'.join(['''<tr><td><a href="%s/project/view/%s">%s</a></td><td><a href="%s/schedulingunit/view/blueprint/%s">%s</a></td><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td></tr>\n''' % ( + base_url, su.project, su.project, + base_url, su.id, su.id, + su.status.value, + su.on_sky_start_time.strftime('%Y-%m-%d %H:%M') if su.on_sky_start_time else '', + su.on_sky_stop_time.strftime('%Y-%m-%d %H:%M') if su.on_sky_stop_time else '', + round(su.on_sky_duration.total_seconds()/60.0), + su.main_observation_scheduled_central_lst.strftime('%H:%M') if su.main_observation_scheduled_central_lst else '', + su.target_pointings_astropy) for su in scheduled_or_running_units]) + html_doc = '''<!DOCTYPE html> + <html> + <head> + <style> + table { + border-collapse: collapse; + height: 100%%; + width: 100%%; + } + th { + background-color: #AAAAAA; + font-weight: bold; + text-align: left; + } + tr:nth-child(even) { + background-color: #EEEEEE; + } + tr:nth-child(odd) { + background-color: #CCCCCC; + } + tr:hover { + background-color: #DDDDDD; + } + </style> + <title>LOFAR observing schedule</title> + </head> + <body> + <table> + %s + </table> + </body> + </html> + ''' % (table_rows,) + + return HttpResponse(html_doc, content_type='text/html') + + if 'json' in request.headers.get('Accept','').lower(): + result = serializers.SchedulingUnitBlueprintPublicSerializer(scheduled_or_running_units, many=True, context={'request': request}).data + return JsonResponse(result, status=status.HTTP_200_OK, safe=False) + + return HttpResponseServerError() + diff --git a/SAS/TMSS/backend/src/tmss/urls.py b/SAS/TMSS/backend/src/tmss/urls.py index 1917123caf8..51c1d660121 100644 --- a/SAS/TMSS/backend/src/tmss/urls.py +++ b/SAS/TMSS/backend/src/tmss/urls.py @@ -268,7 +268,8 @@ frontend_urlpatterns = [ urlpatterns = [url(r'^api$', RedirectView.as_view(url='/api/')), url(r'^api/', include(urlpatterns)), url(r'^oidc$', RedirectView.as_view(url='/oidc/')), - url(r'^oidc/', include('mozilla_django_oidc.urls')), + url(r'^oidc/', include('mozilla_django_oidc.urls')), + url(r'^schedule', views.public_schedule), url(r'', include(frontend_urls)), url(r'^.*', include(frontend_urlpatterns)), ] -- GitLab