kopia lustrzana https://github.com/simonw/datasette
rodzic
b2372605d6
commit
9d21914069
95
app.py
95
app.py
|
@ -1,6 +1,7 @@
|
||||||
from sanic import Sanic
|
from sanic import Sanic
|
||||||
from sanic import response
|
from sanic import response
|
||||||
from sanic.exceptions import NotFound
|
from sanic.exceptions import NotFound
|
||||||
|
from sanic.views import HTTPMethodView
|
||||||
from sanic_jinja2 import SanicJinja2
|
from sanic_jinja2 import SanicJinja2
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
@ -17,6 +18,10 @@ HASH_BLOCK_SIZE = 1024 * 1024
|
||||||
conns = {}
|
conns = {}
|
||||||
|
|
||||||
|
|
||||||
|
app = Sanic(__name__)
|
||||||
|
jinja = SanicJinja2(app)
|
||||||
|
|
||||||
|
|
||||||
def get_conn(name):
|
def get_conn(name):
|
||||||
if name not in conns:
|
if name not in conns:
|
||||||
info = ensure_build_metadata()[name]
|
info = ensure_build_metadata()[name]
|
||||||
|
@ -66,8 +71,26 @@ def ensure_build_metadata(regenerate=False):
|
||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
|
|
||||||
app = Sanic(__name__)
|
class BaseView(HTTPMethodView):
|
||||||
jinja = SanicJinja2(app)
|
template = None
|
||||||
|
|
||||||
|
async def get(self, request, db_name, **kwargs):
|
||||||
|
name, hash, should_redirect = resolve_db_name(db_name)
|
||||||
|
if should_redirect:
|
||||||
|
return response.redirect(should_redirect)
|
||||||
|
try:
|
||||||
|
as_json = kwargs.pop('as_json')
|
||||||
|
except KeyError:
|
||||||
|
as_json = False
|
||||||
|
data = self.data(request, name, hash, **kwargs)
|
||||||
|
if as_json:
|
||||||
|
return response.json(data)
|
||||||
|
else:
|
||||||
|
return jinja.render(
|
||||||
|
self.template,
|
||||||
|
request,
|
||||||
|
**data,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def sqlerrors(fn):
|
def sqlerrors(fn):
|
||||||
|
@ -99,45 +122,39 @@ async def favicon(request):
|
||||||
return response.text('')
|
return response.text('')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/<db_name:[^/]+$>')
|
class DatabaseView(BaseView):
|
||||||
@sqlerrors
|
template = 'database.html'
|
||||||
async def database(request, db_name):
|
|
||||||
name, hash, should_redirect = resolve_db_name(db_name)
|
def data(self, request, name, hash):
|
||||||
if should_redirect:
|
conn = get_conn(name)
|
||||||
return response.redirect(should_redirect)
|
rows = conn.execute('select * from sqlite_master')
|
||||||
conn = get_conn(name)
|
columns = [r[0] for r in rows.description]
|
||||||
rows = conn.execute('select * from sqlite_master')
|
return {
|
||||||
headers = [r[0] for r in rows.description]
|
'database': name,
|
||||||
return jinja.render(
|
'database_hash': hash,
|
||||||
'database.html',
|
'rows': rows,
|
||||||
request,
|
'columns': columns,
|
||||||
database=name,
|
}
|
||||||
database_hash=hash,
|
|
||||||
headers=headers,
|
|
||||||
rows=rows,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/<db_name:[^/]+>/<table:[^/]+$>')
|
class TableView(BaseView):
|
||||||
@sqlerrors
|
template = 'table.html'
|
||||||
async def table(request, db_name, table):
|
|
||||||
# The name should have the hash - if it
|
def data(self, request, name, hash, table):
|
||||||
# does not, serve a redirect
|
conn = get_conn(name)
|
||||||
name, hash, should_redirect = resolve_db_name(db_name)
|
rows = conn.execute('select * from {} limit 20'.format(table))
|
||||||
if should_redirect:
|
columns = [r[0] for r in rows.description]
|
||||||
return response.redirect(should_redirect + '/' + table)
|
return {
|
||||||
conn = get_conn(name)
|
'database': name,
|
||||||
rows = conn.execute('select * from {} limit 20'.format(table))
|
'database_hash': hash,
|
||||||
headers = [r[0] for r in rows.description]
|
'table': table,
|
||||||
return jinja.render(
|
'rows': rows,
|
||||||
'table.html',
|
'columns': columns,
|
||||||
request,
|
}
|
||||||
database=name,
|
|
||||||
database_hash=hash,
|
|
||||||
table=table,
|
app.add_route(DatabaseView.as_view(), '/<db_name:[^/]+?><as_json:(.json)?$>')
|
||||||
headers=headers,
|
app.add_route(TableView.as_view(), '/<db_name:[^/]+>/<table:[^/]+?><as_json:(.json)?$>')
|
||||||
rows=rows,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def resolve_db_name(db_name):
|
def resolve_db_name(db_name):
|
||||||
|
|
|
@ -9,14 +9,14 @@ td {
|
||||||
</style>
|
</style>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
{% for header in headers %}<th scope="col">{{ header }}</th>{% endfor %}
|
{% for column in columns %}<th scope="col">{{ column }}</th>{% endfor %}
|
||||||
</tr>
|
</tr>
|
||||||
{% for row in rows %}
|
{% for row in rows %}
|
||||||
<tr>
|
<tr>
|
||||||
{% for td in row %}
|
{% for td in row %}
|
||||||
<td>
|
<td>
|
||||||
{% if loop.index == 2 and row.type == "table" %}
|
{% if loop.index == 2 and row.type == "table" %}
|
||||||
<a href="/{{ database }}/{{ td }}">{{ td }}</a>
|
<a href="/{{ database }}-{{ database_hash }}/{{ td }}">{{ td }}</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ td }}
|
{{ td }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -12,7 +12,7 @@ td {
|
||||||
</style>
|
</style>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
{% for header in headers %}<th scope="col">{{ header }}</th>{% endfor %}
|
{% for column in columns %}<th scope="col">{{ column }}</th>{% endfor %}
|
||||||
</tr>
|
</tr>
|
||||||
{% for row in rows %}
|
{% for row in rows %}
|
||||||
<tr>
|
<tr>
|
||||||
|
|
Ładowanie…
Reference in New Issue