flask file upload working

This commit is contained in:
Jacob Delgado 2024-08-08 21:27:49 -07:00
parent 71815a6533
commit f11dd091f1
10 changed files with 226 additions and 18 deletions

4
backend/.env Normal file
View File

@ -0,0 +1,4 @@
SECRET_KEY=MVPhXY*yNXPE2MbXDdpxXk
REDIS_PASSWORD=eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
POSTGRESQL_DATABASE_URL='postgresql+psycopg2://arufa:Plop2099@localhost:5432/arufalab'
# POSTGRESQL_DATABASE_URL => 'postgresql+psycopg2://arufa:password@host:port/database'

Binary file not shown.

Binary file not shown.

View File

@ -21,8 +21,16 @@ app.config["SESSION_TYPE"] = 'redis'
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_USE_SIGNER"] = True
app.config["SESSION_REDIS"] = redis.from_url("redis://192.168.50.107:6379")
# upload directory
app.config["UPLOAD_DIRECTORY"] = 'uploads/'
# app.config["REDIS_PASSWORD"] = os.environ["REDIS_PASSWORD"]
# File value limit
app.config["MAX_CONTENT_LENGTH"] = 16 * 1024 * 1024 # 16MB
# List of allowed file extensions
app.config['ALLOWED_EXTENSIONS'] = ['.jpg', '.jpeg', '.png', '.gif']
db = SQLAlchemy(app)
server_session = Session(app)

Binary file not shown.

View File

@ -1,16 +1,45 @@
from flask import Flask, render_template, request
from flask import Flask, render_template, request, redirect, send_from_directory
from config import app, db, bcrypt
from models import Contact, User
from werkzeug.utils import secure_filename
from werkzeug.exceptions import RequestEntityTooLarge
import os
@app.route('/')
def index():
return render_template('index.html')
files = os.listdir(app.config['UPLOAD_DIRECTORY'])
images = []
@app.route('/api/upload', methods=['POST'])
for file in files:
if os.path.splitext(file)[1].lower() in app.config['ALLOWED_EXTENSIONS']:
images.append(file)
return render_template('index.html', images=images)
@app.route('/upload', methods=["POST"])
def upload():
try:
file = request.files['file']
file_extension = os.path.splitext(file.filename)[1] # [0] is the filename
# save the file if it exists
if file:
if file_extension not in app.config['ALLOWED_EXTENSIONS']:
return 'File is not an image'
file.save(os.path.join(
app.config['UPLOAD_DIRECTORY'],
secure_filename(file.filename)
))
except RequestEntityTooLarge: # except Exception would catch all errors instead of specified
return 'File is larger than the limit of 16mb.'
return redirect('/')
# Handle Images
@app.route('/serve-image/<filename>', methods=['GET'])
def serve_image(filename):
return send_from_directory(app.config['UPLOAD_DIRECTORY'], filename)
# save the file
file.save(f'uploads/{file.filename}')
# Main
if __name__ == "__main__":

34
backend/models.py Normal file
View File

@ -0,0 +1,34 @@
from config import db
from uuid import uuid4
class Contact(db.Model):
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(80), unique=False, nullable=False)
last_name = db.Column(db.String(80), unique=False, nullable=False)
email = db.Column(db.String(120), unique=False, nullable=False)
def to_json(self):
return {
"id": self.id,
"firstName":self.first_name,
"lastName":self.last_name,
"email": self.email,
}
def get_uuid():
return uuid4().hex
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.String(32), primary_key=True, unique=True, default=get_uuid)
email = db.Column(db.String(345), unique=True)
password = db.Column(db.Text, nullable=False)
# class Category(db.Model):
# __tablename__ = "categories"
# id = db.Column(db.String(32), primary_key=True, unique=True, default=get_uuid)
# name = db.Column(db.String(345), default='New Shirt')
# number = db.Column(db.Integer)
# sale = db.Column(db.Boolean, default=False)

View File

@ -5,3 +5,6 @@ flask-cors
python-dotenv
flask-session
redis
Flask-Migrate
flask_validator
psycopg2-binary

130
backend/static/styles.css Normal file
View File

@ -0,0 +1,130 @@
:root {
--black: #000000;
--almost-black: #080708;
--blue: #3772FF;
--blue-light: #3787ff;
--red: #DF2935;
--yellow: #FDCA40;
--light: #E6E8E6;
--white: #FFFFFF;
}
* {
position: relative;
box-sizing: border-box;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
font-size: 22px;
line-height: 1.5;
color: var(--white);
background: var(--black);
background-image: linear-gradient(to bottom right, var(--almost-black), var(--black));
}
.app {
height: 100vh;
display: flex;
}
.form-section {
padding: 15px 0 0 15px;
width: 25%;
color: var(--light);
flex-shrink: 0;
}
.images-section {
padding: 15px 0 0 15px;
width: 75%;
height: 100vh;
align-content: flex-start;
flex-wrap: wrap;
display: flex;
overflow-y: auto;
}
.images-section a {
margin: 0 15px 15px 0;
padding-bottom: 20%;
content: '';
width: calc(33.33% - 15px);
height: 0;
display: block;
}
.images-section img {
position: absolute;
top: 0;
width: 100%;
height: 100%;
border-radius: 4px;
object-fit: cover;
display: block;
}
@media screen and (max-width: 1200px) {
.app {
flex-direction: column;
}
.form-section {
padding-right: 15px;
padding-bottom: 15px;
width: 100%;
}
.images-section {
padding-top: 0;
width: 100%;
height: auto;
}
}
@media screen and (max-width: 800px) {
.images-section a {
padding-bottom: 60%;
width: calc(100% - 15px);
}
}
/* Forms */
form {
width: 100%;
flex-direction: column;
display: flex;
}
input[type='file'] {
margin: 0 0 12px;
padding: 10px 10px;
border-radius: 4px;
font-size: 22px;
color: var(--almost-black);
background: var(--white);
}
input[type='submit'],
button[type='button'] {
padding: 13px 20px;
font-size: 22px;
font-weight: bold;
color: var(--white);
border: none;
border-radius: 4px;
outline: none;
box-shadow: none;
cursor: pointer;
background: var(--blue);
background-image: linear-gradient(to bottom, var(--blue-light), var(--blue));
transition: box-shadow .2s ease;
}
input[type='submit']:hover,
button[type='button']:hover {
box-shadow: inset 0 -25px 25px var(--blue-light);
}

View File

@ -11,20 +11,20 @@
<div class="app">
<div class="form-section">
<form aciton="/api/upload" method="post" enctype="multipart/form-data">
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" name="Upload">
<input type="submit" value="Upload">
</form>
<!-- Form will go here -->
</div>
<div class="images-section">
<!-- Images will go here -->
{% for image in images %}
<a href="{{ url_for('serve_image', filename=image) }}" target="_blank">
<img src="{{ url_for('serve_image', filename=image) }}"/>
</a>
{% endfor %}
</div>
</div>