refactor error handling, create voting macro

This commit is contained in:
Ben Harris 2020-06-14 19:54:41 -04:00
parent 21a8681d2d
commit 89401a7189
12 changed files with 77 additions and 64 deletions

56
app.py
View File

@ -5,7 +5,7 @@ import sqlite3, random
from flask import *
from pagination import Pagination
PER_PAGE = 10
PER_PAGE = 15
app = Flask(__name__)
@ -50,38 +50,38 @@ app.jinja_env.globals["url_for_other_page"] = url_for_other_page
def get_post(id=1):
row = query_db("SELECT * FROM QUOTES WHERE ID=?", (id,))
row = query_db("SELECT * FROM quotes WHERE ID = ?", (id,))
if not row:
return False, []
return True, row[0]
def get_random_post():
return query_db("SELECT * FROM QUOTES ORDER BY RANDOM() LIMIT 1", one=True)
return query_db("SELECT * FROM quotes ORDER BY RANDOM() LIMIT 1", one=True)
def get_next_post_id():
return query_db("SELECT MAX(ID) FROM QUOTES", one=True)[0] + 1
return query_db("SELECT MAX(id) FROM quotes", one=True)[0] + 1
def insert_new_post(id, text):
query_db("INSERT INTO QUOTES VALUES (?,?,?)", (id, text, 0))
query_db("INSERT INTO quotes VALUES (?, ?, ?)", (id, text, 0))
get_db().commit()
def vote(id, d=1):
query_db("UPDATE QUOTES SET SCORE=SCORE+? WHERE ID=?", (d, id))
query_db("UPDATE quotes SET score = score + ? WHERE id = ?", (d, id))
get_db().commit()
def count_all_quotes():
return query_db("SELECT COUNT(*) FROM QUOTES", one=True)[0]
return query_db("SELECT COUNT(*) FROM quotes", one=True)[0]
def get_quotes_for_page(page):
offset = count_all_quotes() - ((page - 1) * PER_PAGE) + 1
return query_db(
"SELECT * FROM QUOTES WHERE ID < ? ORDER BY ID DESC LIMIT ?", (offset, PER_PAGE)
"SELECT * FROM quotes WHERE id < ? ORDER BY id DESC LIMIT ?", (offset, PER_PAGE)
)
@ -89,9 +89,9 @@ def get_top_quotes_for_page(page):
offset = (page - 1) * PER_PAGE
return query_db(
"""
SELECT * FROM QUOTES WHERE ID NOT IN
(SELECT ID FROM QUOTES ORDER BY SCORE DESC, ID DESC LIMIT ?)
ORDER BY SCORE DESC, ID DESC LIMIT ?
SELECT * FROM quotes WHERE id NOT IN
(SELECT id FROM quotes ORDER BY score DESC, id DESC LIMIT ?)
ORDER BY score DESC, id DESC LIMIT ?
""",
(offset, PER_PAGE),
)
@ -114,24 +114,26 @@ def search_quotes_db(searchterm):
@app.route("/", defaults={"page": 1})
@app.route("/page/<int:page>")
def home(page):
count = count_all_quotes()
quotes = get_quotes_for_page(page)
if not quotes and page != 1:
abort(404)
return render_template("oops.html", page=page)
return render_template(
"index.html", pagination=Pagination(page, PER_PAGE, count), quotes=quotes
"index.html",
pagination=Pagination(page, PER_PAGE, count_all_quotes()),
quotes=quotes,
)
@app.route("/top", defaults={"page": 1})
@app.route("/top/<int:page>")
def top(page):
count = count_all_quotes()
quotes = get_top_quotes_for_page(page)
if not quotes and page != 1:
abort(404)
return render_template("oops.html", page=page)
return render_template(
"top.html", pagination=Pagination(page, PER_PAGE, count), quotes=quotes
"top.html",
pagination=Pagination(page, PER_PAGE, count_all_quotes()),
quotes=quotes,
)
@ -143,14 +145,20 @@ def quote(id):
return render_template("quote.html", row=row)
@app.route("/quote/<int:id>/upvote")
@app.route("/upvote/<int:id>")
def upvote(id):
ok, row = get_post(id)
if not ok:
return render_template("oops.html", id=id)
vote(id, 1)
return redirect(url_for("quote", id=id), code=307)
@app.route("/quote/<int:id>/downvote")
@app.route("/downvote/<int:id>")
def downvote(id):
ok, row = get_post(id)
if not ok:
return render_template("oops.html", id=id)
vote(id, -1)
return redirect(url_for("quote", id=id), code=307)
@ -171,19 +179,13 @@ def submit():
@app.route("/random")
def randomquote():
def random():
return render_template("quote.html", row=get_random_post())
@app.route("/search", methods=["GET", "POST"])
def search():
query = request.args.get("q")
results = search_quotes_db(query)
return render_template(
"search-results.html", results=results, total=len(results), query=query
"search-results.html", results=search_quotes_db(query), query=query
)
@app.route("/js/<path:path>")
def send_js(path):
return send_from_directory("js", path)

BIN
static/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -6,9 +6,9 @@
<title>{% block title %}~chat irc quote database{% endblock %}</title>
<link rel="stylesheet" href="https://tilde.team/css/hacker.css">
<style>
pre { white-space: pre-wrap; }
pre { white-space: pre-wrap; }
</style>
<link rel="icon" type="image/png" sizes="96x96" href="https://tilde.team/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="96x96" href="{{ url_for('static', filename='favicon.png') }}">
</head>
<body style="padding-top: 70px;">
@ -22,14 +22,14 @@ pre { white-space: pre-wrap; }
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">~chat qdb</a>
<a class="navbar-brand" href="{{ url_for('home') }}">~chat qdb</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="https://tilde.chat">&lt; ~chat</a></li>
<li><a href="/top">top</a></li>
<li><a href="/random">random</a></li>
<li><a href="/quote/submit">submit</a></li>
<li><a href="https://tilde.chat/">&lt; ~chat</a></li>
<li><a href="{{ url_for('top') }}">top</a></li>
<li><a href="{{ url_for('random') }}">random</a></li>
<li><a href="{{ url_for('submitform') }}">submit</a></li>
</ul>
<form class="navbar-form navbar-right" action="{{ url_for('search') }}">
<div class="form-group">
@ -43,13 +43,13 @@ pre { white-space: pre-wrap; }
<h1>{% block pagetitle %}~chat irc quote database{% endblock %}</h1>
{% block content %}
<p>this is an irc quote database, in the style of <a href="http://bash.org">bash.org</a>, that aims to catalog moments on ~chat irc.</p>
<p>this is an irc quote database, in the style of <a href="http://bash.org">bash.org</a>, that aims to catalog moments on tilde.chat.</p>
{% endblock %}
</div>
<script src="/js/jquery.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
<script src="{{ url_for('static', filename='jquery.min.js') }}"></script>
<script src="{{ url_for('static', filename='bootstrap.min.js') }}"></script>
</body>
</html>

View File

@ -1,16 +1,16 @@
{% extends 'base.html' %}
{% import 'pagination.html' as pages %}
{% import 'macros.html' as macros %}
{% block content %}
{{ super() }}
{{ pages.render(pagination) }}
{{ macros.paginate(pagination) }}
{% for quote in quotes %}
<hr>
<pre>{{quote[1]}}</pre>
<p>score: {{ quote[2] }} (<a href="/quote/{{quote[0]}}/upvote">upvote</a>/<a href="/quote/{{quote[0]}}/downvote">downvote</a>) (<a href="/quote/{{quote[0]}}">permalink</a>)</p>
<pre>{{ quote['content'] }}</pre>
<p>{{ macros.voting_buttons(quote['id'], quote['score']) }}</p>
{% endfor %}
<hr>
{{ pages.render(pagination) }}
{{ macros.paginate(pagination) }}
{% endblock %}

View File

@ -1,7 +1,7 @@
{% macro render(pagination) %}
{% macro paginate(pagination) %}
<div class="pagination">
{% if pagination.has_prev %}
<a href="{{ url_for_other_page(pagination.page - 1) }}">&lt; prev</a>
<a href="{{ url_for_other_page(pagination.page - 1) }}">&larr;</a>
{% endif %}
{%- for page in pagination.iter_pages() %}
@ -12,12 +12,18 @@
<strong>{{ page }}</strong>
{% endif %}
{% else %}
<span class="ellipsis"></span>
<span class="ellipsis">&#8230;</span>
{% endif %}
{%- endfor %}
{% if pagination.has_next %}
<a href="{{ url_for_other_page(pagination.page + 1) }}">next &gt;</a>
<a href="{{ url_for_other_page(pagination.page + 1) }}">&rarr;</a>
{% endif %}
</div>
{% endmacro %}
{% macro voting_buttons(id, score) %}
<a href="{{ url_for('quote', id=id) }}">{{ id }}</a>:
score: {{ score }}
<a href="{{ url_for('upvote', id=id) }}">&uarr;</a>/<a href="{{ url_for('downvote', id=id) }}">&darr;</a>
{% endmacro %}

View File

@ -1,10 +1,13 @@
{% extends 'base.html' %}
{% block title %}~chat IRC quote database - big woops!{% endblock %}
{% block title %}big woops! - ~chat IRC quote database{% endblock %}
{% block pagetitle %}big woops!{% endblock %}
{% block content %}
<p>I'm sorry, but something has gone terribly wrong. Please try again later!</p>
{% if id %}
<p>quote {{ id }} does not exist. <a href="/quote/submit">submit a new one?</a></p>
<p>quote {{ id }} does not exist. <a href="{{ url_for('submit') }}">submit a new one?</a></p>
{% endif %}
{% if page %}
<p>page {{ page }} does not exist. <a href="{{ url_for('home') }}">go back home</a></p>
{% endif %}
{% endblock %}

View File

@ -1,10 +1,10 @@
{% extends 'base.html' %}
{% block title %}~chat IRC quote database - quote {{ row[0] }}{% endblock %}
{% block pagetitle %}quote {{ row[0] }}{% endblock %}
{% block title %}quote {{ row['id'] }} - ~chat IRC quote database{% endblock %}
{% block pagetitle %}quote {{ row['id'] }}{% endblock %}
{% import 'macros.html' as macros %}
{% block content %}
<p>score: {{ row[2] }}
(<a href="/quote/{{row[0]}}/upvote">upvote</a>/<a href="/quote/{{row[0]}}/downvote">downvote</a>)
</p>
<pre>{{row[1]}}</pre>
<pre>{{ row['content'] }}</pre>
<p>{{ macros.voting_buttons(row['id'], row['score']) }}</p>
{% endblock %}

View File

@ -1,14 +1,15 @@
{% extends 'base.html' %}
{% block title %}search results{% endblock%}
{% block pagetitle %}search results{% endblock %}
{% block content %}
<p>found {{ total }} results for <code>{{ query }}</code></p>
<p>matches are indicated by square brackets</p>
<p>found {{ results|length }} results for <code>{{ query }}</code></p>
<p>matches are indicated by [square brackets]</p>
{% for quote in results %}
<hr>
<p><a href="{{ url_for('quote', id=quote[0]) }}">{{ quote[0] }}</a></p>
<pre>{{ quote[1] }}</pre>
<p><a href="/quote/{{ quote[0] }}">permalink</a></p>
{% endfor %}
{% endblock %}

View File

@ -1,10 +1,10 @@
{% extends 'base.html' %}
{% block title %}~chat IRC quote database - submit a quote!{% endblock %}
{% block title %}submit a quote! - ~chat quote database{% endblock %}
{% block pagetitle %}submit a quote!{% endblock %}
{% block content %}
<p>please check with the people whose logs you're submitting for consent to post.</p>
<form action="/submit" method="POST">
<form action="{{ url_for('submit') }}" method="POST">
<p>quote:</p>
<textarea class="form-control" name="quote" rows="8" cols="80"></textarea>
<br>

View File

@ -1,17 +1,18 @@
{% extends 'base.html' %}
{% import 'pagination.html' as pages %}
{% import 'macros.html' as macros %}
{% block title %}top quotes | ~chat qdb{% endblock %}
{% block pagetitle %}top quotes of all time{% endblock %}
{% block content %}
{{ pages.render(pagination) }}
{{ macros.paginate(pagination) }}
{% for quote in quotes %}
<hr>
<pre>{{quote[1]}}</pre>
<p>score: {{ quote[2] }} (<a href="/quote/{{quote[0]}}/upvote">upvote</a>/<a href="/quote/{{quote[0]}}/downvote">downvote</a>) (<a href="/quote/{{quote[0]}}">permalink</a>)</p>
<pre>{{ quote['content'] }}</pre>
<p>{{ macros.voting_buttons(quote['id'], quote['score']) }}</p>
{% endfor %}
{{ pages.render(pagination) }}
<hr>
{{ macros.paginate(pagination) }}
{% endblock %}