97 lines
3.3 KiB
Python
97 lines
3.3 KiB
Python
import os
|
|
|
|
from loguru import logger
|
|
|
|
from PIL import Image
|
|
from io import BytesIO
|
|
from django.core.files.storage import default_storage
|
|
|
|
from django import conf
|
|
from django.http import HttpRequest, HttpResponse
|
|
from django.contrib.auth.decorators import login_required
|
|
|
|
from ..models import ImageMemo
|
|
|
|
|
|
@login_required
|
|
def document_image(request, pk):
|
|
"""Given a document uuid, look it up, ensure that it belongs to the current user and respond with an image"""
|
|
# find document with given ID (pk path param) and current user id
|
|
document = ImageMemo.objects.filter(id=pk, author__id=request.user.id).first()
|
|
|
|
if not document:
|
|
logger.debug(f"No memo found for user={request.user.id} and memo_id={pk}")
|
|
return HttpResponse(content="Document not found", status=404)
|
|
|
|
# look up the file on disk
|
|
|
|
if not default_storage.exists(document.image.name):
|
|
logger.warning(
|
|
f"The file associated with memo {document.id} does not exist"
|
|
)
|
|
return HttpResponse(content="Document not found", status=404)
|
|
|
|
# Return the thumbnail as an HTTP response
|
|
with default_storage.open(document.image.name,'rb') as f:
|
|
return HttpResponse(f.read(), content_type="image/jpeg")
|
|
|
|
|
|
@login_required
|
|
def document_thumbnail(request: HttpRequest, pk: str):
|
|
"""Given a document uuid, look it up, ensure that it belongs to the current user and respond with a thumbnail"""
|
|
|
|
# find document with given ID (pk path param) and current user id
|
|
document = ImageMemo.objects.filter(id=pk, author__id=request.user.id).first()
|
|
|
|
if not document:
|
|
logger.debug(f"No memo found for user={request.user.id} and memo_id={pk}")
|
|
return HttpResponse(content="Document not found", status=404)
|
|
|
|
# look up the file on disk
|
|
|
|
# get thumb directory from django setting
|
|
thumbnail_dir = getattr(conf.settings, "THUMBNAIL_DIR", "thumbnails")
|
|
|
|
thumb_max_width = getattr(conf.settings, "THUMBNAIL_MAX_WIDTH", 420)
|
|
|
|
thumb_path = os.path.join(thumbnail_dir, str(document.id) + ".jpg")
|
|
|
|
if not default_storage.exists(thumb_path):
|
|
|
|
if not default_storage.exists(document.image.name):
|
|
logger.warning(
|
|
f"The file associated with memo {document.id} does not exist"
|
|
)
|
|
return HttpResponse(content="Document not found", status=404)
|
|
|
|
# Open the image using PIL
|
|
image = Image.open(default_storage.open(document.image.name))
|
|
|
|
# get the image width and height
|
|
width = int(image.size[0])
|
|
height = int(image.size[1])
|
|
|
|
# find the ratio of the width to height
|
|
ratio = round(width / float(height), 3)
|
|
|
|
# max width of thumbnail is 240, calculate height based on ratio
|
|
thumb_height = int(thumb_max_width * ratio)
|
|
|
|
# Create a thumbnail
|
|
image.thumbnail((thumb_max_width, thumb_height)) # Adjust size as needed
|
|
|
|
# if the image format is not jpeg, convert as needed
|
|
if image.format != "JPEG":
|
|
image = image.convert("RGB")
|
|
|
|
# Save the thumbnail to a BytesIO object
|
|
thumb_io = BytesIO()
|
|
image.save(thumb_io, format="JPEG")
|
|
thumb_io.seek(0)
|
|
|
|
default_storage.save(thumb_path, thumb_io)
|
|
|
|
# Return the thumbnail as an HTTP response
|
|
with open(thumb_path, "rb") as f:
|
|
return HttpResponse(f.read(), content_type="image/jpeg")
|