mirror of
https://github.com/Hopiu/django-imagekit.git
synced 2026-05-17 09:11:05 +00:00
Merge branch 'ik-next' into templatetags
This commit is contained in:
commit
bdecf75e0a
4 changed files with 35 additions and 69 deletions
|
|
@ -3,3 +3,4 @@ from appconf import AppConf
|
||||||
|
|
||||||
class ImageKitConf(AppConf):
|
class ImageKitConf(AppConf):
|
||||||
DEFAULT_IMAGE_CACHE_BACKEND = 'imagekit.imagecache.PessimisticImageCacheBackend'
|
DEFAULT_IMAGE_CACHE_BACKEND = 'imagekit.imagecache.PessimisticImageCacheBackend'
|
||||||
|
CACHE_DIR = 'CACHE/images'
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
|
from django.conf import settings
|
||||||
|
from hashlib import md5
|
||||||
import os
|
import os
|
||||||
|
import pickle
|
||||||
from .lib import StringIO
|
from .lib import StringIO
|
||||||
from .processors import ProcessorPipeline
|
from .processors import ProcessorPipeline
|
||||||
from .utils import (img_to_fobj, open_image, IKContentFile, extension_to_format,
|
from .utils import (img_to_fobj, open_image, IKContentFile, extension_to_format,
|
||||||
UnknownExtensionError)
|
suggest_extension, UnknownExtensionError)
|
||||||
|
|
||||||
|
|
||||||
class SpecFileGenerator(object):
|
class SpecFileGenerator(object):
|
||||||
|
|
@ -14,14 +17,18 @@ class SpecFileGenerator(object):
|
||||||
self.autoconvert = autoconvert
|
self.autoconvert = autoconvert
|
||||||
self.storage = storage
|
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):
|
def process_content(self, content, filename=None, source_file=None):
|
||||||
img = open_image(content)
|
img = open_image(content)
|
||||||
original_format = img.format
|
original_format = img.format
|
||||||
|
|
||||||
# Run the processors
|
# Run the processors
|
||||||
processors = self.processors
|
processors = self.get_processors(source_file)
|
||||||
if callable(processors):
|
|
||||||
processors = processors(source_file)
|
|
||||||
img = ProcessorPipeline(processors or []).process(img)
|
img = ProcessorPipeline(processors or []).process(img)
|
||||||
|
|
||||||
options = dict(self.options or {})
|
options = dict(self.options or {})
|
||||||
|
|
@ -42,6 +49,25 @@ class SpecFileGenerator(object):
|
||||||
content = IKContentFile(filename, imgfile.read(), format=format)
|
content = IKContentFile(filename, imgfile.read(), format=format)
|
||||||
return img, content
|
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):
|
def generate_file(self, filename, source_file, save=True):
|
||||||
"""
|
"""
|
||||||
Generates a new image file by processing the source file and returns
|
Generates a new image file by processing the source file and returns
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ class ImageSpecField(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, processors=None, format=None, options=None,
|
def __init__(self, processors=None, format=None, options=None,
|
||||||
image_field=None, pre_cache=None, storage=None, cache_to=None,
|
image_field=None, pre_cache=None, storage=None, autoconvert=True,
|
||||||
autoconvert=True, image_cache_backend=None):
|
image_cache_backend=None):
|
||||||
"""
|
"""
|
||||||
:param processors: A list of processors to run on the original image.
|
:param processors: A list of processors to run on the original image.
|
||||||
:param format: The format of the output file. If not provided,
|
:param format: The format of the output file. If not provided,
|
||||||
|
|
@ -36,21 +36,6 @@ class ImageSpecField(object):
|
||||||
original image.
|
original image.
|
||||||
:param storage: A Django storage system to use to save the generated
|
:param storage: A Django storage system to use to save the generated
|
||||||
image.
|
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
|
:param autoconvert: Specifies whether automatic conversion using
|
||||||
``prepare_image()`` should be performed prior to saving.
|
``prepare_image()`` should be performed prior to saving.
|
||||||
:param image_cache_backend: An object responsible for managing the state
|
:param image_cache_backend: An object responsible for managing the state
|
||||||
|
|
@ -74,7 +59,6 @@ class ImageSpecField(object):
|
||||||
autoconvert=autoconvert, storage=storage)
|
autoconvert=autoconvert, storage=storage)
|
||||||
self.image_field = image_field
|
self.image_field = image_field
|
||||||
self.storage = storage
|
self.storage = storage
|
||||||
self.cache_to = cache_to
|
|
||||||
self.image_cache_backend = image_cache_backend or \
|
self.image_cache_backend = image_cache_backend or \
|
||||||
get_default_image_cache_backend()
|
get_default_image_cache_backend()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,4 @@
|
||||||
import os
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
from django.db.models.fields.files import ImageField, ImageFieldFile
|
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):
|
class ImageSpecFieldFile(ImageFieldFile):
|
||||||
|
|
@ -89,52 +83,13 @@ class ImageSpecFieldFile(ImageFieldFile):
|
||||||
if save:
|
if save:
|
||||||
self.instance.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
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"""
|
"""
|
||||||
Specifies the filename that the cached image will use. The user can
|
Specifies the filename that the cached image will use.
|
||||||
control this by providing a `cache_to` method to the ImageSpecField.
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
name = getattr(self, '_name', None)
|
return self.field.generator.generate_filename(self.source_file)
|
||||||
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
|
|
||||||
|
|
||||||
@name.setter
|
@name.setter
|
||||||
def name(self, value):
|
def name(self, value):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue