django-imagekit/imagekit/models.py

114 lines
4.1 KiB
Python
Raw Normal View History

2008-12-31 18:40:51 +00:00
import os
2008-12-28 21:48:21 +00:00
from datetime import datetime
from django.conf import settings
2009-01-08 20:04:20 +00:00
from django.core.files.base import ContentFile
2008-12-28 21:48:21 +00:00
from django.db import models
2008-12-31 17:54:47 +00:00
from django.db.models.base import ModelBase
from django.utils.translation import ugettext_lazy as _
2009-01-04 18:30:03 +00:00
from imagekit import specs
2009-01-08 21:11:15 +00:00
from imagekit.lib import *
from imagekit.options import Options
2009-01-08 20:04:20 +00:00
from imagekit.utils import img_to_fobj
2008-12-28 21:48:21 +00:00
# Modify image file buffer size.
ImageFile.MAXBLOCK = getattr(settings, 'PIL_IMAGEFILE_MAXBLOCK', 256 * 2 ** 10)
2008-12-28 21:48:21 +00:00
2009-01-14 16:09:17 +00:00
class ImageModelBase(ModelBase):
2009-01-03 14:44:43 +00:00
def __init__(cls, name, bases, attrs):
2009-01-14 16:09:17 +00:00
parents = [b for b in bases if isinstance(b, ImageModelBase)]
if not parents:
return
user_opts = getattr(cls, 'IKOptions', None)
2009-01-04 18:30:03 +00:00
opts = Options(user_opts)
2009-01-03 14:44:43 +00:00
try:
2009-01-09 14:07:10 +00:00
module = __import__(opts.spec_module, {}, {}, [''])
except ImportError:
2009-01-08 22:02:24 +00:00
raise ImportError('Unable to load imagekit config module: %s' % \
2009-01-09 14:07:10 +00:00
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]:
2009-01-04 22:14:13 +00:00
setattr(cls, spec.name(), specs.Descriptor(spec))
opts.specs.append(spec)
setattr(cls, '_ik', opts)
2009-01-14 16:09:17 +00:00
class ImageModel(models.Model):
2008-12-28 21:48:21 +00:00
""" Abstract base class implementing all core ImageKit functionality
2009-01-14 16:09:17 +00:00
Subclasses of ImageModel can override the inner IKOptions class to customize
2008-12-28 21:48:21 +00:00
storage locations and other options.
"""
2009-01-14 16:09:17 +00:00
__metaclass__ = ImageModelBase
2008-12-28 21:48:21 +00:00
class Meta:
abstract = True
class IKOptions:
pass
2009-01-04 22:14:13 +00:00
def admin_thumbnail_view(self):
2009-01-09 14:34:44 +00:00
prop = getattr(self, self._ik.admin_thumbnail_spec, None)
2009-01-04 22:14:13 +00:00
if prop is None:
2009-01-09 14:34:44 +00:00
return 'An "%s" image spec has not been defined.' % \
self._ik.admin_thumbnail_spec
2009-01-04 22:14:13 +00:00
else:
if hasattr(self, 'get_absolute_url'):
return u'<a href="%s"><img src="%s"></a>' % \
(self.get_absolute_url(), prop.url)
else:
return u'<a href="%s"><img src="%s"></a>' % \
2009-01-08 18:37:15 +00:00
(self._imgfield.url, prop.url)
2009-01-04 22:14:13 +00:00
admin_thumbnail_view.short_description = _('Thumbnail')
admin_thumbnail_view.allow_tags = True
2009-01-04 18:30:03 +00:00
@property
def _imgfield(self):
return getattr(self, self._ik.image_field)
2008-12-28 21:48:21 +00:00
def _clear_cache(self):
2009-01-04 22:14:13 +00:00
for spec in self._ik.specs:
prop = getattr(self, spec.name())
prop._delete()
2008-12-28 21:48:21 +00:00
def _pre_cache(self):
2009-01-04 22:14:13 +00:00
for spec in self._ik.specs:
if spec.pre_cache:
prop = getattr(self, spec.name())
prop._create()
2008-12-28 21:48:21 +00:00
2009-01-08 21:42:26 +00:00
def save(self, clear_cache=True, *args, **kwargs):
2009-01-08 21:44:35 +00:00
is_new_object = self._get_pk_val is None
2009-01-14 16:09:17 +00:00
super(ImageModel, self).save(*args, **kwargs)
2009-01-08 21:44:35 +00:00
if is_new_object:
2009-01-08 21:42:26 +00:00
clear_cache = False
2009-01-08 20:04:20 +00:00
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)
2009-01-08 21:42:26 +00:00
if clear_cache:
self._clear_cache()
self._pre_cache()
2008-12-28 21:48:21 +00:00
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()
2009-01-09 14:34:44 +00:00
models.Model.delete(self)