mirror of
https://github.com/Hopiu/django-imagekit.git
synced 2026-03-16 21:30:23 +00:00
Broken models into multiple files
This commit is contained in:
parent
72310161d1
commit
9662ec2be0
3 changed files with 130 additions and 115 deletions
|
|
@ -1,14 +1,15 @@
|
|||
from imagekit import specs
|
||||
from imagekit.specs import ImageSpec
|
||||
from imagekit import processors
|
||||
|
||||
|
||||
class ResizeThumbnail(specs.Resize):
|
||||
class ResizeThumbnail(processors.Resize):
|
||||
width = 100
|
||||
height = 75
|
||||
crop = True
|
||||
|
||||
class EnhanceSmall(specs.Adjustment):
|
||||
class EnhanceSmall(processors.Adjustment):
|
||||
contrast = 1.2
|
||||
sharpness = 1.1
|
||||
|
||||
class Thumbnail(specs.Spec):
|
||||
class Thumbnail(ImageSpec):
|
||||
processors = [ResizeThumbnail, EnhanceSmall]
|
||||
|
|
|
|||
|
|
@ -4,97 +4,10 @@ from django.conf import settings
|
|||
from django.db import models
|
||||
from django.db.models.base import ModelBase
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
import specs
|
||||
from imagekit.options import Options
|
||||
from imagekit import specs
|
||||
|
||||
|
||||
class IKProperty(object):
|
||||
def __init__(self, obj, spec):
|
||||
self._img = None
|
||||
self._obj = obj
|
||||
self.spec = spec
|
||||
|
||||
def create(self):
|
||||
self.spec.process(self.image, self.path)
|
||||
|
||||
def delete(self):
|
||||
if self.exists:
|
||||
os.remove(self.path)
|
||||
self._img = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
filename, extension = os.path.splitext(self.obj._image_basename())
|
||||
return self.spec._ik.cache_filename_format % \
|
||||
{'filename': filename,
|
||||
'sizename': self.spec.name,
|
||||
'extension': extension.lstrip('.')}
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
return os.abspath(os.path.join(self._obj._cache_dir(), self.spec.name)
|
||||
|
||||
@property
|
||||
def url(self):
|
||||
if not self.exists:
|
||||
self.create()
|
||||
return '/'.join([self._obj._cache_url(), self.name])
|
||||
|
||||
@property
|
||||
def exists(self):
|
||||
return os.path.isfile(self.path)
|
||||
|
||||
@property
|
||||
def image(self):
|
||||
if self._img is None:
|
||||
if not self.exists():
|
||||
self.create()
|
||||
self._img = Image.open(self.path)
|
||||
return self._img
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
return self.image.size[0]
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
return self.image.size[1]
|
||||
|
||||
@property
|
||||
def file(self):
|
||||
if not self.exists:
|
||||
self.create()
|
||||
return open(self.path)
|
||||
|
||||
|
||||
class IKOptions(object):
|
||||
# Images will be resized to fit if they are larger than max_image_size
|
||||
max_image_size = None
|
||||
# Media subdirectories
|
||||
image_dir_name = 'images'
|
||||
cache_dir_name = 'cache'
|
||||
# If given the image view count will be saved as this field name
|
||||
save_count_on_model_as = None
|
||||
# String pattern used to generate cache file names
|
||||
cache_filename_format = "%(filename)s_%(specname)s.%(extension)s"
|
||||
# Configuration options coded in the models itself
|
||||
config_module = 'imagekit.ikconfig'
|
||||
|
||||
def __init__(self, opts):
|
||||
for key, value in opts.__dict__.iteritems():
|
||||
setattr(self, key, value)
|
||||
|
||||
|
||||
class IKDescriptor(object):
|
||||
def __init__(self, spec):
|
||||
self._spec = spec
|
||||
self._prop = None
|
||||
|
||||
def __get__(self, obj, type=None):
|
||||
if self._prop is None:
|
||||
self._prop = IKProperty(obj, self._spec)
|
||||
return self._prop
|
||||
|
||||
|
||||
class IKModelBase(ModelBase):
|
||||
def __init__(cls, name, bases, attrs):
|
||||
|
||||
|
|
@ -103,7 +16,7 @@ class IKModelBase(ModelBase):
|
|||
return
|
||||
|
||||
user_opts = getattr(cls, 'IK', None)
|
||||
opts = IKOptions(user_opts)
|
||||
opts = Options(user_opts)
|
||||
|
||||
setattr(cls, '_ik', opts)
|
||||
|
||||
|
|
@ -113,9 +26,8 @@ class IKModelBase(ModelBase):
|
|||
raise ImportError('Unable to load imagekit config module: %s' % opts.config_module)
|
||||
|
||||
for spec in [spec for spec in module.__dict__.values() if \
|
||||
isinstance(spec, type)]:
|
||||
if issubclass(spec, specs.Size):
|
||||
setattr(cls, spec.__name__.lower(), IKDescriptor(spec))
|
||||
issubclass(spec, specs.ImageSpec)]:
|
||||
setattr(cls, spec.name, specs.Descriptor(spec))
|
||||
|
||||
|
||||
class IKModel(models.Model):
|
||||
|
|
@ -162,19 +74,19 @@ class IKModel(models.Model):
|
|||
|
||||
class IK:
|
||||
pass
|
||||
|
||||
def _image_basename(self):
|
||||
""" Returns the basename of the original image file """
|
||||
return os.path.basename(self.image.path)
|
||||
|
||||
def _cache_dir(self):
|
||||
|
||||
@property
|
||||
def cache_dir(self):
|
||||
""" Returns the path to the image cache directory """
|
||||
return os.path.join(os.path.dirname(self.image.path), self.IKConfig.cache_dir)
|
||||
return os.path.join(os.path.dirname(self._obj.image.path),
|
||||
self._ik.cache_dir_name)
|
||||
|
||||
def _cache_url(self):
|
||||
@property
|
||||
def cache_url(self):
|
||||
""" Returns a url pointing to the image cache directory """
|
||||
return '/'.join([os.path.dirname(self.image.url), self.IKConfig.cache_dir])
|
||||
|
||||
return '/'.join([os.path.dirname(self._obj.image.url),
|
||||
self._ik.cache_dir_name])
|
||||
|
||||
def _cache_spec(self, spec):
|
||||
if self._file_exists(spec):
|
||||
return
|
||||
|
|
@ -210,7 +122,7 @@ class IKModel(models.Model):
|
|||
if os.path.isfile(accessor.path):
|
||||
os.remove(accessor.path)
|
||||
if remove_dirs:
|
||||
self._cleanup_cache_dirs
|
||||
self._cleanupget_cache_dirs
|
||||
|
||||
def _cleanup_cache_dirs(self):
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -1,12 +1,114 @@
|
|||
""" Base imagekit specification classes
|
||||
""" ImageKit image specifications
|
||||
|
||||
This module holds the base implementations and defaults for imagekit
|
||||
specification classes. Users import and subclass these classes to define new
|
||||
specifications.
|
||||
All imagekit specifications must inherit from the ImageSpec class. Models
|
||||
inheriting from IKModel will be modified with a descriptor/accessor for each
|
||||
spec found.
|
||||
|
||||
"""
|
||||
class Spec(object):
|
||||
class ImageSpec(object):
|
||||
cache_on_save = False
|
||||
output_quality = 70
|
||||
increment_count = False
|
||||
pre_cache = False
|
||||
jpeg_quality = 70
|
||||
processors = []
|
||||
|
||||
@property
|
||||
@classmethod
|
||||
def name(cls):
|
||||
return getattr(cls, 'access_as', cls.__name__.lower())
|
||||
|
||||
@classmethod
|
||||
def create(cls, image, filename):
|
||||
processed_image = image.copy()
|
||||
for proc in cls.processors:
|
||||
processed_image = proc.process(processed_image)
|
||||
try:
|
||||
if image.format != 'JPEG':
|
||||
try:
|
||||
processed_image.save(im_filename)
|
||||
return
|
||||
except KeyError:
|
||||
pass
|
||||
processed_image.save(filename, 'JPEG',
|
||||
quality=int(cls.output_quality),
|
||||
optimize=True)
|
||||
except IOError, e:
|
||||
if os.path.isfile(filename):
|
||||
os.unlink(filename)
|
||||
raise e
|
||||
return processed_image
|
||||
|
||||
|
||||
class Accessor(object):
|
||||
def __init__(self, obj, spec):
|
||||
self._img = None
|
||||
self._obj = obj
|
||||
self.spec = spec
|
||||
|
||||
def create(self):
|
||||
self._img = self.spec.create(self.image, self.path)
|
||||
|
||||
def delete(self):
|
||||
if self.exists:
|
||||
os.remove(self.path)
|
||||
self._img = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
filename, ext = os.path.splitext(os.path.basename(self._obj.image.path))
|
||||
return self.spec._ik.cache_filename_format % \
|
||||
{'filename': filename,
|
||||
'sizename': self.spec.name,
|
||||
'extension': ext.lstrip('.')}
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
return os.abspath(os.path.join(self._obj.cache_dir, self.name)
|
||||
|
||||
@property
|
||||
def url(self):
|
||||
if not self.exists:
|
||||
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)
|
||||
return '/'.join([self._obj.cache_url, self.name])
|
||||
|
||||
@property
|
||||
def exists(self):
|
||||
return os.path.isfile(self.path)
|
||||
|
||||
@property
|
||||
def image(self):
|
||||
if self._img is None:
|
||||
if not self.exists():
|
||||
self.create()
|
||||
else:
|
||||
self._img = Image.open(self.path)
|
||||
return self._img
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
return self.image.size[0]
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
return self.image.size[1]
|
||||
|
||||
@property
|
||||
def file(self):
|
||||
if not self.exists:
|
||||
self.create()
|
||||
return open(self.path)
|
||||
|
||||
|
||||
class Descriptor(object):
|
||||
def __init__(self, spec):
|
||||
self._spec = spec
|
||||
self._prop = None
|
||||
|
||||
def __get__(self, obj, type=None):
|
||||
if self._prop is None:
|
||||
self._prop = Accessor(obj, self._spec)
|
||||
return self._prop
|
||||
|
|
|
|||
Loading…
Reference in a new issue