Skip to content

Commit

Permalink
Merge pull request #1410 from firm1/import-images-from-archives
Browse files Browse the repository at this point in the history
Import d'une archive d'images dans une galerie
  • Loading branch information
Eskimon committed Sep 7, 2014
2 parents 581572f + dead3cf commit 809aec0
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 2 deletions.
Binary file added fixtures/archive-gallery.zip
Binary file not shown.
3 changes: 3 additions & 0 deletions templates/gallery/gallery/details.html
Expand Up @@ -33,6 +33,9 @@
<a href="{% url "zds.gallery.views.new_image" gallery.pk %}" class="new-btn ico-after more blue">
Ajouter une image
</a>
<a href="{% url "zds.gallery.views.import_image" gallery.pk %}" class="new-btn ico-after more blue">
Importer une archive
</a>
{% endblock %}


Expand Down
36 changes: 36 additions & 0 deletions zds/gallery/forms.py
Expand Up @@ -149,6 +149,42 @@ def clean(self):
return cleaned_data


class ArchiveImageForm(forms.Form):
file = forms.FileField(
label='Sélectionnez l\'archive contenant les images à charger',
required=True
)

def __init__(self, *args, **kwargs):
super(ArchiveImageForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_class = 'clearfix'
self.helper.form_method = 'post'

self.helper.layout = Layout(
Field('file'),
ButtonHolder(
StrictButton('Importer', type='submit'),
HTML('<a class="btn btn-cancel" '
u'href="{{ gallery.get_absolute_url }}">Annuler</a>'),
),
)

def clean(self):
cleaned_data = super(ArchiveImageForm, self).clean()

file = cleaned_data.get('file')
extension=file.name.split('.')[-1]

if extension != "zip":
self._errors['file'] = self.error_class(
[u"Le champ n'accepte que les fichiers zip"])
if 'file' in cleaned_data:
del cleaned_data['file']

return cleaned_data


class UpdateImageForm(ImageForm):
def __init__(self, *args, **kwargs):
super(ImageForm, self).__init__(*args, **kwargs)
Expand Down
14 changes: 13 additions & 1 deletion zds/gallery/tests/tests_forms.py
Expand Up @@ -5,7 +5,7 @@
from django.test import TestCase
from django.core.files.uploadedfile import SimpleUploadedFile

from zds.gallery.forms import GalleryForm, UserGalleryForm, ImageForm, ImageAsAvatarForm
from zds.gallery.forms import GalleryForm, UserGalleryForm, ImageForm, ImageAsAvatarForm, ArchiveImageForm
from zds.member.factories import ProfileFactory
from zds import settings

Expand Down Expand Up @@ -81,6 +81,18 @@ def test_valid_image_form(self):

self.assertTrue(form.is_valid())
upload_file.close()

def test_valid_archive_image_form(self):
upload_file = open(os.path.join(settings.SITE_ROOT, 'fixtures', 'archive-gallery.zip'), 'r')

data = {}
files = {
'file': SimpleUploadedFile(upload_file.name, upload_file.read())
}
form = ArchiveImageForm(data, files)

self.assertTrue(form.is_valid())
upload_file.close()

def test_empty_title_image_form(self):
upload_file = open(os.path.join(settings.SITE_ROOT, 'fixtures', 'logo.png'), 'r')
Expand Down
36 changes: 36 additions & 0 deletions zds/gallery/tests/tests_views.py
Expand Up @@ -616,3 +616,39 @@ def test_fail_gallery_not_exist(self):
)

self.assertEqual(404, response.status_code)

def test_import_images_in_gallery(self):
login_check = self.client.login(username=self.profile1.user.username, password='hostel77')
self.assertTrue(login_check)

with open(os.path.join(settings.SITE_ROOT, 'fixtures', 'archive-gallery.zip'), 'r') as fp:
response = self.client.post(
reverse(
'zds.gallery.views.import_image',
args=[self.gallery.pk]
),
{
'file': fp
},
follow=False
)
self.assertEqual(302, response.status_code)
self.assertEqual(Image.objects.filter(gallery=self.gallery).count(), 1)

def test_denies_import_images_in_gallery(self):
login_check = self.client.login(username=self.profile2.user.username, password='hostel77')
self.assertTrue(login_check)

with open(os.path.join(settings.SITE_ROOT, 'fixtures', 'archive-gallery.zip'), 'r') as fp:
response = self.client.post(
reverse(
'zds.gallery.views.import_image',
args=[self.gallery.pk]
),
{
'file': fp
},
follow=True
)
self.assertEqual(403, response.status_code)
self.assertEqual(Image.objects.filter(gallery=self.gallery).count(), 0)
2 changes: 2 additions & 0 deletions zds/gallery/urls.py
Expand Up @@ -21,4 +21,6 @@
'zds.gallery.views.delete_image'),
url(r'^image/editer/(?P<gal_pk>\d+)/(?P<img_pk>\d+)/$',
'zds.gallery.views.edit_image'),
url(r'^image/importer/(?P<gal_pk>\d+)/$',
'zds.gallery.views.import_image'),
)
84 changes: 83 additions & 1 deletion zds/gallery/views.py
Expand Up @@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-

from datetime import datetime
from PIL import Image as ImagePIL
from django.conf import settings
from django.contrib import messages
from django.http import Http404
Expand All @@ -11,13 +12,19 @@
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
from django.shortcuts import redirect, get_object_or_404
from zds.gallery.forms import ImageForm, UpdateImageForm, GalleryForm, UserGalleryForm, ImageAsAvatarForm
from zds.gallery.forms import ArchiveImageForm, ImageForm, UpdateImageForm, GalleryForm, UserGalleryForm, ImageAsAvatarForm
from zds.gallery.models import UserGallery, Image, Gallery
from zds.tutorial.models import Tutorial
from zds.member.decorator import can_write_and_read_now
from zds.utils import render_template
from zds.utils import slugify

from django.core.files import File
from zds.tutorial.models import Tutorial
import zipfile
import shutil
import os
from django.db import transaction


@login_required
Expand Down Expand Up @@ -297,3 +304,78 @@ def new_image(request, gal_pk):
form = ImageForm(initial={"new_image": True}) # A empty, unbound form
return render_template("gallery/image/new.html", {"form": form,
"gallery": gal})

@can_write_and_read_now
@login_required
@transaction.atomic
def import_image(request, gal_pk):
"""Create images from zip archive."""

gal = get_object_or_404(Gallery, pk=gal_pk)

try:
gal_mode = UserGallery.objects.get(gallery=gal, user=request.user)
if gal_mode.mode != 'W':
raise PermissionDenied
except:
raise PermissionDenied

#if request is POST
if request.method == "POST":
form = ArchiveImageForm(request.POST, request.FILES)
if form.is_valid():
archive = request.FILES["file"]
temp = os.path.join(settings.SITE_ROOT, "temp")
if not os.path.exists(temp):
os.makedirs(temp)
zfile = zipfile.ZipFile(archive, "a")
for i in zfile.namelist():
ph_temp = os.path.abspath(os.path.join(temp, i))
(dirname, filename) = os.path.split(i)
#if directory doesn't exist, created on
if not os.path.exists(os.path.dirname(ph_temp)):
os.makedirs(os.path.dirname(ph_temp))
#if file is directory, don't create file
if filename.strip() == "":
continue
data = zfile.read(i)
# create file for image
fp = open(ph_temp, "wb")
fp.write(data)
fp.close()
title = os.path.basename(i)
# if size is too large don't save
if os.stat(ph_temp).st_size > settings.IMAGE_MAX_SIZE:
messages.error(request, u"L'image {} n'a pas pu être importée dans la galerie car elle est beaucoup trop lourde".format(title))
continue
# if it's not an image, pass
try:
im = ImagePIL.open(ph_temp)
except IOError:
continue
f = File(open(ph_temp, "rb"))
f.name = title
# create picture in database
pic = Image()
pic.gallery = gal
pic.title = title
pic.pubdate = datetime.now()
pic.physical = f
pic.save()
f.close()

zfile.close()

if os.path.exists(temp):
shutil.rmtree(temp)

# Redirect to the newly uploaded gallery
return redirect(reverse("zds.gallery.views.gallery_details",
args=[gal.pk, gal.slug]))
else:
return render_template("gallery/image/new.html", {"form": form,
"gallery": gal})
else:
form = ArchiveImageForm(initial={"new_image": True}) # A empty, unbound form
return render_template("gallery/image/new.html", {"form": form,
"gallery": gal})

0 comments on commit 809aec0

Please sign in to comment.