diff data/plugin/parser/text_x_arnica.py @ 268:bb780f830e66

refactored for using the new Image object
author Reimar Bauer <rb.proj AT googlemail DOT com>
date Sun, 14 Sep 2008 16:49:18 +0200
parents 6ec6242fae3a
children 1e3e876e38fb
line wrap: on
line diff
--- a/data/plugin/parser/text_x_arnica.py	Sun Sep 14 00:46:38 2008 +0200
+++ b/data/plugin/parser/text_x_arnica.py	Sun Sep 14 16:49:18 2008 +0200
@@ -14,26 +14,17 @@
     @license: GNU GPL, see COPYING for details.
 """
 
-import os, re, StringIO
+import os, re, time
 from random import randint
 
-from MoinMoin import caching, wikiutil
-from MoinMoin.action import AttachFile, cache
+from MoinMoin import wikiutil
+from MoinMoin.action import AttachFile
 from MoinMoin.packages import packLine
 from MoinMoin.Page import Page
 from MoinMoin.util.dataset import TupleDataset, Column
+from MoinMoin.util import timefuncs
 from MoinMoin.widget.browser import DataBrowserWidget
 
-try:
-    import Image
-except ImportError:
-    Image = None
-
-try:
-    import ExifTags
-except ImportError:
-    ExifTags = None
-
 parser_name = __name__.split('.')[-1]
 
 
@@ -45,8 +36,8 @@
                     only_items=False, template_itemlist=False,
                     album=False, album_title=unicode, album_image=u'',
                     renew=False,
-                    thumbnail_width=wikiutil.UnitArgument('128', float, ['px', ], defaultunit='px'),
-                    webnail_width=wikiutil.UnitArgument('640', float, ['px', ], defaultunit='px')):
+                    thumbnail_width=128,
+                    webnail_width=640):
     """ dummy function to initialize all default parameters for arnica. The parameters are checked for wrong input.
     @param target_page: page to read attachments from. empty pagename is current page.
     @param columns: number of columns for thumbnails
@@ -68,16 +59,6 @@
     @param thumbnail_width: default width of thumbnail is 128px
     @param webnail_width: default width of webnail is 640px
     """
-    if thumbnail_width:
-        if thumbnail_width[1] == 'px':
-            thumbnail_width = '%dpx' % int(thumbnail_width[0])
-        else:
-            thumbnail_width = '%g%s' % thumbnail_width
-    if webnail_width:
-        if webnail_width[1] == 'px':
-            webnail_width = '%dpx' % int(webnail_width[0])
-        else:
-            webnail_width = '%g%s' % webnail_width
     return locals()
 
 def _get_files(request, pagename):
@@ -113,46 +94,14 @@
             # saves the state of valid input
             self.init_settings = True
         except ValueError, err:
-            msg = u"arnica: %s" % err.args[0]
             # ToDo use formatter
-            request.write(self.formatter.text(msg))
+            request.write(self.formatter.text(err))
 
         self.inner_table_style = ' style="border-style:none; margin:10px;"'
         self.td_style = ' align="center" style="padding:0; margin:2px 2px; border-style:none"'
-        self.arnica_image = {} # self.arnica_image[image] = (webnail, thumbnail, imgtype, exif_date, description, order)
-
-    def get_exif_info(self, file_name, key):
-        """ gets exif info from image file
-        @param: file_name name of file
-        @key: cache key for file_name
-        """
-        date = "--"
-        if not (Image and ExifTags):
-            # in that case no hint about a missing module
-            return date
-
-        if wikiutil.isPicture(file_name):
-            date_key = 'D%s' % key
+        self.arnica_image = {} # self.arnica_image[image] = (webnail, thumbnail, exif_date, description, order)
 
-            if cache.exists(self.request, date_key):
-                cache_date = caching.CacheEntry(self.request, cache.cache_arena, date_key+'.data',
-                                       cache.cache_scope, do_locking=False)
-                return cache_date.content()
-
-            try:
-                im = Image.open(file_name)
-                rawExif = im._getexif().items()
-            except (IOError, AttributeError, KeyError):
-                pass
-            else:
-                for key, value in rawExif:
-                    if ExifTags.TAGS.get(key) == 'DateTimeOriginal':
-                        date = str(value)
-                        date = date.replace(':', '-', 2)
-                        date = date[0:19]
-                        cache.put(self.request, date_key, date, filename=file_name, content_type='text/plain')
-                        break
-        return date
+        self.Image = wikiutil.importWikiPlugin(self.request.cfg, "macro", "Image", function="Image")
 
     def html_tools_restricted(self, this_target):
         """ shows restricted tools
@@ -198,7 +147,7 @@
         @param image: image as key for corresponding data
         """
         image_names = self.arnica_image.keys()
-        index = [self.arnica_image[img][5] for img in image_names]
+        index = [self.arnica_image[img][4] for img in image_names]
         selected_images = [image_names[int(idx)] for idx in index]
 
         html = """
@@ -230,9 +179,8 @@
         "htdocs": self.request.cfg.url_prefix_static,
         "tablestyle": self.inner_table_style,
         "style": self.td_style,
-        "thumbnail_width": self.thumbnail_width,
-        "description": packLine([self.arnica_image[image][4]] + [self.arnica_image[img][3] for img in selected_images]),
-        "exif_date": packLine([self.arnica_image[image][3]] + [self.arnica_image[img][3] for img in selected_images]),
+        "description": packLine([self.arnica_image[image][3]] + [self.arnica_image[img][2] for img in selected_images]),
+        "exif_date": packLine([self.arnica_image[image][2]] + [self.arnica_image[img][2] for img in selected_images]),
         "target": self.arnica_image[image][0],
         "original_images": packLine([image] + selected_images),
         "images": packLine([self.arnica_image[image][0]] + [self.arnica_image[img][0] for img in selected_images]),
@@ -262,7 +210,7 @@
         html = ''
         if self.show_date:
             html = '<div class="html-show-date">%(this_exif_date)s</div>' % {
-                "this_exif_date": self.formatter.text(self.arnica_image[image][3])}
+                "this_exif_date": self.formatter.text(self.arnica_image[image][2])}
         return html
 
     def html_show_alias(self, image):
@@ -273,13 +221,13 @@
         html = ''
         if self.show_text:
             html = '<div class="html-show-alias"> %(this_alias)s</div>' % {
-                    "this_alias": self.to_wikitext(self.arnica_image[image][4])}
+                    "this_alias": self.to_wikitext(self.arnica_image[image][3])}
         return html
 
     def html_arrange_thumbnails(self, image, selected_images):
         """ defines arrangement of thumbnail, text, date and tools
         @param image: image as key for corresponding data
-        @param selected_images: ordered list of selected images 
+        @param selected_images: ordered list of selected images
         """
 
         title = ""
@@ -311,43 +259,39 @@
         "style": self.inner_table_style,
         "url": Page(self.request, self.pagename).url(self.request),
         "pagename": self.pagename,
-        "description": packLine([self.arnica_image[image][4]] + [self.arnica_image[img][4] for img in selected_images]),
-        "exif_date": packLine([self.arnica_image[image][3]] + [self.arnica_image[img][3] for img in selected_images]),
+        "description": packLine([self.arnica_image[image][3]] + [self.arnica_image[img][3] for img in selected_images]),
+        "exif_date": packLine([self.arnica_image[image][2]] + [self.arnica_image[img][2] for img in selected_images]),
         "target": self.arnica_image[image][0],
         "original_images": packLine([image] + selected_images),
         "images": packLine([self.arnica_image[image][0]] + [self.arnica_image[img][0] for img in selected_images]),
-        "thumbnail": cache.url(self.request, self.arnica_image[image][1]),
-        "thumbnail_width": self.thumbnail_width,
+        "thumbnail": self.arnica_image[image][1],
         "html_tools": self.html_show_tools(image),
         "date_html": self.html_show_date(image),
         "alias_html": self.html_show_alias(image),
         }
         return html
 
-    def define_thumb_webnails(self, path, files, image_alias):
+    def define_thumb_webnails(self, files, image_alias):
         """ creates lists for thumbnails and webnails
-        @param path: path to attachment
         @param files: file names of images
         @param image_alias: text alias for image file
         """
         order = 0
         for attfile in files:
-            if os.path.join(path, attfile):
-                description = attfile
-                if image_alias.get(attfile):
-                    # use alias
-                    description = image_alias.get(attfile)[0]
-                fname, ext = os.path.splitext(attfile)
-                key = cache.key(self.request, itemname=self.pagename, attachname=attfile)
-                webnail = 'W_%s_%s' % (self.webnail_width, key)
-                thumbfile = 'T_%s_%s' % (self.thumbnail_width, key)
-                imgtype = "jpeg"
-                if ext in ('.gif', '.png'):
-                    imgtype = 'png'
-
-                exif_date = self.formatter.text(self.get_exif_info(os.path.join(path, attfile), key))
-                self.arnica_image[attfile] = (webnail, thumbfile, imgtype, exif_date, description, str(order))
-                order += 1
+            description = attfile
+            if image_alias.get(attfile):
+                # use alias
+                description = image_alias.get(attfile)[0]
+            itemname = self.request.formatter.page.page_name + '/' + attfile
+            img = self.Image(self.request, itemname)
+            webnail = img.url(size=(self.webnail_width, self.webnail_width))
+            thumbnail = img.url(size=(self.thumbnail_width, self.thumbnail_width))
+            try:
+                exif_date = time.strftime("%Y-%m-%d %H:%M:%S", timefuncs.tmtuple(img.exif["DateTimeOriginal"]))
+            except KeyError:
+                exif_date = '--'
+            self.arnica_image[attfile] = (webnail, thumbnail, exif_date, description, str(order))
+            order += 1
 
     def to_wikitext(self, text):
         """ converts text to wiki name if it is written as WikiName or [[wikiname]]
@@ -421,95 +365,9 @@
         if self.reverse_sort:
             all_files.reverse()
         if all_files:
-            self.define_thumb_webnails(path, all_files, image_alias)
+            self.define_thumb_webnails(all_files, image_alias)
         return all_files
 
-    def create_thumbnail_and_webnail_image(self):
-        """ creates thumbnails and webnails cache files for given image type
-        @param image: filename of image
-        @param webnail: name of webnail file
-        @param thumbnail: name of thumbnail file
-        @param image_type: filetype of image
-        """
-        _ = self.request.getText
-        if not Image:
-            msg = _('The parser %(parser)s needs python imaging library (PIL) installed') % {'parser': parser_name}
-            self.request.write(self.formatter.text(msg))
-            return
-
-        path = AttachFile.getAttachDir(self.request, self.pagename, create=1)
-        for image in self.arnica_image.keys():
-            imagef = os.path.join(path, image)
-            if os.path.getsize(imagef) == 0:
-                continue
-
-            if self.renew:
-                cache.remove(self.request, self.arnica_image[image][0])
-                cache.remove(self.request, self.arnica_image[image][1])
-
-            if not cache.exists(self.request, self.arnica_image[image][0]) or not cache.exists(self.request, self.arnica_image[image][1]):
-                try:
-                    im_obj = Image.open(imagef)
-                except IOError:
-                    msg = _("Can not access attachment: %(filename)s. Often the case for this error is a truncated image attachment.") % {"filename": os.path.basename(imagef)}
-                    self.request.write(self.formatter.text(msg))
-                    continue
-                else:
-                    # ToDo may be it is better to just copy the image to the new location
-                    # currently PIL does not support exif information
-                    if self.image_for_webnail:
-                        buf = StringIO.StringIO()
-                        im_obj.save(buf, self.arnica_image[image][2])
-                        buf.flush()
-                        buf.seek(0)
-                        cache.put(self.request, self.arnica_image[image][0], buf, filename=imagef)
-            # XXX later, a unit conversion method for using other units than 'px' is needed
-            if not cache.exists(self.request, self.arnica_image[image][0]):
-                try:
-                    exif = im_obj._getexif()
-                except (AttributeError, KeyError):
-                    exif = None
-                try:
-                    im_obj.thumbnail((int(self.webnail_width.strip('px')), int(self.webnail_width.strip('px'))), Image.ANTIALIAS)
-                except IOError:
-                    #  one reason can be that the image file is truncated
-                    return
-                if exif:
-                    try:
-                        process = {
-                            1: lambda x: x,
-                            2: lambda x: x.transpose(Image.FLIP_LEFT_RIGHT),
-                            3: lambda x: x.transpose(Image.ROTATE_180),
-                            4: lambda x: x.transpose(Image.FLIP_TOP_BOTTOM),
-                            5: lambda x: x.transpose(Image.ROTATE_90).transpose(Image.FLIP_TOP_BOTTOM),
-                            6: lambda x: x.transpose(Image.ROTATE_270),
-                            7: lambda x: x.transpose(Image.ROTATE_90).transpose(Image.FLIP_LEFT_RIGHT),
-                            8: lambda x: x.transpose(Image.ROTATE_90),
-                        }
-                        im_obj = process[exif[274]](im_obj)
-                    except KeyError:
-                        pass
-
-                buf = StringIO.StringIO()
-                im_obj.save(buf, self.arnica_image[image][2])
-                buf.flush()
-                buf.seek(0)
-                cache.put(self.request, self.arnica_image[image][0], buf, filename=image)
-                buf.close()
-
-            if not cache.exists(self.request, self.arnica_image[image][1]):
-                try:
-                    im_obj.thumbnail((int(self.thumbnail_width.strip('px')), int(self.thumbnail_width.strip('px'))), Image.ANTIALIAS)
-                except IOError:
-                    # one reason can be that the image file is truncated
-                    return
-                buf = StringIO.StringIO()
-                im_obj.save(buf, self.arnica_image[image][2])
-                buf.flush()
-                buf.seek(0)
-                cache.put(self.request, self.arnica_image[image][1], buf, filename=image)
-                buf.close()
-
     def render(self, formatter):
         """ renders thumbnails """
 
@@ -545,7 +403,6 @@
             self.request.write(self.formatter.div(0))
             self.request.write(self.formatter.div(0))
 
-        self.create_thumbnail_and_webnail_image()
         cols = min([self.columns, len(self.arnica_image)])
         if self.album:
             cols = 1
@@ -556,7 +413,7 @@
         col_count = 1
         result = []
         image_names = self.arnica_image.keys()
-        index = [self.arnica_image[img][5] for img in image_names]
+        index = [self.arnica_image[img][4] for img in image_names]
         selected_images = [image_names[int(idx)] for idx in index]
         if self.album:
             album_image = self.album_image or self.arnica_image.keys()[0] #self.high_resolution_image[0]
@@ -594,7 +451,7 @@
         dummy = '''<form action="%s" method="POST" name="dbw.form"><div><div>''' % Page(self.request, self.pagename).url(self.request)
         html = html.replace(dummy, '').replace("</div></div></form>", "")
         return html
-        
+
 
     def format(self, formatter):
         """ parser output """