Skip to content

Commit

Permalink
Preserve file type on optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
noirbizarre committed May 28, 2017
1 parent 4786d0f commit ce26b11
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 47 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Current
- Use setuptools entry points to register backends.
- Added `NONE` extensions specification
- Added `list_files` to `Storage` to list the current bucket files
- Image optimization preserve file type as much as possible

0.3.0 (2017-03-05)
------------------
Expand Down
4 changes: 2 additions & 2 deletions flask_fs/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def resize(file, size):

image.thumbnail(size, Image.ANTIALIAS)

return _img_to_file(image)
return _img_to_file(image)


def optimize(file):
Expand All @@ -66,6 +66,6 @@ def _img_to_file(image):
out = six.BytesIO()
if image.mode == 'CMYK':
image = image.convert('RGBA')
image.save(out, 'png', optimize=True)
image.save(out, image.format or 'png', optimize=True)
out.seek(0)
return out
12 changes: 6 additions & 6 deletions flask_fs/mongo.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,25 +118,25 @@ def save(self, file_or_wfs, filename=None, bbox=None, overwrite=None):
else:
should_optimize = current_app.config['FS_IMAGES_OPTIMIZE']

def name(size=None, new_ext=None):
def name(size=None):
if size:
return '.'.join(['-'.join([basename, str(size)]), new_ext or ext])
return '.'.join(['-'.join([basename, str(size)]), ext])
else:
return '.'.join([basename, new_ext or ext])
return '.'.join([basename, ext])

if self.max_size:
resized = resize(file_or_wfs, self.max_size)
file_or_wfs.seek(0)
if resized:
self.original = self.fs.save(file_or_wfs, name('original'), **kwargs)
self.filename = self.fs.save(resized, name(new_ext='png'), **kwargs)
self.filename = self.fs.save(resized, name(), **kwargs)
else:
self.filename = self.fs.save(file_or_wfs, name(), **kwargs)
elif should_optimize:
optimized = optimize(file_or_wfs)
file_or_wfs.seek(0)
self.original = self.fs.save(file_or_wfs, name('original'), **kwargs)
self.filename = self.fs.save(optimized, name(new_ext='png'), **kwargs)
self.filename = self.fs.save(optimized, name(), **kwargs)
else:
self.filename = self.fs.save(file_or_wfs, name(), **kwargs)

Expand All @@ -146,7 +146,7 @@ def name(size=None, new_ext=None):
file_or_wfs.seek(0)
thumbnail = make_thumbnail(file_or_wfs, size, self.bbox)
self.thumbnails[str(size)] = self.fs.save(FileStorage(thumbnail),
name(size, 'png'),
name(size),
**kwargs)
return self.filename

Expand Down
15 changes: 13 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

import pytest

BIN_FILE = os.path.join(os.path.dirname(__file__), 'flask.png')
PNG_FILE = os.path.join(os.path.dirname(__file__), 'flask.png')
JPG_FILE = os.path.join(os.path.dirname(__file__), 'flask.jpg')


class TestConfig:
Expand All @@ -37,7 +38,17 @@ def app():

@pytest.fixture
def binfile():
return BIN_FILE
return PNG_FILE


@pytest.fixture
def pngfile():
return PNG_FILE


@pytest.fixture
def jpgfile():
return JPG_FILE


class Utils(object):
Expand Down
Binary file added tests/flask.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
88 changes: 51 additions & 37 deletions tests/test_mongoengine.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,14 +227,10 @@ class Tester(db.Document):
assert tester.file.filename == expected_filename


class ImageFieldTest(MongoEngineTestCase):
@pytest.fixture
def image(self, binfile):
return open(binfile, 'rb')

class ImageFieldTestMixin(MongoEngineTestCase):
@pytest.fixture
def resource(self, utils, image):
return utils.filestorage('flask.png', image)
return utils.filestorage('flask.{0}'.format(self.ext), image)

def test_default_validate(self, storage):
class Tester(db.Document):
Expand All @@ -253,7 +249,7 @@ def test_save_file(self, storage, image):
class Tester(db.Document):
image = ImageField(fs=storage)

filename = 'test.png'
filename = 'test.{0}'.format(self.ext)

tester = Tester()
tester.image.save(image, filename)
Expand Down Expand Up @@ -283,7 +279,7 @@ def test_save_filestorage(self, storage, resource, image):
class Tester(db.Document):
image = ImageField(fs=storage)

filename = 'flask.png'
filename = 'flask.{0}'.format(self.ext)

tester = Tester()
tester.image.save(resource)
Expand Down Expand Up @@ -315,8 +311,8 @@ def test_save_optimize_settings(self, app, storage, resource, image):
class Tester(db.Document):
image = ImageField(fs=storage)

filename = 'flask.png'
filename_original = 'flask-original.png'
filename = 'flask.{0}'.format(self.ext)
filename_original = 'flask-original.{0}'.format(self.ext)

tester = Tester()
tester.image.save(resource)
Expand Down Expand Up @@ -355,8 +351,8 @@ def test_save_optimize_attribute(self, app, storage, resource, image):
class Tester(db.Document):
image = ImageField(fs=storage, optimize=True)

filename = 'flask.png'
filename_original = 'flask-original.png'
filename = 'flask.{0}'.format(self.ext)
filename_original = 'flask-original.{0}'.format(self.ext)

tester = Tester()
tester.image.save(resource)
Expand Down Expand Up @@ -397,8 +393,8 @@ def test_save_max_size(self, storage, resource, image):
class Tester(db.Document):
image = ImageField(fs=storage, max_size=max_size)

filename = 'flask.png'
filename_original = 'flask-original.png'
filename = 'flask.{0}'.format(self.ext)
filename_original = 'flask-original.{0}'.format(self.ext)

tester = Tester()
tester.image.save(resource)
Expand Down Expand Up @@ -439,9 +435,9 @@ def test_save_thumbnails(self, storage, image, resource):
class Tester(db.Document):
image = ImageField(fs=storage, thumbnails=sizes)

filename = 'flask.png'
filename_150 = 'flask-150.png'
filename_32 = 'flask-32.png'
filename = 'flask.{0}'.format(self.ext)
filename_150 = 'flask-150.{0}'.format(self.ext)
filename_32 = 'flask-32.{0}'.format(self.ext)

tester = Tester()
tester.image.save(resource)
Expand Down Expand Up @@ -491,9 +487,9 @@ def test_save_thumbnails_with_bbox(self, storage, resource, image):
sizes = [150, 32]
bbox = (10, 10, 100, 100)

filename = 'flask.png'
filename_150 = 'flask-150.png'
filename_32 = 'flask-32.png'
filename = 'flask.{0}'.format(self.ext)
filename_150 = 'flask-150.{0}'.format(self.ext)
filename_32 = 'flask-32.{0}'.format(self.ext)

class Tester(db.Document):
image = ImageField(fs=storage, thumbnails=sizes)
Expand Down Expand Up @@ -552,18 +548,18 @@ def test_save_wih_two_fields(self, storage, resource):
sizes = [32]
bbox = (10, 10, 100, 100)

filename = 'flask.png'
filename_32 = 'flask-32.png'
filename = 'flask.{0}'.format(self.ext)
filename_32 = 'flask-32.{0}'.format(self.ext)

filename2 = 'flask2.png'
filename2 = 'flask2.{0}'.format(self.ext)

class Tester(db.Document):
image = ImageField(fs=storage, thumbnails=sizes)
image2 = ImageField(fs=storage)

tester = Tester()
tester.image.save(resource, bbox=bbox)
tester.image2.save(resource, filename='flask2.png')
tester.image2.save(resource, filename='flask2.{0}'.format(self.ext))
tester.validate()

assert tester.image
Expand Down Expand Up @@ -597,9 +593,9 @@ def test_save_and_update(self, storage, resource):
sizes = [150, 32]
bbox = (10, 10, 100, 100)

filename = 'flask.png'
filename_150 = 'flask-150.png'
filename_32 = 'flask-32.png'
filename = 'flask.{0}'.format(self.ext)
filename_150 = 'flask-150.{0}'.format(self.ext)
filename_32 = 'flask-32.{0}'.format(self.ext)

class Tester(db.Document):
image = ImageField(fs=storage, thumbnails=sizes)
Expand All @@ -621,11 +617,11 @@ class Tester(db.Document):
def test_best_match(self, storage, resource):
sizes = [150, 32]

# filename = 'flask.png'
filename_150 = 'flask-150.png'
filename_32 = 'flask-32.png'
# filename = 'flask.{0}'.format(self.ext)
filename_150 = 'flask-150.{0}'.format(self.ext)
filename_32 = 'flask-32.{0}'.format(self.ext)

filename2 = 'flask2.png'
filename2 = 'flask2.{0}'.format(self.ext)

class Tester(db.Document):
image = ImageField(fs=storage, thumbnails=sizes)
Expand Down Expand Up @@ -660,7 +656,7 @@ def test_save_with_upload_to(self, storage, resource):
class Tester(db.Document):
image = ImageField(fs=storage, upload_to=upload_to)

filename = 'flask.png'
filename = 'flask.{0}'.format(self.ext)

tester = Tester()
tester.image.save(resource)
Expand All @@ -686,7 +682,7 @@ def test_save_with_callable_upload_to(self, storage, resource):
class Tester(db.Document):
image = ImageField(fs=storage, upload_to=lambda o: upload_to)

filename = 'flask.png'
filename = 'flask.{0}'.format(self.ext)

tester = Tester()
tester.image.save(resource)
Expand Down Expand Up @@ -714,7 +710,7 @@ class Tester(db.Document):
tester.image.save(resource)
tester.validate()

expected_filename = 'prefix/filename.png'
expected_filename = 'prefix/filename.{0}'.format(self.ext)
assert tester.image
assert tester.image.filename == expected_filename
assert expected_filename in storage
Expand All @@ -732,7 +728,7 @@ def test_save_with_callable_basename_override(self, storage, resource):
class Tester(db.Document):
image = ImageField(fs=storage, basename=lambda o: 'prefix/filename')

expected_filename = 'other.png'
expected_filename = 'other.{0}'.format(self.ext)

tester = Tester()
tester.image.save(resource, expected_filename)
Expand All @@ -755,8 +751,8 @@ def test_rerender(self, app, storage, resource, image):
class Tester(db.Document):
image = ImageField(fs=storage, optimize=True)

filename = 'flask.png'
filename_original = 'flask-original.png'
filename = 'flask.{0}'.format(self.ext)
filename_original = 'flask-original.{0}'.format(self.ext)

storage.write(filename, image)

Expand Down Expand Up @@ -795,3 +791,21 @@ class Tester(db.Document):
assert original.size == source.size
assert optimized.size == source.size
assert os.stat(path_optimized).st_size < os.stat(path_original).st_size


class ImageFieldPngTest(ImageFieldTestMixin):
ext = 'png'

@pytest.fixture
def image(self, pngfile):
with open(pngfile, 'rb') as f:
yield f


class ImageFieldJpgTest(ImageFieldTestMixin):
ext = 'jpg'

@pytest.fixture
def image(self, jpgfile):
with open(jpgfile, 'rb') as f:
yield f

0 comments on commit ce26b11

Please sign in to comment.