From c0b79a227d893c464cb37c2e9171f799111ee2a0 Mon Sep 17 00:00:00 2001 From: Eric Eldredge Date: Mon, 15 Oct 2012 23:53:05 -0400 Subject: [PATCH] Remove ImageSpecFieldFile in favor of ImageSpecFile --- imagekit/files.py | 23 +++--- imagekit/models/fields/files.py | 122 +------------------------------- imagekit/models/fields/utils.py | 25 ++++++- imagekit/utils.py | 6 ++ 4 files changed, 44 insertions(+), 132 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index 0d9837f..b3b543c 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -15,6 +15,9 @@ class ImageSpecFile(ImageFieldFile): self.source_file = source_file self.spec_id = spec_id + def get_hash(self): + return self.spec.get_hash(self.source_file) + @property def url(self): self.validate() @@ -37,14 +40,18 @@ class ImageSpecFile(ImageFieldFile): @property def name(self): - 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) + 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) def generate(self, save=True): return self.spec.generate_file(self.name, self.source_file, save) diff --git a/imagekit/models/fields/files.py b/imagekit/models/fields/files.py index 691ce6b..f0fc542 100644 --- a/imagekit/models/fields/files.py +++ b/imagekit/models/fields/files.py @@ -1,124 +1,4 @@ -from django.db.models.fields.files import ImageField, ImageFieldFile - - -class ImageSpecFieldFile(ImageFieldFile): - def __init__(self, instance, field, attname): - super(ImageSpecFieldFile, self).__init__(instance, field, None) - self.attname = attname - - def get_hash(self): - return self.field.spec.get_hash(self.source_file) - - @property - def source_file(self): - field_name = getattr(self.field, 'image_field', None) - if field_name: - field_file = getattr(self.instance, field_name) - else: - image_fields = [getattr(self.instance, f.attname) for f in \ - self.instance.__class__._meta.fields if \ - isinstance(f, ImageField)] - if len(image_fields) == 0: - raise Exception('%s does not define any ImageFields, so your' \ - ' %s ImageSpecField has no image to act on.' % \ - (self.instance.__class__.__name__, self.attname)) - elif len(image_fields) > 1: - raise Exception('%s defines multiple ImageFields, but you' \ - ' have not specified an image_field for your %s' \ - ' ImageSpecField.' % (self.instance.__class__.__name__, - self.attname)) - else: - field_file = image_fields[0] - return field_file - - def _require_file(self): - if not self.source_file: - raise ValueError("The '%s' attribute's image_field has no file associated with it." % self.attname) - self.field.spec.image_cache_strategy.invoke_callback('access', self) - - def clear(self): - return self.field.spec.image_cache_backend.clear(self) - - def invalidate(self): - return self.field.spec.image_cache_backend.invalidate(self) - - def validate(self): - return self.field.spec.image_cache_backend.validate(self) - - def generate(self, save=True): - """ - Generates a new image file by processing the source file and returns - the content of the result, ready for saving. - - """ - return self.field.spec.generate_file(self.name, self.source_file, - save) - - def delete(self, save=False): - """ - Pulled almost verbatim from ``ImageFieldFile.delete()`` and - ``FieldFile.delete()`` but with the attempts to reset the instance - property removed. - - """ - # Clear the image dimensions cache - if hasattr(self, '_dimensions_cache'): - del self._dimensions_cache - - # Only close the file if it's already open, which we know by the - # presence of self._file. - if hasattr(self, '_file'): - self.close() - del self.file - - if self.name and self.storage.exists(self.name): - try: - self.storage.delete(self.name) - except NotImplementedError: - pass - - # Delete the filesize cache. - if hasattr(self, '_size'): - del self._size - self._committed = False - - if save: - self.instance.save() - - @property - def name(self): - """ - Specifies the filename that the cached image will use. - - """ - return self.field.spec.generate_filename(self.source_file) - - @name.setter - def name(self, value): - # TODO: Figure out a better way to handle this. We really don't want - # to allow anybody to set the name, but ``File.__init__`` (which is - # called by ``ImageSpecFieldFile.__init__``) does, so we have to allow - # it at least that one time. - pass - - @property - def storage(self): - return getattr(self, '_storage', None) or self.field.storage or self.source_file.storage - - @storage.setter - def storage(self, storage): - self._storage = storage - - def __getstate__(self): - return dict( - attname=self.attname, - instance=self.instance, - ) - - def __setstate__(self, state): - self.attname = state['attname'] - self.instance = state['instance'] - self.field = getattr(self.instance.__class__, self.attname) +from django.db.models.fields.files import ImageFieldFile class ProcessedImageFieldFile(ImageFieldFile): diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index 3014b53..dab6170 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -1,4 +1,5 @@ -from .files import ImageSpecFieldFile +from ...files import ImageSpecFile +from django.db.models.fields.files import ImageField class ImageSpecFileDescriptor(object): @@ -10,8 +11,26 @@ class ImageSpecFileDescriptor(object): if instance is None: return self.field else: - img_spec_file = ImageSpecFieldFile(instance, self.field, - self.attname) + field_name = getattr(self.field, 'image_field', None) + if field_name: + source_file = getattr(instance, field_name) + else: + image_fields = [getattr(instance, f.attname) for f in \ + instance.__class__._meta.fields if \ + isinstance(f, ImageField)] + if len(image_fields) == 0: + raise Exception('%s does not define any ImageFields, so your' \ + ' %s ImageSpecField has no image to act on.' % \ + (instance.__class__.__name__, self.attname)) + elif len(image_fields) > 1: + raise Exception('%s defines multiple ImageFields, but you' \ + ' have not specified an image_field for your %s' \ + ' ImageSpecField.' % (instance.__class__.__name__, + self.attname)) + else: + source_file = image_fields[0] + img_spec_file = ImageSpecFile(self.field.spec, source_file, + self.attname) instance.__dict__[self.attname] = img_spec_file return img_spec_file diff --git a/imagekit/utils.py b/imagekit/utils.py index 35671ac..d33d83d 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -440,6 +440,12 @@ class SpecWrapper(object): self.autoconvert = getattr(spec, 'autoconvert', True) self.storage = getattr(spec, 'storage', None) self.image_cache_backend = getattr(spec, 'image_cache_backend', None) + # TODO: get_hash default return value. + self.get_hash = getattr(spec, 'get_hash', lambda f: None) + # TODO: generate_filename default return value. + self.generate_filename = getattr(spec, 'generate_filename', lambda f: None) + # TODO: generate_file default return value. + self.generate_file = getattr(spec, 'generate_file', lambda f: None) if not self.image_cache_backend: from .imagecache.backends import get_default_image_cache_backend