From d3898cae9bfdef9af5d546937c9d7b3505a9ab9f Mon Sep 17 00:00:00 2001
From: jeslefcourt <32883811+jeslefcourt@users.noreply.github.com>
Date: Thu, 21 Nov 2024 09:04:47 -0800
Subject: [PATCH 1/2] Adding error handling for bounding box

---
 app/actions/configurations.py | 27 +++++++++++++++++++++++----
 app/actions/handlers.py       |  2 +-
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/app/actions/configurations.py b/app/actions/configurations.py
index 34792a0..af238ba 100644
--- a/app/actions/configurations.py
+++ b/app/actions/configurations.py
@@ -58,14 +58,33 @@ def validate_json(cls, v):
     def validate_bounding_box(cls, v):
         if(not v):
             raise ValueError("Did not receive a bounding box configuration.")
-        coords = json.loads(v)
-        if(len(coords) != 4):
+        v = json.loads(v)
+        if(len(v) != 4):
             raise ValueError("Did not receive four values in bounding box configuration.")
-        for coord in coords:
+        for i in range(0,4):
             try:
-                float(coord)
+                v[i] = float(v[i])
             except:
                 raise ValueError(f"Could not parse bounding box values {v}.")
+
+        if(v[0] < -90 or v[0] > 90):
+            raise ValueError(f"NE Latitude {v[0]} must be between -90 and 90")
+
+        if(v[1] < -180 or v[1] > 180):
+            raise ValueError(f"NE Longitude {v[1]} must be between -180 and 180")
+        
+        if(v[2] < -90 or v[2] > 90):
+            raise ValueError(f"SW Latitude {v[2]} must be between -90 and 90")
+
+        if(v[3] < -180 or v[3] > 180):
+            raise ValueError(f"SW Longitude {v[2]} must be between -180 and 180")
+        
+        if(v[0] <= v[2]):
+            raise ValueError(f"NE Latitude {v[0]} must be greater than SW Latitude {v[2]}")
+        
+        if(v[1] <= v[3]):
+            raise ValueError(f"NE Longitude {v[1]} must be greater than SW Longitude {v[2]}")
+        
         return v
 
     class Config:
diff --git a/app/actions/handlers.py b/app/actions/handlers.py
index 5a64baf..86aa409 100644
--- a/app/actions/handlers.py
+++ b/app/actions/handlers.py
@@ -47,7 +47,7 @@ def get_inaturalist_observations(integration: Integration, config: PullEventsCon
 
     nelat = nelng = swlat = swlng = None
     if(config.bounding_box):
-        nelat, nelng, swlat, swlng = json.loads(config.bounding_box)
+        nelat, nelng, swlat, swlng = config.bounding_box
 
     target_taxa = []
     for taxa in config.taxa:

From b6545da9cdffe5ba38ff342e7b234018f8fcfb14 Mon Sep 17 00:00:00 2001
From: jeslefcourt <32883811+jeslefcourt@users.noreply.github.com>
Date: Thu, 21 Nov 2024 12:20:44 -0800
Subject: [PATCH 2/2] Changed quality grade to an array instead of a
 comma-separated string.

---
 app/actions/handlers.py | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/app/actions/handlers.py b/app/actions/handlers.py
index 86aa409..736c97f 100644
--- a/app/actions/handlers.py
+++ b/app/actions/handlers.py
@@ -54,17 +54,12 @@ def get_inaturalist_observations(integration: Integration, config: PullEventsCon
         target_taxa.append(str(taxa))
     target_taxa = ",".join(target_taxa)
 
-    quality_grade = []
-    for qg in config.quality_grade:
-        quality_grade.append(str(qg))
-    quality_grade = ",".join(quality_grade)
-
     fields = ",".join(["observed_on", "created_at", "id", "captive", "obscured", "place_guess", "quality_grade", "species_guess", "updated_at", 
                        "uri", "photos", "user", "location", "place_ids", "taxon", "photos.large_url", "photos.url", "taxon.id", "taxon.rank", "taxon.name",
                        "taxon.preferred_common_name", "taxon.wikipedia_url", "taxon.conservation_status", "user.id", "user.name", "user.login",
                        "annotations.controlled_attribute_id", "annotations.controlled_value_id"])
 
-    inat_count_req = get_observations_v2(page = 1, per_page = 0, updated_since = since, project_id = config.projects, quality_grade = quality_grade,
+    inat_count_req = get_observations_v2(page = 1, per_page = 0, updated_since = since, project_id = config.projects, quality_grade = config.quality_grade,
                                       taxon_id=target_taxa, nelat = float(nelat), nelng = float(nelng), swlat = float(swlat), swlng = float(swlng),
                                       order_by = "updated_at", order="asc")
 
@@ -76,7 +71,7 @@ def get_inaturalist_observations(integration: Integration, config: PullEventsCon
         logger.debug(f"Loading page {page} of {pages} from iNaturalist")
 
         response = get_observations_v2(page = page, per_page = 200, updated_since = since, project_id = config.projects,
-                                       quality_grade = quality_grade, taxon_id = target_taxa,
+                                       quality_grade = config.quality_grade, taxon_id = target_taxa,
                                        nelat = nelat, nelng = nelng, swlat = swlat, swlng = swlng,
                                        order_by = 'updated_at', order="asc", fields=fields)