Parcourir la source

Endpoint de confirmacion de envio + retoques

Tomás Ponce Gessi il y a 3 ans
Parent
commit
c8c9833daa
4 fichiers modifiés avec 32 ajouts et 21 suppressions
  1. 3 13
      app/api/models.py
  2. 2 2
      app/api/tasks.py
  3. 5 4
      app/api/urls.py
  4. 22 2
      app/api/views.py

+ 3 - 13
app/api/models.py

@@ -1,9 +1,7 @@
 from django.db import models
 from .validators import json_email_array, json_not_empty_string_array
 from django.utils import timezone
-
-# TODO! Move to ENV file...
-PROGRAMMED_REPORTS_SERVICE_AUTH_TOKEN = "juwiV9MjP4r3NTsvd9qRsPQ2FMdk5soJjxksYKhruza3wskG23h4cygTEPiFAGo2"
+from django.conf import settings
 
 
 class ProgrammedReport(models.Model):
@@ -30,9 +28,6 @@ class ProgrammedReport(models.Model):
         validators=[json_not_empty_string_array, json_email_array])
 
     # Metodo que envía la petición a Clima para enviar el reporte.
-    # TODO! Tecnicamente start_date y end_date podrían ser calculados por el modelo,
-    # hay que ver si hay un caso borde que requiere de que el llamador especifique el rango.
-    # Basicamente: Testear
     def send_report(self, start_date, end_date):
         import requests
         from django.conf import settings
@@ -41,6 +36,7 @@ class ProgrammedReport(models.Model):
         start = start_date.strftime("%d/%m/%Y %H:%M")
         end = end_date.strftime("%d/%m/%Y %H:%M")
         response = requests.post(settings.CLIMA_URL + "/async_report_handler", {
+            "id": self.id,
             "user_id": self.user_id,
             "format": self.format,
             "stations": self.stations,
@@ -49,7 +45,7 @@ class ProgrammedReport(models.Model):
             "start_date": start,
             "end_date": end,
             "notified_emails": self.notified_emails
-        }, headers={"AUTHORIZATION": PROGRAMMED_REPORTS_SERVICE_AUTH_TOKEN})
+        }, headers={"AUTHORIZATION": settings.PROGRAMMED_REPORTS_SERVICE_AUTH_TOKEN})
 
         if response.status_code != 200:
             import logging
@@ -57,9 +53,3 @@ class ProgrammedReport(models.Model):
                 "No se pudo enviar el reporte asincrono: %s\n Reason: %s", self, response.reason)
             # TODO! Seria ideal enviar un email al administrador para ver que paso.
             return False
-
-        # TODO! Si se utiliza una Message Queue para la confirmación del envío entonces
-        # hay que mover esto al listener de la Queue.
-        self.last_report_date = timezone.now()
-        self.save()
-        return True

+ 2 - 2
app/api/tasks.py

@@ -3,15 +3,15 @@ from django.utils import timezone
 
 
 # Task que determina que reportes deben ser enviados:
+# Ejecutado por Cron (Ver settings.py)
 def send_programmed_reports_task():
     timenow = timezone.now()
     for preport in ProgrammedReport.objects.all():
         # Calculamos la fecha en la que debe ser enviado
-        # TODO! Y si se guarda el duedate en el modelo? Puede ser recalculado en cada save()
         duedate = (preport.last_report_date +
                    preport.frequency) if preport.last_report_date is not None else preport.start_report_date
         if timenow > duedate:
-            # Si hay que enviarlo calculamos el rango de envío. (Ver TODO! en el metodo send_report)
+            # Calculamos el rango de envio:
             start_date = preport.last_report_date if preport.last_report_date is not None else preport.start_report_date
             end_date = start_date + preport.frequency
             # Se envía el reporte

+ 5 - 4
app/api/urls.py

@@ -1,8 +1,9 @@
+from django.urls import path
 from rest_framework.routers import SimpleRouter
-from .views import ProgrammedReportViewSet
-
+from .views import ProgrammedReportViewSet, ProgrammedReportSentConfirmation
 
 router = SimpleRouter()
 router.register(r'preports', ProgrammedReportViewSet, "preport")
-
-urlpatterns = router.urls
+urlpatterns = [
+    path(r'preports-confirmation', ProgrammedReportSentConfirmation.as_view())
+] + router.urls

+ 22 - 2
app/api/views.py

@@ -1,7 +1,13 @@
-from rest_framework import viewsets
+from urllib import response
+from rest_framework import viewsets, views
+from rest_framework.response import Response
+from rest_framework.parsers import JSONParser
 from .models import ProgrammedReport
 from .serializers import ProgrammedReportSerializer
 from .permissions import IsOmixomUser
+from django.conf import settings
+from django.utils import timezone
+from rest_framework import status
 
 
 # API de Programmed Reports:
@@ -14,7 +20,7 @@ from .permissions import IsOmixomUser
 #   - (Create) POST /                -> Crear un nuevo Programmed Report
 #   - (Retrieve) GET /{id}/          -> Obtener la informacion de un Programmed Report
 #   - (Update) PUT /{id}/            -> Actualizar un Programmed Report (requiere todos los fields)
-#   - (Partial_Update) PATCH /{id}/  -> Actualizar algunos fields de un Programmed Repor
+#   - (Partial_Update) PATCH /{id}/  -> Actualizar algunos fields de un Programmed Report
 #   - (Delete) DELETE /{id}/         -> Elimina un Programmed Report
 
 class ProgrammedReportViewSet(viewsets.ModelViewSet):
@@ -27,3 +33,17 @@ class ProgrammedReportViewSet(viewsets.ModelViewSet):
         user_id = self.request.data["user_id"]
         qs = ProgrammedReport.objects.filter(user_id=user_id)
         return qs
+
+# Endpoint para la confirmacion de envio de un reporte programado por parte de Clima:
+class ProgrammedReportSentConfirmation(views.APIView):
+    parser_classes = [JSONParser]
+
+    def post(self, request, format=None):
+        if(settings.PROGRAMMED_REPORTS_SERVICE_AUTH_TOKEN != request.META.get("HTTP_AUTHORIZATION")):
+            return Response("Invalid Access Credentials.", status.HTTP_403_FORBIDDEN)
+        report = ProgrammedReport.objects.filter(id=request.data.get("id")).first()
+        if report is None:
+            return Response("Invalid Report.", status.HTTP_400_BAD_REQUEST)
+        report.last_report_date = timezone.now()
+        report.save()
+        return Response("Ok", status.HTTP_200_OK)