Use shortpixel to compress and resize images

This commit is contained in:
Gabriel Augendre 2020-08-27 22:03:22 +02:00
parent 9f6ffcb1a3
commit 57c1fe1ce8
No known key found for this signature in database
GPG key ID: 1E693F4CE4AEE7B4
3 changed files with 58 additions and 11 deletions

View file

@ -1,6 +1,9 @@
import json
import tempfile import tempfile
from pathlib import Path from pathlib import Path
import requests
from django.conf import settings
from django.core.files import File from django.core.files import File
from django.db import models from django.db import models
from PIL import Image from PIL import Image
@ -15,24 +18,63 @@ class Attachment(models.Model):
if self.processed_file: if self.processed_file:
return super().save(*args, **kwargs) return super().save(*args, **kwargs)
if self.id is None:
super().save(*args, **kwargs)
try: try:
image = Image.open(self.original_file.path) image = Image.open(self.original_file.path)
except IOError: except IOError:
return self.save(*args, **kwargs) return super().save(*args, **kwargs)
max_width = 640
if image.width > max_width: # Submit job to shortpixel
ratio = image.height / image.width base_data = {
height = round(max_width * ratio) "key": settings.SHORTPIXEL_API_KEY,
output = image.resize((max_width, height)) "plugin_version": "gabno",
else: "wait": 20,
output = image.copy() }
current_path = Path(image.filename) 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_dir = Path(tempfile.mkdtemp())
temp_path = temp_dir / (current_path.stem + "-resized" + current_path.suffix) temp_path = temp_dir / (current_path.stem + "-processed" + current_path.suffix)
output.save(temp_path) 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: with open(temp_path, "rb") as output_file:
f = File(output_file) f = File(output_file)
self.processed_file.save(temp_path.name, f, save=False) self.processed_file.save(temp_path.name, f, save=False)
temp_path.unlink() temp_path.unlink()
temp_dir.rmdir() temp_dir.rmdir()
return super().save(*args, **kwargs) return super().save(*args, **kwargs)

View file

@ -70,6 +70,7 @@ INSTALLED_APPS = [
"articles", "articles",
"attachments", "attachments",
"anymail", "anymail",
"django_cleanup.apps.CleanupConfig",
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -175,3 +176,5 @@ BLOG = {
"description": "My take on tech-related subjects (but not only)", "description": "My take on tech-related subjects (but not only)",
"base_url": os.getenv("BLOG_BASE_URL", "https://gabnotes.org/"), "base_url": os.getenv("BLOG_BASE_URL", "https://gabnotes.org/"),
} }
SHORTPIXEL_API_KEY = os.getenv("SHORTPIXEL_API_KEY")

View file

@ -4,3 +4,5 @@ gunicorn==20.0.4
Pygments==2.6.1 Pygments==2.6.1
django-anymail[mailgun]==7.2.1 django-anymail[mailgun]==7.2.1
pillow==7.2.0 pillow==7.2.0
django-cleanup==5.0.0
requests==2.24.0