From cb6c84069eb5b1f12aeb4e9ea0f428a8f825ad2e Mon Sep 17 00:00:00 2001 From: Marijn Doeve Date: Tue, 23 Mar 2021 10:51:17 +0100 Subject: [PATCH] Cleanup Made is more presentable, added a README and a simple cleanup. --- .vscode/settings.json | 3 + Pipfile | 4 +- Pipfile.lock | 102 ++++++++++++---------------------- README.md | 18 ++++++ app.py | 10 ++++ model.py | 2 +- templates/adm/uploadfile.html | 4 +- templates/main/contact.html | 10 ++-- templates/main/footer.html | 2 +- templates/main/index.html | 2 +- templates/main/nav.html | 2 +- 11 files changed, 78 insertions(+), 81 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 README.md diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a808068 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.pythonPath": "/Users/marijn/.local/share/virtualenvs/mvl-flask-HZyO5HXA/bin/python" +} \ No newline at end of file diff --git a/Pipfile b/Pipfile index 25848f3..5a5bb9b 100644 --- a/Pipfile +++ b/Pipfile @@ -9,7 +9,7 @@ verify_ssl = true flask = "*" flask-sqlalchemy = "*" gunicorn = "*" -psycopg2-binary = "*" +psycopg2 = "*" [requires] -python_version = "3.7" +python_version = "3.9" diff --git a/Pipfile.lock b/Pipfile.lock index e62ea3c..ec0c36a 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "c2d61bd8088f47c3f29ed6dbe2aa8a396284e7587021c1bc00d6ae8685e517dc" + "sha256": "2d1f5f4e8498d9eed144ea06b0fe5ccce9e748352cf2001b01cf94d60161a496" }, "pipfile-spec": 6, "requires": { - "python_version": "3.7" + "python_version": "3.9" }, "sources": [ { @@ -21,23 +21,24 @@ "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==7.1.2" }, "flask": { "hashes": [ - "sha256:ad7c6d841e64296b962296c2c2dabc6543752985727af86a975072dea984b6f3", - "sha256:e7d32475d1de5facaa55e3958bc4ec66d3762076b074296aa50ef8fdc5b9df61" + "sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060", + "sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557" ], "index": "pypi", - "version": "==1.0.3" + "version": "==1.1.2" }, "flask-sqlalchemy": { "hashes": [ - "sha256:0c9609b0d72871c540a7945ea559c8fdf5455192d2db67219509aed680a3d45a", - "sha256:8631bbea987bc3eb0f72b1f691d47bd37ceb795e73b59ab48586d76d75a7c605" + "sha256:2bda44b43e7cacb15d4e05ff3cc1f8bc97936cc464623424102bfc2c35e95912", + "sha256:f12c3d4cc5cc7fdcc148b9527ea05671718c3ea45d50c7e732cceb33f574b390" ], "index": "pypi", - "version": "==2.4.0" + "version": "==2.5.1" }, "greenlet": { "hashes": [ @@ -85,30 +86,23 @@ "sha256:f8450d5ef759dbe59f84f2c9f77491bb3d3c44bc1a573746daf086e70b14c243", "sha256:f97d83049715fd9dec7911860ecf0e17b48d8725de01e45de07d8ac0bd5bc378" ], - "markers": "python_version >= '3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==1.0.0" }, "gunicorn": { "hashes": [ - "sha256:aa8e0b40b4157b36a5df5e599f45c9c76d6af43845ba3b3b0efe2c70473c2471", - "sha256:fa2662097c66f920f53f70621c6c58ca4a3c4d3434205e608e121b5b3b71f4f3" + "sha256:1904bb2b8a43658807108d59c3f3d56c2b6121a701161de0ddf9ad140073c626", + "sha256:cd4a810dd51bf497552cf3f863b575dabd73d6ad6a91075b65936b151cbf4f9c" ], "index": "pypi", - "version": "==19.9.0" - }, - "importlib-metadata": { - "hashes": [ - "sha256:742add720a20d0467df2f444ae41704000f50e1234f46174b51f9c6031a1bd71", - "sha256:b74159469b464a99cb8cc3e21973e4d96e05d3024d337313fedb618a6e86e6f4" - ], - "markers": "python_version < '3.8'", - "version": "==3.7.3" + "version": "==20.0.4" }, "itsdangerous": { "hashes": [ "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.1.0" }, "jinja2": { @@ -116,7 +110,7 @@ "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419", "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6" ], - "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==2.11.3" }, "markupsafe": { @@ -174,41 +168,29 @@ "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be", "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.1.1" }, - "psycopg2-binary": { + "psycopg2": { "hashes": [ - "sha256:080c72714784989474f97be9ab0ddf7b2ad2984527e77f2909fcd04d4df53809", - "sha256:110457be80b63ff4915febb06faa7be002b93a76e5ba19bf3f27636a2ef58598", - "sha256:171352a03b22fc099f15103959b52ee77d9a27e028895d7e5fde127aa8e3bac5", - "sha256:19d013e7b0817087517a4b3cab39c084d78898369e5c46258aab7be4f233d6a1", - "sha256:249b6b21ae4eb0f7b8423b330aa80fab5f821b9ffc3f7561a5e2fd6bb142cf5d", - "sha256:2ac0731d2d84b05c7bb39e85b7e123c3a0acd4cda631d8d542802c88deb9e87e", - "sha256:2b6d561193f0dc3f50acfb22dd52ea8c8dfbc64bcafe3938b5f209cc17cb6f00", - "sha256:2bd23e242e954214944481124755cbefe7c2cf563b1a54cd8d196d502f2578bf", - "sha256:3e1239242ca60b3725e65ab2f13765fc199b03af9eaf1b5572f0e97bdcee5b43", - "sha256:3eb70bb697abbe86b1d2b1316370c02ba320bfd1e9e35cf3b9566a855ea8e4e5", - "sha256:51a2fc7e94b98bd1bb5d4570936f24fc2b0541b63eccadf8fdea266db8ad2f70", - "sha256:52f1bdafdc764b7447e393ed39bb263eccb12bfda25a4ac06d82e3a9056251f6", - "sha256:5b3581319a3951f1e866f4f6c5e42023db0fae0284273b82e97dfd32c51985cd", - "sha256:63c1b66e3b2a3a336288e4bcec499e0dc310cd1dceaed1c46fa7419764c68877", - "sha256:8123a99f24ecee469e5c1339427bcdb2a33920a18bb5c0d58b7c13f3b0298ba3", - "sha256:85e699fcabe7f817c0f0a412d4e7c6627e00c412b418da7666ff353f38e30f67", - "sha256:8dbff4557bbef963697583366400822387cccf794ccb001f1f2307ed21854c68", - "sha256:908d21d08d6b81f1b7e056bbf40b2f77f8c499ab29e64ec5113052819ef1c89b", - "sha256:af39d0237b17d0a5a5f638e9dffb34013ce2b1d41441fd30283e42b22d16858a", - "sha256:af51bb9f055a3f4af0187149a8f60c9d516cf7d5565b3dac53358796a8fb2a5b", - "sha256:b2ecac57eb49e461e86c092761e6b8e1fd9654dbaaddf71a076dcc869f7014e2", - "sha256:cd37cc170678a4609becb26b53a2bc1edea65177be70c48dd7b39a1149cabd6e", - "sha256:d17e3054b17e1a6cb8c1140f76310f6ede811e75b7a9d461922d2c72973f583e", - "sha256:d305313c5a9695f40c46294d4315ed3a07c7d2b55e48a9010dad7db7a66c8b7f", - "sha256:dd0ef0eb1f7dd18a3f4187226e226a7284bda6af5671937a221766e6ef1ee88f", - "sha256:e1adff53b56db9905db48a972fb89370ad5736e0450b96f91bcf99cadd96cfd7", - "sha256:f0d43828003c82dbc9269de87aa449e9896077a71954fbbb10a614c017e65737", - "sha256:f78e8b487de4d92640105c1389e5b90be3496b1d75c90a666edd8737cc2dbab7" + "sha256:00195b5f6832dbf2876b8bf77f12bdce648224c89c880719c745b90515233301", + "sha256:068115e13c70dc5982dfc00c5d70437fe37c014c808acce119b5448361c03725", + "sha256:26e7fd115a6db75267b325de0fba089b911a4a12ebd3d0b5e7acb7028bc46821", + "sha256:2c93d4d16933fea5bbacbe1aaf8fa8c1348740b2e50b3735d1b0bf8154cbf0f3", + "sha256:56007a226b8e95aa980ada7abdea6b40b75ce62a433bd27cec7a8178d57f4051", + "sha256:56fee7f818d032f802b8eed81ef0c1232b8b42390df189cab9cfa87573fe52c5", + "sha256:6a3d9efb6f36f1fe6aa8dbb5af55e067db802502c55a9defa47c5a1dad41df84", + "sha256:a49833abfdede8985ba3f3ec641f771cca215479f41523e99dace96d5b8cce2a", + "sha256:ad2fe8a37be669082e61fb001c185ffb58867fdbb3e7a6b0b0d2ffe232353a3e", + "sha256:b8cae8b2f022efa1f011cc753adb9cbadfa5a184431d09b273fb49b4167561ad", + "sha256:d160744652e81c80627a909a0e808f3c6653a40af435744de037e3172cf277f5", + "sha256:d5062ae50b222da28253059880a871dc87e099c25cb68acf613d9d227413d6f7", + "sha256:f22ea9b67aea4f4a1718300908a2fb62b3e4276cf00bd829a97ab5894af42ea3", + "sha256:f974c96fca34ae9e4f49839ba6b78addf0346777b46c4da27a7bf54f48d3057d", + "sha256:fb23f6c71107c37fd667cb4ea363ddeb936b348bbd6449278eb92c189699f543" ], "index": "pypi", - "version": "==2.8.3" + "version": "==2.8.6" }, "sqlalchemy": { "hashes": [ @@ -247,30 +229,16 @@ "sha256:facacaea95e0822f7bbeaa6909b30b2836b14cff8790209d52a0c866e240b673", "sha256:ff76d7dbf33f62e30e5a1d1b095d46afcdc49e42cbe33ce12014110147466700" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", "version": "==1.4.2" }, - "typing-extensions": { - "hashes": [ - "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918", - "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c", - "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f" - ], - "markers": "python_version < '3.8'", - "version": "==3.7.4.3" - }, "werkzeug": { "hashes": [ "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43", "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c" ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==1.0.1" - }, - "zipp": { - "hashes": [ - "sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76", - "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098" - ], - "version": "==3.4.1" } }, "develop": {} diff --git a/README.md b/README.md new file mode 100644 index 0000000..43af504 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# Portfolio Website + +A quick portfolio website made to run on Heroku without any storage bucket. + + +Tables can be created with: +```python + >>> from app import db + >>> db.create_all() +``` + +## Missing features + +- Migrations +- Multiple categories +- An admin interface to add things (other then pictures) to the portfolio. +- A login-system +- A JQuery-free website \ No newline at end of file diff --git a/app.py b/app.py index 1f47c06..0d9cc50 100644 --- a/app.py +++ b/app.py @@ -9,6 +9,7 @@ from model import db, Post, Category, ImageBase64 # Check for environment variable env_vars = ["DATABASE_URL", "PASSWORD", 'SECRET_KEY'] + for env_var in env_vars: if not os.getenv(env_var): raise RuntimeError(f"{env_var} is not set") @@ -28,12 +29,14 @@ db.init_app(app) def index(): posts = Post.get_posts() print(posts[0].title) + return render_template("main/index.html", posts=posts) @app.route('/') def category(category_name): category_item = Category.query.filter(func.lower(Category.name) == category_name.replace('_', ' ')).first() + if not category_item: return abort(404) @@ -50,6 +53,7 @@ def contact(): @app.route("/api/post/", methods=["POST"]) def get_post(post_id): post = Post.query.get(post_id) + if post: return jsonify({"success": True, "post": post.serialize}) else: @@ -59,9 +63,12 @@ def get_post(post_id): @app.route('/images/') def get_image(filename): image_b64 = ImageBase64.query.filter(ImageBase64.filename == filename).first() + if not image_b64: return abort(404) + image = standard_b64decode(image_b64.data) + return send_file(BytesIO(image), mimetype=image_b64.mimetype, attachment_filename=filename) @@ -71,10 +78,13 @@ def file_uploaded(): if not request.form.get('password') == os.getenv('PASSWORD'): flash("Wrong Password") return redirect("/adm/uploadfile") + # check if the post request has the file part if 'files' not in request.files: return redirect("/adm/uploadfile") + files = request.files.getlist('files') + # if user does not select file, browser also # submit an empty part without filename for file in files: diff --git a/model.py b/model.py index d328b66..9bd3b01 100644 --- a/model.py +++ b/model.py @@ -53,6 +53,6 @@ class ImageBase64(db.Model): class Category(db.Model): - __tablename__ = "category" + __tablename__ = "categories" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), nullable=False) diff --git a/templates/adm/uploadfile.html b/templates/adm/uploadfile.html index cd48147..5faf126 100644 --- a/templates/adm/uploadfile.html +++ b/templates/adm/uploadfile.html @@ -1,6 +1,6 @@ {% extends 'adm/layout.html' %} {% block title %} - Upload File - mvl + Upload File {% endblock %} {% block main %} {% if get_flashed_messages() %} @@ -13,7 +13,7 @@
- +
diff --git a/templates/main/contact.html b/templates/main/contact.html index e712173..ea3fb9a 100644 --- a/templates/main/contact.html +++ b/templates/main/contact.html @@ -5,15 +5,13 @@

Hoi!

-

Na het behalen van mijn diploma 'Product Design' van de Hogeschool van Amsterdam in februari 2018 ben - ik gaan werken bij een grafisch ontwerpbureau in Haarlem. - Daarnaast ben ik steeds meer bezig met eigen opdrachten, zoals te zien is in dit portfolio.

+

- - -
diff --git a/templates/main/footer.html b/templates/main/footer.html index 162a41c..217017b 100644 --- a/templates/main/footer.html +++ b/templates/main/footer.html @@ -1,3 +1,3 @@
- © 2019 Marlous van Leeuwen & Marijn Jansen + © Marijn Doeve
\ No newline at end of file diff --git a/templates/main/index.html b/templates/main/index.html index ffba0fe..0355cd4 100644 --- a/templates/main/index.html +++ b/templates/main/index.html @@ -1,6 +1,6 @@ {% extends "main/layout.html" %} -{% block title %}Marlous van Leeuwen{% endblock %} +{% block title %}{% endblock %} {% block main %}
diff --git a/templates/main/nav.html b/templates/main/nav.html index 29388fe..4a10647 100644 --- a/templates/main/nav.html +++ b/templates/main/nav.html @@ -8,7 +8,7 @@