113 lines
4.2 KiB
Python
113 lines
4.2 KiB
Python
|
#!/usr/bin/env python
|
||
|
# vim:fileencoding=utf-8
|
||
|
from django.core.exceptions import ImproperlyConfigured
|
||
|
from django.utils.importlib import import_module
|
||
|
|
||
|
__author__ = 'zeus'
|
||
|
|
||
|
import os
|
||
|
import zipfile
|
||
|
from django.db import models
|
||
|
from django.utils.translation import ugettext_lazy as _
|
||
|
from django.conf import settings
|
||
|
from django.core.files.base import ContentFile
|
||
|
try:
|
||
|
import Image as PILImage
|
||
|
except ImportError:
|
||
|
from PIL import Image as PILImage
|
||
|
|
||
|
from imagestore.models import Album, Image
|
||
|
|
||
|
TEMP_DIR = getattr(settings, 'TEMP_DIR', 'temp/')
|
||
|
|
||
|
|
||
|
def process_zipfile(uploaded_album):
|
||
|
if os.path.isfile(uploaded_album.zip_file.path):
|
||
|
# TODO: implement try-except here
|
||
|
zip = zipfile.ZipFile(uploaded_album.zip_file.path)
|
||
|
bad_file = zip.testzip()
|
||
|
if bad_file:
|
||
|
raise Exception('"%s" in the .zip archive is corrupt.' % bad_file)
|
||
|
|
||
|
if not uploaded_album.album:
|
||
|
uploaded_album.album = Album.objects.create(name=uploaded_album.new_album_name)
|
||
|
|
||
|
from cStringIO import StringIO
|
||
|
for filename in sorted(zip.namelist()):
|
||
|
if filename.startswith('__'): # do not process meta files
|
||
|
continue
|
||
|
print filename
|
||
|
data = zip.read(filename)
|
||
|
if len(data):
|
||
|
try:
|
||
|
# the following is taken from django.forms.fields.ImageField:
|
||
|
# load() could spot a truncated JPEG, but it loads the entire
|
||
|
# image in memory, which is a DoS vector. See #3848 and #18520.
|
||
|
# verify() must be called immediately after the constructor.
|
||
|
PILImage.open(StringIO(data)).verify()
|
||
|
except Exception, ex:
|
||
|
# if a "bad" file is found we just skip it.
|
||
|
print('Error verify image: %s' % ex.message)
|
||
|
continue
|
||
|
if hasattr(data, 'seek') and callable(data.seek):
|
||
|
print 'seeked'
|
||
|
data.seek(0)
|
||
|
try:
|
||
|
img = Image(album=uploaded_album.album)
|
||
|
img.image.save(filename, ContentFile(data))
|
||
|
img.save()
|
||
|
except Exception, ex:
|
||
|
print('error create Image: %s' % ex.message)
|
||
|
zip.close()
|
||
|
uploaded_album.delete()
|
||
|
|
||
|
|
||
|
upload_processor_function = getattr(settings, 'IMAGESTORE_UPLOAD_ALBUM_PROCESSOR', None)
|
||
|
upload_processor = process_zipfile
|
||
|
if upload_processor_function:
|
||
|
i = upload_processor_function.rfind('.')
|
||
|
module, attr = upload_processor_function[:i], upload_processor_function[i+1:]
|
||
|
try:
|
||
|
mod = import_module(module)
|
||
|
except ImportError as e:
|
||
|
raise ImproperlyConfigured('Error importing request processor module %s: "%s"' % (module, e))
|
||
|
try:
|
||
|
upload_processor = getattr(mod, attr)
|
||
|
except AttributeError:
|
||
|
raise ImproperlyConfigured('Module "%s" does not define a "%s" callable request processor' % (module, attr))
|
||
|
|
||
|
|
||
|
class AlbumUpload(models.Model):
|
||
|
"""
|
||
|
Just re-written django-photologue GalleryUpload method
|
||
|
"""
|
||
|
zip_file = models.FileField(_('images file (.zip)'), upload_to=TEMP_DIR,
|
||
|
help_text=_('Select a .zip file of images to upload into a new Gallery.'))
|
||
|
album = models.ForeignKey(
|
||
|
Album,
|
||
|
null=True,
|
||
|
blank=True,
|
||
|
help_text=_('Select an album to add these images to. leave this empty to create a new album from the supplied title.')
|
||
|
)
|
||
|
new_album_name = models.CharField(
|
||
|
max_length=255,
|
||
|
blank=True,
|
||
|
verbose_name=_('New album name'),
|
||
|
help_text=_('If not empty new album with this name will be created and images will be upload to this album')
|
||
|
)
|
||
|
tags = models.CharField(max_length=255, blank=True, verbose_name=_('tags'))
|
||
|
|
||
|
class Meta(object):
|
||
|
verbose_name = _('Album upload')
|
||
|
verbose_name_plural = _('Album uploads')
|
||
|
app_label = 'imagestore'
|
||
|
|
||
|
def save(self, *args, **kwargs):
|
||
|
super(AlbumUpload, self).save(*args, **kwargs)
|
||
|
upload_processor(self)
|
||
|
|
||
|
def delete(self, *args, **kwargs):
|
||
|
storage, path = self.zip_file.storage, self.zip_file.path
|
||
|
super(AlbumUpload, self).delete(*args, **kwargs)
|
||
|
storage.delete(path)
|