Merge branch 'ik-next' into templatetags

This commit is contained in:
Eric Eldredge 2012-09-05 21:47:39 -04:00
commit bdecf75e0a
4 changed files with 35 additions and 69 deletions

View file

@ -3,3 +3,4 @@ from appconf import AppConf
class ImageKitConf(AppConf):
DEFAULT_IMAGE_CACHE_BACKEND = 'imagekit.imagecache.PessimisticImageCacheBackend'
CACHE_DIR = 'CACHE/images'

View file

@ -1,8 +1,11 @@
from django.conf import settings
from hashlib import md5
import os
import pickle
from .lib import StringIO
from .processors import ProcessorPipeline
from .utils import (img_to_fobj, open_image, IKContentFile, extension_to_format,
UnknownExtensionError)
suggest_extension, UnknownExtensionError)
class SpecFileGenerator(object):
@ -14,14 +17,18 @@ class SpecFileGenerator(object):
self.autoconvert = autoconvert
self.storage = storage
def get_processors(self, source_file):
processors = self.processors
if callable(processors):
processors = processors(source_file)
return processors
def process_content(self, content, filename=None, source_file=None):
img = open_image(content)
original_format = img.format
# Run the processors
processors = self.processors
if callable(processors):
processors = processors(source_file)
processors = self.get_processors(source_file)
img = ProcessorPipeline(processors or []).process(img)
options = dict(self.options or {})
@ -42,6 +49,25 @@ class SpecFileGenerator(object):
content = IKContentFile(filename, imgfile.read(), format=format)
return img, content
def generate_filename(self, source_file):
source_filename = source_file.name
filename = None
if source_filename:
hash = md5(''.join([
pickle.dumps(self.get_processors(source_file)),
self.format,
pickle.dumps(self.options),
str(self.autoconvert),
])).hexdigest()
extension = suggest_extension(source_filename, self.format)
filename = os.path.normpath(os.path.join(
settings.IMAGEKIT_CACHE_DIR,
os.path.splitext(source_filename)[0],
'%s%s' % (hash, extension)))
return filename
def generate_file(self, filename, source_file, save=True):
"""
Generates a new image file by processing the source file and returns

View file

@ -20,8 +20,8 @@ class ImageSpecField(object):
"""
def __init__(self, processors=None, format=None, options=None,
image_field=None, pre_cache=None, storage=None, cache_to=None,
autoconvert=True, image_cache_backend=None):
image_field=None, pre_cache=None, storage=None, autoconvert=True,
image_cache_backend=None):
"""
:param processors: A list of processors to run on the original image.
:param format: The format of the output file. If not provided,
@ -36,21 +36,6 @@ class ImageSpecField(object):
original image.
:param storage: A Django storage system to use to save the generated
image.
:param cache_to: Specifies the filename to use when saving the image
cache file. This is modeled after ImageField's ``upload_to`` and
can be either a string (that specifies a directory) or a
callable (that returns a filepath). Callable values should
accept the following arguments:
- instance -- The model instance this spec belongs to
- path -- The path of the original image
- specname -- the property name that the spec is bound to on
the model instance
- extension -- A recommended extension. If the format of the
spec is set explicitly, this suggestion will be
based on that format. if not, the extension of the
original file will be passed. You do not have to use
this extension, it's only a recommendation.
:param autoconvert: Specifies whether automatic conversion using
``prepare_image()`` should be performed prior to saving.
:param image_cache_backend: An object responsible for managing the state
@ -74,7 +59,6 @@ class ImageSpecField(object):
autoconvert=autoconvert, storage=storage)
self.image_field = image_field
self.storage = storage
self.cache_to = cache_to
self.image_cache_backend = image_cache_backend or \
get_default_image_cache_backend()

View file

@ -1,10 +1,4 @@
import os
import datetime
from django.db.models.fields.files import ImageField, ImageFieldFile
from django.utils.encoding import force_unicode, smart_str
from ...utils import suggest_extension
class ImageSpecFieldFile(ImageFieldFile):
@ -89,52 +83,13 @@ class ImageSpecFieldFile(ImageFieldFile):
if save:
self.instance.save()
def _default_cache_to(self, instance, path, specname, extension):
"""
Determines the filename to use for the transformed image. Can be
overridden on a per-spec basis by setting the cache_to property on
the spec.
"""
filepath, basename = os.path.split(path)
filename = os.path.splitext(basename)[0]
new_name = '%s_%s%s' % (filename, specname, extension)
return os.path.join('cache', filepath, new_name)
@property
def name(self):
"""
Specifies the filename that the cached image will use. The user can
control this by providing a `cache_to` method to the ImageSpecField.
Specifies the filename that the cached image will use.
"""
name = getattr(self, '_name', None)
if not name:
filename = self.source_file.name
new_filename = None
if filename:
cache_to = self.field.cache_to or self._default_cache_to
if not cache_to:
raise Exception('No cache_to or default_cache_to value'
' specified')
if callable(cache_to):
suggested_extension = suggest_extension(
self.source_file.name, self.field.generator.format)
new_filename = force_unicode(
datetime.datetime.now().strftime(
smart_str(cache_to(self.instance,
self.source_file.name, self.attname,
suggested_extension))))
else:
dir_name = os.path.normpath(
force_unicode(datetime.datetime.now().strftime(
smart_str(cache_to))))
filename = os.path.normpath(os.path.basename(filename))
new_filename = os.path.join(dir_name, filename)
self._name = new_filename
return self._name
return self.field.generator.generate_filename(self.source_file)
@name.setter
def name(self, value):