Make Pillow optional due to external dependencies (#326)

Fixes #325.

`Pillow` has a number of external dependencies needed for installation. Since most media files are detected correctly with `imghdr` and `Pillow` is used as a fallback we can make it optional.

`Pillow` support was added in #320 to fix #281.
This commit is contained in:
Jaisen Mathai 2019-07-14 17:36:09 -07:00 committed by GitHub
parent 50c6e3597f
commit 87e0420fba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 17 deletions

View File

@ -12,10 +12,8 @@ import os
import re import re
import time import time
from datetime import datetime from datetime import datetime
from PIL import Image
from re import compile from re import compile
from elodie import log from elodie import log
from .media import Media from .media import Media
@ -38,6 +36,15 @@ class Photo(Media):
# We only want to parse EXIF once so we store it here # We only want to parse EXIF once so we store it here
self.exif = None self.exif = None
# Optionally import Pillow - see gh-325
# https://github.com/jmathai/elodie/issues/325
self.pillow = None
try:
from PIL import Image
self.pillow = Image
except ImportError:
pass
def get_date_taken(self): def get_date_taken(self):
"""Get the date which the photo was taken. """Get the date which the photo was taken.
@ -98,22 +105,28 @@ class Photo(Media):
if(extension != 'heic'): if(extension != 'heic'):
# gh-4 This checks if the source file is an image. # gh-4 This checks if the source file is an image.
# It doesn't validate against the list of supported types. # It doesn't validate against the list of supported types.
# We check with imghdr and pillow.
if(imghdr.what(source) is None): if(imghdr.what(source) is None):
# imghdr won't detect all variants of images (https://bugs.python.org/issue28591) # Pillow is used as a fallback and if it's not available we trust
# see https://github.com/jmathai/elodie/issues/281 # what imghdr returned.
# before giving up, we use `pillow` imaging library to detect file type if(self.pillow is None):
#
# It is important to note that the library doesn't decode or load the
# raster data unless it really has to. When you open a file,
# the file header is read to determine the file format and extract
# things like mode, size, and other properties required to decode the file,
# but the rest of the file is not processed until later.
try:
im = Image.open(source)
except IOError:
return False
if(im.format is None):
return False return False
else:
# imghdr won't detect all variants of images (https://bugs.python.org/issue28591)
# see https://github.com/jmathai/elodie/issues/281
# before giving up, we use `pillow` imaging library to detect file type
#
# It is important to note that the library doesn't decode or load the
# raster data unless it really has to. When you open a file,
# the file header is read to determine the file format and extract
# things like mode, size, and other properties required to decode the file,
# but the rest of the file is not processed until later.
try:
im = self.pillow.open(source)
except IOError:
return False
if(im.format is None):
return False
return extension in self.extensions return extension in self.extensions

View File

@ -165,6 +165,11 @@ def test_is_valid_fallback_using_pillow():
assert photo.is_valid() assert photo.is_valid()
def test_pillow_not_loaded():
photo = Photo(helper.get_file('imghdr-error.jpg'))
photo.pillow = None
assert photo.is_valid() == False
def test_set_album(): def test_set_album():
temporary_folder, folder = helper.create_working_folder() temporary_folder, folder = helper.create_working_folder()