From a10a5a879330f2e6b1192fe33d41c2933a49c217 Mon Sep 17 00:00:00 2001 From: Fluffy-Bean Date: Fri, 13 Jan 2023 18:29:07 +0000 Subject: [PATCH] Generate thumbnails on the fly with PIL Removed the need of having 3 copies of an image Fixes more Sass(y) stuff --- gallery/__init__.py | 2 +- gallery/api.py | 102 +++++++++--------- gallery/image.py | 3 +- gallery/templates/image.html | 66 +++++++++--- gallery/templates/index.html | 2 +- gallery/templates/layout.html | 2 +- gallery/user/themes/default/style.scss | 38 ++++++- gallery/user/themes/default/ui/main.scss | 2 + .../themes/default/variables/variables.scss | 6 +- setup.py | 2 +- 10 files changed, 149 insertions(+), 76 deletions(-) diff --git a/gallery/__init__.py b/gallery/__init__.py index ea44ec9..459afab 100644 --- a/gallery/__init__.py +++ b/gallery/__init__.py @@ -5,7 +5,7 @@ print(""" | |_| | | | | | |_| | |__| __/ (_| \\__ \\ \\___/|_| |_|_|\\__, |_____\\___|\\__, |___/ |___/ |___/ -Created by Fluffy Bean - Version 110123 +Created by Fluffy Bean - Version 130123 """) # Import base packages diff --git a/gallery/api.py b/gallery/api.py index da036d7..6a5dee6 100644 --- a/gallery/api.py +++ b/gallery/api.py @@ -1,95 +1,97 @@ -from flask import Blueprint, render_template, current_app, send_from_directory, request, g, abort, flash +from flask import Blueprint, render_template, current_app, send_from_directory, send_file, request, g, abort, flash from werkzeug.utils import secure_filename from gallery.auth import login_required from gallery.db import get_db -from PIL import Image +from PIL import Image, ImageOps +import io import os from uuid import uuid4 blueprint = Blueprint('viewsbp', __name__, url_prefix='/api') -@blueprint.route('/uploads//') -def uploads(quality, file): - dir = os.path.join(current_app.config['UPLOAD_FOLDER'], secure_filename(quality)) - file = secure_filename(file) +@blueprint.route('/uploads//', methods=['GET']) +def uploads(file, quality): + # If quality is 0, return original file + if quality == 0: + return send_from_directory(current_app.config['UPLOAD_FOLDER'], secure_filename(file), as_attachment=True) - return send_from_directory(dir, file, as_attachment=True) + # Set variables + set_ext = {'jpg': 'jpeg', 'jpeg': 'jpeg', 'png': 'png', 'webp': 'webp'} + buff = io.BytesIO() + + # Open image and set extension + img = Image.open(os.path.join(current_app.config['UPLOAD_FOLDER'], secure_filename(file))) + img_ext = os.path.splitext(secure_filename(file))[-1].lower().replace('.', '') + img_ext = set_ext[img_ext] + + # Resize image and orientate correctly + img.thumbnail((quality, quality), Image.LANCZOS) + img = ImageOps.exif_transpose(img) + img.save(buff, img_ext) + + # Seek to beginning of buffer and return + buff.seek(0) + return send_file(buff, mimetype='image/'+img_ext) @blueprint.route('/upload', methods=['POST']) @login_required def upload(): - file = request.files['file'] + form_file = request.files['file'] form = request.form - - # Check if file has been submitted - if not file: - flash('No selected file') + + if not form_file: return abort(404) - # New file name and check if file extension is allowed - file_ext = os.path.splitext(file.filename)[1].lower() - file_name = f"GWAGWA_{uuid4().__str__()}{file_ext}" + img_ext = os.path.splitext(secure_filename(form_file.filename))[-1].lower() + img_name = f"GWAGWA_{uuid4().__str__()}{img_ext}" - if not file_ext in current_app.config['ALLOWED_EXTENSIONS']: - return 'File extension not allowed: '+file_ext + if not img_ext in current_app.config['ALLOWED_EXTENSIONS']: + return 'File extension not allowed: '+img_ext + # Save to database try: - file.save(os.path.join(current_app.instance_path, current_app.config['UPLOAD_FOLDER']+'/original', file_name)) - except: - return 'Could not save file' - - # Resize image - thumbnail_size = 300, 300 - preview_size = 1000, 1000 - img_file = Image.open(os.path.join(current_app.instance_path, current_app.config['UPLOAD_FOLDER']+'/original', file_name)) - - try: - # save thumbnail - img_file.thumbnail(thumbnail_size, Image.Resampling.LANCZOS) - img_file.save(os.path.join(current_app.instance_path, current_app.config['UPLOAD_FOLDER']+'/thumbnail', file_name)) - - # save preview - img_file.thumbnail(preview_size, Image.Resampling.LANCZOS) - img_file.save(os.path.join(current_app.instance_path, current_app.config['UPLOAD_FOLDER']+'/preview', file_name)) + db = get_db() + db.execute( + 'INSERT INTO posts (file_name, author_id, description, alt)' + ' VALUES (?, ?, ?, ?)', + (img_name, g.user['id'], form['description'], form['alt']) + ) + db.commit() except Exception as e: - return 'Could not resize image: '+ str(e) + abort(500) - db = get_db() - db.execute( - 'INSERT INTO posts (file_name, author_id, description, alt)' - ' VALUES (?, ?, ?, ?)', - (file_name, g.user['id'], form['description'], form['alt']) - ) - db.commit() + # Save file + try: + form_file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], img_name)) + except: + abort(500) return 'Gwa Gwa' @blueprint.route('/remove/', methods=['POST']) @login_required def remove(id): - image = get_db().execute( + img = get_db().execute( 'SELECT author_id, file_name FROM posts WHERE id = ?', (id,) ).fetchone() - if image is None: + if img is None: abort(404) - if image['author_id'] != g.user['id']: + if img['author_id'] != g.user['id']: abort(403) try: - os.remove(os.path.join(current_app.instance_path, current_app.config['UPLOAD_FOLDER'], 'original', image['file_name'])) - os.remove(os.path.join(current_app.instance_path, current_app.config['UPLOAD_FOLDER'], 'thumbnail', image['file_name'])) - os.remove(os.path.join(current_app.instance_path, current_app.config['UPLOAD_FOLDER'], 'preview', image['file_name'])) + os.remove(os.path.join(current_app.config['UPLOAD_FOLDER'], img['file_name'])) except Exception as e: - return 'file error: '+str(e) + abort(500) try: db = get_db() db.execute('DELETE FROM posts WHERE id = ?', (id,)) db.commit() except: - return 'database error' + abort(500) return 'Gwa Gwa' \ No newline at end of file diff --git a/gallery/image.py b/gallery/image.py index 1571d4e..4f31706 100644 --- a/gallery/image.py +++ b/gallery/image.py @@ -25,7 +25,7 @@ def image(id): # Get exif data from image try: - file = Image.open(os.path.join(current_app.instance_path, current_app.config['UPLOAD_FOLDER'], 'original', image['file_name'])) + file = Image.open(os.path.join(current_app.config['UPLOAD_FOLDER'], 'original', image['file_name'])) raw_exif = file.getexif() human_exif = {} @@ -43,6 +43,7 @@ def image(id): except: # Cringe, no file present human_exif = False + file = False # All in le head return render_template('image.html', image=image, exif=human_exif, file=file) \ No newline at end of file diff --git a/gallery/templates/image.html b/gallery/templates/image.html index 0007eec..5e08977 100644 --- a/gallery/templates/image.html +++ b/gallery/templates/image.html @@ -1,13 +1,13 @@ {% extends 'layout.html' %} {% block header %} - leaves + leaves {% endblock %} {% block content %}
@@ -17,7 +17,7 @@
@@ -62,26 +62,62 @@
+ {% if image['alt'] != '' %} +
+
+ + + +

Alt

+
+
+

{{ image['alt'] }}

+
+
+ {% endif %} {% if image['description'] != '' %}
-

Description

-

{{ image['description'] }}

+
+ + + +

Description

+
+
+

{{ image['description'] }}

+
{% endif %}
-

Info

-

Filename: {{ image['file_name'] }}

-

Image ID: {{ image['id'] }}

-

Author: {{ image['author_id'] }}

-

Upload date: {{ image['created_at'] }}

-

Dimensions: {{ file['width'] }}x{{ file['height'] }}

+
+ + + +

Info

+
+
+

Filename: {{ image['file_name'] }}

+

Image ID: {{ image['id'] }}

+

Author: {{ image['author_id'] }}

+

Upload date: {{ image['created_at'] }}

+ {% if file is not false %} +

Dimensions: {{ file['width'] }}x{{ file['height'] }}

+ {% endif %} +
{% if exif is not false %}
-

Exif

- {% for tag in exif %} -

{{ tag }}: {{ exif[tag] }}

- {% endfor %} +
+ + + +

Metadata

+
+
+ {% for tag in exif %} +

{{ tag }}: {{ exif[tag] }}

+ {% endfor %} +
{% endif %} diff --git a/gallery/templates/index.html b/gallery/templates/index.html index 1abe18e..32e25ac 100644 --- a/gallery/templates/index.html +++ b/gallery/templates/index.html @@ -15,7 +15,7 @@

{{ image['file_name'] }}

- + {% endfor %} diff --git a/gallery/templates/layout.html b/gallery/templates/layout.html index 2fb99a0..06215a1 100644 --- a/gallery/templates/layout.html +++ b/gallery/templates/layout.html @@ -9,6 +9,7 @@ +