mirror of
https://github.com/Hopiu/django-imagekit.git
synced 2026-03-25 01:10:24 +00:00
Removed Format processor
The Format processor was really a special case and didn't do any processing at all. Instead, ImageSpec just knew to look for it and responded accordingly. Therefore, it's been replaced with a `format` property on ImageSpec. This warranted a deeper look at how the format and extension were being deduced (when not explicitly provided); the results are documented in-code, though the goal was "no surprises."
This commit is contained in:
parent
80c785f2e5
commit
a71b3ca337
2 changed files with 62 additions and 17 deletions
|
|
@ -35,14 +35,6 @@ class Adjust(ImageProcessor):
|
|||
return img, fmt
|
||||
|
||||
|
||||
class Format(ImageProcessor):
|
||||
format = 'JPEG'
|
||||
extension = 'jpg'
|
||||
|
||||
def process(self, img, fmt, obj, spec):
|
||||
return img, self.format
|
||||
|
||||
|
||||
class Reflection(ImageProcessor):
|
||||
background_color = '#FFFFFF'
|
||||
size = 0.0
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ spec found.
|
|||
import os
|
||||
import datetime
|
||||
from StringIO import StringIO
|
||||
from imagekit import processors
|
||||
from imagekit.lib import *
|
||||
from imagekit.utils import img_to_fobj
|
||||
from django.core.files.base import ContentFile
|
||||
|
|
@ -23,6 +22,26 @@ class ImageSpec(object):
|
|||
quality = 70
|
||||
increment_count = False
|
||||
storage = None
|
||||
format = None
|
||||
|
||||
cache_to = None
|
||||
"""Specifies the filename to use when saving the image cache file. This is
|
||||
modeled after ImageField's `upload_to` and can accept 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.
|
||||
|
||||
If you have not explicitly set a format on your ImageSpec, the extension of
|
||||
the path returned by this function will be used to infer one.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, processors=None, **kwargs):
|
||||
if processors:
|
||||
|
|
@ -38,8 +57,9 @@ class ImageSpec(object):
|
|||
img = image.copy()
|
||||
for proc in self.processors:
|
||||
img, fmt = proc.process(img, fmt, obj, self)
|
||||
img.format = fmt
|
||||
return img, fmt
|
||||
format = self.format or fmt
|
||||
img.format = format
|
||||
return img, format
|
||||
|
||||
def contribute_to_class(self, cls, name):
|
||||
setattr(cls, name, Descriptor(self, name))
|
||||
|
|
@ -53,8 +73,24 @@ class Accessor(object):
|
|||
self.spec = spec
|
||||
self.property_name = property_name
|
||||
|
||||
@property
|
||||
def _format(self):
|
||||
"""The format used to save the cache file. If the format is set
|
||||
explicitly on the ImageSpec, that format will be used. Otherwise, the
|
||||
format will be inferred from the extension of the cache filename (see
|
||||
the `name` property).
|
||||
|
||||
"""
|
||||
format = self.spec.format
|
||||
if not format:
|
||||
# Get the real (not suggested) extension.
|
||||
extension = os.path.splitext(self.name)[1].lower()
|
||||
# Try to guess the format from the extension.
|
||||
format = Image.EXTENSION.get(extension)
|
||||
return format or self._img.format or 'JPEG'
|
||||
|
||||
def _get_imgfile(self):
|
||||
format = self._img.format or 'JPEG'
|
||||
format = self._format
|
||||
if format != 'JPEG':
|
||||
imgfile = img_to_fobj(self._img, format)
|
||||
else:
|
||||
|
|
@ -94,8 +130,29 @@ class Accessor(object):
|
|||
if self._imgfield:
|
||||
return self._storage.exists(self.name)
|
||||
|
||||
@property
|
||||
def _suggested_extension(self):
|
||||
if self.spec.format:
|
||||
# Try to look up an extension by the format
|
||||
extensions = [k.lstrip('.') for k, v in Image.EXTENSION.iteritems() \
|
||||
if v == self.spec.format.upper()]
|
||||
else:
|
||||
extensions = []
|
||||
original_extension = os.path.splitext(self._imgfield.name)[1].lstrip('.')
|
||||
if not extensions or original_extension.lower() in extensions:
|
||||
# If the original extension matches the format, use it.
|
||||
extension = original_extension
|
||||
else:
|
||||
extension = extensions[0]
|
||||
return extension
|
||||
|
||||
@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 ImageSpec.
|
||||
|
||||
"""
|
||||
filename = self._imgfield.name
|
||||
if filename:
|
||||
cache_to = getattr(self.spec, 'cache_to', None) or \
|
||||
|
|
@ -104,13 +161,9 @@ class Accessor(object):
|
|||
if not cache_to:
|
||||
raise Exception('No cache_to or default_cache_to value specified')
|
||||
if callable(cache_to):
|
||||
extension = os.path.splitext(filename)[1]
|
||||
for processor in self.spec.processors:
|
||||
if isinstance(processor, processors.Format):
|
||||
extension = processor.extension
|
||||
new_filename = force_unicode(datetime.datetime.now().strftime( \
|
||||
smart_str(cache_to(self._obj, self._imgfield.name, \
|
||||
self.property_name, extension.lstrip('.')))))
|
||||
self.property_name, self._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))
|
||||
|
|
|
|||
Loading…
Reference in a new issue