Merge branch 'release/0.4.0'

* release/0.4.0:
  Think it's time to bump to 0.4.0.
  Adding Markus and Matt to AUTHORS.
  Added ability to specify specs in IKOptions directly.
  Improve fault tolerance of Accessor._delete()
  fix issue #12
  proper python comments in readme
  Adding Josh to the contributors list.
  Being a good PyPI citizen.
  allowing any fields on the object to be specified for use in naming of generated images; default to allowing pk
  Added the pk of the object into the dictionary of values passed to the string formatting for cache_filename.
  Added the quality property in the readme's ImageSpec classes just to show it is possible to change it at will.
  Fixes: CMYK files from Photoshop fails to load with exception -2
This commit is contained in:
Bryan Veloso 2011-09-07 16:00:09 -07:00
commit 2482a8df4f
8 changed files with 47 additions and 23 deletions

View file

@ -12,4 +12,8 @@ Maintainers:
Contributors:
* Josh Ourisman (joshourisman)
* Jonathan Slenders (jonathanslenders)
* Matthew Tretter (matthewwithanm)
* Markus Kaiserswerth (mkai)

View file

@ -67,12 +67,14 @@ Create your specifications.
# now we can define our thumbnail spec
class Thumbnail(ImageSpec):
quality = 90 # defaults to 70
access_as = 'thumbnail_image'
pre_cache = True
processors = [ResizeThumb, EnchanceThumb]
# and our display spec
class Display(ImageSpec):
quality = 90 # defaults to 70
increment_count = True
processors = [ResizeDisplay]

View file

@ -2,10 +2,10 @@
Django ImageKit
Author: Justin Driscoll <justin.driscoll@gmail.com>
Version: 0.3.6
Version: 0.4.0
"""
__author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett'
__version__ = (0, 3, 6)
__version__ = (0, 4, 0)

View file

@ -44,17 +44,18 @@ class ImageModelBase(ModelBase):
return
user_opts = getattr(cls, 'IKOptions', None)
opts = Options(user_opts)
try:
module = __import__(opts.spec_module, {}, {}, [''])
except ImportError:
raise ImportError('Unable to load imagekit config module: %s' % \
opts.spec_module)
for spec in [spec for spec in module.__dict__.values() \
if isinstance(spec, type) \
and issubclass(spec, specs.ImageSpec) \
and spec != specs.ImageSpec]:
if not opts.specs:
try:
module = __import__(opts.spec_module, {}, {}, [''])
except ImportError:
raise ImportError('Unable to load imagekit config module: %s' \
% opts.spec_module)
opts.specs.extend([spec for spec in module.__dict__.values() \
if isinstance(spec, type) \
and issubclass(spec, specs.ImageSpec) \
and spec != specs.ImageSpec])
for spec in opts.specs:
setattr(cls, spec.name(), specs.Descriptor(spec))
opts.specs.append(spec)
setattr(cls, '_ik', opts)
@ -121,10 +122,13 @@ class ImageModel(models.Model):
self._imgfield.save(name, content, save)
def save(self, clear_cache=True, *args, **kwargs):
is_new_object = self._get_pk_val() is None
super(ImageModel, self).save(*args, **kwargs)
if is_new_object and self._imgfield:
is_new_object = self._get_pk_val() is None
if is_new_object:
clear_cache = False
if self._imgfield:
spec = self._ik.preprocessor_spec
if spec is not None:
newfile = self._imgfield.storage.open(str(self._imgfield))

View file

@ -13,12 +13,14 @@ class Options(object):
preprocessor_spec = None
cache_dir = 'cache'
save_count_as = None
cache_filename_fields = ['pk', ]
cache_filename_format = "%(filename)s_%(specname)s.%(extension)s"
admin_thumbnail_spec = 'admin_thumbnail'
spec_module = 'imagekit.defaults'
specs = None
#storage = defaults to image_field.storage
def __init__(self, opts):
for key, value in opts.__dict__.iteritems():
setattr(self, key, value)
self.specs = []
self.specs = list(self.specs or [])

View file

@ -68,7 +68,10 @@ class Accessor(object):
def _delete(self):
if self._obj._imgfield:
self._obj._storage.delete(self.name)
try:
self._obj._storage.delete(self.name)
except (NotImplementedError, IOError):
return
def _exists(self):
if self._obj._imgfield:
@ -82,10 +85,17 @@ class Accessor(object):
for processor in self.spec.processors:
if issubclass(processor, processors.Format):
extension = processor.extension
filename_format_dict = {'filename': filename,
'specname': self.spec.name(),
'extension': extension.lstrip('.')}
cache_filename_fields = self._obj._ik.cache_filename_fields
filename_format_dict.update(dict(zip(
cache_filename_fields,
[getattr(self._obj, field) for
field in cache_filename_fields])))
cache_filename = self._obj._ik.cache_filename_format % \
{'filename': filename,
'specname': self.spec.name(),
'extension': extension.lstrip('.')}
filename_format_dict
if callable(self._obj._ik.cache_dir):
return self._obj._ik.cache_dir(self._obj, filepath,
cache_filename)

View file

@ -4,6 +4,6 @@ import tempfile
def img_to_fobj(img, format, **kwargs):
tmp = tempfile.TemporaryFile()
img.save(tmp, format, **kwargs)
img.convert('RGB').save(tmp, format, **kwargs)
tmp.seek(0)
return tmp

View file

@ -3,7 +3,7 @@ from distutils.core import setup
setup(
name='django-imagekit',
version='0.3.6',
version='0.4.0',
description='Automated image processing for Django models.',
author='Justin Driscoll',
author_email='justin@driscolldev.com',
@ -19,11 +19,13 @@ setup(
classifiers=[
'Development Status :: 3 - Alpha',
'Environment :: Web Environment',
'Framework :: Django',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Framework :: Django',
'Programming Language :: Python :: 2.5',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Topic :: Utilities'
]
)