Simon Willison 2018-06-07 15:26:49 +00:00 zatwierdzone przez GitHub
commit 8c6663d3cc
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
2 zmienionych plików z 143 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,78 @@
from collections import namedtuple
from datasette.views.database import DatabaseView
from datasette.views.special import JsonDataView
from datasette.views.table import TableView
RouteResult = namedtuple('RouteResult', ('view', 'kwargs', 'redirect'))
def redirect(path):
return RouteResult(None, None, path)
def resolve(path, database_exists, table_exists, database_hash):
bits = path.split('/')
# Kill the leading /:
del bits[0]
# /-/...
if bits[0] == '-':
return resolve_special(bits[1:])
# /databasename
bit = bits[0]
rest = ''
if bits[1:]:
rest = '/'.join([''] + bits[1:])
# Might be database-databasehash
if '-' in bit:
database, databasehash = bit.rsplit('-', 1)
if database_exists(database):
# Is the hash correct?
expected_hash = database_hash(database)
if expected_hash == databasehash:
if not rest:
return RouteResult(
DatabaseView, {'database': database}, None
)
else:
# Pass on to table logic
return resolve_table(rest, database, table_exists)
else:
# Bad hash, redirect
return redirect('/{}-{}{}'.format(
database, expected_hash, rest)
)
# If we get here, maybe the full string is a DB name?
if database_exists(bit):
database = bit
databasehash = database_hash(bit)
return redirect('/{}-{}{}'.format(database, databasehash, rest))
return None
def resolve_table(rest, database, table_exists):
# TODO: Rows, views, canned queries
table = rest.lstrip('/')
if not table_exists(database, table):
return None
return RouteResult(TableView, {'database': database, 'table': table}, None)
specials = {'inspect', 'metadata', 'versions', 'plugins', 'config'}
def resolve_special(path_bits):
if len(path_bits) != 1:
return None
filename = path_bits[0]
as_json = False
if filename.endswith('.json'):
as_json = True
filename = filename.replace('.json', '')
if filename not in specials:
return None
kwargs = {
'filename': filename,
}
if as_json:
kwargs['format'] = 'json'
return RouteResult(JsonDataView, kwargs, None)

Wyświetl plik

@ -0,0 +1,65 @@
from datasette import routes
from datasette.views.database import DatabaseView
from datasette.views.special import JsonDataView
from datasette.views.table import TableView
import pytest
MOCK_DATABASES = {
# database: set-of-tables
'foo': {'bar'},
'foo-bar': {'baz'}
}
MOCK_DATABASE_HASHES = {
'foo': 'foohash',
'foo-bar': 'foobarhash',
}
def database_exists(database):
return database in MOCK_DATABASES
def table_exists(database, table):
print('table_exists: ', database, table)
return table in MOCK_DATABASES.get(database, set())
def database_hash(database):
return MOCK_DATABASE_HASHES[database]
@pytest.mark.parametrize('path,expected', [
('/does-not-exist', None),
# This should redirect
('/foo', routes.RouteResult(
None, None, '/foo-foohash'
)),
('/foo-bar-badhash', routes.RouteResult(
None, None, '/foo-bar-foobarhash'
)),
('/foo-foohash', routes.RouteResult(
DatabaseView, {'database': 'foo'}, None
)),
# Table views
('/foo/bar', routes.RouteResult(
None, None, '/foo-foohash/bar'
)),
('/foo/bad', routes.RouteResult(
None, None, '/foo-foohash/bad'
)),
('/foo-foohash/bad', None),
('/foo-foohash/bar', routes.RouteResult(
TableView, {'database': 'foo', 'table': 'bar'}, None
)),
] + [
('/-/{}'.format(filename), routes.RouteResult(
JsonDataView, {'filename': filename}, None
)) for filename in ('inspect', 'metadata', 'versions', 'plugins', 'config')
] + [
('/-/{}.json'.format(filename), routes.RouteResult(
JsonDataView, {'filename': filename, 'format': 'json'}, None
)) for filename in ('inspect', 'metadata', 'versions', 'plugins', 'config')
])
def test_routes(path, expected):
actual = routes.resolve(path, database_exists, table_exists, database_hash)
assert actual == expected