Though it's not the case with `FileSystemStorage`, attempting to delete
a nonexistent file can cause an exception (as in #80). We want to avoid
these errors but don't want to suppress others raised in the process of
deleting the file, so we first check to see if the file exists.
The `options` argument for `ImageSpec` and `ProcessedImageField`
replaces `quality` and provides a more general solution, allowing the
user access to PIL's format-specific options (including "quality",
"progressive", and "optimize" for JPEGs).
After #51 presented a good use case, we decided to make this part of
the API (i.e. remove the underscore). The default value for the `lazy`
kwarg is changed to `True` to reduce the likelihood of accidental
regeneration of images. Closes#54.
At first, we only had a small amount of code for preserving
transparency in `img_to_fobj`, but as that code grew it became apparent
that it really didn't belong in the utility function. This commit
creates an `AutoConvert` processor which is automatically run before
saving unless you disable it by passing `autoconvert=False` to your
`ImageSpec` or `ProcessedImageField` constructor. `img_to_fobj` is once
again a simple utility function for creating a file object from a PIL
image.
Previously, we set it to an arbitrary large number (which turned out
not to be large enough in some cases). Since we may have been
overriding something the user explicitly chose (and our value may be
overridden by another app), that probably wasn't good. After this
change, `MAXBLOCK` is only increased when it needs to be--and even
then, only temporarily.
IK relies on PIL's EXTENSION list to map formats to extensions.
However, this list normally isn't populated until an image is loaded.
This change forces the population of the list before examining it.
* 'new_api' of https://github.com/matthewwithanm/django-imagekit: (63 commits)
fixing typo
ImageSpecFile is a proper File
Typo fix
A list of ImageSpec names are now stored on the model.
AdminThumbnailView is now AdminThumbnail
Docs typo fix
Adds explicit import of resize module to processors
fixing bad import in docs
adding name to AUTHORS
adding test for new api
Moved Crop and Fit to resize module.
More docs edits.
Typo fix.
Installation instructions.
Embracing duck typing.
Documentation!
Fix bug
Bound fields are now cached on the model instance.
Transpose processor now supports auto EXIF orientation.
Fix filename formatting.
...
Conflicts:
AUTHORS
README.rst
docs/Makefile
docs/conf.py
docs/index.rst
imagekit/__init__.py
imagekit/defaults.py
imagekit/management/commands/ikflush.py
imagekit/models.py
imagekit/options.py
imagekit/processors.py
imagekit/specs.py
tests/core/tests.py
Previously, ImageSpecFile was a file-like object, but didn't actually
extend any of the file classes. Because of this, some of Django's file-
handling code was duplicated. More importantly, instances didn't always
behave as one might expect (if one were familiar with ImageFields),
particularly when the source image was empty. This could have been
especially confusing in templates. (For example, because
ImageSpecFields whose source images didn't exist were still truthy.)
Previously, ImageSpecFile instances were retrieved (for saving and deleting,
among other possibilities) by iterating over the model instance's attributes.
This change adds ImageSpecFile names to a list (spec_file_names) on an
imagekit meta object on the model (_ik), making later retrieval much cheaper
and more straightforward.
I never liked that the "AdminThumbnailView" was supposed to be defined
on the model, but never looked into it.
This commit puts the definition back where it belongs: in the admin.
Instead of requiring you to add a field (with view logic) to your
model, you now just add a property to your admin class and specify
that property in the `list_display` list.
Eric's fixes in c00ea10b0a meant that
some of the code that already existed to reuse objects would actually
be run for the first time. Naturally, there were some bugs; namely, I
was storing a filename (instead of a File object) in `_file` and a bad
else clause.
Replaced calls to Image.open with an open_image utility function.
The open_image utility calls Image.open, but then wraps the opened Image's
copy method with a version that preserves EXIF data. This allows an
ImageSpec to copy the original image, yet still provide all the original
image's exif data to the processor pipeline.
Centralized access of _img, tried to reduce re-calculation of some
properties, renamed _imgfield to source_file to reflect the fact that
it's an ImageFieldFile and not an ImageField.
The process of choosing an image format has been cleaned up and
Processors' role in determining the format has been removed.
Previously, processors would return a tuple containing the modified
image and the format. Other parts of IK overrode PIL's Image.format
with the target format, although that had no effect on PIL and the fact
that it didn't throw an error was just lucky.
Removed the save and clear_cache methods from ImageModel (along with helpers).
Now, whenever an ImageSpec is contributed to a model, handlers are created for
the post_save and post_delete signals. The post_save handler does the work of
running the ImageSpec processors and caching the resulting file, while the
post_delete handler does the work cleaning up the cached files.
You're no longer restricted to just one, special-case admin thumbnail. Make as
many as you want by adding AdminThumbnailView properties to your model and
including them in your admin class's `list_display` tuple. You can also provide
a custom template. Note that (because this change introduces templates to
imagekit), imagekit is now required in INSTALLED_APPS.
Ideally we could get this stuff out of the model, but we'll have to look into
whether that's possible without making things really complicated.
By creating the Descriptor using contribute_to_class (instead of in
ImageModelBase's __init__), we take the first step towards eliminating the need
to extend ImageModel at all.
This works kind of like Django's models' _default_manager. If your specs don't
specify an image_field, and your IKOptions don't specify a default_image_field,
the first ImageField your model defines will be used.