Cleanup
Made is more presentable, added a README and a simple cleanup.
This commit is contained in:
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"python.pythonPath": "/Users/marijn/.local/share/virtualenvs/mvl-flask-HZyO5HXA/bin/python"
|
||||
}
|
||||
4
Pipfile
4
Pipfile
@@ -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
102
Pipfile.lock
generated
@@ -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
18
README.md
Normal 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
10
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('/<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:
|
||||
|
||||
2
model.py
2
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)
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<footer class="small text-center text-muted">
|
||||
© 2019 Marlous van Leeuwen & Marijn Jansen
|
||||
© Marijn Doeve
|
||||
</footer>
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends "main/layout.html" %}
|
||||
|
||||
{% block title %}Marlous van Leeuwen{% endblock %}
|
||||
{% block title %}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<main class="container">
|
||||
|
||||
@@ -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 %}"
|
||||
|
||||
Reference in New Issue
Block a user