mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-11-04 01:12:08 +01:00 
			
		
		
		
	Merge branch 'image_upload' into 'beta'
Move image upload code to form clean See merge request bde/nk20!112
This commit is contained in:
		@@ -1,7 +1,11 @@
 | 
			
		||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
import io
 | 
			
		||||
 | 
			
		||||
from PIL import Image
 | 
			
		||||
from django import forms
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.contrib.auth.forms import AuthenticationForm
 | 
			
		||||
from django.contrib.auth.models import User
 | 
			
		||||
from django.forms import CheckboxSelectMultiple
 | 
			
		||||
@@ -77,6 +81,38 @@ class ImageForm(forms.Form):
 | 
			
		||||
    width = forms.FloatField(widget=forms.HiddenInput())
 | 
			
		||||
    height = forms.FloatField(widget=forms.HiddenInput())
 | 
			
		||||
 | 
			
		||||
    def clean(self):
 | 
			
		||||
        """Load image and crop"""
 | 
			
		||||
        cleaned_data = super().clean()
 | 
			
		||||
 | 
			
		||||
        # Image size is limited by Django DATA_UPLOAD_MAX_MEMORY_SIZE
 | 
			
		||||
        image = cleaned_data.get('image')
 | 
			
		||||
        if image:
 | 
			
		||||
            # Let Pillow detect and load image
 | 
			
		||||
            try:
 | 
			
		||||
                im = Image.open(image)
 | 
			
		||||
            except OSError:
 | 
			
		||||
                # Rare case in which Django consider the upload file as an image
 | 
			
		||||
                # but Pil is unable to load it
 | 
			
		||||
                raise forms.ValidationError(_('This image cannot be loaded.'))
 | 
			
		||||
 | 
			
		||||
            # Crop image
 | 
			
		||||
            x = cleaned_data.get('x', 0)
 | 
			
		||||
            y = cleaned_data.get('y', 0)
 | 
			
		||||
            w = cleaned_data.get('width', 200)
 | 
			
		||||
            h = cleaned_data.get('height', 200)
 | 
			
		||||
            im = im.crop((x, y, x + w, y + h))
 | 
			
		||||
            im = im.resize(
 | 
			
		||||
                (settings.PIC_WIDTH, settings.PIC_RATIO * settings.PIC_WIDTH),
 | 
			
		||||
                Image.ANTIALIAS,
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            # Save
 | 
			
		||||
            image.file = io.BytesIO()
 | 
			
		||||
            im.save(image.file, "PNG")
 | 
			
		||||
 | 
			
		||||
        return cleaned_data
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ClubForm(forms.ModelForm):
 | 
			
		||||
    def clean(self):
 | 
			
		||||
 
 | 
			
		||||
@@ -55,12 +55,18 @@ SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
    /* SCRIPT TO OPEN THE MODAL WITH THE PREVIEW */
 | 
			
		||||
    $("#id_image").change(function (e) {
 | 
			
		||||
      if (this.files && this.files[0]) {
 | 
			
		||||
        var reader = new FileReader();
 | 
			
		||||
        reader.onload = function (e) {
 | 
			
		||||
          $("#modal-image").attr("src", e.target.result);
 | 
			
		||||
          $("#modalCrop").modal("show");
 | 
			
		||||
        // Check the image size
 | 
			
		||||
        if (this.files[0].size > 2*1024*1024) {
 | 
			
		||||
          alert("Ce fichier est trop volumineux.")
 | 
			
		||||
	} else {
 | 
			
		||||
          // Read the selected image file
 | 
			
		||||
          var reader = new FileReader();
 | 
			
		||||
          reader.onload = function (e) {
 | 
			
		||||
            $("#modal-image").attr("src", e.target.result);
 | 
			
		||||
            $("#modalCrop").modal("show");
 | 
			
		||||
          }
 | 
			
		||||
          reader.readAsDataURL(this.files[0]);
 | 
			
		||||
        }
 | 
			
		||||
        reader.readAsDataURL(this.files[0]);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
@@ -104,4 +110,4 @@ SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,8 @@
 | 
			
		||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
import io
 | 
			
		||||
from datetime import timedelta, date
 | 
			
		||||
 | 
			
		||||
from PIL import Image
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.contrib.auth import logout
 | 
			
		||||
from django.contrib.auth.mixins import LoginRequiredMixin
 | 
			
		||||
@@ -263,6 +261,7 @@ class PictureUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin, Det
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
    def get_success_url(self):
 | 
			
		||||
        """Redirect to profile page after upload"""
 | 
			
		||||
        return reverse_lazy('member:user_detail', kwargs={'pk': self.object.id})
 | 
			
		||||
 | 
			
		||||
    def post(self, request, *args, **kwargs):
 | 
			
		||||
@@ -271,26 +270,9 @@ class PictureUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin, Det
 | 
			
		||||
        return self.form_valid(form) if form.is_valid() else self.form_invalid(form)
 | 
			
		||||
 | 
			
		||||
    def form_valid(self, form):
 | 
			
		||||
        """Save image to note"""
 | 
			
		||||
        image_field = form.cleaned_data['image']
 | 
			
		||||
        x = form.cleaned_data['x']
 | 
			
		||||
        y = form.cleaned_data['y']
 | 
			
		||||
        w = form.cleaned_data['width']
 | 
			
		||||
        h = form.cleaned_data['height']
 | 
			
		||||
        # image crop and resize
 | 
			
		||||
        image_file = io.BytesIO(image_field.read())
 | 
			
		||||
        # ext = image_field.name.split('.')[-1].lower()
 | 
			
		||||
        # TODO: support GIF format
 | 
			
		||||
        image = Image.open(image_file)
 | 
			
		||||
        image = image.crop((x, y, x + w, y + h))
 | 
			
		||||
        image_clean = image.resize((settings.PIC_WIDTH,
 | 
			
		||||
                                    settings.PIC_RATIO * settings.PIC_WIDTH),
 | 
			
		||||
                                   Image.ANTIALIAS)
 | 
			
		||||
        image_file = io.BytesIO()
 | 
			
		||||
        image_clean.save(image_file, "PNG")
 | 
			
		||||
        image_field.file = image_file
 | 
			
		||||
        # renaming
 | 
			
		||||
        filename = "{}_pic.png".format(self.object.note.pk)
 | 
			
		||||
        image_field.name = filename
 | 
			
		||||
        image_field.name = "{}_pic.png".format(self.object.note.pk)
 | 
			
		||||
        self.object.note.display_image = image_field
 | 
			
		||||
        self.object.note.save()
 | 
			
		||||
        return super().form_valid(form)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user