From 8878a71c14876c641b4c5f5269dfdbfc2d8f706d Mon Sep 17 00:00:00 2001 From: Paul Bienkowski Date: Thu, 28 Jul 2022 13:54:29 +0200 Subject: [PATCH] Limit map date filter to weeks (mondays) --- api/obs/api/routes/tiles.py | 33 ++++++++++++++++++++- frontend/src/pages/MapPage/LayerSidebar.tsx | 6 ++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/api/obs/api/routes/tiles.py b/api/obs/api/routes/tiles.py index e90d4ee..7d8eb80 100644 --- a/api/obs/api/routes/tiles.py +++ b/api/obs/api/routes/tiles.py @@ -1,8 +1,9 @@ from gzip import decompress from sqlite3 import connect +from datetime import datetime, time, timedelta import dateutil.parser -from sanic.exceptions import Forbidden +from sanic.exceptions import Forbidden, InvalidUsage from sanic.response import raw from sqlalchemy import select, text @@ -31,6 +32,24 @@ def get_tile(filename, zoom, x, y): return content and content[0] or None +def round_date(date, to="weeks", up=False): + if to != "weeks": + raise ValueError(f"cannot round to {to}") + + midnight = time(0, 0, 0, 0) + start_of_day = date.date() # ignore time + weekday = date.weekday() + + is_rounded = date.time() == midnight and weekday == 0 + if is_rounded: + return date + + if up: + return datetime.combine(start_of_day + timedelta(days=7 - weekday), midnight) + else: + return datetime.combine(start_of_day - timedelta(days=weekday), midnight) + + # regenerate approx. once each day TILE_CACHE_MAX_AGE = 3600 * 24 @@ -52,6 +71,18 @@ async def tiles(req, zoom: int, x: int, y: str): start = req.ctx.get_single_arg("start", default=None, convert=parse_date) end = req.ctx.get_single_arg("end", default=None, convert=parse_date) + start = round_date(start, to="weeks", up=False) if start else None + end = round_date(end, to="weeks", up=True) if end else None + + import logging + + logging.info("start end %s %s", start, end) + + if start is not None and end is not None and start >= end: + raise InvalidUsage( + "end date must be later than start date (note: dates are rounded to weeks)" + ) + tile = await req.ctx.db.scalar( text( f"select data from getmvt(:zoom, :x, :y, :user_id, :min_time, :max_time) as b(data, key);" diff --git a/frontend/src/pages/MapPage/LayerSidebar.tsx b/frontend/src/pages/MapPage/LayerSidebar.tsx index 25739e0..329435e 100644 --- a/frontend/src/pages/MapPage/LayerSidebar.tsx +++ b/frontend/src/pages/MapPage/LayerSidebar.tsx @@ -264,6 +264,8 @@ function LayerSidebar({ @@ -279,6 +281,8 @@ function LayerSidebar({ @@ -294,6 +298,8 @@ function LayerSidebar({