Skip to content
This repository has been archived by the owner on Sep 22, 2020. It is now read-only.

Commit

Permalink
Fix imports of optional dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
relekang committed Apr 3, 2015
1 parent 7f67355 commit b1b4d22
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 43 deletions.
15 changes: 7 additions & 8 deletions tests/test_engines.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

from PIL import Image

from thumbnails.engines import (BaseThumbnailEngine, DummyEngine, PgmagickEngine, PillowEngine,
WandEngine)
from thumbnails.engines import DummyEngine, PgmagickEngine, PillowEngine, WandEngine
from thumbnails.engines.base import BaseThumbnailEngine
from thumbnails.errors import ThumbnailError
from thumbnails.images import SourceFile, Thumbnail

Expand All @@ -17,8 +17,7 @@
class EngineTestMixin(object):

def setUp(self):
if self.ENGINE:
self.engine = self.ENGINE()
self.engine = self.ENGINE()
self.filename = os.path.join(os.path.dirname(__file__), 'test_image.jpg')
self.file = SourceFile(self.filename)
self.url = SourceFile('http://puppies.lkng.me/400x600/')
Expand All @@ -36,15 +35,15 @@ def assertSize(self, thumbnail, width, height):
def assertRawData(self, raw_data):
self.assertEqual(hashlib.sha1(raw_data).hexdigest(), self.RAW_DATA_HASH)

@mock.patch('thumbnails.engines.BaseThumbnailEngine.create')
@mock.patch('thumbnails.engines.BaseThumbnailEngine.cleanup')
@mock.patch('thumbnails.engines.base.BaseThumbnailEngine.create')
@mock.patch('thumbnails.engines.base.BaseThumbnailEngine.cleanup')
def test_get_thumbnail(self, mock_create, mock_cleanup):
self.engine.get_thumbnail(self.file, '200', None, None)
self.assertTrue(mock_create.called)
self.assertTrue(mock_cleanup.called)

@mock.patch('thumbnails.engines.BaseThumbnailEngine.create', side_effect=ThumbnailError(''))
@mock.patch('thumbnails.engines.BaseThumbnailEngine.cleanup')
@mock.patch('thumbnails.engines.base.BaseThumbnailEngine.create', side_effect=ThumbnailError(''))
@mock.patch('thumbnails.engines.base.BaseThumbnailEngine.cleanup')
def test_get_thumbnail_fail(self, mock_create, mock_cleanup):
self.engine.get_thumbnail(self.file, '200', None, None)
self.assertTrue(mock_create.called)
Expand Down
2 changes: 2 additions & 0 deletions thumbnails/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-

from thumbnails.conf import settings
from thumbnails.engines import DummyEngine
from thumbnails.helpers import get_engine, generate_filename, get_cache_backend
Expand Down Expand Up @@ -29,6 +30,7 @@ def get_thumbnail(original, size, **options):
detected file type as well as the one specified in ``THUMBNAIL_FALLBACK_FORMAT``.
:return: A Thumbnail object
"""

engine = get_engine()
cache = get_cache_backend()
original = SourceFile(original)
Expand Down
22 changes: 3 additions & 19 deletions thumbnails/engines/__init__.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
# -*- coding: utf-8 -*-
from thumbnails.engines.base import BaseThumbnailEngine # noqa
from thumbnails.engines.dummy import DummyEngine # noqa


try:
from thumbnails.engines.pillow_engine import PillowEngine # noqa
except ImportError:
PillowEngine = None


try:
from thumbnails.engines.wand_engine import WandEngine # noqa
except ImportError:
WandEngine = None


try:
from thumbnails.engines.pgmagick_engine import PgmagickEngine # noqa
except ImportError:
PgmagickEngine = None
from thumbnails.engines.pillow_engine import PillowEngine # noqa
from thumbnails.engines.wand_engine import WandEngine # noqa
from thumbnails.engines.pgmagick_engine import PgmagickEngine # noqa
25 changes: 15 additions & 10 deletions thumbnails/engines/pgmagick_engine.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
from base64 import b64decode

from pgmagick import Blob, Geometry, Image, ImageType

from .base import BaseThumbnailEngine


Expand All @@ -11,15 +9,23 @@ class PgmagickEngine(BaseThumbnailEngine):
Image backend for pgmagick, requires the pgmagick package.
"""

def __init__(self):
super(PgmagickEngine, self).__init__()
from pgmagick import Blob, Geometry, Image, ImageType
self._Blob = Blob
self._Geometry = Geometry
self._Image = Image
self._ImageType = ImageType

def engine_load_image(self, original):
blob = Blob()
blob = self._Blob()
blob.update(original.open().read())
return Image(blob)
return self._Image(blob)

def engine_raw_data(self, image, options):
image.magick(self.get_format(image, options))
image.quality(options['quality'])
blob = Blob()
blob = self._Blob()
image.write(blob)
return b64decode(blob.base64())

Expand All @@ -28,14 +34,14 @@ def engine_image_size(self, image):
return geometry.width(), geometry.height()

def engine_scale(self, image, width, height):
geometry = Geometry(width, height)
geometry = self._Geometry(width, height)
image.scale(geometry)
return image

def engine_crop(self, image, size, crop, options):
x, y = crop
width, height = size
geometry = Geometry(width, height, x, y)
geometry = self._Geometry(width, height, x, y)
image.crop(geometry)
return image

Expand All @@ -44,14 +50,13 @@ def engine_cleanup(self, original):

def engine_colormode(self, image, colormode):
if colormode == 'RGB':
image.type(ImageType.TrueColorMatteType)
image.type(self._ImageType.TrueColorMatteType)
elif colormode == 'GRAY':
image.type(ImageType.GrayscaleMatteType)
image.type(self._ImageType.GrayscaleMatteType)
return image

def engine_get_format(self, image):
_format = image.format()
# pgmagick in python 2.7 gives full length formats instead of abbrevations
if _format == 'Joint Photographic Experts Group JFIF format':
return 'JPEG'
if _format == 'Portable Network Graphics':
Expand Down
13 changes: 9 additions & 4 deletions thumbnails/engines/pillow_engine.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
from PIL import Image, ImageFile

from thumbnails.compat import BytesIO
from thumbnails.errors import ThumbnailError
Expand All @@ -12,16 +11,22 @@ class PillowEngine(BaseThumbnailEngine):
Thumbnail engine for Pillow
"""

def __init__(self):
super(PillowEngine, self).__init__()
from PIL import Image, ImageFile
self._Image = Image
self._ImageFile = ImageFile

def engine_load_image(self, original):
image = Image.open(BytesIO(original.open().read()))
image = self._Image.open(BytesIO(original.open().read()))
try:
image.load()
except (IOError, OSError) as e:
raise ThumbnailError('Could not load image', exception=e)
return image

def engine_raw_data(self, image, options):
ImageFile.MAXBLOCK = max(ImageFile.MAXBLOCK, int(image.size[0] * image.size[1]))
self._ImageFile.MAXBLOCK = max(self._ImageFile.MAXBLOCK, int(image.size[0] * image.size[1]))
pillow_options = {
'format': self.get_format(image, options),
'quality': options['quality'],
Expand All @@ -34,7 +39,7 @@ def engine_image_size(self, image):
return image.size

def engine_scale(self, image, width, height):
return image.resize((width, height), resample=Image.ANTIALIAS)
return image.resize((width, height), resample=self._Image.ANTIALIAS)

def engine_crop(self, image, size, crop, options):
x, y = crop
Expand Down
7 changes: 5 additions & 2 deletions thumbnails/engines/wand_engine.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
from wand.image import Image

from .base import BaseThumbnailEngine

Expand All @@ -8,12 +7,16 @@ class WandEngine(BaseThumbnailEngine):
"""
Image engine for wand.
"""
def __init__(self):
super(WandEngine, self).__init__()
from wand.image import Image
self._Image = Image

def engine_image_size(self, image):
return image.size

def engine_load_image(self, original):
return Image(blob=original.open().read())
return self._Image(blob=original.open().read())

def engine_scale(self, image, width, height):
image.resize(width, height)
Expand Down

0 comments on commit b1b4d22

Please sign in to comment.