from django.utils.functional import curry
import Image
import os

class ThumbnailMixIn(object):

    def add_accessor_methods(self, *args, **kwargs):
        for size in self.image_sizes:
            setattr(self, 'get_%s_image_url' % size, curry(self._get_SIZE_image_url, size=size))

    def _get_SIZE_image_url(self, size):
        return self.get_image_url(size)

    def create_thumbnails(self):
        for size in self.image_sizes:
            self.create_thumbnail(size)

    def delete_thumbnails(self):
        try:
            for size in self.image_sizes:
                os.remove(self.get_image_path(size))
        except:
            pass

    def create_thumbnail(self, size):
        image_size = self.image_sizes.get(size)
        img = Image.open(self.image.path)
        img.thumbnail((
            image_size.get('width'),
            image_size.get('height')
        ), Image.ANTIALIAS)
        img.save(self.get_image_path(size))

    def get_image_path(self, size):
        return os.sep.join([
            os.path.dirname(self.image.path),
            self.get_image_filename(size)
        ])

    def get_image_url(self, size):
        return '/'.join([
            os.path.dirname(self.image.url),
            self.get_image_filename(size)
        ])

    def get_image_filename(self,size):
        return '_'.join([size,os.path.basename(self.image.path)])

    def admin_thumbnail(self):
        if self.image_sizes.has_key('admin'):
            return '<img src="%s" alt="" />' % (self.get_image_url('admin'))
        return '&nbsp;'
    admin_thumbnail.allow_tags = True

# The model
class Photo(models.Model, ThumbnailMixIn):
    title = models.CharField(max_length=200)
    image = models.ImageField(upload_to='photos') # Must be named image.

    image_sizes = {
        'admin': {'width': 50, 'height': 50}, 
        'small': {'width': 300, 'height': 300}, 
        'medium': {'width': 500, 'height': 500}
    }

# Signals
def add_accessor_methods(sender, instance, signal, *args, **kwargs):
    if hasattr(instance, 'add_accessor_methods'):
        instance.add_accessor_methods()

def create_thumbnails(sender, instance, signal, *args, **kwargs):
    if hasattr(sender, 'create_thumbnails'):
        sender.create_thumbnails(instance)

def delete_thumbnails(sender, instance, signal, *args, **kwargs):
    if hasattr(sender, 'delete_thumbnails'):
        sender.delete_thumbnails(instance)

post_init.connect(add_accessor_methods)
post_save.connect(create_thumbnails, sender=Photo)
post_delete.connect(delete_thumbnails, sender=Photo)

