diff --git a/warehouse/__init__.py b/warehouse/__init__.py index 211efbd5805297e247efe0e81d658afe53e2ef12..e02dcc40cb7c0902631461d458d9ebc951a4e991 100644 --- a/warehouse/__init__.py +++ b/warehouse/__init__.py @@ -6,7 +6,7 @@ from flask import Flask, render_template, request, redirect, url_for, Response, from requests_oauthlib import OAuth2Session from .models import db, Item, Location, Photo -from .utils import render_pdf, print_pdf, qrcode_svg, render_markdown +from .utils import render_pdf, print_pdf, qrcode_svg, render_markdown, send_thumbnail app = Flask(__name__, instance_relative_config=True) app.config.from_pyfile('config.cfg') @@ -183,6 +183,16 @@ def item_locate(item_id): def photo_show(photo_id): return Photo.query.get_or_404(photo_id).send() +@app.route('/photos/<int:photo_id>/small') +def photo_small(photo_id): + photo = Photo.query.get_or_404(photo_id) + return send_thumbnail(photo.image, 130, 100) + +@app.route('/photos/<int:photo_id>/medium') +def photo_medium(photo_id): + photo = Photo.query.get_or_404(photo_id) + return send_thumbnail(photo.image, 390, 300) + @app.route('/C/<code>') @app.route('/c/<code>') def qrcode_url(code): diff --git a/warehouse/models.py b/warehouse/models.py index 866bacce02d920c1ea0df43fd792d73e73acafbb..5803213ca6a6a1afcf692a7602398fa8b7049b39 100644 --- a/warehouse/models.py +++ b/warehouse/models.py @@ -3,6 +3,7 @@ import os from flask import current_app, send_file from flask_sqlalchemy import SQLAlchemy +from PIL import Image db = SQLAlchemy() @@ -41,6 +42,11 @@ class Photo(db.Model): path = os.path.join(current_app.config['UPLOAD_FOLDER'], self.path) return send_file(path, mimetype=self.mimetype) + @property + def image(self): + path = os.path.join(current_app.config['UPLOAD_FOLDER'], self.path) + return Image.open(path, formats=['JPEG']) + def token_typable(): alphabet = '23456789ABCDEFGHJKLMNPQRSTUVWX' # not '01OIYZ' return ''.join([secrets.choice(alphabet) for _ in range(5)]) diff --git a/warehouse/templates/item/list.html b/warehouse/templates/item/list.html index 2df46a6165f005435aeb34c88684f9c4fd99ff0d..985e5037035ad1ef9df8144d7f73d57af1d13cc7 100644 --- a/warehouse/templates/item/list.html +++ b/warehouse/templates/item/list.html @@ -24,7 +24,7 @@ <td style="width: 140px;"> {% if item.photos %} <a href="{{ url_for('item_view', item_id=item.id) }}" style="width: 130px; height: 100px;" class="d-flex align-items-center justify-content-center border text-bg-light"> - <img src="{{ url_for('photo_show', photo_id=(item.photos|first).id) }}" style="max-width: 100%; max-height: 100%;"> + <img src="{{ url_for('photo_small', photo_id=(item.photos|first).id) }}" style="max-width: 100%; max-height: 100%;"> </a> {% endif %} </td> diff --git a/warehouse/templates/item/view.html b/warehouse/templates/item/view.html index ce0d961ea54bb57bb54f5b18c195d51d91b6d37e..7e6905dc975401069616559a267bddb516b5c3d1 100644 --- a/warehouse/templates/item/view.html +++ b/warehouse/templates/item/view.html @@ -39,7 +39,7 @@ {% for photo in item.photos %} <div class="carousel-item {{ 'active' if loop.first }}" style="width: 100%; height: 100%;"> <a href="{{ url_for('photo_show', photo_id=photo.id) }}" style="width: 100%; height: 100%;" class="d-flex align-items-center justify-content-center"> - <img src="{{ url_for('photo_show', photo_id=photo.id) }}" style="max-width: 100%; max-height: 100%;"> + <img src="{{ url_for('photo_medium', photo_id=photo.id) }}" style="max-width: 100%; max-height: 100%;"> </a> </div> {% endfor %} diff --git a/warehouse/utils/__init__.py b/warehouse/utils/__init__.py index 1fbb582e821e73c0a3cd55d1da01b59e2d7cc151..676a459079afb6fda3d98133f2cb72790438a6ac 100644 --- a/warehouse/utils/__init__.py +++ b/warehouse/utils/__init__.py @@ -2,7 +2,8 @@ from .pdf import render_pdf from .ipp import print_pdf from .codes import qrcode_svg -from flask import Markup +import io +from flask import Markup, send_file import markdown import bleach @@ -16,3 +17,11 @@ def render_markdown(text, short=False): result = result.split('<p>', 1)[-1] result = result.split('</p>', 1)[0] return Markup(result) + +def send_thumbnail(img, max_width, max_height): + scale = min(max_width/img.width, max_height/img.height) + img.thumbnail((int(img.width*scale), int(img.height*scale))) + buf = io.BytesIO() + img.save(buf, format='JPEG', quality=70) + buf.seek(0) + return send_file(buf, mimetype='image/jpeg')