mirror of
https://github.com/jazzband/django-avatar.git
synced 2026-03-16 22:20:30 +00:00
Close files in create thumbnail (#252)
* Close the orig file in `create_thumbnail` method * Skip python-magic tests on windows * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Johannes Wilm <mail@johanneswilm.org>
This commit is contained in:
parent
7cb55334c1
commit
80a7c95583
3 changed files with 37 additions and 29 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
* 9.0.0 (in progress)
|
* 9.0.0 (in progress)
|
||||||
|
* Fix files not closed in `create_thumbnail`
|
||||||
* Add Django 5.2 and 6.0 support
|
* Add Django 5.2 and 6.0 support
|
||||||
* Add Python 3.13, 3.14 support
|
* Add Python 3.13, 3.14 support
|
||||||
* Drop Python 3.8, 3.9 support
|
* Drop Python 3.8, 3.9 support
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import binascii
|
import binascii
|
||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
|
from contextlib import closing
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from django.core.files import File
|
from django.core.files import File
|
||||||
|
|
@ -142,8 +143,13 @@ class Avatar(models.Model):
|
||||||
orig = self.avatar.storage.open(self.avatar.name, "rb")
|
orig = self.avatar.storage.open(self.avatar.name, "rb")
|
||||||
except IOError:
|
except IOError:
|
||||||
return # What should we do here? Render a "sorry, didn't work" img?
|
return # What should we do here? Render a "sorry, didn't work" img?
|
||||||
|
|
||||||
|
with closing(orig):
|
||||||
try:
|
try:
|
||||||
image = Image.open(orig)
|
image = Image.open(orig)
|
||||||
|
except IOError:
|
||||||
|
thumb_file = File(orig)
|
||||||
|
else:
|
||||||
image = self.transpose_image(image)
|
image = self.transpose_image(image)
|
||||||
quality = quality or settings.AVATAR_THUMB_QUALITY
|
quality = quality or settings.AVATAR_THUMB_QUALITY
|
||||||
w, h = image.size
|
w, h = image.size
|
||||||
|
|
@ -168,11 +174,6 @@ class Avatar(models.Model):
|
||||||
thumb_file = File(orig)
|
thumb_file = File(orig)
|
||||||
thumb_name = self.avatar_name(width, height)
|
thumb_name = self.avatar_name(width, height)
|
||||||
thumb = self.avatar.storage.save(thumb_name, thumb_file)
|
thumb = self.avatar.storage.save(thumb_name, thumb_file)
|
||||||
except IOError:
|
|
||||||
thumb_file = File(orig)
|
|
||||||
thumb = self.avatar.storage.save(
|
|
||||||
self.avatar_name(width, height), thumb_file
|
|
||||||
)
|
|
||||||
invalidate_cache(self.user, width, height)
|
invalidate_cache(self.user, width, height)
|
||||||
|
|
||||||
def avatar_url(self, width, height=None):
|
def avatar_url(self, width, height=None):
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import math
|
import math
|
||||||
import os.path
|
import os.path
|
||||||
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
|
from unittest import skipIf
|
||||||
|
|
||||||
from django.contrib.admin.sites import AdminSite
|
from django.contrib.admin.sites import AdminSite
|
||||||
from django.core import management
|
from django.core import management
|
||||||
|
|
@ -118,6 +120,7 @@ class AvatarTests(TestCase):
|
||||||
self.assertTrue(avatar.primary)
|
self.assertTrue(avatar.primary)
|
||||||
|
|
||||||
# We allow the .tiff file extension but not the mime type
|
# We allow the .tiff file extension but not the mime type
|
||||||
|
@skipIf(sys.platform == "win32", "Skipping test on Windows platform")
|
||||||
@override_settings(AVATAR_ALLOWED_FILE_EXTS=(".png", ".gif", ".jpg", ".tiff"))
|
@override_settings(AVATAR_ALLOWED_FILE_EXTS=(".png", ".gif", ".jpg", ".tiff"))
|
||||||
@override_settings(
|
@override_settings(
|
||||||
AVATAR_ALLOWED_MIMETYPES=("image/png", "image/gif", "image/jpeg")
|
AVATAR_ALLOWED_MIMETYPES=("image/png", "image/gif", "image/jpeg")
|
||||||
|
|
@ -130,6 +133,7 @@ class AvatarTests(TestCase):
|
||||||
self.assertNotEqual(response.context["upload_avatar_form"].errors, {})
|
self.assertNotEqual(response.context["upload_avatar_form"].errors, {})
|
||||||
|
|
||||||
# We allow the .tiff file extension and the mime type
|
# We allow the .tiff file extension and the mime type
|
||||||
|
@skipIf(sys.platform == "win32", "Skipping test on Windows platform")
|
||||||
@override_settings(AVATAR_ALLOWED_FILE_EXTS=(".png", ".gif", ".jpg", ".tiff"))
|
@override_settings(AVATAR_ALLOWED_FILE_EXTS=(".png", ".gif", ".jpg", ".tiff"))
|
||||||
@override_settings(
|
@override_settings(
|
||||||
AVATAR_ALLOWED_MIMETYPES=("image/png", "image/gif", "image/jpeg", "image/tiff")
|
AVATAR_ALLOWED_MIMETYPES=("image/png", "image/gif", "image/jpeg", "image/tiff")
|
||||||
|
|
@ -141,6 +145,7 @@ class AvatarTests(TestCase):
|
||||||
self.assertEqual(len(response.redirect_chain), 1) # Redirect only if it worked
|
self.assertEqual(len(response.redirect_chain), 1) # Redirect only if it worked
|
||||||
self.assertEqual(response.context["upload_avatar_form"].errors, {})
|
self.assertEqual(response.context["upload_avatar_form"].errors, {})
|
||||||
|
|
||||||
|
@skipIf(sys.platform == "win32", "Skipping test on Windows platform")
|
||||||
@override_settings(AVATAR_ALLOWED_FILE_EXTS=(".jpg", ".png"))
|
@override_settings(AVATAR_ALLOWED_FILE_EXTS=(".jpg", ".png"))
|
||||||
def test_image_without_wrong_extension(self):
|
def test_image_without_wrong_extension(self):
|
||||||
response = upload_helper(self, "imagefilewithoutext")
|
response = upload_helper(self, "imagefilewithoutext")
|
||||||
|
|
@ -148,6 +153,7 @@ class AvatarTests(TestCase):
|
||||||
self.assertEqual(len(response.redirect_chain), 0) # Redirect only if it worked
|
self.assertEqual(len(response.redirect_chain), 0) # Redirect only if it worked
|
||||||
self.assertNotEqual(response.context["upload_avatar_form"].errors, {})
|
self.assertNotEqual(response.context["upload_avatar_form"].errors, {})
|
||||||
|
|
||||||
|
@skipIf(sys.platform == "win32", "Skipping test on Windows platform")
|
||||||
@override_settings(AVATAR_ALLOWED_FILE_EXTS=(".jpg", ".png"))
|
@override_settings(AVATAR_ALLOWED_FILE_EXTS=(".jpg", ".png"))
|
||||||
def test_image_with_wrong_extension(self):
|
def test_image_with_wrong_extension(self):
|
||||||
response = upload_helper(self, "imagefilewithwrongext.ogg")
|
response = upload_helper(self, "imagefilewithwrongext.ogg")
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue