diff --git a/imagekit/management/commands/ikflush.py b/imagekit/management/commands/ikflush.py
deleted file mode 100644
index c03440f..0000000
--- a/imagekit/management/commands/ikflush.py
+++ /dev/null
@@ -1,38 +0,0 @@
-from django.db.models.loading import cache
-from django.core.management.base import BaseCommand, CommandError
-from optparse import make_option
-from imagekit.models import ImageModel
-from imagekit.specs import ImageSpec
-
-
-class Command(BaseCommand):
- help = ('Clears all ImageKit cached files.')
- args = '[apps]'
- requires_model_validation = True
- can_import_settings = True
-
- def handle(self, *args, **options):
- return flush_cache(args, options)
-
-def flush_cache(apps, options):
- """ Clears the image cache
-
- """
- apps = [a.strip(',') for a in apps]
- if apps:
- print 'Flushing cache for %s...' % ', '.join(apps)
- else:
- print 'Flushing caches...'
-
- for app_label in apps:
- app = cache.get_app(app_label)
- models = [m for m in cache.get_models(app) if issubclass(m, ImageModel)]
-
- for model in models:
- for obj in model.objects.all():
- for spec in model._ik.specs:
- prop = getattr(obj, spec.name(), None)
- if prop is not None:
- prop._delete()
- if spec.pre_cache:
- prop._create()
diff --git a/imagekit/models.py b/imagekit/models.py
deleted file mode 100644
index 140715e..0000000
--- a/imagekit/models.py
+++ /dev/null
@@ -1,136 +0,0 @@
-import os
-from datetime import datetime
-from django.conf import settings
-from django.core.files.base import ContentFile
-from django.db import models
-from django.db.models.base import ModelBase
-from django.utils.translation import ugettext_lazy as _
-
-from imagekit import specs
-from imagekit.lib import *
-from imagekit.options import Options
-from imagekit.utils import img_to_fobj
-
-# Modify image file buffer size.
-ImageFile.MAXBLOCK = getattr(settings, 'PIL_IMAGEFILE_MAXBLOCK', 256 * 2 ** 10)
-
-# Choice tuples for specifying the crop origin.
-# These are provided for convenience.
-CROP_HORZ_CHOICES = (
- (0, _('left')),
- (1, _('center')),
- (2, _('right')),
-)
-
-CROP_VERT_CHOICES = (
- (0, _('top')),
- (1, _('center')),
- (2, _('bottom')),
-)
-
-
-class ImageModelBase(ModelBase):
- """ ImageModel metaclass
-
- This metaclass parses IKOptions and loads the specified specification
- module.
-
- """
- def __init__(cls, name, bases, attrs):
- parents = [b for b in bases if isinstance(b, ImageModelBase)]
- if not parents:
- return
- user_opts = getattr(cls, 'IKOptions', None)
- opts = Options(user_opts)
- try:
- module = __import__(opts.spec_module, {}, {}, [''])
- except ImportError:
- raise ImportError('Unable to load imagekit config module: %s' % \
- opts.spec_module)
- for spec in [spec for spec in module.__dict__.values() \
- if isinstance(spec, type) \
- and issubclass(spec, specs.ImageSpec) \
- and spec != specs.ImageSpec]:
- setattr(cls, spec.name(), specs.Descriptor(spec))
- opts.specs.append(spec)
- setattr(cls, '_ik', opts)
-
-
-class ImageModel(models.Model):
- """ Abstract base class implementing all core ImageKit functionality
-
- Subclasses of ImageModel are augmented with accessors for each defined
- image specification and can override the inner IKOptions class to customize
- storage locations and other options.
-
- """
- __metaclass__ = ImageModelBase
-
- class Meta:
- abstract = True
-
- class IKOptions:
- pass
-
- def admin_thumbnail_view(self):
- if not self._imgfield:
- return None
- prop = getattr(self, self._ik.admin_thumbnail_spec, None)
- if prop is None:
- return 'An "%s" image spec has not been defined.' % \
- self._ik.admin_thumbnail_spec
- else:
- if hasattr(self, 'get_absolute_url'):
- return u'
' % \
- (self.get_absolute_url(), prop.url)
- else:
- return u'
' % \
- (self._imgfield.url, prop.url)
- admin_thumbnail_view.short_description = _('Thumbnail')
- admin_thumbnail_view.allow_tags = True
-
- @property
- def _imgfield(self):
- return getattr(self, self._ik.image_field)
-
- def _clear_cache(self):
- for spec in self._ik.specs:
- prop = getattr(self, spec.name())
- prop._delete()
-
- def _pre_cache(self):
- for spec in self._ik.specs:
- if spec.pre_cache:
- prop = getattr(self, spec.name())
- prop._create()
-
- def save(self, clear_cache=True, *args, **kwargs):
- is_new_object = self._get_pk_val is None
- super(ImageModel, self).save(*args, **kwargs)
- if is_new_object:
- clear_cache = False
- spec = self._ik.preprocessor_spec
- if spec is not None:
- newfile = self._imgfield.storage.open(str(self._imgfield))
- img = Image.open(newfile)
- img = spec.process(img, None)
- format = img.format or 'JPEG'
- if format != 'JPEG':
- imgfile = img_to_fobj(img, format)
- else:
- imgfile = img_to_fobj(img, format,
- quality=int(spec.quality),
- optimize=True)
- content = ContentFile(imgfile.read())
- newfile.close()
- name = str(self._imgfield)
- self._imgfield.storage.delete(name)
- self._imgfield.storage.save(name, content)
- if clear_cache and self._imgfield != '':
- self._clear_cache()
- self._pre_cache()
-
- def delete(self):
- assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname)
- self._clear_cache()
- models.Model.delete(self)
diff --git a/imagekit/options.py b/imagekit/options.py
deleted file mode 100644
index 022cc9e..0000000
--- a/imagekit/options.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Imagekit options
-from imagekit import processors
-from imagekit.specs import ImageSpec
-
-
-class Options(object):
- """ Class handling per-model imagekit options
-
- """
- image_field = 'image'
- crop_horz_field = 'crop_horz'
- crop_vert_field = 'crop_vert'
- preprocessor_spec = None
- cache_dir = 'cache'
- save_count_as = None
- cache_filename_format = "%(filename)s_%(specname)s.%(extension)s"
- admin_thumbnail_spec = 'admin_thumbnail'
- spec_module = 'imagekit.defaults'
-
- def __init__(self, opts):
- for key, value in opts.__dict__.iteritems():
- setattr(self, key, value)
- self.specs = []
\ No newline at end of file
diff --git a/imagekit/specs.py b/imagekit/specs.py
deleted file mode 100644
index a6832ba..0000000
--- a/imagekit/specs.py
+++ /dev/null
@@ -1,119 +0,0 @@
-""" ImageKit image specifications
-
-All imagekit specifications must inherit from the ImageSpec class. Models
-inheriting from ImageModel will be modified with a descriptor/accessor for each
-spec found.
-
-"""
-import os
-from StringIO import StringIO
-from imagekit.lib import *
-from imagekit.utils import img_to_fobj
-from django.core.files.base import ContentFile
-
-class ImageSpec(object):
- pre_cache = False
- quality = 70
- increment_count = False
- processors = []
-
- @classmethod
- def name(cls):
- return getattr(cls, 'access_as', cls.__name__.lower())
-
- @classmethod
- def process(cls, image, obj):
- processed_image = image.copy()
- for proc in cls.processors:
- processed_image = proc.process(processed_image, obj)
- return processed_image
-
-
-class Accessor(object):
- def __init__(self, obj, spec):
- self._img = None
- self._obj = obj
- self.spec = spec
-
- def _get_imgfile(self):
- format = self._img.format or 'JPEG'
- if format != 'JPEG':
- imgfile = img_to_fobj(self._img, format)
- else:
- imgfile = img_to_fobj(self._img, format,
- quality=int(self.spec.quality),
- optimize=True)
- return imgfile
-
- def _create(self):
- if self._exists():
- return
- # process the original image file
- fp = self._obj._imgfield.storage.open(self._obj._imgfield.name)
- fp.seek(0)
- fp = StringIO(fp.read())
- try:
- self._img = self.spec.process(Image.open(fp), self._obj)
- # save the new image to the cache
- content = ContentFile(self._get_imgfile().read())
- self._obj._imgfield.storage.save(self.name, content)
- except IOError:
- pass
-
- def _delete(self):
- self._obj._imgfield.storage.delete(self.name)
-
- def _exists(self):
- return self._obj._imgfield.storage.exists(self.name)
-
- def _basename(self):
- filename, extension = \
- os.path.splitext(os.path.basename(self._obj._imgfield.name))
- return self._obj._ik.cache_filename_format % \
- {'filename': filename,
- 'specname': self.spec.name(),
- 'extension': extension.lstrip('.')}
-
- @property
- def name(self):
- return os.path.join(self._obj._ik.cache_dir, self._basename())
-
- @property
- def url(self):
- self._create()
- if self.spec.increment_count:
- fieldname = self._obj._ik.save_count_as
- if fieldname is not None:
- current_count = getattr(self._obj, fieldname)
- setattr(self._obj, fieldname, current_count + 1)
- self._obj.save(clear_cache=False)
- return self._obj._imgfield.storage.url(self.name)
-
- @property
- def file(self):
- self._create()
- return self._obj._imgfield.storage.open(self.name)
-
- @property
- def image(self):
- if self._img is None:
- self._create()
- if self._img is None:
- self._img = Image.open(self.file)
- return self._img
-
- @property
- def width(self):
- return self.image.size[0]
-
- @property
- def height(self):
- return self.image.size[1]
-
-
-class Descriptor(object):
- def __init__(self, spec):
- self._spec = spec
-
- def __get__(self, obj, type=None):
- return Accessor(obj, self._spec)
diff --git a/imagekit/tests.py b/imagekit/tests.py
deleted file mode 100644
index 8c2eb5e..0000000
--- a/imagekit/tests.py
+++ /dev/null
@@ -1,86 +0,0 @@
-import os
-import tempfile
-import unittest
-from django.conf import settings
-from django.core.files.base import ContentFile
-from django.db import models
-from django.test import TestCase
-
-from imagekit import processors
-from imagekit.models import ImageModel
-from imagekit.specs import ImageSpec
-from imagekit.lib import Image
-
-
-class ResizeToWidth(processors.Resize):
- width = 100
-
-class ResizeToHeight(processors.Resize):
- height = 100
-
-class ResizeToFit(processors.Resize):
- width = 100
- height = 100
-
-class ResizeCropped(ResizeToFit):
- crop = ('center', 'center')
-
-class TestResizeToWidth(ImageSpec):
- access_as = 'to_width'
- processors = [ResizeToWidth]
-
-class TestResizeToHeight(ImageSpec):
- access_as = 'to_height'
- processors = [ResizeToHeight]
-
-class TestResizeCropped(ImageSpec):
- access_as = 'cropped'
- processors = [ResizeCropped]
-
-class TestPhoto(ImageModel):
- """ Minimal ImageModel class for testing """
- image = models.ImageField(upload_to='images')
-
- class IKOptions:
- spec_module = 'imagekit.tests'
-
-
-class IKTest(TestCase):
- """ Base TestCase class """
- def setUp(self):
- # create a test image using tempfile and PIL
- self.tmp = tempfile.TemporaryFile()
- Image.new('RGB', (800, 600)).save(self.tmp, 'JPEG')
- self.tmp.seek(0)
- self.p = TestPhoto()
- self.p.image.save(os.path.basename('test.jpg'),
- ContentFile(self.tmp.read()))
- self.p.save()
- # destroy temp file
- self.tmp.close()
-
- def test_setup(self):
- self.assertEqual(self.p.image.width, 800)
- self.assertEqual(self.p.image.height, 600)
-
- def test_to_width(self):
- self.assertEqual(self.p.to_width.width, 100)
- self.assertEqual(self.p.to_width.height, 75)
-
- def test_to_height(self):
- self.assertEqual(self.p.to_height.width, 133)
- self.assertEqual(self.p.to_height.height, 100)
-
- def test_crop(self):
- self.assertEqual(self.p.cropped.width, 100)
- self.assertEqual(self.p.cropped.height, 100)
-
- def test_url(self):
- tup = (settings.MEDIA_URL, self.p._ik.cache_dir, 'test_to_width.jpg')
- self.assertEqual(self.p.to_width.url, "%s%s/%s" % tup)
-
- def tearDown(self):
- # make sure image file is deleted
- path = self.p.image.path
- self.p.delete()
- self.failIf(os.path.isfile(path))