mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2025-10-27 08:49:27 +00:00
Implement spot API filtering
This commit is contained in:
@@ -69,13 +69,45 @@ class WebServer:
|
|||||||
# Utility method to apply filters to the overall spot list and return only a subset. Enables query parameters in
|
# Utility method to apply filters to the overall spot list and return only a subset. Enables query parameters in
|
||||||
# the main "spots" GET call. The "query" parameter should be the result of bottle's request.query, and is a MultiDict
|
# the main "spots" GET call. The "query" parameter should be the result of bottle's request.query, and is a MultiDict
|
||||||
def get_spot_list_with_filters(self, query):
|
def get_spot_list_with_filters(self, query):
|
||||||
spot_subset = self.spot_list[:]
|
# Create a shallow copy of the spot list, ordered by spot time. We'll then filter it accordingly.
|
||||||
|
# We can filter by spot time and received time with "since" and "received_since", which take a UNIX timestamp
|
||||||
|
# in seconds UTC.
|
||||||
|
# We can also filter by source, sig, band, mode, dx_continent and de_continent. Each of these accepts a single
|
||||||
|
# value or a comma-separated list.
|
||||||
|
# We can provide a "limit" number as well. Spots are always returned newest-first; "limit" limits to only the
|
||||||
|
# most recent X spots.
|
||||||
|
spots = sorted(self.spot_list, key=lambda spot: spot.time, reverse=True)
|
||||||
for k in query.keys():
|
for k in query.keys():
|
||||||
print(k + ": " + query.get(k))
|
match k:
|
||||||
return spot_subset
|
case "since":
|
||||||
|
since = datetime.fromtimestamp(int(query.get(k)), pytz.UTC)
|
||||||
|
spots = [s for s in spots if s.time > since]
|
||||||
|
case "received_since":
|
||||||
|
since = datetime.fromtimestamp(int(query.get(k)), pytz.UTC)
|
||||||
|
spots = [s for s in spots if s.received_time > since]
|
||||||
|
case "source":
|
||||||
|
sources = query.get(k).split(",")
|
||||||
|
spots = [s for s in spots if s.source in sources]
|
||||||
|
case "sig":
|
||||||
|
sigs = query.get(k).split(",")
|
||||||
|
spots = [s for s in spots if s.sig in sigs]
|
||||||
|
case "band":
|
||||||
|
bands = query.get(k).split(",")
|
||||||
|
spots = [s for s in spots if s.band in bands]
|
||||||
|
case "mode":
|
||||||
|
modes = query.get(k).split(",")
|
||||||
|
spots = [s for s in spots if s.mode in modes]
|
||||||
|
case "dx_continent":
|
||||||
|
dxconts = query.get(k).split(",")
|
||||||
|
spots = [s for s in spots if s.dx_continent in dxconts]
|
||||||
|
case "de_continent":
|
||||||
|
deconts = query.get(k).split(",")
|
||||||
|
spots = [s for s in spots if s.de_continent in deconts]
|
||||||
|
# If we have a "limit" parameter, we apply that last, regardless of where it appeared in the list of keys.
|
||||||
|
if "limit" in query.keys():
|
||||||
|
spots = spots[:int(query.get("limit"))]
|
||||||
|
return spots
|
||||||
|
|
||||||
|
|
||||||
|
# Todo serve Server-Sent Events to frontend? - see https://medium.com/@tdenton8772/streaming-api-design-using-python-and-javascript-1b0ce8adb703
|
||||||
|
|
||||||
# Todo serve Server-Sent Events to frontend - see https://medium.com/@tdenton8772/streaming-api-design-using-python-and-javascript-1b0ce8adb703
|
|
||||||
# Todo serve apidocs
|
# Todo serve apidocs
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
// TODO get all data into JS on first load
|
// TODO get all data into JS on first load
|
||||||
// TODO subscribe to SSE to get updates, merge with local data, sort, refresh display
|
|
||||||
// TODO cap at a sensible number of lines in the table, throw away other data, make the number configurable
|
|
||||||
// TODO populate table more nicely
|
// TODO populate table more nicely
|
||||||
// TODO filtering (applied locally)
|
// TODO filtering & limit (applied via new request to server)
|
||||||
// TODO look and feel
|
// TODO look and feel
|
||||||
|
|
||||||
$.getJSON('/api/spots', function(jsonData) {
|
$.getJSON('/api/spots', function(jsonData) {
|
||||||
|
|||||||
Reference in New Issue
Block a user