From 452dbd31ea27a4afb3bbac18efd8346677d99296 Mon Sep 17 00:00:00 2001 From: schneefux Date: Fri, 10 Jun 2016 20:24:28 +0200 Subject: refactor, lint --- app.py | 430 ++++++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 279 insertions(+), 151 deletions(-) diff --git a/app.py b/app.py index f1a5eab..9de83ec 100644 --- a/app.py +++ b/app.py @@ -1,13 +1,13 @@ #!/usr/bin/python3 +# pylint: disable=missing-docstring,invalid-name +import sqlite3 import hashlib import os import re -from config import config from flask import ( Flask, render_template, make_response, - Markup, request, abort, g, @@ -16,16 +16,35 @@ from flask import ( session, flash ) -import sqlite3 +from config import config -class dbProxy(object): - def __init__(self, db, rootName): - self.conn = sqlite3.connect(db) - self.conn.row_factory = self.dict_factory - self.c = self.conn.cursor() +class Markup(object): + tagmark = "_" + + def prettify_text(self, text): + html = re.sub('<[^<]+?>', '', text) + html = re.sub(r"/(\w+)/", '\\1', html) + html = re.sub(r"\*(\w+)\*", '\\1', html) + html = re.sub(r"#(\w+)", '#\\1', html) + html = html.replace("\n", "
") + return html, text + + def clean_html(self, text): + # allow "downgrading" html to text on next edit + # by stripping html tags + html = text + text = re.sub('<[^<]+?>', '', text) + return html, text + + +class DBSchemaHandler(object): + def __init__(self, conn, c, prefix): + self.conn = conn + self.c = c + self.prefix = prefix - self.prefix = "v1b" if self.database_v() == '-1': self.create_v1b() if self.database_v() == '0': @@ -35,13 +54,6 @@ class dbProxy(object): if self.database_v() == '1a': self.migrate_v1ato1b() - self.rootUser(rootName) - - self.tagmark = "_" - - def close(self): - self.conn.close() - def database_v(self): versions = { 'jokes': '0', @@ -50,48 +62,54 @@ class dbProxy(object): 'v1b_jokes': '1b' } for ver in versions: - if self.c.execute("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name=?", (ver,)).fetchone()['COUNT(*)'] == 1: + if self.c.execute("SELECT COUNT(*) FROM sqlite_master " + + "WHERE type='table' AND name=?", + (ver,)).fetchone()['COUNT(*)'] == 1: return versions[ver] return '-1' - def dict_factory(self, cursor, row): - d = {} - for idx, col in enumerate(cursor.description): - d[col[0]] = row[idx] - return d - - def prettifyText(self, text): - html = re.sub('<[^<]+?>', '', text) - html = re.sub(r"/(\w+)/", '\\1', html) - html = re.sub(r"\*(\w+)\*", '\\1', html) - html = re.sub(r"#(\w+)", '#\\1', html) - html = html.replace("\n", "
") - return html - def create_v0(self): app.logger.warning("creating new v0 database") - self.c.execute("CREATE TABLE jokes(id INTEGER PRIMARY KEY NOT NULL, text TEXT, upvotes INTEGER, downvotes INTEGER, reports INTEGER)") - self.c.execute("CREATE TABLE votes(id INTEGER PRIMARY KEY NOT NULL, ip TEXT, jokeid INTEGER, type INTEGER)") + self.c.execute("CREATE TABLE jokes(" + + "id INTEGER PRIMARY KEY NOT NULL, " + + "text TEXT, upvotes INTEGER, " + + "downvotes INTEGER, reports INTEGER)") + self.c.execute("CREATE TABLE votes(" + + "id INTEGER PRIMARY KEY NOT NULL, " + + "ip TEXT, jokeid INTEGER, type INTEGER)") self.conn.commit() def create_v1(self): app.logger.warning("creating new v1 database") - self.c.execute("CREATE TABLE v1_jokes(id INTEGER PRIMARY KEY NOT NULL, text TEXT, format TEXT, user INTEGER)") - self.c.execute("CREATE TABLE v1_users(id INTEGER PRIMARY KEY NOT NULL, identifier TEXT)") - self.c.execute("CREATE TABLE v1_votes(id INTEGER PRIMARY KEY NOT NULL, joke INTEGER, user INTEGER, type TEXT)") + self.c.execute("CREATE TABLE v1_jokes(" + + "id INTEGER PRIMARY KEY NOT NULL, " + + "text TEXT, format TEXT, user INTEGER)") + self.c.execute("CREATE TABLE v1_users(" + + "id INTEGER PRIMARY KEY NOT NULL, " + + "identifier TEXT)") + self.c.execute("CREATE TABLE v1_votes(" + + "id INTEGER PRIMARY KEY NOT NULL, " + + "joke INTEGER, user INTEGER, type TEXT)") self.conn.commit() def create_v1a(self): app.logger.warning("creating new " + self.prefix + " database") - self.c.execute("CREATE TABLE " + self.prefix + "_jokes(id INTEGER PRIMARY KEY NOT NULL, text TEXT, format TEXT, user INTEGER)") - self.c.execute("CREATE TABLE " + self.prefix + "_votes(id INTEGER PRIMARY KEY NOT NULL, joke INTEGER, user INTEGER, type TEXT)") - self.c.execute("CREATE TABLE " + self.prefix + "_users(id INTEGER PRIMARY KEY NOT NULL, identifier TEXT, role TEXT DEFAULT 'guest', password TEXT DEFAULT '', salt TEXT DEFAULT '')") + self.c.execute("CREATE TABLE " + self.prefix + "_jokes(" + + "id INTEGER PRIMARY KEY NOT NULL, " + + "text TEXT, format TEXT, user INTEGER)") + self.c.execute("CREATE TABLE " + self.prefix + "_votes(" + + "id INTEGER PRIMARY KEY NOT NULL, " + + "joke INTEGER, user INTEGER, type TEXT)") + self.c.execute("CREATE TABLE " + self.prefix + "_users(" + + "id INTEGER PRIMARY KEY NOT NULL, " + + "identifier TEXT, role TEXT DEFAULT 'guest', " + + "password TEXT DEFAULT '', salt TEXT DEFAULT '')") self.conn.commit() def create_v1b(self): self.create_v1a() - def migrate_v0to1(self): + def migrate_v0to1(self): # pylint: disable=too-many-locals app.logger.warning("migrating database from v0 to v1") self.create_v1() @@ -101,7 +119,8 @@ class dbProxy(object): # create new jokes j = self.c.execute("SELECT * FROM jokes").fetchall() j = [(int(n['id']), n['text'], anonymous) for n in j] - self.c.executemany("INSERT INTO v1_jokes(id, text, format, user) VALUES(?, ?, 'html', ?)", j) + self.c.executemany("INSERT INTO v1_jokes(id, text, format, user) " + + "VALUES(?, ?, 'html', ?)", j) votes = self.c.execute("SELECT * FROM votes").fetchall() @@ -112,14 +131,17 @@ class dbProxy(object): # create votes for vote in votes: - user = int(self.c.execute("SELECT id FROM v1_users WHERE identifier=?", (vote['ip'],)).fetchone()['id']) + user = int(self.c.execute("SELECT id FROM v1_users " + + "WHERE identifier=?", + (vote['ip'],)).fetchone()['id']) if vote['type'] == -1: vtype = 'down' if vote['type'] == 0: vtype = 'report' if vote['type'] == 1: vtype = 'up' - self.c.execute("INSERT INTO v1_votes(joke, user, type) VALUES(?, ?, ?)", (vote['jokeid'], user, vtype)) + self.c.execute("INSERT INTO v1_votes(joke, user, type) " + + "VALUES(?, ?, ?)", (vote['jokeid'], user, vtype)) # create pre-v0 votes jokes = self.c.execute("SELECT id FROM v1_jokes").fetchall() @@ -131,11 +153,19 @@ class dbProxy(object): ("report", "reports") ) for newtype, oldtype in types: - legal_votes = int(self.c.execute("SELECT COUNT(*) FROM v1_votes WHERE id=? AND type=?", (joke, newtype)).fetchone()['COUNT(*)']) - real_votes = int(self.c.execute("SELECT * FROM jokes WHERE id=?", (joke,)).fetchone()[oldtype]) + legal_votes = int(self.c.execute("SELECT COUNT(*) FROM " + + "v1_votes WHERE id=? " + + "AND type=?", (joke, newtype)) + .fetchone()['COUNT(*)']) + real_votes = int(self.c.execute("SELECT * FROM jokes " + + "WHERE id=?", + (joke,)).fetchone()[oldtype]) diff = real_votes - legal_votes if diff: - self.c.executemany("INSERT INTO v1_votes(joke, user, type) VALUES(?, ?, ?)", [(joke, anonymous, newtype)]*diff) + self.c.executemany("INSERT INTO " + + "v1_votes(joke, user, type) " + + "VALUES(?, ?, ?)", + [(joke, anonymous, newtype)]*diff) # drop old tables self.c.execute("DROP TABLE jokes") @@ -148,8 +178,13 @@ class dbProxy(object): app.logger.warning("migrating database from v1 to v1a") self.c.execute("ALTER TABLE v1_jokes RENAME TO v1a_jokes") self.c.execute("ALTER TABLE v1_votes RENAME TO v1a_votes") - self.c.execute("CREATE TABLE v1a_users(id INTEGER PRIMARY KEY, identifier TEXT, role TEXT DEFAULT 'guest', password TEXT DEFAULT '', salt TEXT DEFAULT '')") - self.c.execute("INSERT INTO v1a_users(id, identifier) SELECT id, identifier FROM v1_users") + self.c.execute("CREATE TABLE v1a_users(" + + "id INTEGER PRIMARY KEY, identifier TEXT, " + + "role TEXT DEFAULT 'guest', " + + "password TEXT DEFAULT '', " + + "salt TEXT DEFAULT '')") + self.c.execute("INSERT INTO v1a_users(id, identifier) SELECT id, " + + "identifier FROM v1_users") self.c.execute("DROP TABLE v1_users") self.conn.commit() @@ -158,57 +193,100 @@ class dbProxy(object): self.c.execute("ALTER TABLE v1a_jokes RENAME TO v1b_jokes") self.c.execute("ALTER TABLE v1a_votes RENAME TO v1b_votes") self.c.execute("ALTER TABLE v1a_users RENAME TO v1b_users") - self.c.execute("UPDATE v1b_jokes SET format='prettytext' WHERE format='markdown'") + self.c.execute("UPDATE v1b_jokes SET format='prettytext' " + + "WHERE format='markdown'") self.c.execute("UPDATE v1b_votes SET type='down' WHERE type='report'") self.conn.commit() - def getJokes(self, user=None, filter=None, sortby='rank'): + +class DBProxy(object): + def __init__(self, database, rootName): + def dict_factory(cursor, row): + dic = {} + for idx, col in enumerate(cursor.description): + dic[col[0]] = row[idx] + return dic + + self.conn = sqlite3.connect(database) + self.conn.row_factory = dict_factory + self.c = self.conn.cursor() + + self.prefix = "v1b" + DBSchemaHandler(self.conn, self.c, self.prefix) + + self.root_user(rootName) + + def close(self): + self.conn.close() + + def score(self, jokeid): + users = self.c.execute("SELECT id FROM " + self.prefix + + "_users WHERE role='user'").fetchall() + users = [u['id'] for u in users] + votewhere = "SELECT COUNT(*) FROM " + self.prefix + "_votes WHERE " + # TODO optimize queries + score = 0 + score += self.c.execute( + votewhere + "joke=? AND type='up'", + (jokeid,)).fetchone()['COUNT(*)'] + score -= self.c.execute( + votewhere + "joke=? AND type='down'", + (jokeid,)).fetchone()['COUNT(*)'] + for user in users: + # user's scores count 10 times more + score += self.c.execute( + votewhere + "joke=? AND type='up' AND user=?", + (jokeid, user)).fetchone()['COUNT(*)'] * 9 + score -= self.c.execute( + votewhere + "joke=? AND type='down' AND user=?", + (jokeid, user)).fetchone()['COUNT(*)'] * 9 + return score + + def get_jokes(self, user=None, search=None, sortby='rank'): # user: return with user-specific attributes, also return deleted jokes - # filter: return jokes including the specified word + # search: return jokes including the specified word # sortby: rank - calculated by score and freshness, score - only score ret_jokes = [] - jokes = self.c.execute("SELECT * FROM " + self.prefix + "_jokes ORDER BY id ASC").fetchall() + jokes = self.c.execute("SELECT * FROM " + self.prefix + + "_jokes ORDER BY id ASC").fetchall() votewhere = "SELECT COUNT(*) FROM " + self.prefix + "_votes WHERE " - users = self.c.execute("SELECT id FROM " + self.prefix + "_users WHERE role='user'").fetchall() - users = [u['id'] for u in users] - iamroot = not self.c.execute("SELECT COUNT(*) FROM " + self.prefix + "_users WHERE id=? AND role='super'", (user,)).fetchone()['COUNT(*)'] == 0 + iamroot = not self.c.execute("SELECT COUNT(*) FROM " + self.prefix + + "_users WHERE id=? AND role='super'", + (user,)).fetchone()['COUNT(*)'] == 0 for joke in jokes: ret_joke = { 'id': joke['id'] } # mark jokes the user has already interacted with - ret_joke['upvoted'] = not self.c.execute(votewhere + "joke=? AND user=? AND type='up'", (joke['id'], user)).fetchone()['COUNT(*)'] == 0 - ret_joke['downvoted'] = not self.c.execute(votewhere + "joke=? AND user=? AND type='down'", (joke['id'], user)).fetchone()['COUNT(*)'] == 0 + ret_joke['upvoted'] = not self.c.execute( + votewhere + "joke=? AND user=? AND type='up'", + (joke['id'], user)).fetchone()['COUNT(*)'] == 0 + ret_joke['downvoted'] = not self.c.execute( + votewhere + "joke=? AND user=? AND type='down'", + (joke['id'], user)).fetchone()['COUNT(*)'] == 0 # allow deletion ret_joke['mine'] = (joke['user'] == user or iamroot) if joke['format'] == 'prettytext': - ret_joke['html'] = self.prettifyText(joke['text']) - ret_joke['text'] = joke['text'] + ret_joke['html'], ret_joke['text'] = Markup().prettify_text( + joke['text']) if joke['format'] == 'html': - ret_joke['html'] = joke['text'] - ret_joke['text'] = re.sub('<[^<]+?>', '', joke['text']) + ret_joke['html'], ret_joke['text'] = Markup().clean_html( + joke['text']) - if filter != None: # simple search - filter = re.sub(r"^" + self.tagmark, "#", filter) - if filter.lower() not in ret_joke['text'].lower(): + if search is not None: # simple search + search = re.sub(r"^" + Markup.tagmark, "#", search) + if search.lower() not in ret_joke['text'].lower(): continue - # actual scoring - # TODO optimize queries - score = 0 - score += self.c.execute(votewhere + "joke=? AND type='up'", (joke['id'],)).fetchone()['COUNT(*)'] - score -= self.c.execute(votewhere + "joke=? AND type='down'", (joke['id'],)).fetchone()['COUNT(*)'] - for u in users: - # user's scores count 10 times more - score += self.c.execute(votewhere + "joke=? AND type='up' AND user=?", (joke['id'], u)).fetchone()['COUNT(*)'] * 9 - score -= self.c.execute(votewhere + "joke=? AND type='down' AND user=?", (joke['id'], u)).fetchone()['COUNT(*)'] * 9 - - ret_joke['score'] = score + ret_joke['score'] = self.score(joke['id']) + # TODO maybe do something based on dates ret_joke['freshness'] = jokes[-1]['id'] - joke['id'] # skip other's jokes marked as deleted - if not self.c.execute("SELECT COUNT(*) FROM " + self.prefix + "_votes WHERE type='delete' AND joke=?", (joke['id'],)).fetchone()['COUNT(*)'] == 0: + if not self.c.execute("SELECT COUNT(*) FROM " + self.prefix + + "_votes WHERE type='delete' AND joke=?", + (joke['id'],)).fetchone()['COUNT(*)'] == 0: # deleted if ret_joke['mine']: ret_joke['deleted'] = True @@ -218,187 +296,233 @@ class dbProxy(object): ret_jokes.append(ret_joke) - if sortby == 'rank': - sorter = lambda j: (j['score']+1)/pow(j['freshness']+1, 2) - if sortby == 'score': - sorter = lambda j: j['score'] + def sorter(j): + if sortby == 'rank': + return (j['score']+1)/pow(j['freshness']+1, 2) + if sortby == 'score': + return j['score'] ret_jokes = sorted(ret_jokes, key=sorter, reverse=True) return ret_jokes - def addUser(self, name, password): - if self.getUser(name=name) != -2: + def add_user(self, name, password): + if self.get_user(name=name) != -2: return -1 # already registered password = password.encode('utf-8') salt = os.urandom(32).hex().encode('utf-8') password = hashlib.sha512(password + salt).hexdigest() - self.c.execute("INSERT INTO " + self.prefix + "_users(identifier, password, salt, role) VALUES(?, ?, ?, 'user')", (name, password, salt)) + self.c.execute("INSERT INTO " + self.prefix + + "_users(identifier, password, salt, role) " + + "VALUES(?, ?, ?, 'user')", (name, password, salt)) self.conn.commit() return self.c.lastrowid - def getUser(self, cookie=None, name=None, password=None): + def get_user(self, cookie=None, name=None, password=None): # cookie != None: return or create guest uid # name != None: return user uid or -2 (not found) - # name, password != None: return user uid, -2 (not found) or -1 (wrong password) - if cookie != None: - user = self.c.execute("SELECT id FROM " + self.prefix + "_users WHERE role='guest' AND identifier=?", (cookie,)).fetchone() + # name, password != None: uid, -2 (not found) or -1 (wrong password) + if cookie is not None: + user = self.c.execute("SELECT id FROM " + self.prefix + + "_users WHERE role='guest' AND identifier=?", + (cookie,)).fetchone() if user: # existing guest uid = int(user['id']) else: # create guest - self.c.execute("INSERT INTO " + self.prefix + "_users(identifier) VALUES(?)", (cookie,)) + self.c.execute("INSERT INTO " + self.prefix + + "_users(identifier) VALUES(?)", + (cookie,)) self.conn.commit() uid = self.c.lastrowid else: - if name != None: - user = self.c.execute("SELECT id FROM " + self.prefix + "_users WHERE identifier=?", (name,)).fetchone() + if name is not None: + user = self.c.execute("SELECT id FROM " + self.prefix + + "_users WHERE identifier=?", + (name,)).fetchone() if user: # existing user uid = int(user['id']) - if password != None: + if password is not None: password = password.encode('utf-8') - auth = self.c.execute("SELECT password, salt FROM " + self.prefix + "_users WHERE id=?", (uid,)).fetchone() - if hashlib.sha512(password + auth['salt']).hexdigest() != auth['password']: + auth = self.c.execute( + "SELECT password, salt FROM " + self.prefix + + "_users WHERE id=?", (uid,)).fetchone() + calc = hashlib.sha512(password + auth['salt']) + if calc.hexdigest() != auth['password']: uid = -1 # auth failed else: uid = -2 # nonexistent return uid - def rootUser(self, name): + def root_user(self, name): app.logger.warning("converting %s to superuser", name) - self.c.execute("UPDATE " + self.prefix + "_users SET role='super' WHERE identifier=?", (name,)) + self.c.execute("UPDATE " + self.prefix + "_users SET role='super' " + + "WHERE identifier=?", (name,)) self.conn.commit() - def addJoke(self, text, user): - self.c.execute("INSERT INTO " + self.prefix + "_jokes(text, format, user) VALUES(?, 'prettytext', ?)", (text, user)) + def add_joke(self, text, user): + self.c.execute( + "INSERT INTO " + self.prefix + "_jokes(text, format, user) " + + "VALUES(?, 'prettytext', ?)", (text, user)) self.conn.commit() - def updateJoke(self, text, joke): - self.c.execute("UPDATE " + self.prefix + "_jokes SET text=?, format='prettytext' WHERE id=?", (text, joke)) + def update_joke(self, text, joke): + self.c.execute("UPDATE " + self.prefix + "_jokes " + + "SET text=?, format='prettytext' WHERE id=?", + (text, joke)) self.conn.commit() - def removeJoke(self, joke, user): - self.c.execute("INSERT INTO " + self.prefix + "_votes(joke, user, type) VALUES(?, ?, 'delete')", (joke, user)) + def remove_joke(self, joke, user): + self.c.execute( + "INSERT INTO " + self.prefix + "_votes(joke, user, type) " + + "VALUES(?, ?, 'delete')", (joke, user)) self.conn.commit() - def voteJoke(self, joke, down, user): - self.c.execute("INSERT INTO " + self.prefix + "_votes(joke, user, type) VALUES(?, ?, ?)", (joke, user, 'down' if down else 'up')) + def vote_joke(self, joke, down, user): + self.c.execute( + "INSERT INTO " + self.prefix + "_votes(joke, user, type) " + + "VALUES(?, ?, ?)", (joke, user, 'down' if down else 'up')) self.conn.commit() - def unvoteJoke(self, joke, user): - self.c.execute("DELETE FROM " + self.prefix + "_votes WHERE joke=? AND user=?", (joke, user)) + def unvote_joke(self, joke, user): + self.c.execute("DELETE FROM " + self.prefix + "_votes " + + "WHERE joke=? AND user=?", (joke, user)) self.conn.commit() - def hasVoted(self, joke, user): - return not self.c.execute("SELECT COUNT(*) FROM " + self.prefix + "_votes WHERE joke=? AND user=?", (joke, user)).fetchone()['COUNT(*)'] == 0 + def has_voted(self, joke, user): + return not self.c.execute("SELECT COUNT(*) FROM " + self.prefix + + "_votes WHERE joke=? AND user=?", + (joke, user)).fetchone()['COUNT(*)'] == 0 - def mayModifyJoke(self, joke, user): - if self.c.execute("SELECT role FROM " + self.prefix + "_users WHERE id=?", (user,)).fetchone()['role'] == 'super': + def may_modify_joke(self, joke, user): + if self.c.execute("SELECT role FROM " + self.prefix + + "_users WHERE id=?", + (user,)).fetchone()['role'] == 'super': return True - if int(self.c.execute("SELECT user FROM " + self.prefix + "_jokes WHERE id=?", (joke,)).fetchone()['user']) == user: + if int(self.c.execute("SELECT user FROM " + self.prefix + + "_jokes WHERE id=?", + (joke,)).fetchone()['user']) == user: return True return False def db(): - db = getattr(g, "_database", None) - if db is None: - db = g._database = dbProxy("votes.db", config['superuser']) - return db + database = getattr(g, "_database", None) + if database is None: + database = g._database = DBProxy("votes.db", config['superuser']) + return database app = Flask(__name__) PERPAGE = 10 + @app.teardown_appcontext -def close_db(exception): - db = getattr(g, "_database", None) - if db is not None: - db.close() +def close_db(exception): # pylint: disable=unused-argument + database = getattr(g, "_database", None) + if database is not None: + database.close() + def userid(): if 'userlogin' in session: - uid = db().getUser(name=session['userlogin']) + uid = db().get_user(name=session['userlogin']) if uid != -2: return uid - if not 'guestlogin' in session: + if 'guestlogin' not in session: session['guestlogin'] = os.urandom(32).hex() - return db().getUser(cookie=session['guestlogin']) + return db().get_user(cookie=session['guestlogin']) + @app.route('/') def root(): return page(0) + @app.route('/page/') def page(num): - filter = request.args.get('filter') - jokes = db().getJokes(user=userid(), filter=filter) + search = request.args.get('filter') + jokes = db().get_jokes(user=userid(), search=search) user = {'loggedin': False} if 'userlogin' in session: user['loggedin'] = True user['name'] = session['userlogin'] - if filter: - filter = re.sub(r"^" + db().tagmark, "#", filter) # TODO find a cleaner way - r = make_response(render_template('index.html', currentpage=num, tag=filter, perpage=PERPAGE, jokes=jokes, user=user)) - r.headers.set('X-SmoothState-Location', request.path) - return r + if search: + # TODO find a cleaner way + search = re.sub(r"^" + Markup.tagmark, "#", search) + resp = make_response( + render_template( + 'index.html', + currentpage=num, + tag=search, + perpage=PERPAGE, + jokes=jokes, + user=user)) + resp.headers.set('X-SmoothState-Location', request.path) + return resp + @app.route('/submit', methods=['POST']) def submit(): text = request.form['text'] - db().addJoke(text, userid()) + db().add_joke(text, userid()) return redirect(request.referrer) + @app.route('/edit', methods=['POST']) def edit(): text = request.form['text'] joke = int(request.form['id']) - if not db().mayModifyJoke(joke, userid()): + if not db().may_modify_joke(joke, userid()): abort(403) - db().updateJoke(text, joke) + db().update_joke(text, joke) return redirect(request.referrer) + @app.route('/upvote', methods=['POST']) def upvote(): joke = int(request.form['id']) - if db().hasVoted(joke, userid()): - db().unvoteJoke(joke, userid()) - db().voteJoke(joke, False, userid()) + if db().has_voted(joke, userid()): + db().unvote_joke(joke, userid()) + db().vote_joke(joke, False, userid()) return redirect(request.referrer) + @app.route('/downvote', methods=['POST']) def downvote(): joke = int(request.form['id']) - if db().hasVoted(joke, userid()): - db().unvoteJoke(joke, userid()) - db().voteJoke(joke, True, userid()) + if db().has_voted(joke, userid()): + db().unvote_joke(joke, userid()) + db().vote_joke(joke, True, userid()) return redirect(request.referrer) + @app.route('/delete', methods=['POST']) def delete(): joke = int(request.form['id']) - if not db().mayModifyJoke(joke, userid()): + if not db().may_modify_joke(joke, userid()): abort(403) - db().removeJoke(joke, userid()) + db().remove_joke(joke, userid()) return redirect(request.referrer) + @app.route('/undelete', methods=['POST']) def undelete(): joke = int(request.form['id']) - if not db().mayModifyJoke(joke, userid()): + if not db().may_modify_joke(joke, userid()): abort(403) - db().unvoteJoke(joke, userid()) + db().unvote_joke(joke, userid()) return redirect(request.referrer) + @app.route('/login', methods=['POST']) def login(): - if not 'guestlogin' in session: + if 'guestlogin' not in session: session['guestlogin'] = os.urandom(32).hex() - cookie = session['guestlogin'] name = request.form['user'] - pw = request.form['password'] - if db().addUser(name, pw) >= 0: + passw = request.form['password'] + if db().add_user(name, passw) >= 0: flash('Erfolgreich registriert.') - res = db().getUser(name=name, password=pw) + res = db().get_user(name=name, password=passw) if res == -2: flash('Benutzer existiert nicht.') if res == -1: @@ -408,6 +532,7 @@ def login(): flash('Erfolgreich eingeloggt.') return redirect(request.referrer) + @app.route('/logout', methods=['POST']) def logout(): if 'userlogin' in session: @@ -416,20 +541,23 @@ def logout(): session['guestlogin'] = os.urandom(32).hex() return redirect(request.referrer) + @app.route('/export') def export(): - filter = request.args.get('filter') - jokes = db().getJokes(filter=filter, sortby='score') + search = request.args.get('filter') + jokes = db().get_jokes(search=search, sortby='score') texts = [j['text'] for j in jokes] - r = make_response("\n\r\n\r".join(texts)) - r.headers['Content-Type'] = 'text/plain; charset=utf-8'; - return r + res = make_response("\n\r\n\r".join(texts)) + res.headers['Content-Type'] = 'text/plain; charset=utf-8' + return res + # TODO use nginx for this @app.route('/static/') def get_static(path): return send_from_directory('static', path) + @app.route('/robots.txt') def robotstxt(): return send_from_directory('static', 'robots.txt') -- cgit v1.3.1