diff --git a/data/handle_old_schema.sql b/data/handle_old_schema.sql new file mode 100644 index 0000000..437854f --- /dev/null +++ b/data/handle_old_schema.sql @@ -0,0 +1,4 @@ +create table if not exists tags ( + id integer primary key autoincrement, + tagName text not null +); \ No newline at end of file diff --git a/data/schema.sql b/data/schema.sql index 6a3ffff..fa6bbb2 100644 --- a/data/schema.sql +++ b/data/schema.sql @@ -1,4 +1,4 @@ -drop table if exists cards; +-- drop table if exists cards; create table cards ( id integer primary key autoincrement, type tinyint not null, /* 1 for vocab, 2 for code */ @@ -6,3 +6,8 @@ create table cards ( back text not null, known boolean default 0 ); + +create table tags ( + id integer primary key autoincrement, + tagName text not null +); diff --git a/flash_cards.py b/flash_cards.py index 6d34a44..bbe68d1 100644 --- a/flash_cards.py +++ b/flash_cards.py @@ -5,16 +5,20 @@ from flask import Flask, request, session, g, redirect, url_for, abort, \ app = Flask(__name__) app.config.from_object(__name__) +nameDB='cards.db' +pathDB='db' -# 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 load_config(): + app.config.update(dict( + DATABASE=os.path.join(app.root_path, pathDB, nameDB), + SECRET_KEY='development key', + USERNAME='admin', + PASSWORD='default' + )) + app.config.from_envvar('CARDS_SETTINGS', silent=True) +if __name__ == "__main__": + load_config() def connect_db(): rv = sqlite3.connect(app.config['DATABASE']) @@ -28,7 +32,6 @@ def init_db(): 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. @@ -44,21 +47,10 @@ def close_db(error): 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(): if session.get('logged_in'): - return redirect(url_for('general')) + return redirect(url_for('list_db')) else: return redirect(url_for('login')) @@ -75,7 +67,8 @@ def cards(): ''' cur = db.execute(query) 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/') @@ -92,15 +85,20 @@ def filter_cards(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: - return redirect(url_for('cards')) + return redirect(url_for('show')) 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) 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']) @@ -130,7 +128,8 @@ def edit(card_id): ''' cur = db.execute(query, [card_id]) 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']) @@ -158,7 +157,7 @@ def edit_card(): ]) db.commit() flash('Card saved.') - return redirect(url_for('cards')) + return redirect(url_for('show')) @app.route('/delete/') @@ -171,43 +170,51 @@ def delete(card_id): flash('Card deleted.') return redirect(url_for('cards')) - -@app.route('/general') -@app.route('/general/') -def general(card_id=None): - if not session.get('logged_in'): - return redirect(url_for('login')) - return memorize("general", card_id) - - -@app.route('/code') -@app.route('/code/') -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: +@app.route('/memorize') +@app.route('/memorize/') +@app.route('/memorize/') +def memorize(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(type) + card = get_card(card_type) if not card: - flash("You've learned all the " + card_type + " cards.") - return redirect(url_for('cards')) + 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) + short_answer=short_answer, tags=tags) + +@app.route('/memorize_known') +@app.route('/memorize_known/') +@app.route('/memorize_known/') +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): @@ -252,8 +259,7 @@ def mark_known(card_id, card_type): db.execute('UPDATE cards SET known = 1 WHERE id = ?', [card_id]) db.commit() 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']) def login(): @@ -266,7 +272,7 @@ def login(): else: session['logged_in'] = True session.permanent = True # stay logged in - return redirect(url_for('cards')) + return redirect(url_for('index')) return render_template('login.html', error=error) @@ -277,5 +283,191 @@ def logout(): 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() + 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//') +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/') +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//') +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__': app.run(host='0.0.0.0') diff --git a/static/general.js b/static/general.js index b72bad7..5587358 100644 --- a/static/general.js +++ b/static/general.js @@ -40,11 +40,11 @@ $(document).ready(function(){ $('.toggleButton').removeClass('toggleSelected'); $(this).addClass('toggleSelected'); - if (checkedVal == '1') { - $('textarea[name=back]').attr('rows', 5); - } else { - $('textarea[name=back]').attr('rows', 12); - } + // if (checkedVal == '1') { + // $('textarea[name=back]').attr('rows', 5); + // } else { + // $('textarea[name=back]').attr('rows', 12); + // } $('.fieldFront').show(); $('.fieldBack').show(); diff --git a/static/style.css b/static/style.css index 7750666..df864ab 100644 --- a/static/style.css +++ b/static/style.css @@ -7,7 +7,7 @@ textarea { font-family: monospace; } -.cardContent h4 { +.cardContent .tagContent h4 { margin-top: 0; } diff --git a/templates/cards.html b/templates/cards.html index 08b8906..5162154 100644 --- a/templates/cards.html +++ b/templates/cards.html @@ -5,12 +5,11 @@

Add a Card

- -
@@ -33,44 +32,5 @@ -
- All - General - Code - Known - Unknown -
- -
-
- - - {% for card in cards %} - - - - - {% else %} - - - - {% endfor %} -
- - -

- {{ card.front }} -

- {% if card.type == 1 %} - {{ card.back|replace("\n", "
")|safe }} - {% else %} -
{{ card.back|escape }}
- {% endif %} -
- No cards to show. -
- - - {% endblock %} diff --git a/templates/createDb.html b/templates/createDb.html new file mode 100644 index 0000000..d3c1d05 --- /dev/null +++ b/templates/createDb.html @@ -0,0 +1,17 @@ +{% extends "layout.html" %} +{% block body %} + +
+

Init database

+ +
+ + +
+
+ +
+ +
+ +{% endblock %} diff --git a/templates/edit.html b/templates/edit.html index d18f7a8..51c19dd 100644 --- a/templates/edit.html +++ b/templates/edit.html @@ -1,17 +1,24 @@ {% extends "layout.html" %} {% block body %} -
+

Edit Card #{{ card.id }}

-
diff --git a/templates/editTag.html b/templates/editTag.html new file mode 100644 index 0000000..08c87e6 --- /dev/null +++ b/templates/editTag.html @@ -0,0 +1,18 @@ +{% extends "layout.html" %} +{% block body %} +
+

Edit Tag #{{ tag.id }}

+ +
+ + +
+ +
+
+ + +
+ +
+{% endblock %} diff --git a/templates/layout.html b/templates/layout.html index 7fcfda9..37a5874 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -24,8 +24,12 @@
  • log in
  • {% else %}
  • cards
  • -
  • general
  • -
  • code
  • +
  • tags
  • +
  • show
  • +
  • list database
  • +
  • create database
  • +
  • memorize
  • +
  • memorize known items
  •     
  • log out
  • {% endif %} diff --git a/templates/listDb.html b/templates/listDb.html new file mode 100644 index 0000000..9275b92 --- /dev/null +++ b/templates/listDb.html @@ -0,0 +1,25 @@ +{% extends "layout.html" %} +{% block body %} + + + {% for db in dbs %} + + + + + {% else %} + + + + {% endfor %} +
    + Load + +

    + {{ db }} +

    +
    + No dbs to show. +
    + +{% endblock %} \ No newline at end of file diff --git a/templates/memorize.html b/templates/memorize.html index ab93369..be3cccb 100644 --- a/templates/memorize.html +++ b/templates/memorize.html @@ -4,8 +4,9 @@
    - General - Code + {% for tag in tags %} + {{tag.tagName}} + {% endfor %}
    @@ -81,7 +82,7 @@     - + Next Card @@ -92,7 +93,7 @@


    - + bookmark this card (#{{ card.id }}) diff --git a/templates/memorize_known.html b/templates/memorize_known.html new file mode 100644 index 0000000..d09ea76 --- /dev/null +++ b/templates/memorize_known.html @@ -0,0 +1,82 @@ +{% extends "layout.html" %} +{% block body %} + +
    +
    +
    + {% for tag in tags %} + {{tag.tagName}} + {% endfor %} +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    +

    {{ card.front }}

    +
    +
    +
    +
    +
    +
    +
    +
    + {% if card.type == 1 %} + {% if short_answer %} +
    + {% endif %} + {{ card.back|replace("\n", "
    ")|safe }} + {% if short_answer %} +
    + {% endif %} + {% else %} +
    {{ card.back|escape }}
    + {% endif %} +
    +
    +
    +
    +
    +
    + + + + +{% endblock %} diff --git a/templates/show.html b/templates/show.html new file mode 100644 index 0000000..e84e082 --- /dev/null +++ b/templates/show.html @@ -0,0 +1,45 @@ +{% extends "layout.html" %} +{% block body %} + + +
    + all + {% for tag in tags %} + {{tag.tagName}} + {% endfor %} + known + unknown +
    + +
    +
    + + + {% for card in cards %} + + + + + {% else %} + + + + {% endfor %} +
    + + +

    + {{ card.front }} +

    + {% if card.type == 1 %} + {{ card.back|replace("\n", "
    ")|safe }} + {% else %} +
    {{ card.back|escape }}
    + {% endif %} +
    + No cards to show. +
    + +{% endblock %} diff --git a/templates/tags.html b/templates/tags.html new file mode 100644 index 0000000..ce619c4 --- /dev/null +++ b/templates/tags.html @@ -0,0 +1,44 @@ +{% extends "layout.html" %} +{% block body %} + +
    +

    Add a Tag

    +
    +
    + + +
    +
    + +
    +
    +
    + + +
    +
    + + + {% for tag in tags %} + + + + + {% else %} + + + + {% endfor %} +
    + + +

    + {{ tag.tagName }} +

    +
    + No tags to show. +
    + +{% endblock %}