From 57c1fe1ce8d9e6a0ac2319b1be95cdf02894ad61 Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Thu, 27 Aug 2020 22:03:22 +0200 Subject: [PATCH] Use shortpixel to compress and resize images --- attachments/models.py | 64 +++++++++++++++++++++++++++++++++++-------- blog/settings.py | 3 ++ requirements.txt | 2 ++ 3 files changed, 58 insertions(+), 11 deletions(-) diff --git a/attachments/models.py b/attachments/models.py index d17987f..3595a7c 100644 --- a/attachments/models.py +++ b/attachments/models.py @@ -1,6 +1,9 @@ +import json import tempfile from pathlib import Path +import requests +from django.conf import settings from django.core.files import File from django.db import models from PIL import Image @@ -15,24 +18,63 @@ class Attachment(models.Model): if self.processed_file: return super().save(*args, **kwargs) + if self.id is None: + super().save(*args, **kwargs) try: image = Image.open(self.original_file.path) except IOError: - return self.save(*args, **kwargs) - max_width = 640 - if image.width > max_width: - ratio = image.height / image.width - height = round(max_width * ratio) - output = image.resize((max_width, height)) - else: - output = image.copy() - current_path = Path(image.filename) + return super().save(*args, **kwargs) + + # Submit job to shortpixel + base_data = { + "key": settings.SHORTPIXEL_API_KEY, + "plugin_version": "gabno", + "wait": 20, + } + post_data = { + "lossy": 1, + "resize": 3, + "resize_width": 640, + "resize_height": 10000, + "file_paths": json.dumps( + [f"{self.original_file.name}:{self.original_file.path}"] + ), + } + data = {**base_data, **post_data} + url = "https://api.shortpixel.com/v2/post-reducer.php" + with open(self.original_file.path, "rb") as original_file: + response = requests.post( + url=url, data=data, files={self.original_file.name: original_file} + ) + res = response.json() + res_data = res[0] + + # Loop until it's done + post_data = { + "key": settings.SHORTPIXEL_API_KEY, + "plugin_version": "gabno", + "wait": 20, + "file_urls": json.dumps([res_data["OriginalURL"]]), + } + check_data = {**base_data, **post_data} + while res_data["Status"]["Code"] == "1": + response = requests.post(url=url, data=check_data,) + res_data = response.json()[0] + + # Download image + current_path = Path(self.original_file.path) temp_dir = Path(tempfile.mkdtemp()) - temp_path = temp_dir / (current_path.stem + "-resized" + current_path.suffix) - output.save(temp_path) + temp_path = temp_dir / (current_path.stem + "-processed" + current_path.suffix) + img = requests.get(res_data["LossyURL"], stream=True) + with open(temp_path, "wb") as temp_file: + for chunk in img: + temp_file.write(chunk) + + # Link it to our model with open(temp_path, "rb") as output_file: f = File(output_file) self.processed_file.save(temp_path.name, f, save=False) + temp_path.unlink() temp_dir.rmdir() return super().save(*args, **kwargs) diff --git a/blog/settings.py b/blog/settings.py index b30f6e4..afd89e9 100644 --- a/blog/settings.py +++ b/blog/settings.py @@ -70,6 +70,7 @@ INSTALLED_APPS = [ "articles", "attachments", "anymail", + "django_cleanup.apps.CleanupConfig", ] MIDDLEWARE = [ @@ -175,3 +176,5 @@ BLOG = { "description": "My take on tech-related subjects (but not only)", "base_url": os.getenv("BLOG_BASE_URL", "https://gabnotes.org/"), } + +SHORTPIXEL_API_KEY = os.getenv("SHORTPIXEL_API_KEY") diff --git a/requirements.txt b/requirements.txt index 22ff154..fa46005 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,5 @@ gunicorn==20.0.4 Pygments==2.6.1 django-anymail[mailgun]==7.2.1 pillow==7.2.0 +django-cleanup==5.0.0 +requests==2.24.0