forked from tildeverse/quotes
148 lines
3.3 KiB
Python
148 lines
3.3 KiB
Python
import sqlite3, random
|
|
|
|
from flask import *
|
|
from pagination import Pagination
|
|
|
|
PER_PAGE = 10
|
|
|
|
app = Flask(__name__)
|
|
|
|
DATABASE = "quotes.db"
|
|
|
|
|
|
# util methods
|
|
|
|
|
|
def get_db():
|
|
db = getattr(g, "_database", None)
|
|
if db is None:
|
|
db = g._database = sqlite3.connect(DATABASE)
|
|
db.row_factory = sqlite3.Row
|
|
return db
|
|
|
|
|
|
def query_db(query, args=(), one=False):
|
|
cur = get_db().execute(query, args)
|
|
rv = cur.fetchall()
|
|
cur.close()
|
|
return (rv[0] if rv else None) if one else rv
|
|
|
|
|
|
@app.teardown_request
|
|
def teardown(exc):
|
|
db = getattr(g, "_database", None)
|
|
if db is not None:
|
|
db.close()
|
|
|
|
|
|
def url_for_other_page(page):
|
|
args = request.view_args.copy()
|
|
args["page"] = page
|
|
return url_for(request.endpoint, **args)
|
|
|
|
|
|
app.jinja_env.globals["url_for_other_page"] = url_for_other_page
|
|
|
|
|
|
# db helper methods
|
|
|
|
|
|
def get_post(id=1):
|
|
row = query_db("SELECT * FROM QUOTES WHERE ID=?", (id,))
|
|
if not row:
|
|
return False, []
|
|
return True, row[0]
|
|
|
|
|
|
def get_next_post_id():
|
|
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))
|
|
get_db().commit()
|
|
|
|
|
|
def vote(id, d=1):
|
|
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]
|
|
|
|
|
|
def get_quotes_for_page(page, per_page, order_by="ID DESC"):
|
|
offset = count_all_quotes() - ((page - 1) * per_page) + 1
|
|
return query_db(
|
|
"SELECT * FROM QUOTES WHERE ID < ? ORDER BY {} LIMIT ?".format(order_by),
|
|
(offset, per_page),
|
|
)
|
|
|
|
|
|
# routes
|
|
|
|
|
|
@app.route("/", defaults={"page": 1})
|
|
@app.route("/page/<int:page>")
|
|
def home(page):
|
|
count = count_all_quotes()
|
|
quotes = get_quotes_for_page(page, PER_PAGE)
|
|
if not quotes and page != 1:
|
|
abort(404)
|
|
return render_template(
|
|
"index.html", pagination=Pagination(page, PER_PAGE, count), quotes=quotes
|
|
)
|
|
|
|
|
|
@app.route("/top", defaults={"page": 1})
|
|
@app.route("/top/<int:page>")
|
|
def top(page):
|
|
count = count_all_quotes()
|
|
quotes = get_quotes_for_page(page, PER_PAGE, order_by="SCORE DESC")
|
|
if not quotes and page != 1:
|
|
abort(404)
|
|
return render_template(
|
|
"top.html", pagination=Pagination(page, PER_PAGE, count), quotes=quotes
|
|
)
|
|
|
|
|
|
@app.route("/quote/<int:id>")
|
|
def quote(id):
|
|
ok, row = get_post(id)
|
|
if not ok:
|
|
return render_template("oops.html", id=id)
|
|
return render_template("quote.html", row=row)
|
|
|
|
|
|
@app.route("/quote/<int:id>/upvote")
|
|
def upvote(id):
|
|
vote(id, 1)
|
|
return redirect(url_for("quote", id=id), code=307)
|
|
|
|
|
|
@app.route("/quote/<int:id>/downvote")
|
|
def downvote(id):
|
|
vote(id, -1)
|
|
return redirect(url_for("quote", id=id), code=307)
|
|
|
|
|
|
@app.route("/quote/submit")
|
|
def submitform():
|
|
return render_template("submit.html")
|
|
|
|
|
|
@app.route("/submit", methods=["POST"])
|
|
def submit():
|
|
if request.form["quote"]:
|
|
nid = get_next_post_id()
|
|
insert_new_post(nid, request.form["quote"])
|
|
return redirect(url_for("quote", id=nid), code=302)
|
|
else:
|
|
return redirect(url_for("submitform"), code=307)
|
|
|
|
|
|
@app.route("/random")
|
|
def randomquote():
|
|
return redirect(url_for("quote", id=random.randint(1, get_next_post_id() - 1)))
|