From 310c3a3e059b89d05a38e373744928c1b54e54db Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Mon, 19 Oct 2020 17:33:59 -0700 Subject: [PATCH] New datasette.urls URL builders, refs #904 --- datasette/app.py | 32 ++++++++++++++++++++++++++++++- datasette/templates/database.html | 14 +++++++------- datasette/templates/index.html | 5 ++--- datasette/templates/query.html | 6 +++--- datasette/templates/row.html | 8 ++++---- datasette/templates/table.html | 10 +++++----- datasette/utils/__init__.py | 2 ++ datasette/views/base.py | 18 +---------------- datasette/views/database.py | 2 +- datasette/views/index.py | 2 +- tests/test_cli.py | 9 +++++++-- 11 files changed, 64 insertions(+), 44 deletions(-) diff --git a/datasette/app.py b/datasette/app.py index b768a298..b8e27f3c 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -56,7 +56,7 @@ from .utils import ( resolve_env_secrets, sqlite3, to_css_class, - SpatialiteNotFound, + HASH_LENGTH, ) from .utils.asgi import ( AsgiLifespan, @@ -321,6 +321,10 @@ class Datasette: self._root_token = secrets.token_hex(32) self.client = DatasetteClient(self) + @property + def urls(self): + return Urls(self) + async def invoke_startup(self): for hook in pm.hook.startup(datasette=self): await await_me_maybe(hook) @@ -748,6 +752,7 @@ class Datasette: template_context = { **context, **{ + "urls": self.urls, "actor": request.actor if request else None, "display_actor": display_actor, "show_logout": request is not None and "ds_actor" in request.cookies, @@ -1259,3 +1264,28 @@ class DatasetteClient: async def request(self, method, path, **kwargs): async with httpx.AsyncClient(app=self.app) as client: return await client.request(method, self._fix(path), **kwargs) + + +class Urls: + def __init__(self, ds): + self.ds = ds + + def instance(self): + return self.ds.config("base_url") + + def static(self, path): + return "{}-/static/{}".format(self.instance(), path) + + def database(self, database): + db = self.ds.databases[database] + base_url = self.ds.config("base_url") + if self.ds.config("hash_urls") and db.hash: + return "{}{}-{}".format(base_url, database, db.hash[:HASH_LENGTH]) + else: + return "{}{}".format(base_url, database) + + def table(self, database, table): + return "{}/{}".format(self.database(database), urllib.parse.quote_plus(table)) + + def query(self, database, query): + return "{}/{}".format(self.database(database), urllib.parse.quote_plus(query)) diff --git a/datasette/templates/database.html b/datasette/templates/database.html index 5ae51ef7..2f844b6a 100644 --- a/datasette/templates/database.html +++ b/datasette/templates/database.html @@ -11,7 +11,7 @@ {% block nav %}

- home + home

{{ super() }} {% endblock %} @@ -23,7 +23,7 @@ {% block description_source_license %}{% include "_description_source_license.html" %}{% endblock %} {% if allow_execute_sql %} -
+

Custom SQL query

@@ -36,7 +36,7 @@ {% for table in tables %} {% if show_hidden or not table.hidden %}

-

{{ table.name }}{% if table.private %} 🔒{% endif %}{% if table.hidden %} (hidden){% endif %}

+

{{ table.name }}{% if table.private %} 🔒{% endif %}{% if table.hidden %} (hidden){% endif %}

{% for column in table.columns[:9] %}{{ column }}{% if not loop.last %}, {% endif %}{% endfor %}{% if table.columns|length > 9 %}...{% endif %}

{% if table.count is none %}Many rows{% else %}{{ "{:,}".format(table.count) }} row{% if table.count == 1 %}{% else %}s{% endif %}{% endif %}

@@ -44,14 +44,14 @@ {% endfor %} {% if hidden_count and not show_hidden %} -

... and {{ "{:,}".format(hidden_count) }} hidden table{% if hidden_count == 1 %}{% else %}s{% endif %}

+

... and {{ "{:,}".format(hidden_count) }} hidden table{% if hidden_count == 1 %}{% else %}s{% endif %}

{% endif %} {% if views %}

Views

{% endif %} @@ -60,13 +60,13 @@

Queries

{% endif %} {% if allow_download %} -

Download SQLite DB: {{ database }}.db {{ format_bytes(size) }}

+

Download SQLite DB: {{ database }}.db {{ format_bytes(size) }}

{% endif %} {% include "_codemirror_foot.html" %} diff --git a/datasette/templates/index.html b/datasette/templates/index.html index c1adfc59..06e09635 100644 --- a/datasette/templates/index.html +++ b/datasette/templates/index.html @@ -10,7 +10,7 @@ {% block description_source_license %}{% include "_description_source_license.html" %}{% endblock %} {% for database in databases %} -

{{ database.name }}{% if database.private %} 🔒{% endif %}

+

{{ database.name }}{% if database.private %} 🔒{% endif %}

{% if database.show_table_row_counts %}{{ "{:,}".format(database.table_rows_sum) }} rows in {% endif %}{{ database.tables_count }} table{% if database.tables_count != 1 %}s{% endif %}{% if database.tables_count and database.hidden_tables_count %}, {% endif -%} {% if database.hidden_tables_count -%} @@ -21,8 +21,7 @@ {{ "{:,}".format(database.views_count) }} view{% if database.views_count != 1 %}s{% endif %} {% endif %}

-

{% for table in database.tables_and_views_truncated %}{{ table.name }}{% if table.private %} 🔒{% endif %}{% if not loop.last %}, {% endif %}{% endfor %}{% if database.tables_and_views_more %}, ...{% endif %}

+

{% for table in database.tables_and_views_truncated %}{{ table.name }}{% if table.private %} 🔒{% endif %}{% if not loop.last %}, {% endif %}{% endfor %}{% if database.tables_and_views_more %}, ...{% endif %}

{% endfor %} {% endblock %} diff --git a/datasette/templates/query.html b/datasette/templates/query.html index be180f33..911119bb 100644 --- a/datasette/templates/query.html +++ b/datasette/templates/query.html @@ -20,8 +20,8 @@ {% block nav %}

- home / - {{ database }} + home / + {{ database }}

{{ super() }} {% endblock %} @@ -32,7 +32,7 @@ {% block description_source_license %}{% include "_description_source_license.html" %}{% endblock %} - +

Custom SQL query{% if display_rows %} returning {% if truncated %}more than {% endif %}{{ "{:,}".format(display_rows|length) }} row{% if display_rows|length == 1 %}{% else %}s{% endif %}{% endif %} {% if hide_sql %}(show){% else %}(hide){% endif %}

{% if not hide_sql %} {% if editable and allow_execute_sql %} diff --git a/datasette/templates/row.html b/datasette/templates/row.html index cd49a497..916980b6 100644 --- a/datasette/templates/row.html +++ b/datasette/templates/row.html @@ -17,9 +17,9 @@ {% block nav %}

- home / - {{ database }} / - {{ table }} + home / + {{ database }} / + {{ table }}

{{ super() }} {% endblock %} @@ -38,7 +38,7 @@