* matthewwithanm/whencontrol:
Rename cache_state_backend to image_cache_backend
Add NonValidatingCacheStateBackend
Some documentation
Only invalidate spec file if source changes
Rename DefaultCacheStateBackend
generate method (optionally) saves file
Rename force flag to force-revalidation
Add clear method for when future validation is unwanted
Commands for validating and invalidating the cache
Fix var name typo
Spec files now accessible through _ik attr
Remove unused import
First shot at cache state backend implementation
Conflicts:
imagekit/models/fields.py
`resize.Crop` actually hasn't been moved to `crop.Crop` (as the removed
class claimed). In fact, what used to be called `resize.Crop` is now
`resize.Fill`. The confusion is understandable, since it's what
motivated the change in the first place!
This way, there's a creation counterpart to `delete()`. The user
shouldn't have to deal with storage backends to create and delete the
files, and now they don't.
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.
The in-code comments explain it pretty thoroughly but, in short, this
handles a lot more of the situations in which you're converting to or
from formats that support transparency.
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.
Crop doesn't necessarily imply the any scaling is taking place. Several
ideas were discussed, from renaming Crop to combining both processors
into a single Resize processor (as they were in the original IK), but
those solutions were felt to either precluded future extension
(alternative resize modes) or make the API too verbose.
ImageProcessor didn't do anything. I'd rather get it out of there to reduce the
temptation for future IK contributors to do type checking and mess up peoples'
custom processors.
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.
Transpose now takes transposition constants as arguments. Multiple
transpositions can be sequenced together in one Transpose processor.
Auto transposition is not yet supported (PIL strips the EXIF data, so need to
find a workaround for getting that data to the processor).
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.
The original handler implementation ported code from the old ImageModel's
save method, but ended up duplicating the efforts of the ImageSpecFile's
_create method.
In the old IK API, processors (like `Transpose`) were able to access
the file by inspecting the model instance (which carried an options
object that specified the attribute name of the ImageField from which
the file could be extracted). Since the new API allows for multiple
ImageFields (and because IKOptions have been removed), it became
necessary to provide more information. Initially, this was accomplished
by passing the spec to `process()`, however with the addition of
ProcessedImageField, it became clear the a cleaner solution was to pass
only the field file (ImageSpecFile or ProcessedImageFieldFile).
This keeps the ORM stuff (fields, etc.) out of the `ImageProcessor` API
but (because field files, not just regular files, are passed) the
average hacker can still have their processor make use of model
information by accessing the model through the file's `instance`
property.
One handler is created per model instead of per bound image spec.
This cuts down on the number of handlers created, and also offloads the
policing of the handlers in memory to the signal framework. Since they are no
longer being created per spec, the handlers can be weakly referenced.
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.