import logging import psycopg2 import psycopg2.extras from flask import Flask, render_template, g, redirect, request, url_for logging.basicConfig(format="%(asctime)s %(levelname)s %(name)s %(lineno)d | %(message)s", level=logging.DEBUG) app = Flask(__name__) log = logging.getLogger(__name__) @app.route("/") def home(): csr = get_cursor() csr.execute("select * from books where current") books = csr.fetchall() return render_template("home.html", books=books) @app.route("/book/") def book(id): csr = get_cursor() csr.execute("select * from books where id = %s", (id,)) book = csr.fetchone() csr.execute("select * from bookmarks where book = %s order by ts desc", (id,)) bookmarks = csr.fetchall() return render_template("book.html", book=book, bookmarks=bookmarks) @app.route("/book//mark", methods=["POST"]) def bookmark(id): page = request.form["page"] note = request.form["note"] csr = get_cursor() csr.execute( "insert into bookmarks(book, page, note) values(%s, %s, %s)", (id, page, note)) return redirect(url_for("book", id=id), code=303) @app.route("/book/new", methods=["POST"]) def new_book(): title = request.form["title"] csr = get_cursor() csr.execute("insert into books(title, current) values(%s, true) returning *", (title,)) r = csr.fetchone() return redirect(url_for("book", id=r.id), code=303) def get_cursor(): db = get_db() csr = db.cursor(cursor_factory=psycopg2.extras.NamedTupleCursor) return csr def get_db(): if "db" not in g: g.db = psycopg2.connect(dbname="lesetagebuch", user="lesetagebuch") return g.db @app.teardown_appcontext def teardown_db(exception): log.info("in teardown_db: exception = %s", exception) db = g.pop('db', None) if db is not None: if not exception: try: db.commit() except: pass db.rollback() db.close()