django-imagekit/imagekit/base.py
2012-02-13 21:49:09 -05:00

100 lines
3.3 KiB
Python

import os
from django.core.files.images import ImageFile
from django.db.models.fields.files import ImageFieldFile
from .imagecache import get_default_image_cache_backend
from .generators import SpecFileGenerator
from .processors import ProcessorPipeline, AutoConvert
def autodiscover():
"""
Auto-discover INSTALLED_APPS imagespecs.py modules and fail silently when
not present. This forces an import on them to register any admin bits they
may want.
Copied from django.contrib.admin
"""
import copy
from django.conf import settings
from django.utils.importlib import import_module
from django.utils.module_loading import module_has_submodule
from .templatetags import imagekit_tags
for app in settings.INSTALLED_APPS:
mod = import_module(app)
# Attempt to import the app's admin module.
try:
import_module('%s.imagespecs' % app)
except:
# Decide whether to bubble up this error. If the app just
# doesn't have an admin module, we can ignore the error
# attempting to import it, otherwise we want it to bubble up.
if module_has_submodule(mod, 'imagespecs'):
raise
class SpecWrapper(object):
"""
Wraps a user-defined spec object so we can access properties that don't
exist without errors.
"""
def __init__(self, spec):
self.processors = getattr(spec, 'processors', None)
self.format = getattr(spec, 'format', None)
self.options = getattr(spec, 'options', None)
self.autoconvert = getattr(spec, 'autoconvert', True)
self.storage = getattr(spec, 'storage', None)
self.image_cache_backend = getattr(spec, 'image_cache_backend', None) \
or get_default_image_cache_backend()
class ImageSpecFile(ImageFieldFile):
def __init__(self, spec, source_file, spec_id):
spec = SpecWrapper(spec)
self.storage = spec.storage or source_file.storage
self.generator = SpecFileGenerator(processors=spec.processors,
format=spec.format, options=spec.options,
autoconvert=spec.autoconvert, storage=self.storage)
self.spec = spec
self.source_file = source_file
self.spec_id = spec_id
@property
def url(self):
self.validate()
return super(ImageFieldFile, self).url
def _get_file(self):
self.validate()
return super(ImageFieldFile, self).file
file = property(_get_file, ImageFieldFile._set_file, ImageFieldFile._del_file)
def clear(self):
return self.spec.image_cache_backend.clear(self)
def invalidate(self):
return self.spec.image_cache_backend.invalidate(self)
def validate(self):
return self.spec.image_cache_backend.validate(self)
@property
def name(self):
source_filename = self.source_file.name
filepath, basename = os.path.split(source_filename)
filename = os.path.splitext(basename)[0]
extension = self.generator.suggest_extension(source_filename)
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.generator.generate_file(self.name, self.source_file, save)