Made is more presentable, added a README and a simple cleanup.
This commit is contained in:
2021-03-23 10:51:17 +01:00
parent e4abd2e3cf
commit cb6c84069e
11 changed files with 78 additions and 81 deletions

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"python.pythonPath": "/Users/marijn/.local/share/virtualenvs/mvl-flask-HZyO5HXA/bin/python"
}

View File

@@ -9,7 +9,7 @@ verify_ssl = true
flask = "*"
flask-sqlalchemy = "*"
gunicorn = "*"
psycopg2-binary = "*"
psycopg2 = "*"
[requires]
python_version = "3.7"
python_version = "3.9"

102
Pipfile.lock generated
View File

@@ -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": {}

18
README.md Normal file
View File

@@ -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

10
app.py
View File

@@ -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('/<string:category_name>')
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/<int:post_id>", 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/<string:filename>')
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:

View File

@@ -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)

View File

@@ -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 @@
<form class="" method=post enctype=multipart/form-data>
<div class="form-group">
<label for=password>Password</label>
<input class="form-control" id=password type=password name=password>
<input class="form-control" id="password" type="password" name="password">
</div>
<div class="form-group">
<div class="custom-file">

View File

@@ -5,15 +5,13 @@
<div class="row justify-content-center">
<div class="col-12 col-md-6 align-content-center">
<h1 class="text-center">Hoi!</h1>
<p>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.</p>
<p></p>
<div class="text-center ">
<a href="https://www.linkedin.com/in/marlousvanleeuwen/"><i
<a href="#"><i
class="social-icon fab fa-linkedin-in fa-3x fa-fw text-dark"></i></a>
<a href="mailto:marlousvleeuwen@live.nl"><i
<a href="#"><i
class="social-icon far fa-envelope fa-3x fa-fw text-dark"></i></a>
<a href="https://www.instagram.com/marlousvleeuwen/"><i
<a href="#"><i
class="social-icon fab fa-instagram fa-3x fa-fw text-dark"></i></a>
</div>
</div>

View File

@@ -1,3 +1,3 @@
<footer class="small text-center text-muted">
&copy; 2019 Marlous van Leeuwen &amp; Marijn Jansen
&copy; Marijn Doeve
</footer>

View File

@@ -1,6 +1,6 @@
{% extends "main/layout.html" %}
{% block title %}Marlous van Leeuwen{% endblock %}
{% block title %}{% endblock %}
{% block main %}
<main class="container">

View File

@@ -8,7 +8,7 @@
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
{% set items = [("Product Design", 'product_design'), ("Grafisch Vormgeven", "grafisch_vormgeven"), ("Fotografie", "fotografie")] %}
{% set items = [("Nice Title", 'internal_title'),] %}
{% for item in items %}
<li class="nav-item">
<a class="nav-link {% if item[1] == request.path[1:] %}active{% endif %}"