Moved images rendering functions from .zmi module
authorThierry Florac <tflorac@ulthar.net>
Mon, 20 Jul 2020 14:53:39 +0200
changeset 205 a731e29446ca
parent 204 53322ba0ec77
child 206 15510af9adba
Moved images rendering functions from .zmi module
src/pyams_file/image.py
src/pyams_file/thumbnail.py
src/pyams_file/zmi/image.py
--- a/src/pyams_file/image.py	Sun Jul 19 02:01:21 2020 +0200
+++ b/src/pyams_file/image.py	Mon Jul 20 14:53:39 2020 +0200
@@ -10,18 +10,27 @@
 # FOR A PARTICULAR PURPOSE.
 #
 
-__docformat__ = 'restructuredtext'
-
+import random
 import re
+import sys
 from io import BytesIO
 
 from PIL import Image, ImageFilter
+from pyramid.renderers import render
+from zope.dublincore.interfaces import IZopeDublinCore
 from zope.interface import implementer
 from zope.schema.fieldproperty import FieldProperty
 
+from pyams_file.interfaces import IImage, IResponsiveImage, ISVGImage, IThumbnailGeometry, \
+    IThumbnailer, IThumbnails
+from pyams_utils.adapter import ContextAdapter, adapter_config
+from pyams_utils.request import check_request
+from pyams_utils.url import absolute_url
+
+
+__docformat__ = 'restructuredtext'
+
 from pyams_file import _
-from pyams_file.interfaces import IImage, IResponsiveImage, IThumbnailGeometry, IThumbnailer, IThumbnails
-from pyams_utils.adapter import ContextAdapter, adapter_config
 
 
 WEB_FORMATS = ('JPEG', 'PNG', 'GIF')
@@ -267,3 +276,62 @@
 
     label = _("Large screen thumbnail")
     weight = 13
+
+
+#
+# SVG utilities
+#
+
+def render_svg(image, width=None, height=None, request=None, css_class='', img_class=''):
+    """Render SVG file"""
+    options = {'svg': image}
+    if width or height:
+        options['style'] = 'width: {0}{1}; height: {2}{3};'.format(
+            width, 'px' if isinstance(width, int) else '',
+            height, 'px' if isinstance(height, int) else '')
+    else:
+        options['style'] = ''
+    options['css_class'] = css_class
+    result = render('templates/svg-render.pt', options, request)
+    if img_class:
+        result = result.replace('<svg ', '<svg class="{0}" '.format(img_class))
+    return result
+
+
+def render_img(image, width=None, height=None, request=None,
+               css_class='', img_class='', timestamp=False):
+    """Render image thumbnail"""
+    thumbnail = None
+    thumbnails = IThumbnails(image, None)
+    if thumbnails is not None:
+        if width and height:
+            thumbnail = thumbnails.get_thumbnail('{0}x{1}'.format(width, height))
+        elif width and (width != 'auto'):
+            thumbnail = thumbnails.get_thumbnail('w{0}'.format(width))
+        elif height and (height != 'auto'):
+            thumbnail = thumbnails.get_thumbnail('h{0}'.format(height))
+    if thumbnail is None:
+        thumbnail = image
+    if request is None:
+        request = check_request()
+    url = absolute_url(thumbnail, request)
+    if timestamp:
+        dc = IZopeDublinCore(thumbnail, None)
+        if dc is None:
+            timestamp = random.randint(0, sys.maxsize)
+        else:
+            timestamp = dc.modified.timestamp()
+        url += '?_={0}'.format(timestamp)
+    result = '<img src="{0}" class="{1}" />'.format(url, img_class)
+    if css_class:
+        result = '<div class="{0}">{1}</div>'.format(css_class, result)
+    return result
+
+
+def render_image(image, width=None, height=None, request=None,
+                 css_class='', img_class='', timestamp=False):
+    """Render image"""
+    if ISVGImage.providedBy(image):
+        return render_svg(image, width, height, request, css_class, img_class)
+    else:
+        return render_img(image, width, height, request, css_class, img_class, timestamp)
--- a/src/pyams_file/thumbnail.py	Sun Jul 19 02:01:21 2020 +0200
+++ b/src/pyams_file/thumbnail.py	Mon Jul 20 14:53:39 2020 +0200
@@ -10,8 +10,6 @@
 # FOR A PARTICULAR PURPOSE.
 #
 
-__docformat__ = 'restructuredtext'
-
 import logging
 import re
 
@@ -21,20 +19,25 @@
 from pyramid.events import subscriber
 from pyramid.threadlocal import get_current_registry
 from zope.interface import Interface, alsoProvides
-from zope.lifecycleevent import IObjectRemovedEvent, 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, 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_file.image import render_image
+from pyams_file.interfaces import IFileModifiedEvent, IImage, IMediaFile, IThumbnailFile, \
+    IThumbnailer, IThumbnails, IWatermarker
+from pyams_utils.adapter import ContextAdapter, ContextRequestViewAdapter, adapter_config, \
+    get_annotation_adapter
 from pyams_utils.interfaces.tales import ITALESExtension
 from pyams_utils.registry import query_utility
 from pyams_utils.request import check_request
 
 
+__docformat__ = 'restructuredtext'
+
+
 logger = logging.getLogger('PyAMS (file)')
 
 
@@ -202,7 +205,8 @@
                     watermarker = query_utility(IWatermarker)
                     if watermarker is not None:
                         thumbnail_image.seek(0)
-                        thumbnail_image, format = watermarker.add_watermark(thumbnail_image, watermark)
+                        thumbnail_image, format = watermarker.add_watermark(thumbnail_image,
+                                                                            watermark)
                 # create final image
                 thumbnail_image = FileFactory(thumbnail_image)
                 alsoProvides(thumbnail_image, IThumbnailFile)
@@ -263,7 +267,8 @@
         return result
 
 
-@adapter_config(name='thumbnails', context=(Interface, Interface, Interface), provides=ITALESExtension)
+@adapter_config(name='thumbnails', context=(Interface, Interface, Interface),
+                provides=ITALESExtension)
 class ThumbnailsExtension(ContextRequestViewAdapter):
     """extension:thumbnails(image) TALES extension
 
@@ -276,7 +281,8 @@
         return IThumbnails(context, None)
 
 
-@adapter_config(name='thumbnail', context=(Interface, Interface, Interface), provides=ITALESExtension)
+@adapter_config(name='thumbnail', context=(Interface, Interface, Interface),
+                provides=ITALESExtension)
 class ThumbnailExtension(ContextRequestViewAdapter):
     """extension:thumbnail(image, width, height, css_class, img_class) TALES extension
 
--- a/src/pyams_file/zmi/image.py	Sun Jul 19 02:01:21 2020 +0200
+++ b/src/pyams_file/zmi/image.py	Mon Jul 20 14:53:39 2020 +0200
@@ -10,14 +10,9 @@
 # FOR A PARTICULAR PURPOSE.
 #
 
-__docformat__ = 'restructuredtext'
-
-import random
-import sys
 from collections import OrderedDict
 
 import transaction
-from pyramid.renderers import render
 from pyramid.view import view_config
 from transaction.interfaces import ITransactionManager
 from z3c.form import button, field
@@ -26,10 +21,9 @@
 from zope.schema import Bool, Int
 from zope.schema.fieldproperty import FieldProperty
 
-from pyams_file import _
 from pyams_file.image import ThumbnailGeometry
-from pyams_file.interfaces import IFileInfo, IFileModifierForm, IImage, IMediaWidget, IResponsiveImage, ISVGImage, \
-    IThumbnailForm, IThumbnailGeometry, IThumbnailer, IThumbnails
+from pyams_file.interfaces import IFileInfo, IFileModifierForm, IImage, IMediaWidget, \
+    IResponsiveImage, IThumbnailForm, IThumbnailGeometry, IThumbnailer, IThumbnails
 from pyams_file.zmi import FileModifierAction
 from pyams_form.form import DialogDisplayForm, ajax_config
 from pyams_form.help import FormHelp
@@ -44,67 +38,15 @@
 from pyams_template.template import template_config
 from pyams_utils.adapter import adapter_config
 from pyams_utils.interfaces import ICacheKeyValue, VIEW_PERMISSION
-from pyams_utils.request import check_request
 from pyams_utils.url import absolute_url
 from pyams_viewlet.viewlet import Viewlet, viewlet_config
 from pyams_zmi.form import AdminDialogEditForm
 from pyams_zmi.layer import IAdminLayer
 
 
-#
-# SVG utilities
-#
-
-def render_svg(image, width=None, height=None, request=None, css_class='', img_class=''):
-    """Render SVG file"""
-    options = {'svg': image}
-    if width or height:
-        options['style'] = 'width: {0}{1}; height: {2}{3};'.format(width, 'px' if isinstance(width, int) else '',
-                                                                   height, 'px' if isinstance(height, int) else '')
-    else:
-        options['style'] = ''
-    options['css_class'] = css_class
-    result = render('templates/svg-render.pt', options, request)
-    if img_class:
-        result = result.replace('<svg ', '<svg class="{0}" '.format(img_class))
-    return result
-
+__docformat__ = 'restructuredtext'
 
-def render_img(image, width=None, height=None, request=None, css_class='', img_class='', timestamp=False):
-    """Render image thumbnail"""
-    thumbnail = None
-    thumbnails = IThumbnails(image, None)
-    if thumbnails is not None:
-        if width and height:
-            thumbnail = thumbnails.get_thumbnail('{0}x{1}'.format(width, height))
-        elif width and (width != 'auto'):
-            thumbnail = thumbnails.get_thumbnail('w{0}'.format(width))
-        elif height and (height != 'auto'):
-            thumbnail = thumbnails.get_thumbnail('h{0}'.format(height))
-    if thumbnail is None:
-        thumbnail = image
-    if request is None:
-        request = check_request()
-    url = absolute_url(thumbnail, request)
-    if timestamp:
-        dc = IZopeDublinCore(thumbnail, None)
-        if dc is None:
-            timestamp = random.randint(0, sys.maxsize)
-        else:
-            timestamp = dc.modified.timestamp()
-        url += '?_={0}'.format(timestamp)
-    result = '<img src="{0}" class="{1}" />'.format(url, img_class)
-    if css_class:
-        result = '<div class="{0}">{1}</div>'.format(css_class, result)
-    return result
-
-
-def render_image(image, width=None, height=None, request=None, css_class='', img_class='', timestamp=False):
-    """Render image"""
-    if ISVGImage.providedBy(image):
-        return render_svg(image, width, height, request, css_class, img_class)
-    else:
-        return render_img(image, width, height, request, css_class, img_class, timestamp)
+from pyams_file import _
 
 
 #
@@ -121,7 +63,8 @@
 
     @property
     def url(self):
-        return 'MyAMS.ajax.getJSON?url={0}'.format(absolute_url(self.context, self.request, 'rotate.json'))
+        return 'MyAMS.ajax.getJSON?url={0}'.format(
+            absolute_url(self.context, self.request, 'rotate.json'))
 
     def get_url(self):
         return self.url
@@ -145,9 +88,11 @@
             'callback': 'MyAMS.skin.refreshContent',
             'options': {
                 'object_id': 'thumbnail_{0}'.format(cache_key),
-                'content': '<img class="thumbnail" id="thumbnail_{key}" src="{src}" title="{title}" />'.format(
+                'content': '<img class="thumbnail" id="thumbnail_{key}" '
+                           'src="{src}" title="{title}" />'.format(
                     key=cache_key,
-                    src='{0}?_={1}'.format(absolute_url(thumbnail, request), dc.modified.timestamp()),
+                    src='{0}?_={1}'.format(absolute_url(thumbnail, request),
+                                           dc.modified.timestamp()),
                     title=II18n(image).query_attribute('title', request=request)
                 )
             }