Move cache file naming into ImageSpecFile

This commit is contained in:
Matthew Tretter 2012-10-16 23:38:44 -04:00
parent 5ca8b7f4ba
commit 738bbfa9a1
5 changed files with 40 additions and 50 deletions

View file

@ -1,3 +1,4 @@
from django.conf import settings
from django.core.files.base import ContentFile, File from django.core.files.base import ContentFile, File
from django.core.files.images import ImageFile from django.core.files.images import ImageFile
from django.utils.encoding import smart_str, smart_unicode from django.utils.encoding import smart_str, smart_unicode
@ -70,11 +71,10 @@ class BaseImageSpecFile(File):
class ImageSpecFile(ImageFile, BaseImageSpecFile): 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.storage = spec.storage or source_file.storage
self.spec = spec self.spec = spec
self.source_file = source_file self.source_file = source_file
self.spec_id = spec_id
def get_hash(self): def get_hash(self):
return self.spec.get_hash(self.source_file) return self.spec.get_hash(self.source_file)
@ -85,18 +85,17 @@ class ImageSpecFile(ImageFile, BaseImageSpecFile):
@property @property
def name(self): def name(self):
name = self.spec.generate_filename(self.source_file) source_filename = self.source_file.name
if name is not None: filename = None
return name if source_filename:
else: hash = self.spec.get_hash(self.source_file)
source_filename = self.source_file.name ext = suggest_extension(source_filename, self.spec.format)
filepath, basename = os.path.split(source_filename) filename = os.path.normpath(os.path.join(
filename = os.path.splitext(basename)[0] settings.IMAGEKIT_CACHE_DIR,
extension = suggest_extension(source_filename, self.spec.format) os.path.splitext(source_filename)[0],
new_name = '%s%s' % (filename, extension) '%s%s' % (hash, ext)))
cache_filename = ['cache', 'iktt'] + self.spec_id.split(':') + \
[filepath, new_name] return filename
return os.path.join(*cache_filename)
def clear(self): def clear(self):
return self.spec.image_cache_backend.clear(self) return self.spec.image_cache_backend.clear(self)

View file

@ -9,7 +9,20 @@ from ...specs import SpecHost
from ...specs.sources import ImageFieldSpecSource 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
# "<app>:<model>_<field>"
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 The heart and soul of the ImageKit library, ImageSpecField allows you to add
variants of uploaded images to your models. variants of uploaded images to your models.
@ -34,23 +47,14 @@ class ImageSpecField(SpecHost):
def contribute_to_class(self, cls, name): def contribute_to_class(self, cls, name):
setattr(cls, name, ImageSpecFileDescriptor(self, name)) setattr(cls, name, ImageSpecFileDescriptor(self, name))
self.set_spec_id(cls, name)
# Generate a spec_id to register the spec with. The default spec id is
# "<app>:<model>_<field>"
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)
# Add the model and field as a source for this spec id # Add the model and field as a source for this spec id
specs.registry.add_source(ImageFieldSpecSource(cls, self.image_field), specs.registry.add_source(ImageFieldSpecSource(cls, self.image_field),
self.spec_id) self.spec_id)
class ProcessedImageField(models.ImageField, SpecHost): class ProcessedImageField(models.ImageField, SpecHostField):
""" """
ProcessedImageField is an ImageField that runs processors on the uploaded ProcessedImageField is an ImageField that runs processors on the uploaded
image *before* saving it to storage. This is in contrast to specs, which 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, models.ImageField.__init__(self, verbose_name, name, width_field,
height_field, **kwargs) height_field, **kwargs)
def get_filename(self, filename): def contribute_to_class(self, cls, name):
filename = os.path.normpath(self.storage.get_valid_name( self.set_spec_id(cls, name)
os.path.basename(filename))) return super(ProcessedImageField, self).contribute_to_class(cls, name)
name, ext = os.path.splitext(filename)
ext = suggest_extension(filename, self.spec.format)
return u'%s%s' % (name, ext)
try: try:

View file

@ -1,8 +1,12 @@
from django.db.models.fields.files import ImageFieldFile from django.db.models.fields.files import ImageFieldFile
import os
from ...utils import suggest_extension
class ProcessedImageFieldFile(ImageFieldFile): class ProcessedImageFieldFile(ImageFieldFile):
def save(self, name, content, save=True): def save(self, name, content, save=True):
new_filename = self.field.spec.generate_filename(self.instance, name) filename, ext = os.path.splitext(name)
content = self.field.spec.apply(content, new_filename) ext = suggest_extension(name, self.field.spec.format)
return super(ProcessedImageFieldFile, self).save(name, content, save) new_name = '%s%s' % (filename, ext)
content = self.field.spec.apply(content, new_name)
return super(ProcessedImageFieldFile, self).save(new_name, content, save)

View file

@ -29,8 +29,7 @@ class ImageSpecFileDescriptor(object):
self.attname)) self.attname))
else: else:
source_file = image_fields[0] source_file = image_fields[0]
img_spec_file = ImageSpecFile(self.field.spec, source_file, img_spec_file = ImageSpecFile(self.field.spec, source_file)
self.attname)
instance.__dict__[self.attname] = img_spec_file instance.__dict__[self.attname] = img_spec_file
return img_spec_file return img_spec_file

View file

@ -111,19 +111,6 @@ class BaseImageSpec(object):
str(self.autoconvert), str(self.autoconvert),
]).encode('utf-8')).hexdigest() ]).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): def apply(self, content, filename=None):
img = open_image(content) img = open_image(content)
original_format = img.format original_format = img.format