kopia lustrzana https://github.com/simonw/datasette
rodzic
764738dfcb
commit
61419388c1
|
@ -988,7 +988,7 @@ class Datasette:
|
||||||
# Generate a regex snippet to match all registered renderer file extensions
|
# Generate a regex snippet to match all registered renderer file extensions
|
||||||
renderer_regex = "|".join(r"\." + key for key in self.renderers.keys())
|
renderer_regex = "|".join(r"\." + key for key in self.renderers.keys())
|
||||||
|
|
||||||
add_route(IndexView.as_view(self), r"/(?P<as_format>(\.jsono?)?$)")
|
add_route(IndexView.as_view(self), r"/(?P<format>(\.jsono?)?$)")
|
||||||
# TODO: /favicon.ico and /-/static/ deserve far-future cache expires
|
# TODO: /favicon.ico and /-/static/ deserve far-future cache expires
|
||||||
add_route(favicon, "/favicon.ico")
|
add_route(favicon, "/favicon.ico")
|
||||||
|
|
||||||
|
@ -1020,21 +1020,21 @@ class Datasette:
|
||||||
)
|
)
|
||||||
add_route(
|
add_route(
|
||||||
JsonDataView.as_view(self, "metadata.json", lambda: self.metadata()),
|
JsonDataView.as_view(self, "metadata.json", lambda: self.metadata()),
|
||||||
r"/-/metadata(?P<as_format>(\.json)?)$",
|
r"/-/metadata(?P<format>(\.json)?)$",
|
||||||
)
|
)
|
||||||
add_route(
|
add_route(
|
||||||
JsonDataView.as_view(self, "versions.json", self._versions),
|
JsonDataView.as_view(self, "versions.json", self._versions),
|
||||||
r"/-/versions(?P<as_format>(\.json)?)$",
|
r"/-/versions(?P<format>(\.json)?)$",
|
||||||
)
|
)
|
||||||
add_route(
|
add_route(
|
||||||
JsonDataView.as_view(
|
JsonDataView.as_view(
|
||||||
self, "plugins.json", self._plugins, needs_request=True
|
self, "plugins.json", self._plugins, needs_request=True
|
||||||
),
|
),
|
||||||
r"/-/plugins(?P<as_format>(\.json)?)$",
|
r"/-/plugins(?P<format>(\.json)?)$",
|
||||||
)
|
)
|
||||||
add_route(
|
add_route(
|
||||||
JsonDataView.as_view(self, "settings.json", lambda: self._settings),
|
JsonDataView.as_view(self, "settings.json", lambda: self._settings),
|
||||||
r"/-/settings(?P<as_format>(\.json)?)$",
|
r"/-/settings(?P<format>(\.json)?)$",
|
||||||
)
|
)
|
||||||
add_route(
|
add_route(
|
||||||
permanent_redirect("/-/settings.json"),
|
permanent_redirect("/-/settings.json"),
|
||||||
|
@ -1046,15 +1046,15 @@ class Datasette:
|
||||||
)
|
)
|
||||||
add_route(
|
add_route(
|
||||||
JsonDataView.as_view(self, "threads.json", self._threads),
|
JsonDataView.as_view(self, "threads.json", self._threads),
|
||||||
r"/-/threads(?P<as_format>(\.json)?)$",
|
r"/-/threads(?P<format>(\.json)?)$",
|
||||||
)
|
)
|
||||||
add_route(
|
add_route(
|
||||||
JsonDataView.as_view(self, "databases.json", self._connected_databases),
|
JsonDataView.as_view(self, "databases.json", self._connected_databases),
|
||||||
r"/-/databases(?P<as_format>(\.json)?)$",
|
r"/-/databases(?P<format>(\.json)?)$",
|
||||||
)
|
)
|
||||||
add_route(
|
add_route(
|
||||||
JsonDataView.as_view(self, "actor.json", self._actor, needs_request=True),
|
JsonDataView.as_view(self, "actor.json", self._actor, needs_request=True),
|
||||||
r"/-/actor(?P<as_format>(\.json)?)$",
|
r"/-/actor(?P<format>(\.json)?)$",
|
||||||
)
|
)
|
||||||
add_route(
|
add_route(
|
||||||
AuthTokenView.as_view(self),
|
AuthTokenView.as_view(self),
|
||||||
|
@ -1080,22 +1080,18 @@ class Datasette:
|
||||||
PatternPortfolioView.as_view(self),
|
PatternPortfolioView.as_view(self),
|
||||||
r"/-/patterns$",
|
r"/-/patterns$",
|
||||||
)
|
)
|
||||||
add_route(
|
add_route(DatabaseDownload.as_view(self), r"/(?P<database>[^/]+?)\.db$")
|
||||||
DatabaseDownload.as_view(self), r"/(?P<db_name>[^/]+?)(?P<as_db>\.db)$"
|
|
||||||
)
|
|
||||||
add_route(
|
add_route(
|
||||||
DatabaseView.as_view(self),
|
DatabaseView.as_view(self),
|
||||||
r"/(?P<db_name>[^/]+?)(?P<as_format>"
|
r"/(?P<database>[^/]+?)(?P<format>" + renderer_regex + r"|.jsono|\.csv)?$",
|
||||||
+ renderer_regex
|
|
||||||
+ r"|.jsono|\.csv)?$",
|
|
||||||
)
|
)
|
||||||
add_route(
|
add_route(
|
||||||
TableView.as_view(self),
|
TableView.as_view(self),
|
||||||
r"/(?P<db_name>[^/]+)/(?P<table>[^\/\.]+)(\.[a-zA-Z0-9_]+)?$",
|
r"/(?P<database>[^/]+)/(?P<table>[^\/\.]+)(\.[a-zA-Z0-9_]+)?$",
|
||||||
)
|
)
|
||||||
add_route(
|
add_route(
|
||||||
RowView.as_view(self),
|
RowView.as_view(self),
|
||||||
r"/(?P<db_name>[^/]+)/(?P<table>[^/]+?)/(?P<pk_path>[^/]+?)(?P<as_format>"
|
r"/(?P<database>[^/]+)/(?P<table>[^/]+?)/(?P<pks>[^/]+?)(?P<format>"
|
||||||
+ renderer_regex
|
+ renderer_regex
|
||||||
+ r")?$",
|
+ r")?$",
|
||||||
)
|
)
|
||||||
|
|
|
@ -34,8 +34,8 @@ async def render_blob(datasette, database, rows, columns, request, table, view_n
|
||||||
filename_bits = []
|
filename_bits = []
|
||||||
if table:
|
if table:
|
||||||
filename_bits.append(to_css_class(table))
|
filename_bits.append(to_css_class(table))
|
||||||
if "pk_path" in request.url_vars:
|
if "pks" in request.url_vars:
|
||||||
filename_bits.append(request.url_vars["pk_path"])
|
filename_bits.append(request.url_vars["pks"])
|
||||||
filename_bits.append(to_css_class(blob_column))
|
filename_bits.append(to_css_class(blob_column))
|
||||||
if blob_hash:
|
if blob_hash:
|
||||||
filename_bits.append(blob_hash[:6])
|
filename_bits.append(blob_hash[:6])
|
||||||
|
|
|
@ -381,7 +381,7 @@ class DataView(BaseView):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def get(self, request):
|
async def get(self, request):
|
||||||
db_name = request.url_vars["db_name"]
|
db_name = request.url_vars["database"]
|
||||||
database = tilde_decode(db_name)
|
database = tilde_decode(db_name)
|
||||||
_format = self.get_format(request)
|
_format = self.get_format(request)
|
||||||
data_kwargs = {}
|
data_kwargs = {}
|
||||||
|
|
|
@ -32,7 +32,7 @@ class DatabaseView(DataView):
|
||||||
name = "database"
|
name = "database"
|
||||||
|
|
||||||
async def data(self, request, default_labels=False, _size=None):
|
async def data(self, request, default_labels=False, _size=None):
|
||||||
database = tilde_decode(request.url_vars["db_name"])
|
database = tilde_decode(request.url_vars["database"])
|
||||||
await self.check_permissions(
|
await self.check_permissions(
|
||||||
request,
|
request,
|
||||||
[
|
[
|
||||||
|
@ -162,7 +162,7 @@ class DatabaseDownload(DataView):
|
||||||
name = "database_download"
|
name = "database_download"
|
||||||
|
|
||||||
async def get(self, request):
|
async def get(self, request):
|
||||||
database = tilde_decode(request.url_vars["db_name"])
|
database = tilde_decode(request.url_vars["database"])
|
||||||
await self.check_permissions(
|
await self.check_permissions(
|
||||||
request,
|
request,
|
||||||
[
|
[
|
||||||
|
@ -205,7 +205,7 @@ class QueryView(DataView):
|
||||||
named_parameters=None,
|
named_parameters=None,
|
||||||
write=False,
|
write=False,
|
||||||
):
|
):
|
||||||
database = tilde_decode(request.url_vars["db_name"])
|
database = tilde_decode(request.url_vars["database"])
|
||||||
params = {key: request.args.get(key) for key in request.args}
|
params = {key: request.args.get(key) for key in request.args}
|
||||||
if "sql" in params:
|
if "sql" in params:
|
||||||
params.pop("sql")
|
params.pop("sql")
|
||||||
|
|
|
@ -19,7 +19,7 @@ class IndexView(BaseView):
|
||||||
name = "index"
|
name = "index"
|
||||||
|
|
||||||
async def get(self, request):
|
async def get(self, request):
|
||||||
as_format = request.url_vars["as_format"]
|
as_format = request.url_vars["format"]
|
||||||
await self.check_permission(request, "view-instance")
|
await self.check_permission(request, "view-instance")
|
||||||
databases = []
|
databases = []
|
||||||
for name, db in self.ds.databases.items():
|
for name, db in self.ds.databases.items():
|
||||||
|
|
|
@ -15,7 +15,7 @@ class JsonDataView(BaseView):
|
||||||
self.needs_request = needs_request
|
self.needs_request = needs_request
|
||||||
|
|
||||||
async def get(self, request):
|
async def get(self, request):
|
||||||
as_format = request.url_vars["as_format"]
|
as_format = request.url_vars["format"]
|
||||||
await self.check_permission(request, "view-instance")
|
await self.check_permission(request, "view-instance")
|
||||||
if self.needs_request:
|
if self.needs_request:
|
||||||
data = self.data_callback(request)
|
data = self.data_callback(request)
|
||||||
|
|
|
@ -272,7 +272,7 @@ class TableView(RowTableShared):
|
||||||
name = "table"
|
name = "table"
|
||||||
|
|
||||||
async def post(self, request):
|
async def post(self, request):
|
||||||
db_name = tilde_decode(request.url_vars["db_name"])
|
db_name = tilde_decode(request.url_vars["database"])
|
||||||
table = tilde_decode(request.url_vars["table"])
|
table = tilde_decode(request.url_vars["table"])
|
||||||
# Handle POST to a canned query
|
# Handle POST to a canned query
|
||||||
canned_query = await self.ds.get_canned_query(db_name, table, request.actor)
|
canned_query = await self.ds.get_canned_query(db_name, table, request.actor)
|
||||||
|
@ -327,7 +327,7 @@ class TableView(RowTableShared):
|
||||||
_next=None,
|
_next=None,
|
||||||
_size=None,
|
_size=None,
|
||||||
):
|
):
|
||||||
database = tilde_decode(request.url_vars["db_name"])
|
database = tilde_decode(request.url_vars["database"])
|
||||||
table = tilde_decode(request.url_vars["table"])
|
table = tilde_decode(request.url_vars["table"])
|
||||||
try:
|
try:
|
||||||
db = self.ds.databases[database]
|
db = self.ds.databases[database]
|
||||||
|
@ -938,7 +938,7 @@ class RowView(RowTableShared):
|
||||||
name = "row"
|
name = "row"
|
||||||
|
|
||||||
async def data(self, request, default_labels=False):
|
async def data(self, request, default_labels=False):
|
||||||
database = tilde_decode(request.url_vars["db_name"])
|
database = tilde_decode(request.url_vars["database"])
|
||||||
table = tilde_decode(request.url_vars["table"])
|
table = tilde_decode(request.url_vars["table"])
|
||||||
await self.check_permissions(
|
await self.check_permissions(
|
||||||
request,
|
request,
|
||||||
|
@ -948,7 +948,7 @@ class RowView(RowTableShared):
|
||||||
"view-instance",
|
"view-instance",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
pk_values = urlsafe_components(request.url_vars["pk_path"])
|
pk_values = urlsafe_components(request.url_vars["pks"])
|
||||||
db = self.ds.databases[database]
|
db = self.ds.databases[database]
|
||||||
sql, params, pks = await _sql_params_pks(db, table, pk_values)
|
sql, params, pks = await _sql_params_pks(db, table, pk_values)
|
||||||
results = await db.execute(sql, params, truncate=True)
|
results = await db.execute(sql, params, truncate=True)
|
||||||
|
|
|
@ -12,26 +12,26 @@ def routes():
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"path,expected_class,expected_matches",
|
"path,expected_class,expected_matches",
|
||||||
(
|
(
|
||||||
("/", "IndexView", {"as_format": ""}),
|
("/", "IndexView", {"format": ""}),
|
||||||
("/foo", "DatabaseView", {"as_format": None, "db_name": "foo"}),
|
("/foo", "DatabaseView", {"format": None, "database": "foo"}),
|
||||||
("/foo.csv", "DatabaseView", {"as_format": ".csv", "db_name": "foo"}),
|
("/foo.csv", "DatabaseView", {"format": ".csv", "database": "foo"}),
|
||||||
("/foo.json", "DatabaseView", {"as_format": ".json", "db_name": "foo"}),
|
("/foo.json", "DatabaseView", {"format": ".json", "database": "foo"}),
|
||||||
("/foo.humbug", "DatabaseView", {"as_format": None, "db_name": "foo.humbug"}),
|
("/foo.humbug", "DatabaseView", {"format": None, "database": "foo.humbug"}),
|
||||||
("/foo/humbug", "TableView", {"db_name": "foo", "table": "humbug"}),
|
("/foo/humbug", "TableView", {"database": "foo", "table": "humbug"}),
|
||||||
("/foo/humbug.json", "TableView", {"db_name": "foo", "table": "humbug"}),
|
("/foo/humbug.json", "TableView", {"database": "foo", "table": "humbug"}),
|
||||||
("/foo/humbug.blah", "TableView", {"db_name": "foo", "table": "humbug"}),
|
("/foo/humbug.blah", "TableView", {"database": "foo", "table": "humbug"}),
|
||||||
(
|
(
|
||||||
"/foo/humbug/1",
|
"/foo/humbug/1",
|
||||||
"RowView",
|
"RowView",
|
||||||
{"as_format": None, "db_name": "foo", "pk_path": "1", "table": "humbug"},
|
{"format": None, "database": "foo", "pks": "1", "table": "humbug"},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"/foo/humbug/1.json",
|
"/foo/humbug/1.json",
|
||||||
"RowView",
|
"RowView",
|
||||||
{"as_format": ".json", "db_name": "foo", "pk_path": "1", "table": "humbug"},
|
{"format": ".json", "database": "foo", "pks": "1", "table": "humbug"},
|
||||||
),
|
),
|
||||||
("/-/metadata.json", "JsonDataView", {"as_format": ".json"}),
|
("/-/metadata.json", "JsonDataView", {"format": ".json"}),
|
||||||
("/-/metadata", "JsonDataView", {"as_format": ""}),
|
("/-/metadata", "JsonDataView", {"format": ""}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
def test_routes(routes, path, expected_class, expected_matches):
|
def test_routes(routes, path, expected_class, expected_matches):
|
||||||
|
|
Ładowanie…
Reference in New Issue