allow_facet, allow_download, suggest_facets boolean --config

Refs #284
This commit is contained in:
Simon Willison 2018-05-24 18:12:27 -07:00
commit 50920cfe3d
No known key found for this signature in database
GPG key ID: 17E2DEA2588B7F52
9 changed files with 177 additions and 55 deletions

View file

@ -4,7 +4,7 @@ from sanic import response
from datasette.utils import to_css_class, validate_sql_select
from .base import BaseView
from .base import BaseView, DatasetteError
class DatabaseView(BaseView):
@ -29,6 +29,7 @@ class DatabaseView(BaseView):
{"name": query_name, "sql": query_sql}
for query_name, query_sql in (metadata.get("queries") or {}).items()
],
"config": self.ds.config,
}, {
"database_hash": hash,
"show_hidden": request.args.get("_show_hidden"),
@ -42,6 +43,8 @@ class DatabaseView(BaseView):
class DatabaseDownload(BaseView):
async def view_get(self, request, name, hash, **kwargs):
if not self.ds.config["allow_download"]:
raise DatasetteError("Database download is forbidden", status=403)
filepath = self.ds.inspect()[name]["file"]
return await response.file_stream(
filepath,

View file

@ -542,6 +542,8 @@ class TableView(RowTableShared):
facet_size = self.ds.config["default_facet_size"]
metadata_facets = table_metadata.get("facets", [])
facets = metadata_facets[:]
if request.args.get("_facet") and not self.ds.config["allow_facet"]:
raise DatasetteError("_facet= is not allowed", status=400)
try:
facets.extend(request.args["_facet"])
except KeyError:
@ -650,41 +652,44 @@ class TableView(RowTableShared):
# Detect suggested facets
suggested_facets = []
for facet_column in columns:
if facet_column in facets:
continue
suggested_facet_sql = '''
select distinct {column} {from_sql}
{and_or_where} {column} is not null
limit {limit}
'''.format(
column=escape_sqlite(facet_column),
from_sql=from_sql,
and_or_where='and' if from_sql_where_clauses else 'where',
limit=facet_size+1
)
distinct_values = None
try:
distinct_values = await self.ds.execute(
name, suggested_facet_sql, from_sql_params,
truncate=False,
custom_time_limit=self.ds.config["facet_suggest_time_limit_ms"],
if self.ds.config["suggest_facets"] and self.ds.config["allow_facet"]:
for facet_column in columns:
if facet_column in facets:
continue
if not self.ds.config["suggest_facets"]:
continue
suggested_facet_sql = '''
select distinct {column} {from_sql}
{and_or_where} {column} is not null
limit {limit}
'''.format(
column=escape_sqlite(facet_column),
from_sql=from_sql,
and_or_where='and' if from_sql_where_clauses else 'where',
limit=facet_size+1
)
num_distinct_values = len(distinct_values)
if (
num_distinct_values and
num_distinct_values > 1 and
num_distinct_values <= facet_size and
num_distinct_values < filtered_table_rows_count
):
suggested_facets.append({
'name': facet_column,
'toggle_url': path_with_added_args(
request, {'_facet': facet_column}
),
})
except InterruptedError:
pass
distinct_values = None
try:
distinct_values = await self.ds.execute(
name, suggested_facet_sql, from_sql_params,
truncate=False,
custom_time_limit=self.ds.config["facet_suggest_time_limit_ms"],
)
num_distinct_values = len(distinct_values)
if (
num_distinct_values and
num_distinct_values > 1 and
num_distinct_values <= facet_size and
num_distinct_values < filtered_table_rows_count
):
suggested_facets.append({
'name': facet_column,
'toggle_url': path_with_added_args(
request, {'_facet': facet_column}
),
})
except InterruptedError:
pass
# human_description_en combines filters AND search, if provided
human_description_en = filters.human_description_en(extra=search_descriptions)