diff --git a/README.md b/README.md index 6b28f6e..ca08dc8 100644 --- a/README.md +++ b/README.md @@ -21,3 +21,32 @@ It uses: - Python 3 - Flask - other things I need to figure out + +--- + +To Do: + +- [ ] Log in + - [ ] Auth + - [ ] Auth errors + - [ ] Session set + - [ ] Logout +- [ ] Admin Area + - [ ] Admin welcome + - [ ] Vocab + - [ ] List cards by type + - [ ] Add cards + - [ ] Edit card + - [ ] Delete card + - [ ] Code + - [ ] List cards by type + - [ ] Add cards + - [ ] Edit card + - [ ] Delete card +- Card Memorization + - [ ] Card type toggle + - [ ] Show card + - [ ] Flip card + - [ ] Next card + - [ ] Last card + - [ ] Mark as known diff --git a/data/schema.sql b/data/schema.sql new file mode 100644 index 0000000..6a3ffff --- /dev/null +++ b/data/schema.sql @@ -0,0 +1,8 @@ +drop table if exists cards; +create table cards ( + id integer primary key autoincrement, + type tinyint not null, /* 1 for vocab, 2 for code */ + front text not null, + back text not null, + known boolean default 0 +); diff --git a/flash_cards.py b/flash_cards.py index 8391241..b815231 100644 --- a/flash_cards.py +++ b/flash_cards.py @@ -1,11 +1,111 @@ -from flask import Flask +import os +import sqlite3 +from flask import Flask, request, session, g, redirect, url_for, abort, \ + render_template, flash 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, '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() +# return 'Initialized the database.' @app.route('/') def index(): - return 'Hello World, you ready to learn?' + return render_template('index.html') + + +@app.route('/cards') +def cards(): + db = get_db() + cur = db.execute('SELECT type, front, back, known FROM cards ORDER BY id DESC') + cards = cur.fetchall() + return render_template('cards.html', cards=cards) + + +@app.route('/add', methods=['POST']) +def add_card(): + if not session.get('logged_in'): + abort(401) + 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('/login', methods=['GET', 'POST']) +def login(): + error = None + if request.method == 'POST': + # return request.form['username'] + " / " + app.config['USERNAME'] + " / " \ + # + request.form['password'] + " / " + app.config['PASSWORD'] + + if request.form['username'] != app.config['USERNAME']: + error = 'Invalid username' + elif request.form['password'] != app.config['PASSWORD']: + error = 'Invalid password' + else: + session['logged_in'] = True + flash('You were 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')) if __name__ == '__main__': diff --git a/static/style.css b/static/style.css new file mode 100644 index 0000000..466f615 --- /dev/null +++ b/static/style.css @@ -0,0 +1,18 @@ +body { font-family: sans-serif; background: #eee; } +a, h1, h2 { color: #377ba8; } +h1, h2 { font-family: 'Georgia', serif; margin: 0; } +h1 { border-bottom: 2px solid #eee; } +h2 { font-size: 1.2em; } + +.page { margin: 2em auto; width: 80%; border: 5px solid #ccc; + padding: 0.8em; background: white; } +.entries { list-style: none; margin: 0; padding: 0; } +.entries li { margin: 0.8em 1.2em; } +.entries li h2 { margin-left: -1em; } +.add-entry { font-size: 0.9em; border-bottom: 1px solid #ccc; } +.add-entry dl { font-weight: bold; } +.metanav { text-align: right; font-size: 0.8em; padding: 0.3em; + margin-bottom: 1em; background: #fafafa; } +.flash { background: #cee5F5; padding: 0.5em; + border: 1px solid #aacbe2; } +.error { background: #f0d6d6; padding: 0.5em; } diff --git a/templates/cards.html b/templates/cards.html new file mode 100644 index 0000000..a3884f2 --- /dev/null +++ b/templates/cards.html @@ -0,0 +1,43 @@ +{% extends "layout.html" %} +{% block body %} + {% if session.logged_in %} +
+ {% endif %} +{{ card.back|safe }}
+ {% endif %}
+ + Well, hello there. +
+{% endblock %} diff --git a/templates/layout.html b/templates/layout.html new file mode 100644 index 0000000..6dac244 --- /dev/null +++ b/templates/layout.html @@ -0,0 +1,20 @@ + +Error: {{ error }}{% endif %} +
+{% endblock %} \ No newline at end of file