django-avatar/avatar/forms.py

133 lines
4.7 KiB
Python
Raw Normal View History

import os
from django import forms
from django.forms import widgets
2022-08-09 19:17:24 +00:00
from django.template.defaultfilters import filesizeformat
from django.utils.safestring import mark_safe
2022-01-27 20:22:00 +00:00
from django.utils.translation import gettext_lazy as _
from PIL import Image, ImageOps
from avatar.conf import settings
from avatar.models import Avatar
def avatar_img(avatar, width, height):
if not avatar.thumbnail_exists(width, height):
avatar.create_thumbnail(width, height)
2022-07-16 20:50:05 +00:00
return mark_safe(
'<img src="%s" alt="%s" width="%s" height="%s" />'
% (avatar.avatar_url(width, height), str(avatar), width, height)
2022-07-16 20:50:05 +00:00
)
class UploadAvatarForm(forms.Form):
2013-08-01 11:19:56 +00:00
avatar = forms.ImageField(label=_("avatar"))
def __init__(self, *args, **kwargs):
2022-07-16 20:50:05 +00:00
self.user = kwargs.pop("user")
super().__init__(*args, **kwargs)
def clean_avatar(self):
2022-07-16 20:50:05 +00:00
data = self.cleaned_data["avatar"]
if settings.AVATAR_ALLOWED_MIMETYPES:
try:
import magic
except ImportError:
raise ImportError(
"python-magic library must be installed in order to use uploaded file content limitation"
)
# Construct 256 bytes needed for mime validation
magic_buffer = bytes()
for chunk in data.chunks():
magic_buffer += chunk
if len(magic_buffer) >= 256:
break
# https://github.com/ahupp/python-magic#usage
mime = magic.from_buffer(magic_buffer, mime=True)
if mime not in settings.AVATAR_ALLOWED_MIMETYPES:
raise forms.ValidationError(
_(
"File content is invalid. Detected: %(mimetype)s Allowed content types are: %(valid_mime_list)s"
)
% {
"valid_mime_list": ", ".join(settings.AVATAR_ALLOWED_MIMETYPES),
"mimetype": mime,
}
)
if settings.AVATAR_ALLOWED_FILE_EXTS:
root, ext = os.path.splitext(data.name.lower())
if ext not in settings.AVATAR_ALLOWED_FILE_EXTS:
valid_exts = ", ".join(settings.AVATAR_ALLOWED_FILE_EXTS)
2022-07-16 20:50:05 +00:00
error = _(
"%(ext)s is an invalid file extension. "
"Authorized extensions are : %(valid_exts_list)s"
)
raise forms.ValidationError(
error % {"ext": ext, "valid_exts_list": valid_exts}
)
if data.size > settings.AVATAR_MAX_SIZE:
2022-07-16 20:50:05 +00:00
error = _(
"Your file is too big (%(size)s), "
"the maximum allowed size is %(max_valid_size)s"
)
raise forms.ValidationError(
error
% {
"size": filesizeformat(data.size),
"max_valid_size": filesizeformat(settings.AVATAR_MAX_SIZE),
}
)
try:
image = Image.open(data)
ImageOps.exif_transpose(image)
except TypeError:
raise forms.ValidationError(_("Corrupted image"))
count = Avatar.objects.filter(user=self.user).count()
2019-12-03 14:43:31 +00:00
if 1 < settings.AVATAR_MAX_AVATARS_PER_USER <= count:
2022-07-16 20:50:05 +00:00
error = _(
"You already have %(nb_avatars)d avatars, "
"and the maximum allowed is %(nb_max_avatars)d."
)
raise forms.ValidationError(
error
% {
"nb_avatars": count,
"nb_max_avatars": settings.AVATAR_MAX_AVATARS_PER_USER,
}
)
return
class PrimaryAvatarForm(forms.Form):
def __init__(self, *args, **kwargs):
2022-07-16 20:50:05 +00:00
kwargs.pop("user")
width = kwargs.pop("width", settings.AVATAR_DEFAULT_SIZE)
height = kwargs.pop("height", settings.AVATAR_DEFAULT_SIZE)
2022-07-16 20:50:05 +00:00
avatars = kwargs.pop("avatars")
super().__init__(*args, **kwargs)
2022-07-16 20:50:05 +00:00
self.fields["choice"] = forms.ChoiceField(
choices=[(c.id, avatar_img(c, width, height)) for c in avatars],
widget=widgets.RadioSelect,
2022-07-16 20:50:05 +00:00
)
class DeleteAvatarForm(forms.Form):
def __init__(self, *args, **kwargs):
2022-07-16 20:50:05 +00:00
kwargs.pop("user")
width = kwargs.pop("width", settings.AVATAR_DEFAULT_SIZE)
height = kwargs.pop("height", settings.AVATAR_DEFAULT_SIZE)
2022-07-16 20:50:05 +00:00
avatars = kwargs.pop("avatars")
super().__init__(*args, **kwargs)
2022-07-16 20:50:05 +00:00
self.fields["choices"] = forms.MultipleChoiceField(
label=_("Choices"),
choices=[(c.id, avatar_img(c, width, height)) for c in avatars],
widget=widgets.CheckboxSelectMultiple,
2022-07-16 20:50:05 +00:00
)