Adding views and schema.

This commit is contained in:
John Washam
2016-06-30 19:03:09 -07:00
parent 255001f40d
commit 4b1cf0afdb
8 changed files with 240 additions and 2 deletions

View File

@@ -21,3 +21,32 @@ It uses:
- Python 3 - Python 3
- Flask - Flask
- other things I need to figure out - 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

8
data/schema.sql Normal file
View File

@@ -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
);

View File

@@ -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 = 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('/') @app.route('/')
def index(): 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__': if __name__ == '__main__':

18
static/style.css Normal file
View File

@@ -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; }

43
templates/cards.html Normal file
View File

@@ -0,0 +1,43 @@
{% extends "layout.html" %}
{% block body %}
{% if session.logged_in %}
<form action="{{ url_for('add_card') }}" method=post class=add-card>
<dl>
<dt>
<label for="type">Type:</label>
</dt>
<dd>
<select name="type">
<option value="1">General</option>
<option value="2">Code</option>
</select>
</dd>
<dt>
<label for="front">Front:</label>
</dt>
<dd><input type="text" size=30 name="front" /></dd>
<dt>
<label for="back">Back:</label>
</dt>
<dd><textarea name="back" rows="15" cols="60"></textarea></dd>
<dd><input type="submit" value="Save" /></dd>
</dl>
</form>
{% endif %}
<hr />
<ul class=cards>
{% for card in cards %}
<li>
<h3>{{ card.front }}</h3>
{% if card.type == 1 %}
{{ card.back|replace("\n", "<br />") }}
{% else %}
<pre><code>{{ card.back|safe }}</code></pre>
{% endif %}
<hr>
</li>
{% else %}
<li><em>Unbelievable. No cards here so far.</em>
{% endfor %}
</ul>
{% endblock %}

6
templates/index.html Normal file
View File

@@ -0,0 +1,6 @@
{% extends "layout.html" %}
{% block body %}
<p>
Well, hello there.
</p>
{% endblock %}

20
templates/layout.html Normal file
View File

@@ -0,0 +1,20 @@
<!doctype html>
<title>CS Flash Cards</title>
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
<div class=page>
<h1>CS Flash Cards</h1>
<div class=metanav>
{% if not session.logged_in %}
<a href="{{ url_for('login') }}">log in</a>
{% else %}
<a href="{{ url_for('cards') }}">cards</a>
&nbsp;
&nbsp;
<a href="{{ url_for('logout') }}">log out</a>
{% endif %}
</div>
{% for message in get_flashed_messages() %}
<div class=flash>{{ message }}</div>
{% endfor %}
{% block body %}{% endblock %}
</div>

14
templates/login.html Normal file
View File

@@ -0,0 +1,14 @@
{% extends "layout.html" %}
{% block body %}
<h2>Login</h2>
{% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %}
<form action="{{ url_for('login') }}" method=post>
<dl>
<dt>Username:
<dd><input type=text name=username>
<dt>Password:
<dd><input type=password name=password>
<dd><input type=submit value="Log in">
</dl>
</form>
{% endblock %}