From 9a1f2ac5fa0dbf3a92a440b396477f2e3aac0115 Mon Sep 17 00:00:00 2001 From: tmontanaro Date: Mon, 11 Apr 2016 00:31:44 +0200 Subject: [PATCH] first commit --- db_interaction.py | 108 +++++++++++++++++++++++++++++++++++++ db_interaction.pyc | Bin 0 -> 2681 bytes static/rooster.jpg | Bin 0 -> 7530 bytes task_list.db | Bin 0 -> 4096 bytes templates/delete_task.html | 30 +++++++++++ templates/index.html | 23 ++++++++ templates/insert_task.html | 26 +++++++++ templates/show_tasks.html | 19 +++++++ todo_list_flask.py | 71 ++++++++++++++++++++++++ 9 files changed, 277 insertions(+) create mode 100644 db_interaction.py create mode 100644 db_interaction.pyc create mode 100644 static/rooster.jpg create mode 100644 task_list.db create mode 100644 templates/delete_task.html create mode 100644 templates/index.html create mode 100644 templates/insert_task.html create mode 100644 templates/show_tasks.html create mode 100644 todo_list_flask.py diff --git a/db_interaction.py b/db_interaction.py new file mode 100644 index 0000000..6b149b9 --- /dev/null +++ b/db_interaction.py @@ -0,0 +1,108 @@ +''' +Created on Apr 04, 2016 +Copyright (c) 2015-2016 Teodoro Montanaro + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License +@author: tmontanaro +''' + +import sqlite3 + + +def db_insert_task(text, urgent): + ''' + :param text: text that we want to insert as task in the db + :param urgent: 0 if the task is not urgent, 1 otherwise + + This method insert a task in the database + ''' + + # prepare the query text + sql = """INSERT INTO task(todo, urgent) VALUES (?, ?)""" + + #connect to the db + conn = sqlite3.connect("task_list.db") + cursor = conn.cursor() + + try: + #execute the query passing the needed parameters + cursor.execute(sql, (text, urgent) ) + #commit all pending queries + conn.commit() + except Exception,e: + print str(e) + # if something goes wrong: rollback + conn.rollback() + + #close the connection + conn.close() + + +def get_sorted_tasks_list(): + ''' + :param tasks_list: list of existing tasks + + Get existing tasks from the database + ''' + + tasks_list = [] + sql = "SELECT todo FROM task order by todo ASC" #here we order data using "order by" + conn = sqlite3.connect("task_list.db") + + # to remove u from sqlite3 cursor.fetchall() results + conn.text_factory = sqlite3.OptimizedUnicode + + + cursor = conn.cursor() + cursor.execute(sql) + + results = cursor.fetchall() + + # print results + + for task in results: + tasks_list.append(task[0]) #each "task" is a tuple, so we have to take the first element of it + + conn.close() + + return tasks_list + +def db_remove_task(text): + ''' + :param text: text (or part of it) of the task we want to remove from the db + + This method remove from the db all the tasks that contain the specified string + ''' + + # prepare the query text + sql = "delete from task where todo LIKE ?" + + # add percent sign (%) wildcard to select all the strings that contain specified text + # <> + text = "%"+text + "%" + + #connect to the db + conn = sqlite3.connect("task_list.db") + cursor = conn.cursor() + + try: + #execute the query passing the needed parameters + cursor.execute(sql, (text, ) ) + #commit all pending executed queries in the connection + conn.commit() + except Exception,e: + print str(e) + # if something goes wrong: rollback + conn.rollback() + + #close the connection + conn.close() \ No newline at end of file diff --git a/db_interaction.pyc b/db_interaction.pyc new file mode 100644 index 0000000000000000000000000000000000000000..81f716df491fffb08861e5db591bb2e4018ca7a3 GIT binary patch literal 2681 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 + + + + Delete tasks + + +

Here you can delete all the existing tasks that contain a provided string

+

Existing tasks:

+
    + {% for task in tasks_list %} +
  • {{ task }}
  • + {% endfor %} +
+ + {% if substring_for_delete!="" %} +

Removal successfully performed!

+ + {% else %} +
+

+ + +

+
+ {% endif %} + +

Come back home

+ + \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..52d4721 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,23 @@ + + + + + Welcome to the Todo List Manager + + +

Welcome to the Todo List Manager

+

Select the action you want to perform from the following menu:

+ + + + \ No newline at end of file diff --git a/templates/insert_task.html b/templates/insert_task.html new file mode 100644 index 0000000..33be2b2 --- /dev/null +++ b/templates/insert_task.html @@ -0,0 +1,26 @@ + + + + + Login page + + +

Here you can insert a new task

+ + {% if string_for_insertion!="" %} +

Insertion successfully performed!

+ + {% else %} +
+

+ + + +

+
+ {% endif %} + + +

Come back home

+ + \ No newline at end of file diff --git a/templates/show_tasks.html b/templates/show_tasks.html new file mode 100644 index 0000000..c179165 --- /dev/null +++ b/templates/show_tasks.html @@ -0,0 +1,19 @@ + + + + + Show tasks + + +

Existing tasks

+

Here you can see all existing tasks

+
    + {% for task in tasks_list %} +
  • {{ task }}
  • + {% endfor %} +
+ +

Come back home

+ + + \ No newline at end of file diff --git a/todo_list_flask.py b/todo_list_flask.py new file mode 100644 index 0000000..19413e7 --- /dev/null +++ b/todo_list_flask.py @@ -0,0 +1,71 @@ +''' +Created on Apr 11, 2016 +Copyright (c) 2015-2016 Teodoro Montanaro + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License +@author: tmontanaro +''' + + +from flask import Flask, url_for, render_template, request, redirect +import db_interaction + + +app = Flask(__name__) + +@app.route('/') +def hello_world(): + # if no address is given, redirect to the index page + return redirect(url_for('index')) + +@app.route('/index.html') +def index(): + return render_template('index.html') + + +@app.route('/insert_task.html', methods=['GET', 'POST']) +def insert_task(): + if request.method == 'POST': + if ('string_for_insertion' in request.form and request.form['string_for_insertion']!=''): + string_for_insertion = request.form['string_for_insertion'] + if ('urgent_for_insertion' in request.form and request.form['urgent_for_insertion'] == 'on'): + urgent_for_insertion = 1 + else: + urgent_for_insertion = 0 + db_interaction.db_insert_task(string_for_insertion, urgent_for_insertion) + else: + string_for_insertion = "" + else: + string_for_insertion = "" + return render_template('insert_task.html', string_for_insertion = string_for_insertion) + +@app.route('/show_tasks.html') +def show_tasks(): + tasks_list = db_interaction.get_sorted_tasks_list() + return render_template('show_tasks.html', tasks_list=tasks_list) + +@app.route('/delete_task.html', methods=['GET', 'POST']) +def delete_task(): + if request.method == 'POST': + if 'substring_for_delete' in request.form: + substring_for_delete = request.form['substring_for_delete'] + db_interaction.db_remove_task(substring_for_delete) + else: + substring_for_delete = "" + else: + substring_for_delete = "" + tasks_list = db_interaction.get_sorted_tasks_list() + return render_template('delete_task.html', substring_for_delete = substring_for_delete, tasks_list=tasks_list) + + +if __name__ == '__main__': + app.run(debug=True)