Merge pull request #76 from duongban/main
Add tag feature and some utility helpful
This commit is contained in:
4
data/handle_old_schema.sql
Normal file
4
data/handle_old_schema.sql
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
create table if not exists tags (
|
||||||
|
id integer primary key autoincrement,
|
||||||
|
tagName text not null
|
||||||
|
);
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
drop table if exists cards;
|
-- drop table if exists cards;
|
||||||
create table cards (
|
create table cards (
|
||||||
id integer primary key autoincrement,
|
id integer primary key autoincrement,
|
||||||
type tinyint not null, /* 1 for vocab, 2 for code */
|
type tinyint not null, /* 1 for vocab, 2 for code */
|
||||||
@@ -6,3 +6,8 @@ create table cards (
|
|||||||
back text not null,
|
back text not null,
|
||||||
known boolean default 0
|
known boolean default 0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
create table tags (
|
||||||
|
id integer primary key autoincrement,
|
||||||
|
tagName text not null
|
||||||
|
);
|
||||||
|
|||||||
306
flash_cards.py
306
flash_cards.py
@@ -5,16 +5,20 @@ from flask import Flask, request, session, g, redirect, url_for, abort, \
|
|||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config.from_object(__name__)
|
app.config.from_object(__name__)
|
||||||
|
nameDB='cards.db'
|
||||||
|
pathDB='db'
|
||||||
|
|
||||||
# Load default config and override config from an environment variable
|
def load_config():
|
||||||
app.config.update(dict(
|
app.config.update(dict(
|
||||||
DATABASE=os.path.join(app.root_path, 'db', 'cards.db'),
|
DATABASE=os.path.join(app.root_path, pathDB, nameDB),
|
||||||
SECRET_KEY='development key',
|
SECRET_KEY='development key',
|
||||||
USERNAME='admin',
|
USERNAME='admin',
|
||||||
PASSWORD='default'
|
PASSWORD='default'
|
||||||
))
|
))
|
||||||
app.config.from_envvar('CARDS_SETTINGS', silent=True)
|
app.config.from_envvar('CARDS_SETTINGS', silent=True)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
load_config()
|
||||||
|
|
||||||
def connect_db():
|
def connect_db():
|
||||||
rv = sqlite3.connect(app.config['DATABASE'])
|
rv = sqlite3.connect(app.config['DATABASE'])
|
||||||
@@ -28,7 +32,6 @@ def init_db():
|
|||||||
db.cursor().executescript(f.read())
|
db.cursor().executescript(f.read())
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
def get_db():
|
def get_db():
|
||||||
"""Opens a new database connection if there is none yet for the
|
"""Opens a new database connection if there is none yet for the
|
||||||
current application context.
|
current application context.
|
||||||
@@ -44,21 +47,10 @@ def close_db(error):
|
|||||||
if hasattr(g, 'sqlite_db'):
|
if hasattr(g, 'sqlite_db'):
|
||||||
g.sqlite_db.close()
|
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():
|
||||||
if session.get('logged_in'):
|
if session.get('logged_in'):
|
||||||
return redirect(url_for('general'))
|
return redirect(url_for('list_db'))
|
||||||
else:
|
else:
|
||||||
return redirect(url_for('login'))
|
return redirect(url_for('login'))
|
||||||
|
|
||||||
@@ -75,7 +67,8 @@ def cards():
|
|||||||
'''
|
'''
|
||||||
cur = db.execute(query)
|
cur = db.execute(query)
|
||||||
cards = cur.fetchall()
|
cards = cur.fetchall()
|
||||||
return render_template('cards.html', cards=cards, filter_name="all")
|
tags = getAllTag()
|
||||||
|
return render_template('cards.html', cards=cards, tags=tags, filter_name="all")
|
||||||
|
|
||||||
|
|
||||||
@app.route('/filter_cards/<filter_name>')
|
@app.route('/filter_cards/<filter_name>')
|
||||||
@@ -92,15 +85,20 @@ def filter_cards(filter_name):
|
|||||||
}
|
}
|
||||||
|
|
||||||
query = filters.get(filter_name)
|
query = filters.get(filter_name)
|
||||||
|
if(query is None):
|
||||||
|
query = "where type = {0}".format(filter_name)
|
||||||
|
filter_name = int(filter_name)
|
||||||
|
|
||||||
if not query:
|
if not query:
|
||||||
return redirect(url_for('cards'))
|
return redirect(url_for('show'))
|
||||||
|
|
||||||
db = get_db()
|
db = get_db()
|
||||||
fullquery = "SELECT id, type, front, back, known FROM cards " + query + " ORDER BY id DESC"
|
fullquery = "SELECT id, type, front, back, known FROM cards " + \
|
||||||
|
query + " ORDER BY id DESC"
|
||||||
cur = db.execute(fullquery)
|
cur = db.execute(fullquery)
|
||||||
cards = cur.fetchall()
|
cards = cur.fetchall()
|
||||||
return render_template('cards.html', cards=cards, filter_name=filter_name)
|
tags = getAllTag()
|
||||||
|
return render_template('show.html', cards=cards, tags=tags, filter_name=filter_name)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/add', methods=['POST'])
|
@app.route('/add', methods=['POST'])
|
||||||
@@ -130,7 +128,8 @@ def edit(card_id):
|
|||||||
'''
|
'''
|
||||||
cur = db.execute(query, [card_id])
|
cur = db.execute(query, [card_id])
|
||||||
card = cur.fetchone()
|
card = cur.fetchone()
|
||||||
return render_template('edit.html', card=card)
|
tags = getAllTag()
|
||||||
|
return render_template('edit.html', card=card, tags=tags)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/edit_card', methods=['POST'])
|
@app.route('/edit_card', methods=['POST'])
|
||||||
@@ -158,7 +157,7 @@ def edit_card():
|
|||||||
])
|
])
|
||||||
db.commit()
|
db.commit()
|
||||||
flash('Card saved.')
|
flash('Card saved.')
|
||||||
return redirect(url_for('cards'))
|
return redirect(url_for('show'))
|
||||||
|
|
||||||
|
|
||||||
@app.route('/delete/<card_id>')
|
@app.route('/delete/<card_id>')
|
||||||
@@ -171,43 +170,51 @@ def delete(card_id):
|
|||||||
flash('Card deleted.')
|
flash('Card deleted.')
|
||||||
return redirect(url_for('cards'))
|
return redirect(url_for('cards'))
|
||||||
|
|
||||||
|
@app.route('/memorize')
|
||||||
@app.route('/general')
|
@app.route('/memorize/<card_id>')
|
||||||
@app.route('/general/<card_id>')
|
@app.route('/memorize/<card_type>')
|
||||||
def general(card_id=None):
|
def memorize(card_type, card_id=None):
|
||||||
if not session.get('logged_in'):
|
tag = getTag(card_type)
|
||||||
return redirect(url_for('login'))
|
if tag is None:
|
||||||
return memorize("general", card_id)
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/code')
|
|
||||||
@app.route('/code/<card_id>')
|
|
||||||
def code(card_id=None):
|
|
||||||
if not session.get('logged_in'):
|
|
||||||
return redirect(url_for('login'))
|
|
||||||
return memorize("code", card_id)
|
|
||||||
|
|
||||||
|
|
||||||
def memorize(card_type, card_id):
|
|
||||||
if card_type == "general":
|
|
||||||
type = 1
|
|
||||||
elif card_type == "code":
|
|
||||||
type = 2
|
|
||||||
else:
|
|
||||||
return redirect(url_for('cards'))
|
return redirect(url_for('cards'))
|
||||||
|
|
||||||
if card_id:
|
if card_id:
|
||||||
card = get_card_by_id(card_id)
|
card = get_card_by_id(card_id)
|
||||||
else:
|
else:
|
||||||
card = get_card(type)
|
card = get_card(card_type)
|
||||||
if not card:
|
if not card:
|
||||||
flash("You've learned all the " + card_type + " cards.")
|
flash("You've learned all the '" + tag[1] + "' cards.")
|
||||||
return redirect(url_for('cards'))
|
return redirect(url_for('show'))
|
||||||
short_answer = (len(card['back']) < 75)
|
short_answer = (len(card['back']) < 75)
|
||||||
|
tags = getAllTag()
|
||||||
|
card_type = int(card_type)
|
||||||
return render_template('memorize.html',
|
return render_template('memorize.html',
|
||||||
card=card,
|
card=card,
|
||||||
card_type=card_type,
|
card_type=card_type,
|
||||||
short_answer=short_answer)
|
short_answer=short_answer, tags=tags)
|
||||||
|
|
||||||
|
@app.route('/memorize_known')
|
||||||
|
@app.route('/memorize_known/<card_id>')
|
||||||
|
@app.route('/memorize_known/<card_type>')
|
||||||
|
def memorize_known(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_already_known(card_type)
|
||||||
|
if not card:
|
||||||
|
flash("You haven't learned any '" + tag[1] + "' cards yet.")
|
||||||
|
return redirect(url_for('show'))
|
||||||
|
short_answer = (len(card['back']) < 75)
|
||||||
|
tags = getAllTag()
|
||||||
|
card_type = int(card_type)
|
||||||
|
return render_template('memorize_known.html',
|
||||||
|
card=card,
|
||||||
|
card_type=card_type,
|
||||||
|
short_answer=short_answer, tags=tags)
|
||||||
|
|
||||||
|
|
||||||
def get_card(type):
|
def get_card(type):
|
||||||
@@ -252,8 +259,7 @@ def mark_known(card_id, card_type):
|
|||||||
db.execute('UPDATE cards SET known = 1 WHERE id = ?', [card_id])
|
db.execute('UPDATE cards SET known = 1 WHERE id = ?', [card_id])
|
||||||
db.commit()
|
db.commit()
|
||||||
flash('Card marked as known.')
|
flash('Card marked as known.')
|
||||||
return redirect(url_for(card_type))
|
return redirect(url_for('memorize', card_type=card_type))
|
||||||
|
|
||||||
|
|
||||||
@app.route('/login', methods=['GET', 'POST'])
|
@app.route('/login', methods=['GET', 'POST'])
|
||||||
def login():
|
def login():
|
||||||
@@ -266,7 +272,7 @@ def login():
|
|||||||
else:
|
else:
|
||||||
session['logged_in'] = True
|
session['logged_in'] = True
|
||||||
session.permanent = True # stay logged in
|
session.permanent = True # stay logged in
|
||||||
return redirect(url_for('cards'))
|
return redirect(url_for('index'))
|
||||||
return render_template('login.html', error=error)
|
return render_template('login.html', error=error)
|
||||||
|
|
||||||
|
|
||||||
@@ -277,5 +283,191 @@ def logout():
|
|||||||
return redirect(url_for('index'))
|
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/<tag_id>')
|
||||||
|
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()
|
||||||
|
db.execute('INSERT INTO tags (tagName) VALUES (?)',
|
||||||
|
["bookmark"])
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
@app.route('/show')
|
||||||
|
def show():
|
||||||
|
if not session.get('logged_in'):
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
tags = getAllTag()
|
||||||
|
return render_template('show.html', tags=tags, filter_name="")
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
@app.route('/bookmark/<card_type>/<card_id>')
|
||||||
|
def bookmark(card_type, card_id):
|
||||||
|
if not session.get('logged_in'):
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
db = get_db()
|
||||||
|
db.execute('UPDATE cards SET type = ? WHERE id = ?',[card_type,card_id])
|
||||||
|
db.commit()
|
||||||
|
flash('Card saved.')
|
||||||
|
return redirect(url_for('memorize', card_type=card_type))
|
||||||
|
|
||||||
|
@app.route('/list_db')
|
||||||
|
def list_db():
|
||||||
|
if not session.get('logged_in'):
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
dbs = [f for f in os.listdir(pathDB) if os.path.isfile(os.path.join(pathDB, f))]
|
||||||
|
dbs = list(filter(lambda k: '.db' in k, dbs))
|
||||||
|
return render_template('listDb.html', dbs=dbs)
|
||||||
|
|
||||||
|
@app.route('/load_db/<name>')
|
||||||
|
def load_db(name):
|
||||||
|
if not session.get('logged_in'):
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
global nameDB
|
||||||
|
nameDB=name
|
||||||
|
load_config()
|
||||||
|
handle_old_schema()
|
||||||
|
return redirect(url_for('memorize', card_type="1"))
|
||||||
|
|
||||||
|
@app.route('/create_db')
|
||||||
|
def create_db():
|
||||||
|
if not session.get('logged_in'):
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
return render_template('createDb.html')
|
||||||
|
|
||||||
|
@app.route('/init', methods=['POST'])
|
||||||
|
def init():
|
||||||
|
if not session.get('logged_in'):
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
global nameDB
|
||||||
|
nameDB = request.form['dbName'] + '.db'
|
||||||
|
load_config()
|
||||||
|
init_db()
|
||||||
|
init_tag()
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
|
def check_table_tag_exists():
|
||||||
|
db = get_db()
|
||||||
|
cur = db.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='tags'")
|
||||||
|
result = cur.fetchone()
|
||||||
|
print("Table tag : ",result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def create_tag_table():
|
||||||
|
db = get_db()
|
||||||
|
with app.open_resource('data/handle_old_schema.sql', mode='r') as f:
|
||||||
|
db.cursor().executescript(f.read())
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
def handle_old_schema():
|
||||||
|
result = check_table_tag_exists()
|
||||||
|
if(result is None):
|
||||||
|
create_tag_table()
|
||||||
|
init_tag()
|
||||||
|
|
||||||
|
def get_card_already_known(type):
|
||||||
|
db = get_db()
|
||||||
|
|
||||||
|
query = '''
|
||||||
|
SELECT
|
||||||
|
id, type, front, back, known
|
||||||
|
FROM cards
|
||||||
|
WHERE
|
||||||
|
type = ?
|
||||||
|
and known = 1
|
||||||
|
ORDER BY RANDOM()
|
||||||
|
LIMIT 1
|
||||||
|
'''
|
||||||
|
|
||||||
|
cur = db.execute(query, [type])
|
||||||
|
return cur.fetchone()
|
||||||
|
|
||||||
|
@app.route('/mark_unknown/<card_id>/<card_type>')
|
||||||
|
def mark_unknown(card_id, card_type):
|
||||||
|
if not session.get('logged_in'):
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
db = get_db()
|
||||||
|
db.execute('UPDATE cards SET known = 0 WHERE id = ?', [card_id])
|
||||||
|
db.commit()
|
||||||
|
flash('Card marked as unknown.')
|
||||||
|
return redirect(url_for('memorize_known', card_type=card_type))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(host='0.0.0.0')
|
app.run(host='0.0.0.0')
|
||||||
|
|||||||
@@ -40,11 +40,11 @@ $(document).ready(function(){
|
|||||||
$('.toggleButton').removeClass('toggleSelected');
|
$('.toggleButton').removeClass('toggleSelected');
|
||||||
$(this).addClass('toggleSelected');
|
$(this).addClass('toggleSelected');
|
||||||
|
|
||||||
if (checkedVal == '1') {
|
// if (checkedVal == '1') {
|
||||||
$('textarea[name=back]').attr('rows', 5);
|
// $('textarea[name=back]').attr('rows', 5);
|
||||||
} else {
|
// } else {
|
||||||
$('textarea[name=back]').attr('rows', 12);
|
// $('textarea[name=back]').attr('rows', 12);
|
||||||
}
|
// }
|
||||||
|
|
||||||
$('.fieldFront').show();
|
$('.fieldFront').show();
|
||||||
$('.fieldBack').show();
|
$('.fieldBack').show();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ textarea {
|
|||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cardContent h4 {
|
.cardContent .tagContent h4 {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,11 @@
|
|||||||
<h2>Add a Card</h2>
|
<h2>Add a Card</h2>
|
||||||
<form action="{{ url_for('add_card') }}" method="post" class="cardForm">
|
<form action="{{ url_for('add_card') }}" method="post" class="cardForm">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="general" class="toggleButton btn btn-default btn-lg">General
|
{% for tag in tags %}
|
||||||
<input type="radio" name="type" value="1" id="general"/>
|
<label for={{tag.tagName}} class="toggleButton btn btn-default btn-lg">{{tag.tagName}}
|
||||||
</label>
|
<input type="radio" name="type" value={{tag.id}} id={{tag.tagName}}>
|
||||||
<label for="code" class="toggleButton btn btn-default btn-lg">Code
|
|
||||||
<input type="radio" name="type" value="2" id="code"/>
|
|
||||||
</label>
|
</label>
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group fieldFront">
|
<div class="form-group fieldFront">
|
||||||
<label for="front">Front of Card</label>
|
<label for="front">Front of Card</label>
|
||||||
@@ -33,44 +32,5 @@
|
|||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h2>{{ cards|length }} Card{{ '' if (cards|length == 1) else 's' }}</h2>
|
<h2>{{ cards|length }} Card{{ '' if (cards|length == 1) else 's' }}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group btn-group-md" role="group" aria-label="filters">
|
|
||||||
<a href="{{ url_for('filter_cards', filter_name="all") }}" class="btn btn-{{ "primary" if filter_name == "all" else "default" }}">All</a>
|
|
||||||
<a href="{{ url_for('filter_cards', filter_name="general") }}" class="btn btn-{{ "primary" if filter_name == "general" else "default" }}">General</a>
|
|
||||||
<a href="{{ url_for('filter_cards', filter_name="code") }}" class="btn btn-{{ "primary" if filter_name == "code" else "default" }}">Code</a>
|
|
||||||
<a href="{{ url_for('filter_cards', filter_name="known") }}" class="btn btn-{{ "primary" if filter_name == "known" else "default" }}">Known</a>
|
|
||||||
<a href="{{ url_for('filter_cards', filter_name="unknown") }}" class="btn btn-{{ "primary" if filter_name == "unknown" else "default" }}">Unknown</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<table class="table table-bordered">
|
|
||||||
{% for card in cards %}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a href="{{ url_for('edit', card_id=card.id) }}" class="btn btn-xs btn-primary"><i class="fa fa-pencil" aria-hidden="true"></i></a>
|
|
||||||
</td>
|
|
||||||
<td class="cardContent">
|
|
||||||
<h4>
|
|
||||||
{{ card.front }}
|
|
||||||
</h4>
|
|
||||||
{% if card.type == 1 %}
|
|
||||||
{{ card.back|replace("\n", "<br />")|safe }}
|
|
||||||
{% else %}
|
|
||||||
<pre><code>{{ card.back|escape }}</code></pre>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% else %}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<em>No cards to show.</em>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
17
templates/createDb.html
Normal file
17
templates/createDb.html
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{% extends "layout.html" %}
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
<div class="well editPanelTag">
|
||||||
|
<h2>Init database</h2>
|
||||||
|
<form action="{{ url_for('init') }}" method="post" class="dbForm">
|
||||||
|
<div class="form-group fieldDbName">
|
||||||
|
<label for="dbName">Database name</label>
|
||||||
|
<input type="text" name="dbName" id="dbName" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button type="submit" class="saveButton btn btn-lg btn-primary">Create</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -1,17 +1,24 @@
|
|||||||
{% extends "layout.html" %}
|
{% extends "layout.html" %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="well">
|
<div class="well editPanel">
|
||||||
<h2>Edit Card #{{ card.id }}</h2>
|
<h2>Edit Card #{{ card.id }}</h2>
|
||||||
<form action="{{ url_for('edit_card') }}" method="post" class="cardForm">
|
<form action="{{ url_for('edit_card') }}" method="post" class="cardForm">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="general" class="btn btn-default btn-lg">General
|
{% for tag in tags %}
|
||||||
|
<label for={{tag.tagName}} class="toggleButton btn btn-default btn-lg">{{tag.tagName}}
|
||||||
|
<input type="radio" name="type" value={{tag.id}}
|
||||||
|
id={{tag.tagName}} {{ "checked" if (card.type == tag.id) else "" }} />
|
||||||
|
</label>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<!-- <label for="general" class="btn btn-default btn-lg">General
|
||||||
<input type="radio" name="type" value="1"
|
<input type="radio" name="type" value="1"
|
||||||
id="general" {{ "checked" if (card.type == 1) else "" }} />
|
id="general" {{ "checked" if (card.type == 1) else "" }} />
|
||||||
</label>
|
</label>
|
||||||
<label for="code" class="btn btn-default btn-lg">Code
|
<label for="code" class="btn btn-default btn-lg">Code
|
||||||
<input type="radio" name="type" value="2" id="code" {{ "checked" if (card.type == 2) else "" }} />
|
<input type="radio" name="type" value="2" id="code" {{ "checked" if (card.type == 2) else "" }} />
|
||||||
</label>
|
</label> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="front">Front of Card</label>
|
<label for="front">Front of Card</label>
|
||||||
|
|||||||
18
templates/editTag.html
Normal file
18
templates/editTag.html
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{% extends "layout.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<div class="well">
|
||||||
|
<h2>Edit Tag #{{ tag.id }}</h2>
|
||||||
|
<form action="{{ url_for('update_tag') }}" method="post" class="tagForm">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="tagName">Tag name</label>
|
||||||
|
<input type="text" name="tagName" id="tagName" class="form-control" value="{{ tag.tagName|e }}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="hidden" name="tag_id" value="{{ tag.id|e }}" />
|
||||||
|
<button type="submit" class="saveButton btn btn-lg btn-primary">Save</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@@ -24,8 +24,12 @@
|
|||||||
<li><a href="{{ url_for('login') }}">log in</a></li>
|
<li><a href="{{ url_for('login') }}">log in</a></li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li><a href="{{ url_for('cards') }}">cards</a></li>
|
<li><a href="{{ url_for('cards') }}">cards</a></li>
|
||||||
<li><a href="{{ url_for('general') }}">general</a></li>
|
<li><a href="{{ url_for('tags') }}">tags</a></li>
|
||||||
<li><a href="{{ url_for('code') }}">code</a></li>
|
<li><a href="{{ url_for('show') }}">show</a></li>
|
||||||
|
<li><a href="{{ url_for('list_db') }}">list database</a></li>
|
||||||
|
<li><a href="{{ url_for('create_db') }}">create database</a></li>
|
||||||
|
<li><a href="{{ url_for('memorize', card_type='1') }}">memorize</a></li>
|
||||||
|
<li><a href="{{ url_for('memorize_known', card_type='1') }}">memorize known items</a></li>
|
||||||
<li> </li>
|
<li> </li>
|
||||||
<li><a href="{{ url_for('logout') }}">log out</a></li>
|
<li><a href="{{ url_for('logout') }}">log out</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
25
templates/listDb.html
Normal file
25
templates/listDb.html
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{% extends "layout.html" %}
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
<table class="table table-bordered">
|
||||||
|
{% for db in dbs %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="{{ url_for('load_db', name=db) }}" class="btn btn-lg btn-primary">Load</a>
|
||||||
|
</td>
|
||||||
|
<td class="dbContent">
|
||||||
|
<h4>
|
||||||
|
{{ db }}
|
||||||
|
</h4>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% else %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<em>No dbs to show.</em>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -4,8 +4,9 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12 text-center">
|
<div class="col-xs-12 text-center">
|
||||||
<div class="btn-group btn-group-lg" role="group" aria-label="card type">
|
<div class="btn-group btn-group-lg" role="group" aria-label="card type">
|
||||||
<a href="{{ url_for('general') }}" class="btn btn-{{ "primary" if card_type == "general" else "default" }}">General</a>
|
{% for tag in tags %}
|
||||||
<a href="{{ url_for('code') }}" class="btn btn-{{ "primary" if card_type == "code" else "default" }}">Code</a>
|
<a href="{{ url_for('memorize', card_type=tag.id) }}" class="btn btn-{{ "primary" if card_type == tag.id else "default" }}">{{tag.tagName}}</a>
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -81,7 +82,7 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
||||||
<a href="{{ url_for(card_type) }}" class="btn btn-primary btn-lg">
|
<a href="{{ url_for('memorize', card_type=card_type) }}" class="btn btn-primary btn-lg">
|
||||||
Next Card
|
Next Card
|
||||||
<i class="fa fa-arrow-right"></i>
|
<i class="fa fa-arrow-right"></i>
|
||||||
</a>
|
</a>
|
||||||
@@ -92,7 +93,7 @@
|
|||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<a href="{{ url_for(card_type, card_id=card.id) }}" class="btn btn-default btn-sm">
|
<a href="{{ url_for('bookmark', card_type=3, card_id=card.id) }}" class="btn btn-default btn-sm">
|
||||||
<i class="fa fa-bookmark"></i>
|
<i class="fa fa-bookmark"></i>
|
||||||
bookmark this card (#{{ card.id }})
|
bookmark this card (#{{ card.id }})
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
82
templates/memorize_known.html
Normal file
82
templates/memorize_known.html
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
{% extends "layout.html" %}
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12 text-center">
|
||||||
|
<div class="btn-group btn-group-lg" role="group" aria-label="card type">
|
||||||
|
{% for tag in tags %}
|
||||||
|
<a href="{{ url_for('memorize_known', card_type=tag.id) }}" class="btn btn-{{ "primary" if card_type == tag.id else "default" }}">{{tag.tagName}}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<div class="row memorizePanel">
|
||||||
|
<div class="col-xs-8 col-xs-offset-2">
|
||||||
|
<div class="panel panel-default cardFront">
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="alignContainer">
|
||||||
|
<div class="alignMiddle frontText">
|
||||||
|
<h3 class="text-center">{{ card.front }}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-primary cardBack">
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="alignContainer">
|
||||||
|
<div class="alignMiddle frontText">
|
||||||
|
{% if card.type == 1 %}
|
||||||
|
{% if short_answer %}
|
||||||
|
<div class="text-center largerText">
|
||||||
|
{% endif %}
|
||||||
|
{{ card.back|replace("\n", "<br />")|safe }}
|
||||||
|
{% if short_answer %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<pre><code>{{ card.back|escape }}</code></pre>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12 text-center">
|
||||||
|
<a href="javascript:" class="btn btn-primary btn-lg flipCard">
|
||||||
|
<i class="fa fa-exchange"></i>
|
||||||
|
Flip Card
|
||||||
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
<a href="{{ url_for('mark_unknown', card_id=card.id, card_type=card_type) }}" class="btn btn-success btn-lg">
|
||||||
|
<i class="fa fa-check"></i>
|
||||||
|
I Unknow It
|
||||||
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
<a href="{{ url_for('memorize_known', card_type=card_type) }}" class="btn btn-primary btn-lg">
|
||||||
|
Next Card
|
||||||
|
<i class="fa fa-arrow-right"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12 text-center">
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<a href="{{ url_for('bookmark', card_type=3, card_id=card.id) }}" class="btn btn-default btn-sm">
|
||||||
|
<i class="fa fa-bookmark"></i>
|
||||||
|
bookmark this card (#{{ card.id }})
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
45
templates/show.html
Normal file
45
templates/show.html
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{% extends "layout.html" %}
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
<div class="page-header">
|
||||||
|
<h2>{{ cards|length }} Card{{ '' if (cards|length == 1) else 's' }}</h2>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group btn-group-md" role="group" aria-label="filters">
|
||||||
|
<a href="{{ url_for('filter_cards', filter_name="all") }}" class="btn btn-{{ "primary" if filter_name == "all" else "default" }}">all</a>
|
||||||
|
{% for tag in tags %}
|
||||||
|
<a href="{{ url_for('filter_cards', filter_name=tag.id) }}" class="btn btn-{{ "primary" if filter_name == tag.id else "default" }}">{{tag.tagName}}</a>
|
||||||
|
{% endfor %}
|
||||||
|
<a href="{{ url_for('filter_cards', filter_name="known") }}" class="btn btn-{{ "primary" if filter_name == "known" else "default" }}">known</a>
|
||||||
|
<a href="{{ url_for('filter_cards', filter_name="unknown") }}" class="btn btn-{{ "primary" if filter_name == "unknown" else "default" }}">unknown</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<table class="table table-bordered">
|
||||||
|
{% for card in cards %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="{{ url_for('edit', card_id=card.id) }}" class="btn btn-xs btn-primary"><i class="fa fa-pencil" aria-hidden="true"></i></a>
|
||||||
|
</td>
|
||||||
|
<td class="cardContent">
|
||||||
|
<h4>
|
||||||
|
{{ card.front }}
|
||||||
|
</h4>
|
||||||
|
{% if card.type == 1 %}
|
||||||
|
{{ card.back|replace("\n", "<br />")|safe }}
|
||||||
|
{% else %}
|
||||||
|
<pre><code>{{ card.back|escape }}</code></pre>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% else %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<em>No cards to show.</em>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
44
templates/tags.html
Normal file
44
templates/tags.html
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{% extends "layout.html" %}
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
<div class="well editPanelTag">
|
||||||
|
<h2>Add a Tag</h2>
|
||||||
|
<form action="{{ url_for('add_tag') }}" method="post" class="tagForm">
|
||||||
|
<div class="form-group fieldTagName">
|
||||||
|
<label for="tagName">Tag name</label>
|
||||||
|
<input type="text" name="tagName" id="tagName" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button type="submit" class="saveButton btn btn-lg btn-primary">Save</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-header">
|
||||||
|
<h2>{{ tags|length }} Tag{{ '' if (tags|length == 1) else 's' }}</h2>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<table class="table table-bordered">
|
||||||
|
{% for tag in tags %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="{{ url_for('edit_tag', tag_id=tag.id) }}" class="btn btn-xs btn-primary"><i class="fa fa-pencil" aria-hidden="true"></i></a>
|
||||||
|
</td>
|
||||||
|
<td class="tagContent">
|
||||||
|
<h4>
|
||||||
|
{{ tag.tagName }}
|
||||||
|
</h4>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% else %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<em>No tags to show.</em>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user