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  | 
