import os import sqlite3 from flask import Flask, request, session, g, redirect, url_for, abort, \ render_template, flash import logging app = Flask(__name__) app.config.from_object(__name__) # Load default config and override config from an environment variable app.config.update(dict( DATABASE=os.path.join(app.root_path, 'db', 'cards.db'), SECRET_KEY='development key', USERNAME='admin', PASSWORD='default' )) app.config.from_envvar('CARDS_SETTINGS', silent=True) def connect_db(): rv = sqlite3.connect(app.config['DATABASE']) rv.row_factory = sqlite3.Row return rv def init_db(): db = get_db() with app.open_resource('data/schema.sql', mode='r') as f: db.cursor().executescript(f.read()) db.commit() def get_db(): """Opens a new database connection if there is none yet for the current application context. """ if not hasattr(g, 'sqlite_db'): g.sqlite_db = connect_db() return g.sqlite_db @app.teardown_appcontext def close_db(error): """Closes the database again at the end of the request.""" if hasattr(g, 'sqlite_db'): g.sqlite_db.close() # ----------------------------------------------------------- # Uncomment and use this to initialize database, then comment it # You can rerun it to pave the database and start over @app.route('/initdb') def initdb(): init_db() init_tag() return 'Initialized the database.' @app.route('/') def index(): if session.get('logged_in'): return redirect(url_for('mem', card_type="1")) else: return redirect(url_for('login')) @app.route('/cards') def cards(): if not session.get('logged_in'): return redirect(url_for('login')) db = get_db() query = ''' SELECT id, type, front, back, known FROM cards ORDER BY id DESC ''' cur = db.execute(query) cards = cur.fetchall() tags = getAllTag() return render_template('cards.html', cards=cards, tags=tags, filter_name="all") @app.route('/filter_cards/') def filter_cards(filter_name): if not session.get('logged_in'): return redirect(url_for('login')) filters = { "all": "where 1 = 1", "general": "where type = 1", "code": "where type = 2", "known": "where known = 1", "unknown": "where known = 0", } query = filters.get(filter_name) if(query is None): query = "where type = {0}".format(filter_name) filter_name = int(filter_name) if not query: return redirect(url_for('show')) db = get_db() fullquery = "SELECT id, type, front, back, known FROM cards " + \ query + " ORDER BY id DESC" cur = db.execute(fullquery) cards = cur.fetchall() tags = getAllTag() return render_template('show.html', cards=cards, tags=tags, filter_name=filter_name) @app.route('/add', methods=['POST']) def add_card(): if not session.get('logged_in'): return redirect(url_for('login')) db = get_db() db.execute('INSERT INTO cards (type, front, back) VALUES (?, ?, ?)', [request.form['type'], request.form['front'], request.form['back'] ]) db.commit() flash('New card was successfully added.') return redirect(url_for('cards')) @app.route('/edit/') def edit(card_id): if not session.get('logged_in'): return redirect(url_for('login')) db = get_db() query = ''' SELECT id, type, front, back, known FROM cards WHERE id = ? ''' cur = db.execute(query, [card_id]) card = cur.fetchone() tags = getAllTag() return render_template('edit.html', card=card, tags=tags) @app.route('/edit_card', methods=['POST']) def edit_card(): if not session.get('logged_in'): return redirect(url_for('login')) selected = request.form.getlist('known') known = bool(selected) db = get_db() command = ''' UPDATE cards SET type = ?, front = ?, back = ?, known = ? WHERE id = ? ''' db.execute(command, [request.form['type'], request.form['front'], request.form['back'], known, request.form['card_id'] ]) db.commit() flash('Card saved.') return redirect(url_for('show')) @app.route('/delete/') def delete(card_id): if not session.get('logged_in'): return redirect(url_for('login')) db = get_db() db.execute('DELETE FROM cards WHERE id = ?', [card_id]) db.commit() flash('Card deleted.') return redirect(url_for('cards')) @app.route('/mem') @app.route('/mem/') @app.route('/mem/') def mem(card_type, card_id=None): tag = getTag(card_type) if tag is None: return redirect(url_for('cards')) if card_id: card = get_card_by_id(card_id) else: card = get_card(card_type) if not card: flash("You've learned all the '" + tag[1] + "' cards.") return redirect(url_for('show')) short_answer = (len(card['back']) < 75) tags = getAllTag() card_type = int(card_type) return render_template('memorize.html', card=card, card_type=card_type, short_answer=short_answer, tags=tags) def memorize(card_type, card_id): if card_type == "general": type = 1 elif card_type == "code": type = 2 else: return redirect(url_for('cards')) if card_id: card = get_card_by_id(card_id) else: card = get_card(type) if not card: flash("You've learned all the " + card_type + " cards.") return redirect(url_for('cards')) short_answer = (len(card['back']) < 75) tags = getAllTag() return render_template('memorize.html', card=card, card_type=card_type, short_answer=short_answer, tags=tags) def get_card(type): db = get_db() query = ''' SELECT id, type, front, back, known FROM cards WHERE type = ? and known = 0 ORDER BY RANDOM() LIMIT 1 ''' cur = db.execute(query, [type]) return cur.fetchone() def get_card_by_id(card_id): db = get_db() query = ''' SELECT id, type, front, back, known FROM cards WHERE id = ? LIMIT 1 ''' cur = db.execute(query, [card_id]) return cur.fetchone() @app.route('/mark_known//') def mark_known(card_id, card_type): if not session.get('logged_in'): return redirect(url_for('login')) db = get_db() db.execute('UPDATE cards SET known = 1 WHERE id = ?', [card_id]) db.commit() flash('Card marked as known.') return redirect(url_for('mem', card_type=card_type)) @app.route('/login', methods=['GET', 'POST']) def login(): error = None if request.method == 'POST': if request.form['username'] != app.config['USERNAME']: error = 'Invalid username or password!' elif request.form['password'] != app.config['PASSWORD']: error = 'Invalid username or password!' else: session['logged_in'] = True session.permanent = True # stay logged in return redirect(url_for('cards')) return render_template('login.html', error=error) @app.route('/logout') def logout(): session.pop('logged_in', None) flash("You've logged out") return redirect(url_for('index')) def getAllTag(): if not session.get('logged_in'): return redirect(url_for('login')) db = get_db() query = ''' SELECT id, tagName FROM tags ORDER BY id ASC ''' cur = db.execute(query) tags = cur.fetchall() return tags @app.route('/tags') def tags(): if not session.get('logged_in'): return redirect(url_for('login')) tags = getAllTag() return render_template('tags.html', tags=tags, filter_name="all") @app.route('/addTag', methods=['POST']) def add_tag(): if not session.get('logged_in'): return redirect(url_for('login')) db = get_db() db.execute('INSERT INTO tags (tagName) VALUES (?)', [request.form['tagName']]) db.commit() flash('New tag was successfully added.') return redirect(url_for('tags')) @app.route('/editTag/') def edit_tag(tag_id): if not session.get('logged_in'): return redirect(url_for('login')) tag = getTag(tag_id) return render_template('editTag.html', tag=tag) @app.route('/updateTag', methods=['POST']) def update_tag(): if not session.get('logged_in'): return redirect(url_for('login')) db = get_db() command = ''' UPDATE tags SET tagName = ? WHERE id = ? ''' db.execute(command, [request.form['tagName'], request.form['tag_id'] ]) db.commit() flash('Tag saved.') return redirect(url_for('tags')) def init_tag(): if not session.get('logged_in'): return redirect(url_for('login')) db = get_db() db.execute('INSERT INTO tags (tagName) VALUES (?)', ["general"]) db.commit() db.execute('INSERT INTO tags (tagName) VALUES (?)', ["code"]) db.commit() @app.route('/show') def show(): if not session.get('logged_in'): return redirect(url_for('login')) db = get_db() query = ''' SELECT id, type, front, back, known FROM cards ORDER BY id DESC ''' cur = db.execute(query) cards = cur.fetchall() tags = getAllTag() return render_template('show.html', cards=cards, tags=tags, filter_name="all") def getTag(tag_id): if not session.get('logged_in'): return redirect(url_for('login')) db = get_db() query = ''' SELECT id, tagName FROM tags WHERE id = ? ''' cur = db.execute(query, [tag_id]) tag = cur.fetchone() return tag if __name__ == '__main__': app.run(host='0.0.0.0')