diff --git a/datasette/app.py b/datasette/app.py index 977839e0..b8b84168 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -34,7 +34,7 @@ from jinja2.environment import Template from jinja2.exceptions import TemplateNotFound from .views.base import ureg -from .views.database import DatabaseDownload, DatabaseView, TableCreateView +from .views.database import database_download, DatabaseView, TableCreateView from .views.index import IndexView from .views.special import ( JsonDataView, @@ -1363,7 +1363,10 @@ class Datasette: wrap_view(PatternPortfolioView, self), r"/-/patterns$", ) - add_route(DatabaseDownload.as_view(self), r"/(?P[^\/\.]+)\.db$") + add_route( + wrap_view(database_download, self), + r"/(?P[^\/\.]+)\.db$", + ) add_route( DatabaseView.as_view(self), r"/(?P[^\/\.]+)(\.(?P\w+))?$" ) diff --git a/datasette/views/database.py b/datasette/views/database.py index dda82510..ffa79e96 100644 --- a/datasette/views/database.py +++ b/datasette/views/database.py @@ -169,47 +169,45 @@ class DatabaseView(DataView): ) -class DatabaseDownload(DataView): - name = "database_download" +async def database_download(request, datasette): + database = tilde_decode(request.url_vars["database"]) + await datasette.ensure_permissions( + request.actor, + [ + ("view-database-download", database), + ("view-database", database), + "view-instance", + ], + ) + try: + db = datasette.get_database(route=database) + except KeyError: + raise DatasetteError("Invalid database", status=404) - async def get(self, request): - database = tilde_decode(request.url_vars["database"]) - await self.ds.ensure_permissions( - request.actor, - [ - ("view-database-download", database), - ("view-database", database), - "view-instance", - ], - ) - try: - db = self.ds.get_database(route=database) - except KeyError: - raise DatasetteError("Invalid database", status=404) - if db.is_memory: - raise DatasetteError("Cannot download in-memory databases", status=404) - if not self.ds.setting("allow_download") or db.is_mutable: - raise Forbidden("Database download is forbidden") - if not db.path: - raise DatasetteError("Cannot download database", status=404) - filepath = db.path - headers = {} - if self.ds.cors: - add_cors_headers(headers) - if db.hash: - etag = '"{}"'.format(db.hash) - headers["Etag"] = etag - # Has user seen this already? - if_none_match = request.headers.get("if-none-match") - if if_none_match and if_none_match == etag: - return Response("", status=304) - headers["Transfer-Encoding"] = "chunked" - return AsgiFileDownload( - filepath, - filename=os.path.basename(filepath), - content_type="application/octet-stream", - headers=headers, - ) + if db.is_memory: + raise DatasetteError("Cannot download in-memory databases", status=404) + if not datasette.setting("allow_download") or db.is_mutable: + raise Forbidden("Database download is forbidden") + if not db.path: + raise DatasetteError("Cannot download database", status=404) + filepath = db.path + headers = {} + if datasette.cors: + add_cors_headers(headers) + if db.hash: + etag = '"{}"'.format(db.hash) + headers["Etag"] = etag + # Has user seen this already? + if_none_match = request.headers.get("if-none-match") + if if_none_match and if_none_match == etag: + return Response("", status=304) + headers["Transfer-Encoding"] = "chunked" + return AsgiFileDownload( + filepath, + filename=os.path.basename(filepath), + content_type="application/octet-stream", + headers=headers, + ) class QueryView(DataView):