From 738bbfa9a19ac286f985fba4ab2e06ed2f1ee397 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 23:38:44 -0400 Subject: [PATCH] Move cache file naming into ImageSpecFile --- imagekit/files.py | 27 +++++++++++----------- imagekit/models/fields/__init__.py | 37 +++++++++++++++--------------- imagekit/models/fields/files.py | 10 +++++--- imagekit/models/fields/utils.py | 3 +-- imagekit/specs/__init__.py | 13 ----------- 5 files changed, 40 insertions(+), 50 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index 3499643..8b417c4 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -1,3 +1,4 @@ +from django.conf import settings from django.core.files.base import ContentFile, File from django.core.files.images import ImageFile from django.utils.encoding import smart_str, smart_unicode @@ -70,11 +71,10 @@ class BaseImageSpecFile(File): class ImageSpecFile(ImageFile, BaseImageSpecFile): - def __init__(self, spec, source_file, spec_id): + def __init__(self, spec, source_file): self.storage = spec.storage or source_file.storage self.spec = spec self.source_file = source_file - self.spec_id = spec_id def get_hash(self): return self.spec.get_hash(self.source_file) @@ -85,18 +85,17 @@ class ImageSpecFile(ImageFile, BaseImageSpecFile): @property def name(self): - name = self.spec.generate_filename(self.source_file) - if name is not None: - return name - else: - source_filename = self.source_file.name - filepath, basename = os.path.split(source_filename) - filename = os.path.splitext(basename)[0] - extension = suggest_extension(source_filename, self.spec.format) - new_name = '%s%s' % (filename, extension) - cache_filename = ['cache', 'iktt'] + self.spec_id.split(':') + \ - [filepath, new_name] - return os.path.join(*cache_filename) + source_filename = self.source_file.name + filename = None + if source_filename: + hash = self.spec.get_hash(self.source_file) + ext = suggest_extension(source_filename, self.spec.format) + filename = os.path.normpath(os.path.join( + settings.IMAGEKIT_CACHE_DIR, + os.path.splitext(source_filename)[0], + '%s%s' % (hash, ext))) + + return filename def clear(self): return self.spec.image_cache_backend.clear(self) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 148212c..ecc6bbe 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -9,7 +9,20 @@ from ...specs import SpecHost from ...specs.sources import ImageFieldSpecSource -class ImageSpecField(SpecHost): +class SpecHostField(SpecHost): + def set_spec_id(self, cls, name): + # Generate a spec_id to register the spec with. The default spec id is + # ":_" + if not getattr(self, 'spec_id', None): + spec_id = (u'%s:%s_%s' % (cls._meta.app_label, + cls._meta.object_name, name)).lower() + + # Register the spec with the id. This allows specs to be overridden + # later, from outside of the model definition. + super(SpecHostField, self).set_spec_id(spec_id) + + +class ImageSpecField(SpecHostField): """ The heart and soul of the ImageKit library, ImageSpecField allows you to add variants of uploaded images to your models. @@ -34,23 +47,14 @@ class ImageSpecField(SpecHost): def contribute_to_class(self, cls, name): setattr(cls, name, ImageSpecFileDescriptor(self, name)) - - # Generate a spec_id to register the spec with. The default spec id is - # ":_" - if not getattr(self, 'spec_id', None): - self.spec_id = (u'%s:%s_%s' % (cls._meta.app_label, - cls._meta.object_name, name)).lower() - - # Register the spec with the id. This allows specs to be overridden - # later, from outside of the model definition. - self.set_spec_id(self.spec_id) + self.set_spec_id(cls, name) # Add the model and field as a source for this spec id specs.registry.add_source(ImageFieldSpecSource(cls, self.image_field), self.spec_id) -class ProcessedImageField(models.ImageField, SpecHost): +class ProcessedImageField(models.ImageField, SpecHostField): """ ProcessedImageField is an ImageField that runs processors on the uploaded image *before* saving it to storage. This is in contrast to specs, which @@ -76,12 +80,9 @@ class ProcessedImageField(models.ImageField, SpecHost): models.ImageField.__init__(self, verbose_name, name, width_field, height_field, **kwargs) - def get_filename(self, filename): - filename = os.path.normpath(self.storage.get_valid_name( - os.path.basename(filename))) - name, ext = os.path.splitext(filename) - ext = suggest_extension(filename, self.spec.format) - return u'%s%s' % (name, ext) + def contribute_to_class(self, cls, name): + self.set_spec_id(cls, name) + return super(ProcessedImageField, self).contribute_to_class(cls, name) try: diff --git a/imagekit/models/fields/files.py b/imagekit/models/fields/files.py index f7f887a..3c9ffd6 100644 --- a/imagekit/models/fields/files.py +++ b/imagekit/models/fields/files.py @@ -1,8 +1,12 @@ from django.db.models.fields.files import ImageFieldFile +import os +from ...utils import suggest_extension class ProcessedImageFieldFile(ImageFieldFile): def save(self, name, content, save=True): - new_filename = self.field.spec.generate_filename(self.instance, name) - content = self.field.spec.apply(content, new_filename) - return super(ProcessedImageFieldFile, self).save(name, content, save) + filename, ext = os.path.splitext(name) + ext = suggest_extension(name, self.field.spec.format) + new_name = '%s%s' % (filename, ext) + content = self.field.spec.apply(content, new_name) + return super(ProcessedImageFieldFile, self).save(new_name, content, save) diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index dab6170..ce55a18 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -29,8 +29,7 @@ class ImageSpecFileDescriptor(object): self.attname)) else: source_file = image_fields[0] - img_spec_file = ImageSpecFile(self.field.spec, source_file, - self.attname) + img_spec_file = ImageSpecFile(self.field.spec, source_file) instance.__dict__[self.attname] = img_spec_file return img_spec_file diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index e166218..883b4e0 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -111,19 +111,6 @@ class BaseImageSpec(object): str(self.autoconvert), ]).encode('utf-8')).hexdigest() - def generate_filename(self, source_file): - source_filename = source_file.name - filename = None - if source_filename: - hash = self.get_hash(source_file) - 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 apply(self, content, filename=None): img = open_image(content) original_format = img.format