From 9d219140694551453bfa528e0624919eb065f9d6 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Mon, 23 Oct 2017 19:25:48 -0700 Subject: [PATCH] Refactored to use class based views Closes #22 --- app.py | 95 ++++++++++++++++++++++++----------------- templates/database.html | 4 +- templates/table.html | 2 +- 3 files changed, 59 insertions(+), 42 deletions(-) diff --git a/app.py b/app.py index c30bc471..66555ccf 100644 --- a/app.py +++ b/app.py @@ -1,6 +1,7 @@ from sanic import Sanic from sanic import response from sanic.exceptions import NotFound +from sanic.views import HTTPMethodView from sanic_jinja2 import SanicJinja2 import sqlite3 from pathlib import Path @@ -17,6 +18,10 @@ HASH_BLOCK_SIZE = 1024 * 1024 conns = {} +app = Sanic(__name__) +jinja = SanicJinja2(app) + + def get_conn(name): if name not in conns: info = ensure_build_metadata()[name] @@ -66,8 +71,26 @@ def ensure_build_metadata(regenerate=False): return metadata -app = Sanic(__name__) -jinja = SanicJinja2(app) +class BaseView(HTTPMethodView): + 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): @@ -99,45 +122,39 @@ async def favicon(request): return response.text('') -@app.route('/') -@sqlerrors -async def database(request, db_name): - name, hash, should_redirect = resolve_db_name(db_name) - if should_redirect: - return response.redirect(should_redirect) - conn = get_conn(name) - rows = conn.execute('select * from sqlite_master') - headers = [r[0] for r in rows.description] - return jinja.render( - 'database.html', - request, - database=name, - database_hash=hash, - headers=headers, - rows=rows, - ) +class DatabaseView(BaseView): + template = 'database.html' + + def data(self, request, name, hash): + conn = get_conn(name) + rows = conn.execute('select * from sqlite_master') + columns = [r[0] for r in rows.description] + return { + 'database': name, + 'database_hash': hash, + 'rows': rows, + 'columns': columns, + } -@app.route('//') -@sqlerrors -async def table(request, db_name, table): - # The name should have the hash - if it - # does not, serve a redirect - name, hash, should_redirect = resolve_db_name(db_name) - if should_redirect: - return response.redirect(should_redirect + '/' + table) - conn = get_conn(name) - rows = conn.execute('select * from {} limit 20'.format(table)) - headers = [r[0] for r in rows.description] - return jinja.render( - 'table.html', - request, - database=name, - database_hash=hash, - table=table, - headers=headers, - rows=rows, - ) +class TableView(BaseView): + template = 'table.html' + + def data(self, request, name, hash, table): + conn = get_conn(name) + rows = conn.execute('select * from {} limit 20'.format(table)) + columns = [r[0] for r in rows.description] + return { + 'database': name, + 'database_hash': hash, + 'table': table, + 'rows': rows, + 'columns': columns, + } + + +app.add_route(DatabaseView.as_view(), '/') +app.add_route(TableView.as_view(), '//') def resolve_db_name(db_name): diff --git a/templates/database.html b/templates/database.html index 8d4a1e70..f5d36cf8 100644 --- a/templates/database.html +++ b/templates/database.html @@ -9,14 +9,14 @@ td { - {% for header in headers %}{% endfor %} + {% for column in columns %}{% endfor %} {% for row in rows %} {% for td in row %}
{{ header }}{{ column }}
{% if loop.index == 2 and row.type == "table" %} - {{ td }} + {{ td }} {% else %} {{ td }} {% endif %} diff --git a/templates/table.html b/templates/table.html index 706b3ef5..b7ab9cc0 100644 --- a/templates/table.html +++ b/templates/table.html @@ -12,7 +12,7 @@ td { - {% for header in headers %}{% endfor %} + {% for column in columns %}{% endfor %} {% for row in rows %}
{{ header }}{{ column }}