diff --git a/app.py b/app.py index 87c59d5..a40a581 100644 --- a/app.py +++ b/app.py @@ -1,6 +1,13 @@ +import os +import datetime +import hashlib from flask import Flask, session, url_for, redirect, render_template, request, abort, flash from database import list_users, verify, delete_user_from_db, add_user from database import read_note_from_db, write_note_into_db, delete_note_from_db, match_user_id_with_note_id +from database import image_upload_record, list_images_for_user +from werkzeug.utils import secure_filename + + app = Flask(__name__) app.config.from_object('config') @@ -23,6 +30,10 @@ def FUN_404(error): def FUN_405(error): return render_template("page_405.html"), 405 +@app.errorhandler(413) +def FUN_413(error): + return render_template("page_413.html"), 413 + @@ -43,7 +54,13 @@ def FUN_private(): [x[1] for x in notes_list],\ [x[2] for x in notes_list],\ ["/delete_note/" + x[0] for x in notes_list]) - return render_template("private_page.html", notes = notes_table) + + images_list = list_images_for_user(session['current_user']) + images_table = zip([x[0] for x in images_list],\ + [x[1] for x in images_list],\ + [x[2] for x in images_list]) + + return render_template("private_page.html", notes = notes_table, images = images_table) else: return abort(401) @@ -76,6 +93,36 @@ def FUN_delete_note(note_id): delete_note_from_db(note_id) else: return abort(401) + return(redirect(url_for("FUN_private"))) + + +# Reference: http://flask.pocoo.org/docs/0.12/patterns/fileuploads/ +ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif']) +def allowed_file(filename): + return '.' in filename and \ + filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS + +@app.route("/upload_image", methods = ['POST']) +def FUN_upload_image(): + if request.method == 'POST': + # check if the post request has the file part + if 'file' not in request.files: + flash('No file part') + return(redirect(url_for("FUN_private"))) + file = request.files['file'] + # if user does not select file, browser also submit a empty part without filename + if file.filename == '': + flash('No selected file') + return(redirect(url_for("FUN_private"))) + if file and allowed_file(file.filename): + filename = secure_filename(file.filename) + upload_time = str(datetime.datetime.now()) + image_uid = hashlib.sha1(upload_time + filename).hexdigest() + # Save the image into UPLOAD_FOLDER + file.save(os.path.join(app.config['UPLOAD_FOLDER'], image_uid + "-" + filename)) + # Record this uploading in database + image_upload_record(image_uid, session['current_user'], filename, upload_time) + return(redirect(url_for("FUN_private"))) return(redirect(url_for("FUN_private"))) @@ -83,6 +130,7 @@ def FUN_delete_note(note_id): + @app.route("/login", methods = ["POST"]) def FUN_login(): id_submitted = request.form.get("id").upper() diff --git a/config.py b/config.py index 6ecd2c8..c514ec6 100644 --- a/config.py +++ b/config.py @@ -1 +1,3 @@ -SECRET_KEY = "fdsafasd" \ No newline at end of file +SECRET_KEY = "fdsafasd" +UPLOAD_FOLDER = "image_pool" +MAX_CONTENT_LENGTH = 16 * 1024 * 1024 \ No newline at end of file diff --git a/database.py b/database.py index c0966ef..e960ec6 100644 --- a/database.py +++ b/database.py @@ -4,6 +4,7 @@ import datetime user_db_file_location = "database_file/users.db" note_db_file_location = "database_file/notes.db" +image_db_file_location = "database_file/images.db" def list_users(): _conn = sqlite3.connect(user_db_file_location) @@ -41,6 +42,13 @@ def delete_user_from_db(id): _conn.commit() _conn.close() + # when we delete a user from database USERS, we also need to delete all his or her images data from database IMAGES + _conn = sqlite3.connect(image_db_file_location) + _c = _conn.cursor() + _c.execute("delete from images where owner = '" + id + "';") + _conn.commit() + _conn.close() + def add_user(id, pw): _conn = sqlite3.connect(user_db_file_location) _c = _conn.cursor() @@ -101,6 +109,30 @@ def delete_note_from_db(note_id): _conn.commit() _conn.close() +def image_upload_record(uid, owner, image_name, timestamp): + _conn = sqlite3.connect(image_db_file_location) + _c = _conn.cursor() + + command = "insert into images values ('{0}', '{1}', '{2}', '{3}');".format(uid, owner, image_name, timestamp) + _c.execute(command) + + _conn.commit() + _conn.close() + +def list_images_for_user(owner): + _conn = sqlite3.connect(image_db_file_location) + _c = _conn.cursor() + + command = "select uid, timestamp, name from images where owner = '{0}'".format(owner) + _c.execute(command) + result = _c.fetchall() + + _conn.commit() + _conn.close() + + return result + + diff --git a/database_file/images.db b/database_file/images.db new file mode 100644 index 0000000..9ea489d Binary files /dev/null and b/database_file/images.db differ diff --git a/image_pool/3afadaa2a3cbc1fffc6d8229ca1936b9760e1c56-made-with-flask.png b/image_pool/3afadaa2a3cbc1fffc6d8229ca1936b9760e1c56-made-with-flask.png new file mode 100644 index 0000000..ac546db Binary files /dev/null and b/image_pool/3afadaa2a3cbc1fffc6d8229ca1936b9760e1c56-made-with-flask.png differ diff --git a/image_pool/e7c589f2627e1dac3fb9d57ad9ccd6066e67ce31-flask.png b/image_pool/e7c589f2627e1dac3fb9d57ad9ccd6066e67ce31-flask.png new file mode 100644 index 0000000..f98ce46 Binary files /dev/null and b/image_pool/e7c589f2627e1dac3fb9d57ad9ccd6066e67ce31-flask.png differ diff --git a/image_pool/f739cc0a8bc1c3d17cc3dcc4fc5ff70b8266998b-flask-project.png b/image_pool/f739cc0a8bc1c3d17cc3dcc4fc5ff70b8266998b-flask-project.png new file mode 100644 index 0000000..1887100 Binary files /dev/null and b/image_pool/f739cc0a8bc1c3d17cc3dcc4fc5ff70b8266998b-flask-project.png differ diff --git a/templates/index.html b/templates/index.html index f2a3876..cb3d8df 100644 --- a/templates/index.html +++ b/templates/index.html @@ -13,6 +13,7 @@
  • Integrating with Bootstrap
  • Interaction with Database (SQLite)
  • Invoking static resources
  • +
  • Upload files
  • For more basic knowledge of Flask, you can refer to a tutorial on Tutorialspoint.

    diff --git a/templates/page_413.html b/templates/page_413.html new file mode 100644 index 0000000..a870d7c --- /dev/null +++ b/templates/page_413.html @@ -0,0 +1,6 @@ +{% extends "layout.html" %} +{% block page_title %}Request if too big(413){% endblock %} +{% block body %} + {{ super() }} + Please check the file size you're uploading. +{% endblock %} \ No newline at end of file diff --git a/templates/private_page.html b/templates/private_page.html index 202e11b..e96b60b 100644 --- a/templates/private_page.html +++ b/templates/private_page.html @@ -43,4 +43,32 @@ {% endif %} +
    +

    Upload Image

    +
    +

    + +

    + + {% if images %} +

    Your Images

    + + + + + + + + + {% for image_id, timestamp, image_name in images %} + + + + + + + {% endfor %} +
    Image IDTimestampImage Name
    {{ image_id }} {{ timestamp }} {{ image_name }}
    + {% endif %} + {% endblock %} \ No newline at end of file