Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Made modifications to reduce queries when using remote storage. #226

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 10 additions & 1 deletion docs/ref/processors.rst
Expand Up @@ -59,7 +59,7 @@ options used to generate the thumbnail are passed to processors, not just the
ones defined.

Whether a processor actually modifies the image or not, they must always return
an image.
an image.

Use the processor
-----------------
Expand All @@ -73,3 +73,12 @@ module::
THUMBNAIL_PROCESSORS = easy_thumbnails_defaults.THUMBNAIL_PROCESSORS + (
'wb_project.thumbnail_processors.whizzbang_processor',
)

# For Django 1.5 or greater do the following in order to avoid the error,
# "ImproperlyConfigured: The SECRET_KEY setting must not be empty."
def get_easy_thumbnail_processors():
from easy_thumbnails.conf import Settings as easy_thumbnails_defaults
return easy_thumbnails_defaults.THUMBNAIL_PROCESSORS + (
'wb_project.thumbnail_processors.whizzbang_processor',
)
THUMBNAIL_PROCESSORS = get_easy_thumbnail_processors
5 changes: 4 additions & 1 deletion easy_thumbnails/conf.py
Expand Up @@ -18,7 +18,10 @@ def __init__(self, isolated=False, *args, **kwargs):
self.isolated = isolated
self._changed = {}
self._added = []
super(AppSettings, self).__init__(*args, **kwargs)
try:
super(AppSettings, self).__init__(django_settings.SETTINGS_MODULE, **kwargs)
except TypeError:
super(AppSettings, self).__init__(*args, **kwargs)

def get_isolated(self):
return self._isolated
Expand Down
30 changes: 24 additions & 6 deletions easy_thumbnails/files.py
Expand Up @@ -11,6 +11,8 @@
from easy_thumbnails import engine, exceptions, models, utils, signals
from easy_thumbnails.alias import aliases
from easy_thumbnails.conf import settings
from easy_thumbnails.models import Thumbnail
from easy_thumbnails.storage import ThumbnailFileSystemStorage


def get_thumbnailer(obj, relative_name=None):
Expand Down Expand Up @@ -77,11 +79,15 @@ def save_thumbnail(thumbnail_file, storage):
Save a thumbnailed file, returning the saved relative file name.
"""
filename = thumbnail_file.name
if storage.exists(filename):

# Don't waste time deleting a file if using remote storage like S3
is_local_storage = isinstance(storage, ThumbnailFileSystemStorage)
if is_local_storage is True:
try:
storage.delete(filename)
except:
pass

return storage.save(filename, thumbnail_file)


Expand All @@ -100,6 +106,16 @@ def generate_all_aliases(fieldfile, include_global):
for options in all_options.values():
thumbnailer.get_thumbnail(options)

# Because each thumbnail has a modified time that's different from the
# source file's modified time, update all thumbnails so they have the
# same modified time as the source so when the thumbnails are first
# used they aren't regenerated again. Unless you're using the local
# file system, because the local file system doesn't doesn't store
# thumbnail information in the DB.

if thumbnailer.source is not None:
Thumbnail.objects.filter(source_id=thumbnailer.source.pk).update(modified=thumbnailer.source.modified)


class FakeField(object):
name = 'fake'
Expand Down Expand Up @@ -256,6 +272,7 @@ def __init__(self, file=None, name=None, source_storage=None,
self.remote_source = remote_source
self.alias_target = None
self.generate = generate
self.source = None

# Set default properties. For backwards compatibilty, check to see
# if the attribute exists already (it could be set as a class property
Expand Down Expand Up @@ -431,11 +448,11 @@ def thumbnail_exists(self, thumbnail_name):
if source_modtime and thumbnail_modtime is not None:
return thumbnail_modtime and source_modtime <= thumbnail_modtime
# Fall back to using the database cached modification times.
source = self.get_source_cache()
if not source:
self.source = self.get_source_cache()
if not self.source:
return False
thumbnail = self.get_thumbnail_cache(thumbnail_name)
return thumbnail and source.modified <= thumbnail.modified
return thumbnail and self.source.modified <= thumbnail.modified

def get_source_cache(self, create=False, update=False):
if self.remote_source:
Expand All @@ -456,10 +473,11 @@ def get_thumbnail_cache(self, thumbnail_name, create=False, update=False):
update_modified = modtime and utils.fromtimestamp(modtime)
if update:
update_modified = update_modified or utils.now()
source = self.get_source_cache(create=True)
if not self.source:
self.source = self.get_source_cache(create=True)
return models.Thumbnail.objects.get_file(
create=create, update_modified=update_modified,
storage=self.thumbnail_storage, source=source, name=thumbnail_name,
storage=self.thumbnail_storage, source=self.source, name=thumbnail_name,
check_cache_miss=self.thumbnail_check_cache_miss)

def get_source_modtime(self):
Expand Down
2 changes: 2 additions & 0 deletions easy_thumbnails/test_settings.py
Expand Up @@ -5,6 +5,8 @@
MEDIA_ROOT = os.path.normcase(os.path.dirname(os.path.abspath(__file__)))
MEDIA_URL = '/media/'

SECRET_KEY = 'key-for-testing'

DATABASE_ENGINE = 'sqlite3'

DATABASES = {
Expand Down
15 changes: 12 additions & 3 deletions tox.ini
Expand Up @@ -28,6 +28,9 @@ basepython = python2.5
deps =
Django==1.2.4
PIL
setenv =
DJANGO_SETTINGS_MODULE = easy_thumbnails.test_settings
PIP_INSECURE = 1

[testenv:py26-1.2.X]
basepython = python2.6
Expand All @@ -47,6 +50,9 @@ basepython = python2.5
deps =
Django==1.3.1
PIL
setenv =
DJANGO_SETTINGS_MODULE = easy_thumbnails.test_settings
PIP_INSECURE = 1

[testenv:py26-1.3.X]
basepython = python2.6
Expand All @@ -64,17 +70,20 @@ deps =
[testenv:py25]
basepython = python2.5
deps =
https://github.com/django/django/zipball/master
https://www.djangoproject.com/download/1.4.5/tarball/
PIL
setenv =
DJANGO_SETTINGS_MODULE = easy_thumbnails.test_settings
PIP_INSECURE = 1

[testenv:py26]
basepython = python2.6
deps =
https://github.com/django/django/zipball/master
https://www.djangoproject.com/download/1.5.1/tarball/
PIL

[testenv:py27]
basepython = python2.7
deps =
https://github.com/django/django/zipball/master
https://www.djangoproject.com/download/1.5.1/tarball/
PIL