Skip to content

Commit

Permalink
Added ImageField.rerender()
Browse files Browse the repository at this point in the history
  • Loading branch information
noirbizarre committed Mar 4, 2017
1 parent af5d5bb commit 7b48c9a
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 8 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
Resized images are now compressed.
Default image can also be optimized on upload with ``FS_IMAGES_OPTIMIZE = True``
or by specifying `optimize=True` as field parameter.
- ``ImageField`` has now the ability to rerender images with the ``rerender()`` method.

0.2.1 (2017-01-17)
------------------
Expand Down
1 change: 1 addition & 0 deletions docs/mongoengine.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ On instance:
- the `best_url(size)` method match a thumbnail URL given a size
- the `thumbnail(size)` method get a thumbnail filename given a registered size
- the `save` method accept an optionnal `bbox` kwarg for to crop the thumbnails
- the `rerender` method allows to force a new image rendering (taking in account new parameters)
- the instance is callable as shortcut for `best_url()`

.. code-block:: python
Expand Down
26 changes: 18 additions & 8 deletions flask_fs/mongo.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def to_mongo(self):
data['bbox'] = self.bbox
return data

def save(self, file_or_wfs, filename=None, bbox=None):
def save(self, file_or_wfs, filename=None, bbox=None, overwrite=None):
'''Save a Werkzeug FileStorage object'''
self._mark_as_changed()
override = filename is not None
Expand All @@ -111,6 +111,7 @@ def save(self, file_or_wfs, filename=None, bbox=None):

ext = extension(filename)
prefix = self.upload_to(self._instance) if callable(self.upload_to) else self.upload_to
kwargs = {'prefix': prefix, 'overwrite': overwrite}

if self.optimize is not None:
should_optimize = self.optimize
Expand All @@ -127,17 +128,17 @@ def name(size=None, new_ext=None):
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'), prefix=prefix)
self.filename = self.fs.save(resized, name(new_ext='png'), prefix=prefix)
self.original = self.fs.save(file_or_wfs, name('original'), **kwargs)
self.filename = self.fs.save(resized, name(new_ext='png'), **kwargs)
else:
self.filename = self.fs.save(file_or_wfs, name(), prefix=prefix)
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'), prefix=prefix)
self.filename = self.fs.save(optimized, name(new_ext='png'), prefix=prefix)
self.original = self.fs.save(file_or_wfs, name('original'), **kwargs)
self.filename = self.fs.save(optimized, name(new_ext='png'), **kwargs)
else:
self.filename = self.fs.save(file_or_wfs, name(), prefix=prefix)
self.filename = self.fs.save(file_or_wfs, name(), **kwargs)

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

@property
Expand Down Expand Up @@ -186,6 +187,15 @@ def best_url(self, size=None, external=False):
filename = self.thumbnail(best_size)
return self.fs.url(filename, external=external) if filename else None

def rerender(self):
'''
Rerender all derived images from the original.
If optmization settings or expected sizes changed,
they will be used for the new rendering.
'''
with self.fs.open(self.original, 'rb') as img:
self.save(img, filename=self.filename, bbox=self.bbox, overwrite=True)

__call__ = best_url


Expand Down
45 changes: 45 additions & 0 deletions tests/test_mongoengine.py
Original file line number Diff line number Diff line change
Expand Up @@ -750,3 +750,48 @@ class Tester(db.Document):
tester.save()
tester = Tester.objects.get(id=tester.id)
assert tester.image.filename == expected_filename

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'

storage.write(filename, image)

tester = Tester()
tester.image.filename = filename
assert tester.to_mongo() == {
'image': {
'filename': filename,
}
}

tester.image.rerender()
tester.save().reload()

assert tester.image
assert str(tester.image) == tester.image.url
assert tester.image.filename == filename
assert tester.image.original == filename_original
assert filename in storage
assert tester.to_mongo() == {
'_id': tester.pk,
'image': {
'filename': filename,
'original': filename_original,
}
}

path_original = storage.path(filename_original)
path_optimized = storage.path(filename)

with open(path_original, 'rb') as f_orig:
with open(path_optimized, 'rb') as f_optimized:
source = Image.open(image)
original = Image.open(f_orig)
optimized = Image.open(f_optimized)
assert original.size == source.size
assert optimized.size == source.size
assert os.stat(path_optimized).st_size < os.stat(path_original).st_size

0 comments on commit 7b48c9a

Please sign in to comment.