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.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)

View file

@ -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
# "<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
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
# "<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)
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:

View file

@ -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)

View file

@ -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

View file

@ -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