def save(self, delete_zip_import=True, *args, **kwargs): """ If a zip file is uploaded, extract any images from it and add them to the gallery, before removing the zip file. """ super(BaseGallery, self).save(*args, **kwargs) if self.zip_import: zip_file = ZipFile(self.zip_import) for name in zip_file.namelist(): data = zip_file.read(name) try: from PIL import Image image = Image.open(BytesIO(data)) image.load() image = Image.open(BytesIO(data)) image.verify() except ImportError: pass except: continue name = os.path.split(name)[1] # This is a way of getting around the broken nature of # os.path.join on Python 2.x. See also the comment below. if isinstance(name, bytes): encoding = charsetdetect(name)['encoding'] tempname = name.decode(encoding) else: tempname = name # A gallery with a slug of "/" tries to extract files # to / on disk; see os.path.join docs. slug = self.slug if self.slug != "/" else "" path = os.path.join(GALLERIES_UPLOAD_DIR, slug, tempname) try: saved_path = default_storage.save(path, ContentFile(data)) except UnicodeEncodeError: from warnings import warn warn("A file was saved that contains unicode " "characters in its path, but somehow the current " "locale does not support utf-8. You may need to set " "'LC_ALL' to a correct value, eg: 'en_US.UTF-8'.") # The native() call is needed here around str because # os.path.join() in Python 2.x (in posixpath.py) # mixes byte-strings with unicode strings without # explicit conversion, which raises a TypeError as it # would on Python 3. path = os.path.join(GALLERIES_UPLOAD_DIR, slug, native(str(name, errors="ignore"))) saved_path = default_storage.save(path, ContentFile(data)) self.images.add(GalleryImage(file=saved_path)) if delete_zip_import: zip_file.close() self.zip_import.delete(save=True)
def save(self, delete_zip_import=True, *args, **kwargs): """ If a zip file is uploaded, extract any images from it and add them to the gallery, before removing the zip file. """ super().save(*args, **kwargs) if self.zip_import: zip_file = ZipFile(self.zip_import) for name in zip_file.namelist(): data = zip_file.read(name) try: from PIL import Image image = Image.open(BytesIO(data)) image.load() image = Image.open(BytesIO(data)) image.verify() except ImportError: pass except: # noqa continue name = os.path.split(name)[1] # In python3, name is a string. Convert it to bytes. if not isinstance(name, bytes): try: name = name.encode("cp437") except UnicodeEncodeError: # File name includes characters that aren't in cp437, # which isn't supported by most zip tooling. They will # not appear correctly. tempname = name # Decode byte-name. if isinstance(name, bytes): encoding = charsetdetect(name)["encoding"] tempname = name.decode(encoding) # A gallery with a slug of "/" tries to extract files # to / on disk; see os.path.join docs. slug = self.slug if self.slug != "/" else "" path = os.path.join(GALLERIES_UPLOAD_DIR, slug, tempname) try: saved_path = default_storage.save(path, ContentFile(data)) except UnicodeEncodeError: from warnings import warn warn("A file was saved that contains unicode " "characters in its path, but somehow the current " "locale does not support utf-8. You may need to set " "'LC_ALL' to a correct value, eg: 'en_US.UTF-8'.") # The native() call is needed here around str because # os.path.join() in Python 2.x (in posixpath.py) # mixes byte-strings with unicode strings without # explicit conversion, which raises a TypeError as it # would on Python 3. path = os.path.join(GALLERIES_UPLOAD_DIR, slug, str(name, errors="ignore")) saved_path = default_storage.save(path, ContentFile(data)) self.images.create(file=saved_path) if delete_zip_import: zip_file.close() self.zip_import.delete(save=True)