Allow spots and alerts to have multiple activities #143

This commit is contained in:
Ian Renton
2026-09-24 22:57:46 +01:00
parent 81166dccab
commit 4477942bec
34 changed files with 217 additions and 157 deletions
+19 -23
View File
@@ -142,24 +142,19 @@ class APISpotHandler(tornado.web.RequestHandler):
self.set_header("Content-Type", "application/json")
return
# Reject if activity ref format incorrect for activity
if (
spot.activity
and spot.activity_refs
and len(spot.activity_refs) > 0
and spot.activity_refs[0].id
and get_ref_regex_for_activity(spot.activity)
and not re.match(get_ref_regex_for_activity(spot.activity), spot.activity_refs[0].id)
):
self.set_status(422)
self.write(
safe_json_dumps(
f"Error - '{spot.activity_refs[0].id}' does not look like a valid reference for {spot.activity}."
# Reject if any activity ref format is incorrect for its activity
for activity_ref in spot.activity_refs:
ref_regex = get_ref_regex_for_activity(activity_ref.activity) if activity_ref.activity else None
if activity_ref.id and ref_regex and not re.match(ref_regex, activity_ref.id):
self.set_status(422)
self.write(
safe_json_dumps(
f"Error - '{activity_ref.id}' does not look like a valid reference for {activity_ref.activity}."
)
)
)
self.set_header("Cache-Control", "no-store")
self.set_header("Content-Type", "application/json")
return
self.set_header("Cache-Control", "no-store")
self.set_header("Content-Type", "application/json")
return
# Reject upstream submission if not permitted
if submit_upstream and not ALLOW_UPSTREAM_SPOTTING:
@@ -171,7 +166,8 @@ class APISpotHandler(tornado.web.RequestHandler):
# Validate upstream submission requirements
if submit_upstream and upstream_provider_name:
if not spot.activity:
if not spot.activities:
# TODO when we allow spotting to cluster upstream, we need to remove this restriction
self.set_status(422)
self.write(safe_json_dumps("Error - an activity must be selected to submit upstream."))
self.set_header("Cache-Control", "no-store")
@@ -201,7 +197,7 @@ class APISpotHandler(tornado.web.RequestHandler):
# Submit upstream if requested
upstream_warning = None
if submit_upstream and upstream_provider_name:
provider = self._find_provider(upstream_provider_name, spot.activity)
provider = self._find_provider(upstream_provider_name, spot.activities)
if provider:
try:
# Submit spot to the upstream provider
@@ -216,7 +212,7 @@ class APISpotHandler(tornado.web.RequestHandler):
f"Spot was saved locally but upstream submission to {upstream_provider_name} failed."
)
else:
upstream_warning = f"No enabled provider named '{upstream_provider_name}' supports upstream submission for {spot.activity if spot.activity else ''} spots."
upstream_warning = f"No enabled provider named '{upstream_provider_name}' supports upstream submission for {', '.join(spot.activities)} spots."
# If we successfully submitted the spot upstream, don't add it direct to Spothole, otherwise it will be a
# duplicate with what immediately comes back from the API. But if we weren't asked to send it upstream, or
@@ -242,11 +238,11 @@ class APISpotHandler(tornado.web.RequestHandler):
self.set_header("Cache-Control", "no-store")
self.set_header("Content-Type", "application/json")
def _find_provider(self, provider_name, activity) -> SpotProvider | None:
"""Find an enabled provider by name that can submit spots for the given activity."""
def _find_provider(self, provider_name, activities) -> SpotProvider | None:
"""Find an enabled provider by name that can submit spots for at least one of the given activities."""
for p in self._spot_providers:
if p.enabled and p.name == provider_name and p.can_submit_spot(activity):
if p.enabled and p.name == provider_name and any(p.can_submit_spot(a) for a in activities):
return p
return None