mirror of
https://github.com/jazzband/django-avatar.git
synced 2026-03-16 22:20:30 +00:00
Use correct extension for thumbnails, fixes #54
This commit is contained in:
parent
210b54ca09
commit
39f8681e29
4 changed files with 27 additions and 14 deletions
|
|
@ -34,22 +34,21 @@ def avatar_path_handler(
|
||||||
if not filename:
|
if not filename:
|
||||||
# Filename already stored in database
|
# Filename already stored in database
|
||||||
filename = instance.avatar.name
|
filename = instance.avatar.name
|
||||||
if ext and settings.AVATAR_HASH_FILENAMES:
|
if ext:
|
||||||
# An extension was provided, probably because the thumbnail
|
|
||||||
# is in a different format than the file. Use it. Because it's
|
|
||||||
# only enabled if AVATAR_HASH_FILENAMES is true, we can trust
|
|
||||||
# it won't conflict with another filename
|
|
||||||
(root, oldext) = os.path.splitext(filename)
|
(root, oldext) = os.path.splitext(filename)
|
||||||
filename = root + "." + ext.lower()
|
filename = root + "." + ext.lower()
|
||||||
else:
|
else:
|
||||||
# File doesn't exist yet
|
# File doesn't exist yet
|
||||||
|
(root, oldext) = os.path.splitext(filename)
|
||||||
if settings.AVATAR_HASH_FILENAMES:
|
if settings.AVATAR_HASH_FILENAMES:
|
||||||
(root, ext) = os.path.splitext(filename)
|
|
||||||
if settings.AVATAR_RANDOMIZE_HASHES:
|
if settings.AVATAR_RANDOMIZE_HASHES:
|
||||||
filename = binascii.hexlify(os.urandom(16)).decode("ascii")
|
root = binascii.hexlify(os.urandom(16)).decode("ascii")
|
||||||
else:
|
else:
|
||||||
filename = hashlib.md5(force_bytes(filename)).hexdigest()
|
root = hashlib.md5(force_bytes(root)).hexdigest()
|
||||||
filename = filename + ext
|
if ext:
|
||||||
|
filename = root + "." + ext.lower()
|
||||||
|
else:
|
||||||
|
filename = root + oldext.lower()
|
||||||
if width or height:
|
if width or height:
|
||||||
tmppath.extend(["resized", str(width), str(height)])
|
tmppath.extend(["resized", str(width), str(height)])
|
||||||
tmppath.append(os.path.basename(filename))
|
tmppath.append(os.path.basename(filename))
|
||||||
|
|
@ -70,7 +69,7 @@ def find_extension(format):
|
||||||
|
|
||||||
class AvatarField(models.ImageField):
|
class AvatarField(models.ImageField):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(AvatarField, self).__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.max_length = 1024
|
self.max_length = 1024
|
||||||
self.upload_to = avatar_file_path
|
self.upload_to = avatar_file_path
|
||||||
|
|
@ -78,7 +77,7 @@ class AvatarField(models.ImageField):
|
||||||
self.blank = True
|
self.blank = True
|
||||||
|
|
||||||
def deconstruct(self):
|
def deconstruct(self):
|
||||||
name, path, args, kwargs = super(models.ImageField, self).deconstruct()
|
name, path, args, kwargs = super().deconstruct()
|
||||||
return name, path, (), {}
|
return name, path, (), {}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -116,7 +115,7 @@ class Avatar(models.Model):
|
||||||
avatars.update(primary=False)
|
avatars.update(primary=False)
|
||||||
else:
|
else:
|
||||||
avatars.delete()
|
avatars.delete()
|
||||||
super(Avatar, self).save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
def thumbnail_exists(self, width, height=None):
|
def thumbnail_exists(self, width, height=None):
|
||||||
return self.avatar.storage.exists(self.avatar_name(width, height))
|
return self.avatar.storage.exists(self.avatar_name(width, height))
|
||||||
|
|
@ -162,8 +161,6 @@ class Avatar(models.Model):
|
||||||
else:
|
else:
|
||||||
thumb_file = File(orig)
|
thumb_file = File(orig)
|
||||||
thumb_name = self.avatar_name(width, height)
|
thumb_name = self.avatar_name(width, height)
|
||||||
if self.avatar.storage.exists(thumb_name):
|
|
||||||
self.avatar.storage.delete(thumb_name)
|
|
||||||
thumb = self.avatar.storage.save(thumb_name, thumb_file)
|
thumb = self.avatar.storage.save(thumb_name, thumb_file)
|
||||||
except IOError:
|
except IOError:
|
||||||
thumb_file = File(orig)
|
thumb_file = File(orig)
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ def avatar_url(user, width=settings.AVATAR_DEFAULT_SIZE, height=None):
|
||||||
avatar_url = provider.get_avatar_url(user, width, height)
|
avatar_url = provider.get_avatar_url(user, width, height)
|
||||||
if avatar_url:
|
if avatar_url:
|
||||||
return avatar_url
|
return avatar_url
|
||||||
|
return get_default_avatar_url()
|
||||||
|
|
||||||
|
|
||||||
@cache_result()
|
@cache_result()
|
||||||
|
|
|
||||||
|
|
@ -254,6 +254,15 @@ appear on the site. Listed below are those settings:
|
||||||
Path to the Django template to use for confirming a delete of a user's
|
Path to the Django template to use for confirming a delete of a user's
|
||||||
avatar. Defaults to ``avatar/avatar/confirm_delete.html``.
|
avatar. Defaults to ``avatar/avatar/confirm_delete.html``.
|
||||||
|
|
||||||
|
.. py:data:: AVATAR_ALLOWED_MIMETYPES
|
||||||
|
|
||||||
|
Limit allowed avatar image uploads by their actual content payload and what image codecs we wish to support.
|
||||||
|
This limits website user content site attack vectors against image codec buffer overflow and similar bugs.
|
||||||
|
`You must have python-imaging library installed <https://github.com/ahupp/python-magic>`_.
|
||||||
|
Suggested safe setting: ``("image/png", "image/gif", "image/jpeg")``.
|
||||||
|
When enabled you'll get the following error on the form upload *File content is invalid. Detected: image/tiff Allowed content types are: image/png, image/gif, image/jpg*.
|
||||||
|
|
||||||
|
|
||||||
Management Commands
|
Management Commands
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -287,6 +287,12 @@ class AvatarTests(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(image.mode, "RGB")
|
self.assertEqual(image.mode, "RGB")
|
||||||
|
|
||||||
|
def test_automatic_thumbnail_creation_image_type_conversion(self):
|
||||||
|
upload_helper(self, "django_pony_cmyk.jpg")
|
||||||
|
self.assertMediaFileExists(
|
||||||
|
f"/avatars/{self.user.id}/resized/80/80/django_pony_cmyk.png"
|
||||||
|
)
|
||||||
|
|
||||||
def test_thumbnail_transpose_based_on_exif(self):
|
def test_thumbnail_transpose_based_on_exif(self):
|
||||||
upload_helper(self, "image_no_exif.jpg")
|
upload_helper(self, "image_no_exif.jpg")
|
||||||
avatar = get_primary_avatar(self.user)
|
avatar = get_primary_avatar(self.user)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue