Don't generate thumbnail for selections using default geometry
authorThierry Florac <tflorac@ulthar.net>
Tue, 05 Feb 2019 09:39:36 +0100
changeset 175 ab573883a5c7
parent 174 d49bcf382187
child 176 4eb49f19314a
Don't generate thumbnail for selections using default geometry
src/pyams_file/thumbnail.py
--- a/src/pyams_file/thumbnail.py	Tue Feb 05 09:38:25 2019 +0100
+++ b/src/pyams_file/thumbnail.py	Tue Feb 05 09:39:36 2019 +0100
@@ -12,6 +12,7 @@
 
 __docformat__ = 'restructuredtext'
 
+import logging
 import re
 
 import transaction
@@ -20,12 +21,13 @@
 from pyramid.events import subscriber
 from pyramid.threadlocal import get_current_registry
 from zope.interface import Interface, alsoProvides
-from zope.lifecycleevent import ObjectAddedEvent, ObjectCreatedEvent, ObjectRemovedEvent
+from zope.lifecycleevent import IObjectRemovedEvent, ObjectAddedEvent, ObjectCreatedEvent, ObjectRemovedEvent
 from zope.location import locate
 from zope.traversing.interfaces import ITraversable
 
 from pyams_file.file import FileFactory
-from pyams_file.interfaces import IFileModifiedEvent, IImage, IThumbnailFile, IThumbnailer, IThumbnails, IWatermarker
+from pyams_file.interfaces import IFileModifiedEvent, IImage, IMediaFile, IThumbnailFile, IThumbnailer, IThumbnails, \
+    IWatermarker
 from pyams_file.zmi.image import render_image
 from pyams_utils.adapter import ContextAdapter, ContextRequestViewAdapter, adapter_config, get_annotation_adapter
 from pyams_utils.interfaces.tales import ITALESExtension
@@ -33,6 +35,9 @@
 from pyams_utils.request import check_request
 
 
+logger = logging.getLogger('PyAMS (file)')
+
+
 THUMBNAIL_ANNOTATIONS_KEY = 'pyams_file.image.thumbnails'
 THUMBNAIL_GEOMETRY_KEY = 'pyams_file.image.geometry'
 
@@ -123,32 +128,38 @@
             return None, None
 
     def get_selection(self, selection_name, format=None):
+        logger.debug(">>> Requested thumbnail selection: {}".format(selection_name))
         if selection_name in self.thumbnails:
             return self.thumbnails[selection_name]
         geometry = self.get_geometry(selection_name)
-        registry = get_current_registry()
-        thumbnailer = registry.queryAdapter(self.image, IThumbnailer, name=selection_name)
-        if thumbnailer is not None:
-            selection = thumbnailer.create_thumbnail(geometry, format)
-            if selection is not None:
-                if isinstance(selection, tuple):
-                    selection, format = selection
-                else:
-                    format = 'jpeg'
-                selection = FileFactory(selection)
-                alsoProvides(selection, IThumbnailFile)
-                registry.notify(ObjectCreatedEvent(selection))
-                self.thumbnails[selection_name] = selection
-                selection_size = selection.get_image_size()
-                locate(selection, self.image,
-                       '++thumb++{0}:{1}x{2}.{3}'.format(selection_name,
-                                                         selection_size[0],
-                                                         selection_size[1],
-                                                         format))
-                registry.notify(ObjectAddedEvent(selection))
-                return selection
+        if geometry == IThumbnailer(self.image).get_default_geometry():
+            return self.image
+        else:
+            registry = get_current_registry()
+            thumbnailer = registry.queryAdapter(self.image, IThumbnailer, name=selection_name)
+            if thumbnailer is not None:
+                selection = thumbnailer.create_thumbnail(geometry, format)
+                if selection is not None:
+                    if isinstance(selection, tuple):
+                        selection, format = selection
+                    else:
+                        format = 'jpeg'
+                    selection = FileFactory(selection)
+                    alsoProvides(selection, IThumbnailFile)
+                    registry.notify(ObjectCreatedEvent(selection))
+                    self.thumbnails[selection_name] = selection
+                    selection_size = selection.get_image_size()
+                    locate(selection, self.image,
+                           '++thumb++{0}:{1}x{2}.{3}'.format(selection_name,
+                                                             selection_size[0],
+                                                             selection_size[1],
+                                                             format))
+                    logger.debug("  > Generated thumbnail selection: {}".format(selection.__name__))
+                    registry.notify(ObjectAddedEvent(selection))
+                    return selection
 
     def get_thumbnail(self, thumbnail_name, format=None, watermark=None):
+        logger.debug(">>> Requested thumbnail: {}".format(thumbnail_name))
         # check for existing thumbnail
         if thumbnail_name in self.thumbnails:
             return self.thumbnails[thumbnail_name]
@@ -204,25 +215,30 @@
                                                            thumbnail_size[0],
                                                            thumbnail_size[1],
                                                            format))
+                logger.debug("  < Generated thumbnail: {}".format(thumbnail_image.__name__))
                 registry.notify(ObjectAddedEvent(thumbnail_image))
                 return thumbnail_image
 
     def delete_thumbnail(self, thumbnail_name):
         if thumbnail_name in self.thumbnails:
             thumbnail_image = self.thumbnails[thumbnail_name]
-            registry = check_request().registry
+            registry = get_current_registry()
             registry.notify(ObjectRemovedEvent(thumbnail_image))
             del self.thumbnails[thumbnail_name]
+            logger.debug(">>> Removed thumbnail: {}".format(thumbnail_name))
 
     def clear_thumbnails(self):
         [self.delete_thumbnail(thumbnail_name) for thumbnail_name in list(self.thumbnails.keys())]
 
 
-@subscriber(IFileModifiedEvent, context_selector=IImage)
-def handle_modified_file(event):
-    thumbnail = IThumbnails(event.object)
-    thumbnail.clear_geometries()
-    thumbnail.clear_thumbnails()
+@subscriber(IFileModifiedEvent, context_selector=IMediaFile)
+@subscriber(IObjectRemovedEvent, context_selector=IMediaFile)
+def handle_modified_image(event):
+    """Clear thumbnails when an image is updated or removed"""
+    thumbnails = IThumbnails(event.object, None)
+    if thumbnails is not None:
+        thumbnails.clear_geometries()
+        thumbnails.clear_thumbnails()
 
 
 @adapter_config(name='thumb', context=IImage, provides=ITraversable)
@@ -261,7 +277,7 @@
 
 @adapter_config(name='thumbnail', context=(Interface, Interface, Interface), provides=ITALESExtension)
 class ThumbnailExtension(ContextRequestViewAdapter):
-    """extension:thumbnail(image, width, height) TALES extension
+    """extension:thumbnail(image, width, height, css_class, img_class) TALES extension
 
     This TALES extension doesn't return an adapter but HTML code matching given image and dimensions.
     If image is a classic image, an "img" tag with source to thumbnail of required size is returned.