Fix image download code

This commit is contained in:
Oliver Walters 2021-03-17 23:02:32 +11:00
parent 47a1143570
commit 9a710ca28f
2 changed files with 30 additions and 24 deletions

View File

@ -302,6 +302,9 @@
$("#part-image-url").click(function() { $("#part-image-url").click(function() {
launchModalForm( launchModalForm(
'{% url "part-image-download" part.id %}', '{% url "part-image-download" part.id %}',
{
reload: true,
}
); );
}); });
{% endif %} {% endif %}

View File

@ -5,7 +5,7 @@ Django views for interacting with Part app
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from django.core.files import File from django.core.files.base import ContentFile
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db import transaction from django.db import transaction
from django.db.utils import IntegrityError from django.db.utils import IntegrityError
@ -20,10 +20,13 @@ from django.conf import settings
from moneyed import CURRENCIES from moneyed import CURRENCIES
from PIL import Image
from urllib.parse import urlsplit from urllib.parse import urlsplit
from tempfile import TemporaryFile from tempfile import TemporaryFile
import requests import requests
import os import os
import io
from rapidfuzz import fuzz from rapidfuzz import fuzz
from decimal import Decimal, InvalidOperation from decimal import Decimal, InvalidOperation
@ -860,53 +863,53 @@ class PartImageDownloadFromURL(AjaxUpdateView):
# We can now extract a valid URL from the form data # We can now extract a valid URL from the form data
url = form.cleaned_data.get('url', None) url = form.cleaned_data.get('url', None)
response = requests.get(url, stream=True)
# Check that the URL "looks" like an image URL # Check that the URL "looks" like an image URL
if not TestIfImageURL(url): if not TestIfImageURL(url):
form.add_error('url', _('Supplied URL is not one of the supported image formats')) form.add_error('url', _('Supplied URL is not one of the supported image formats'))
return return
# Download the file
response = requests.get(url, stream=True)
self.response = response
# Check for valid response code # Check for valid response code
if not response.status_code == 200: if not response.status_code == 200:
form.add_error('url', f"{_('Invalid response')}: {response.status_code}") form.add_error('url', f"{_('Invalid response')}: {response.status_code}")
return return
# Validate that the returned object is a valid image file response.raw.decode_content = True
if not TestIfImage(response.raw):
form.add_error('url', _('Supplied URL is not a valid image file'))
return
# Save the image object try:
self.image_response = response self.image = Image.open(response.raw).convert('RGB')
self.image.verify()
except:
form.add_error('url', _("Supplied URL is not a valid image file"))
return
def save(self, part, form, **kwargs): def save(self, part, form, **kwargs):
""" """
Save the downloaded image to the part Save the downloaded image to the part
""" """
response = getattr(self, 'image_response', None) fmt = self.image.format
if not response: if not fmt:
return fmt = 'PNG'
with TemporaryFile() as tf: buffer = io.BytesIO()
#for chunk in response.iter_content(chunk_size=2048): self.image.save(buffer, format=fmt)
# tf.write(chunk)
img_data = response.raw.read() # Construct a simplified name for the image
tf.write(img_data) filename = f"part_{part.pk}_image.{fmt.lower()}"
print("Saved to temp file:", tf.name)
tf.seek(0)
part.image.save( part.image.save(
os.path.basename(urlsplit(response.url).path), filename,
File(tf), ContentFile(buffer.getvalue()),
) )
class PartImageUpload(AjaxUpdateView): class PartImageUpload(AjaxUpdateView):
""" View for uploading a new Part image """ """ View for uploading a new Part image """