diff options
author | Daniel Schadt <kingdread@gmx.de> | 2023-03-31 23:57:59 +0200 |
---|---|---|
committer | Daniel Schadt <kingdread@gmx.de> | 2023-03-31 23:57:59 +0200 |
commit | 114274f900904070e941c4a544426b5d9d1267d2 (patch) | |
tree | 336bd54ac82b85253d62e355684114d2291a8b8e | |
parent | ace7c4ab80e7bd7ac2acdebede6437c56636e7b1 (diff) | |
download | fietsboek-114274f900904070e941c4a544426b5d9d1267d2.tar.gz fietsboek-114274f900904070e941c4a544426b5d9d1267d2.tar.bz2 fietsboek-114274f900904070e941c4a544426b5d9d1267d2.zip |
hide ugliness of tile url function
We basically do the same hacky trick in two different places, so maybe
we should put it into a separate function, test it, and if a better
implementation arises, swap it.
-rw-r--r-- | fietsboek/jinja2.py | 9 | ||||
-rw-r--r-- | fietsboek/util.py | 27 | ||||
-rw-r--r-- | fietsboek/views/profile.py | 25 | ||||
-rw-r--r-- | tests/unit/test_util.py | 9 |
4 files changed, 42 insertions, 28 deletions
diff --git a/fietsboek/jinja2.py b/fietsboek/jinja2.py index a3ca7d8..f5ae7d7 100644 --- a/fietsboek/jinja2.py +++ b/fietsboek/jinja2.py @@ -9,6 +9,8 @@ from jinja2.runtime import Context from markupsafe import Markup from pyramid.request import Request +from . import util + @jinja2.pass_context def filter_format_decimal(ctx: Context, value: float) -> str: @@ -94,12 +96,7 @@ def global_embed_tile_layers(request: Request) -> Markup: else: def _url(source): - return ( - request.route_url("tile-proxy", provider=source.layer_id, x="{x}", y="{y}", z="{z}") - .replace("%7Bx%7D", "{x}") - .replace("%7By%7D", "{y}") - .replace("%7Bz%7D", "{z}") - ) + return util.tile_url(request, "tile-proxy", provider=source.layer_id) return Markup( json.dumps( diff --git a/fietsboek/util.py b/fietsboek/util.py index d6d0aea..c507cf1 100644 --- a/fietsboek/util.py +++ b/fietsboek/util.py @@ -322,6 +322,33 @@ def read_localized_resource( return f"{locale_name}:{path}" +def tile_url(request: Request, route_name: str, **kwargs: str) -> str: + """Generates a URL for tiles. + + This is basically :meth:`request.route_url`, but it keeps the + ``{x}``/``{y}``/``{z}`` placeholders intact for consumption by Leaflet. + + Expects that the URL takes a ``x``, ``y`` and ``z`` parameter. + + :param request: The Pyramid request. + :param route_name: The name of the route. + :param kwargs: Remaining route parameters. Will be passed to ``route_url``. + :return: The route URL, with intact placeholders. + """ + # This feels hacky (because it is), but I don't see a better way. The route + # generation is basically a closure that fills the placeholders + # all-or-none, and there is no way to get a "structured" representation of + # the URL without re-parsing it. + # Using {x} triggers the urlquoting, so we need to do some .replace() calls + # in the end anyway. Might as well use something that looks a bit better, + # and not %7Bx%7D. + kwargs["x"] = "__x__" + kwargs["y"] = "__y__" + kwargs["z"] = "__z__" + route = request.route_url(route_name, **kwargs) + return route.replace("__x__", "{x}").replace("__y__", "{y}").replace("__z__", "{z}") + + def secure_filename(filename: str) -> str: r"""Pass it a filename and it will return a secure version of it. This filename can then safely be stored on a regular file system and passed diff --git a/fietsboek/views/profile.py b/fietsboek/views/profile.py index 9f68d2f..4d23ae4 100644 --- a/fietsboek/views/profile.py +++ b/fietsboek/views/profile.py @@ -132,6 +132,7 @@ def profile(request: Request) -> dict: total.moving_time = round_to_seconds(total.moving_time) total.stopped_time = round_to_seconds(total.stopped_time) + user_id = request.context.id heatmap_url = None tilehunt_url = None try: @@ -140,29 +141,9 @@ def profile(request: Request) -> dict: pass else: if user_dir.heatmap_path().is_file(): - heatmap_url = request.route_url( - "user-tile", - user_id=request.context.id, - map="heatmap", - z="ZZZ", - x="XXX", - y="YYY", - ) - heatmap_url = ( - heatmap_url.replace("ZZZ", "{z}").replace("XXX", "{x}").replace("YYY", "{y}") - ) + heatmap_url = util.tile_url(request, "user-tile", user_id=user_id, map="heatmap") if user_dir.tilehunt_path().is_file(): - tilehunt_url = request.route_url( - "user-tile", - user_id=request.context.id, - map="tilehunt", - z="ZZZ", - x="XXX", - y="YYY", - ) - tilehunt_url = ( - tilehunt_url.replace("ZZZ", "{z}").replace("XXX", "{x}").replace("YYY", "{y}") - ) + tilehunt_url = util.tile_url(request, "user-tile", user_id=user_id, map="tilehunt") return { "user": request.context, diff --git a/tests/unit/test_util.py b/tests/unit/test_util.py index b35f218..949acb5 100644 --- a/tests/unit/test_util.py +++ b/tests/unit/test_util.py @@ -82,3 +82,12 @@ def test_tour_metadata(gpx_file): @pytest.mark.parametrize('mps, kph', [(1, 3.6), (10, 36)]) def test_mps_to_kph(mps, kph): assert util.mps_to_kph(mps) == pytest.approx(kph, 0.1) + + +def test_tile_url(app_request): + route_url = util.tile_url(app_request, "tile-proxy", provider="bobby") + + assert "{x}" in route_url + assert "{y}" in route_url + assert "{z}" in route_url + assert "bobby" in route_url |