Attachment 'text_x_gallery2-1.6.0-18.py'

Download

   1 # -*- coding: iso-8859-1 -*-
   2 """
   3     MoinMoin - Gallery2 parser
   4 
   5     PURPOSE:
   6         This parser is used to visualize a couple of images as a thumbnail gallery.
   7         Optional a description of an image could be added including WikiName.
   8         On default the image name and it's creation date is shown.
   9         If you click on a thumbnail you get the webnails shown. By a menue you are able to toggle between the slides.
  10 
  11     CALLING SEQUENCE:
  12       {{{
  13       #!Gallery2 [columns=columns],[filter=filter],[mode=mode],
  14                  [show_text=show_text],[show_date=show_date], [show_tools=show_tools],
  15                  [sort_by_name=sort_by_name],[sort_by_date=sort_by_date], [sort_by_alias=sort_by_alias],
  16                  [reverse_sort=reverse_sort],
  17                  [only_items=only_items],[template_itemlist=template_itemlist],
  18                  [album=album],[album_name=album_name],[front_image=front_image],
  19                  [thumbnail_width=thumbnail_width],[webnail_width=webnail_width],[text_width=text_width],
  20                  [image_for_webnail=image_for_webnail],
  21                  [sequence_name=sequence_name], [sequence_fps=sequence_fps],
  22                  [border_thick=border_thick],[renew=renew],[help=help]
  23       * [image1.jpg alias]
  24       * [image2.jpg alias]
  25       }}}
  26 
  27     KEYWORD PARAMETERS:
  28         columns:           number of columns for thumbnails
  29         filter:            regex to select images
  30         show_text:         default is 1 description is shown
  31                            any other means no description
  32         show_date:         default is 1 date info from exif header if available is shown
  33         show_tools:        default is 1 icon toolbar is show any other disables this
  34         sort_by_name:      default is 1, the images are sorted by name, but not if only_items is 1
  35         sort_by_date:      default is 0, if set to 1 the images are sorted to the modification time
  36                            if they do have all the same time then the result is random
  37         sort_by_alias      default is 0, if set to 1 and only_items set to 1 it is used to order the images by the alias name
  38         reverse_sort:      default is 0, if set to 1 the file list is reversed
  39                            any other means no description
  40         mode:              default is 1 this means description below the image
  41                            any other number means description right of image
  42         only_items:        default is 0 if it is set to 1 only images which are described in listitem are shown
  43                            dependend on the order of the items
  44         template_itemlist: default is 0, if set to 1 an item list is shown which could be copied into the script. 
  45         album:             default is 0 if set to 1 only the first image of a series is shown but slideshow over all images 
  46         album_name:        useful for album. default is 'album' use it as short name for the album. 
  47         front_image:       Useful for album.  default is ''. The first image is shown in front of the album and slideshow.
  48                            If set to an existing image name this is shown in front of album and slideshow. 
  49                            The slide show could start by this somewhere.
  50         border_thick:      default is 1 this is the thickness in pixeln of the outer frame
  51         renew:             default is 0 if set to 1 then all selected thumbnails_* and webnails_* removed.
  52                            Afterwards they are new created.
  53         thumbnail_width:   default is 128
  54         webnail_width:     default is 640
  55         text_width:        default is 140		   
  56         image_for_webnail  default is 0 if set to 1 then the image is shown as preview and not the webnail
  57         sequence_name:     default is ''  if set this name is used for an image
  58                            sequence with an duration of one image per second.
  59         sequence_fps:      (frames per second) default is 1 it is not allowed to set values below 1
  60         help:              default is 0 if set a copy of the CALLING SEQUENCE is shown, 
  61                            (there are some new ideas around to show help to an user so this will be later replaced)
  62                            
  63 
  64     OPTIONAL INPUTS:
  65         itemlist : if it is used and only_items is 1 then only the images in this list are ahown.
  66                    The alias text is used as description of the image instead of the file name
  67 
  68 
  69     EXAMPLE:
  70 = GalleryTest =
  71 
  72 == all images shown, one is decribed ==
  73 {{{
  74 { { {
  75 #!Gallery2
  76 * [100_1185.JPG Bremen, SpaceCenter]
  77 } } }
  78 }}}
  79 
  80 Result: [[BR]]
  81  {{{
  82 #!Gallery2
  83 * [100_1185.JPG Bremen, SpaceCenter]
  84 }}}
  85 
  86 == only thumbnails and only_items ==
  87 {{{
  88 { { {
  89 #!Gallery2 show_text=0,show_tools=0,show_date=0,columns=2,only_items=1
  90  * [100_1185.JPG Bremen, SpaceCenter]
  91  * [100_1194.JPG Bremen]
  92 } } }
  93 }}}
  94 
  95 Result: [[BR]]
  96  {{{
  97 #!Gallery2 show_text=0,show_tools=0,show_date=0,columns=2,only_items=1
  98  * [100_1185.JPG Bremen, SpaceCenter]
  99  * [100_1194.JPG Bremen]
 100 }}}
 101 
 102 == only_items by two columns and text right ==
 103 
 104 {{{
 105 { { {
 106 #!Gallery2 mode=2,columns=2,only_items=1
 107  * [100_1185.JPG Bremen, SpaceCenter]
 108  * [100_1194.JPG Bremen]
 109 } } }
 110 }}}
 111 
 112 Result: [[BR]]
 113  {{{
 114 #!Gallery2 mode=2,columns=2,only_items=1
 115  * [100_1185.JPG Bremen, SpaceCenter]
 116  * [100_1194.JPG Bremen, behind SpaceCenter]
 117 }}}
 118 
 119 ----
 120 
 121 == only_items by two columns, date supressed ==
 122 
 123 {{{
 124 { { {
 125 #!Gallery2 columns=2,only_items=1,show_date=0
 126  * [100_1185.JPG Bremen, SpaceCenter]
 127  * [100_1194.JPG Bremen, behind SpaceCenter]
 128 } } }
 129 }}}
 130 
 131 Result: [[BR]]
 132  {{{
 133 #!Gallery2 columns=2,only_items=1,show_date=0
 134  * [100_1185.JPG Bremen, SpaceCenter]
 135  * [100_1194.JPG Bremen, behind SpaceCenter]
 136 }}}
 137 
 138 
 139 == filter regex used, mode 2, icons and date supressed, one column and border_thick=5 ==
 140 {{{
 141 { { {
 142 #!Gallery2 columns=1,filter=100_118[0-5],mode=2,show_date=0,show_tools=0,border_thick=5
 143 } } }
 144 }}}
 145 
 146 Result: [[BR]]
 147  {{{
 148 #!Gallery2 columns=1,filter=100_118[0-7],mode=2,show_date=0,show_tools=0,border_thick=5
 149 }}}
 150 
 151 == other macro calls ==
 152 {{{
 153 { { {
 154 #!Gallery2 only_items=1,show_date=0
 155  * [100_1189.JPG [[MiniPage(||Bremen||SpaceCenter||\n|| ||SpaceJump||)]]]
 156 } } }
 157 }}}
 158 
 159 Result: [[BR]]
 160  {{{
 161 #!Gallery2 only_items=1,show_date=0
 162  * [100_1189.JPG [[MiniPage(||Bremen||SpaceCenter||\n|| ||SpaceJump||)]]]
 163 }}}
 164 
 165 == renew means always new thumbnails and webnails of selection ==
 166 {{{
 167 { { {
 168 #!Gallery2 only_items=1,show_date=0,show_tools=0,renew=1
 169  * [100_1189.JPG [[MiniPage(||["Bremen"]||SpaceCenter||\n|| ||SpaceJump||)]]]
 170 } } }
 171 }}}
 172 
 173 Result: [[BR]]
 174  {{{
 175 #!Gallery2 only_items=1,show_date=0,renew=1
 176  * [100_1189.JPG [[MiniPage(||["Bremen"]||SpaceCenter||\n|| ||SpaceJump||)]]]
 177 }}}
 178 
 179 == template_itemlist ==
 180 {{{
 181 { { {
 182 #!Gallery2 template_itemlist=1
 183 * [100_1185.JPG Bremen, SpaceCenter]
 184 } } }
 185 }}}
 186 
 187 Result: [[BR]]
 188  {{{
 189 #!Gallery2 template_itemlist=1
 190 * [100_1185.JPG Bremen, SpaceCenter]
 191 }}}
 192 
 193 == help to show Calling Sequence ==
 194  {{{
 195 { { {
 196 #!Gallery2 help=1
 197 } } }
 198 }}}
 199 
 200 Result: [[BR]]
 201 {{{
 202 #!Gallery2 help=1
 203 }}}
 204 
 205 
 206     PROCEDURE:
 207       ABOUT:
 208       While I have first implemented Gallery2 for something like photos I do use it at work since a while for
 209       output of model calculations too.
 210       Because of the possibility to share a standalone playable file to colleagues I have first decided to use
 211       fli or mpeg as output format for an image sequence. mpeg is not quite good for displaying our data
 212       and fli does sometimes eat a lot of cpu power. Both would make a lot of work getting them working
 213       on a non posix OS. For further development it would be better to have a python only version of Gallery2.
 214       That's the reason why I switch the sequence format to flash now. I do use the library of Matthias Kramm
 215       (http://www.swftools.org).
 216       
 217       HOWTO:
 218       Download some images to a page and start with the examples.
 219       Aliasing of the filenames are done by adding an itemlist, see example.
 220 
 221       NEEDS:
 222       This routine requires the Action macro gallery2image which is used to rotate or delete a
 223       selected image. The actual version is gallery2image-1.5.4-13.py.
 224       Only users which have the rights to delete are able to execute this action macro. 
 225       The icons of these are only shown if you have enough rights. 
 226       Furthermore it requires:
 227        * the PIL (Python Imaging Library).
 228        * the EXIF routine from http://home.cfl.rr.com/genecash/digital_camera.html
 229          (you need a modifed version you'll get it from the Gallery2 documentation page)
 230        * the SWF library from http://www.swftools.org
 231 
 232       Do install them to the usual python library path.
 233       
 234       REQUIRED IMAGES:
 235       You have to put them into wiki/mg/ dir. e.g.: http://moinmoin.wikiwikiweb.de/ParserMarket/Gallery2/ModernImages
 236       
 237       GENERAL:
 238       Please remove the Version number from the code!
 239 
 240       If you want to upload many files at once please look on MoinMoin versions less 1.5.0
 241       at FeatureRequests/UploadMultipleAttachmentFiles/RulesForUnzip
 242       
 243       With many images you can get in trouble by the SurgeProtection for attachment. Then you have to adjust the parameters see HelpOnConfiguration/SurgeProtection. 
 244       
 245       RESTRICTIONS:
 246       If you rotate an image at the moment the exif is destroyed. PIL ignores the exif header.
 247       This is not a quite big problem normally files with an EXIF header are right rotated.
 248       
 249       HISTORY:
 250       While recognizing how to write MiniPage I got the idea to write a Gallery Parser.
 251       We have used in our wikis in the past the Gallery macro of SimonRyan.
 252       I have tried to modify it a bit to change it for 1.3 but my python skills weren't enough
 253       or it was easier to write it completly new.
 254       So this one shows now a way how a Gallery could be used by the parser and an action Macro.
 255       Probably it is a good example for others who like to know how to do this
 256 
 257       OUTLOOK:
 258       Dependent on Matthias Kramm's python interface development the webnails could be exchanged to a
 259       flash animation with action controls. That will ommit the javascript slide show and will give less files.
 260       swftools is able to do this by now but that will need an os.system call. At the moment I like to avoid this.
 261       If you are interested the command is swfcombine -o output.swf movie_control.swf viewport=input.swf.
 262       It is still in the code but commented off. movie_control.swf embbeds the controls 24 pixels above the flash so it's a good idea to resize the flash by the -X and -Y option.
 263 
 264     MODIFICATION HISTORY:
 265         Version 1.3.3.-1
 266         @copyright: 2005 by Reimar Bauer (R.Bauer@fz-juelich.de)
 267         @license: GNU GPL, see COPYING for details.
 268         2005-03-26: Version 1.3.3-2 keyword renew added
 269                     creation of thumbnails and webnails in two calls splitted
 270                     Version 1.3.3-3 bug fixed if itemlist is given to describe only some of the images
 271                                     but only_items is not set to 1
 272                                     Example code changed
 273         2005-03-27: Version 1.3.3-4 Action macro added and the form to call it. User which have rights to delete
 274                                     could use the functions of gallery2Image.
 275         2005-08-03: Version 1.3.3-5 theme path for icons corrected and a platform independent path joining
 276                                     os.unlink removed as suggested by CraigJohnson
 277                                     sort_by_name is default if not only_items is 1
 278                                     optional sort_by_date could be used
 279                                     keyword template_itemlist added 
 280                                     keyword help added
 281                                     extra frame by mode=2 removed 
 282         2005-08-06: Version 1.3.5-6 slideshow mode added
 283                                     keyword image_for_webnail added
 284         2005-08-13: Version 1.3.5-7 syntax changed from GET to POST
 285                                     forms instead of links
 286                                     filenames from images submitted to gallery2image too
 287                                     new keyword sort_by_alias
 288                                     internal code clean up
 289                                     this version needs: gallery2image-1.3.5-5.py
 290         2005-08-14: Version 1.3.5-8 (TW) cleanup                                    
 291         2005-08-14: Version 1.3.5-9 html code for tables changed
 292                                     because of the ugly extra space of form elements
 293                                     div tag removed so now we use the page style
 294                                     slide show action goes to right webnail now
 295                                     this version needs: gallery2image-1.3.5-5.py
 296        2005-08-17: Version 1.3.5-10 html code separated in functions     
 297                                     structure of code changed, now you see the thumbnails after creation
 298                                     bug removed if quote is given but file does not exist
 299        2005-09-02: Version 1.3.5-11 keyword album, album_name and front_image added          
 300                                     image urls changed to complete server url      
 301        2005-11-12: Version 1.3.5-12 bug fixed for image_for_webnail=1            
 302                                     bug fixed at last cell table end tr instead of td
 303                                     bug fixed don't render a filename as WikiName
 304                                     bug fixed " is allowed in alias name
 305                                     bug fixed ' is allowed in alias name
 306                                     bug fixed linebreak by a space in alias  
 307                                     not quite a bug but makes it very difficult to code in 
 308                                     gallery2image so additional id removed in alias name
 309       2005-11-17: Version 1.3.5-13  implementation of sequence video clips at first step for posix only 
 310                                     sequence_type could be used to ommit the autoselection
 311                                     fli/flc files are used for gif and png files,  mpeg files for
 312                                     jpeg files. Duration on both is 1 image/second 
 313                                     feature added of recognising the right url pattern (http opr https)
 314       
 315  
 316                                     
 317      Version 1.5.4-16 2006-08-02 based on 1.3.5-13                    
 318      FlorianFesti: major changes    more flexible but better aligned layout
 319                                     better support for border_width=0              
 320                                     use of cfg.url_prefix insted of hard coding /wiki
 321                                          
 322      ReimarBauer:                   PEP8 style
 323                                     mode2 changed to Florians style too
 324                                     some other changes to get things compatible to previous versions
 325                                     flash (swf) format is used as sequence format
 326                                     keyword sequence_fps added
 327                                     keyword eo_info added
 328                                     EXIF.py moved to python lib 
 329                                        used the version of StigIversen
 330                                        
 331                                     file names of webnails and thumbnails does now have a prefix of tmp.   
 332                                     direct serving of webnails and thumbnails is possible but not default
 333                                        You have to set the var document_root in your wikiconfig.py to the absolute path of
 334                                        the wiki alias. For the default installation it is document_root = '/usr/share/moin/htdocs'
 335                                        Using this method MoinMoin can't use acls for the webnails and thumbnails.
 336 
 337     2006-08-11 1.6.0-17 RB ported to 1.6.0 dev alpha version
 338     2006-08-22 1.6.0-18 RB for the call of Frame a test if parameters are submitted is added
 339                                        
 340                                    
 341 """
 342 Dependencies = ['time'] # do not cache
 343 
 344 from MoinMoin.action import AttachFile
 345 from MoinMoin import wikiutil, config
 346 from MoinMoin.Page import Page
 347 
 348 import os, re, sys, Image, StringIO, codecs
 349 from random import randint
 350 
 351 try:
 352     import EXIF
 353 except ImportError:
 354     EXIF = None
 355 
 356 try:
 357     import SWF
 358 except ImportError:
 359     SWF = None
 360 
 361 
 362 from MoinMoin.parser import text_moin_wiki
 363 
 364 class Parser:
 365     extensions = '*'
 366     def __init__(self, raw, request, **kw):
 367         self.sort_by_date = '0'
 368         self.sort_by_name = '1'
 369         self.sort_by_alias = '0'
 370         self.album = '0'
 371         self.album_name = 'album'
 372         self.front_image = ''
 373         self.template_itemlist = '0'
 374         self.reverse_sort = '0'
 375         self.border_thick = '1'
 376         self.columns = '4'
 377         self.filter = '.'
 378         self.mode = '1'
 379         self.help = '0'
 380         self.show_text = '1'
 381         self.show_date = '1'
 382         self.show_tools = '1'
 383         self.only_items = '0'
 384         self.image_for_webnail = '0'
 385         self.renew = '0'
 386         self.thumbnail_width = '128'
 387         self.webnail_width = '640'
 388         self.text_width = '140'
 389         self.sequence_name = ''
 390         self.sequence_fps = '1'
 391         self.eo_info = '0'
 392         
 393         
 394         test = kw.get('format_args', '')
 395         if test:
 396             for arg in kw.get('format_args', '').split(','):
 397                 if arg.find('=') > -1:
 398                     key, value = arg.split('=')
 399                     setattr(self, key, wikiutil.escape(value.strip(), quote=1))
 400 
 401         self.width = str(int(self.thumbnail_width) +
 402                          int(self.text_width))
 403 
 404         self.raw = raw
 405         self.request = request
 406         self.form = request.form
 407         self._ = request.getText
 408 
 409         self.outer_table_style = ' border="%s"' % self.border_thick
 410         self.inner_table_style = ' style="border-style:none; margin:10px;"'
 411         self.td_style = ' align="center" style="padding:0; margin:2px 2px; border-style:none"'
 412 
 413     def images2swf(request, images, swf_filename, swf_fps, description, exif_date):
 414     ## this code is based on
 415     ## http://www.quiss.org/swftools/python/jpeg2swf_exif.py
 416     ## by Matthias Kramm
 417     ##
 418     ## Thanks Matthias
 419 
 420         xmax, ymax = 0, 0
 421         depth = 1
 422         SWF.verbose(0)
 423         # verbose is not used everybody
 424         swf = SWF.create(version=6, bbox=(0, 0, 0, 0), fps=float(swf_fps))
 425 
 426         i = 0
 427         for filename in images:
 428             pic = Image.open(filename)
 429             pic.load()
 430 
 431             width, height = pic.size
 432             if width > xmax: xmax = width
 433             if height > ymax: ymax = height
 434 
 435             pic = pic.convert("RGBA")
 436             image = SWF.Image(pic.im)
 437 
 438             swf.tags += image
 439             shape = SWF.ImageShape(image)
 440             swf.tags += shape
 441             swf.tags += SWF.PlaceObject(shape, depth=depth)
 442             depth += 1
 443             swf.tags += SWF.ShowFrame()
 444 
 445             i += 1
 446 
 447         swf.bbox = (0, 0, xmax, ymax)
 448         swf.save(swf_filename)
 449 
 450         return xmax, ymax
 451 
 452     def show_tools_restricted(self, this_target):
 453         if not self.request.user.may.delete(self.pagename):
 454             return ''
 455 
 456         return '''
 457         <form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data">
 458           <td%(style)s>
 459             <input type="hidden" name="action" value="gallery2image">
 460             <input type="hidden" name="do" value="RL">
 461             <input type="hidden" name="target" value="%(this_target)s">
 462             <input type="image" value="submit" src="%(htdocs)s/img/to_right.png" title="rotate to left">
 463           </td>
 464         </form>
 465         <form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data">
 466           <td%(style)s>
 467             <input type="hidden" name="action" value="gallery2image">
 468             <input type="hidden" name="do" value="RR">
 469             <input type="hidden" name="target" value="%(this_target)s">
 470             <input type="image"  value="submit" src="%(htdocs)s/img/to_left.png" title="rotate to right" >
 471           </td>
 472         </form>
 473         <form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data">
 474           <td%(style)s>
 475             <input type="hidden" name="action" value="gallery2image">
 476             <input type="hidden" name="do" value="RM">
 477             <input type="hidden" name="target" value="%(this_target)s">
 478             <input type="image" value="submit" src="%(htdocs)s/img/to_bak.png" title="move to bak" >
 479            </td>
 480         </form>''' % {
 481             'baseurl': self.request.getBaseURL(),
 482             'style': self.td_style,
 483             'htdocs': self.request.cfg.url_prefix,
 484             "pagename": self.quoted_pagename,
 485             "this_target": this_target}
 486 
 487     def tools_html(self, idx):
 488         this_image = self.full[idx]
 489 
 490         text = '''
 491             <TABLE align="center" width="%(thumbnail_width)s"%(tablestyle)s>
 492                 <TR>
 493                     <form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data">
 494                         <td%(style)s>
 495                             <input type="hidden" name="action" value="AttachFile">
 496                             <input type="hidden" name="do" value="get">
 497                             <input type="hidden" name="target" value='%(this_target)s'>
 498                             <input type="image" value="submit" src="%(htdocs)s/img/to_full.png" title="load image">
 499                         </td>
 500                     </form>
 501                     <form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data">
 502                         <td%(style)s>
 503                             <input type="hidden" name="action" value="gallery2image">
 504                             <input type="hidden" name="do" value="VS">
 505                             <input type="hidden" name="full" value='%(full)s'>
 506                             <input type="hidden" name="alias" value='%(description)s'>
 507                             <input type="hidden" name="target" value='%(target)s'>
 508                             <input type="hidden" name="exif_date" value='%(exif_date)s'>
 509                             <input type="image" value="submit" src="%(htdocs)s/img/to_slide.png" title="slide_show" >
 510                        </td>
 511                     </form>
 512                     %(show_tools_restricted)s
 513                 </TR>
 514             </TABLE>'''   % {
 515             "baseurl": self.request.getScriptname(),
 516             "pagename": self.quoted_pagename,
 517             "htdocs": self.request.cfg.url_prefix,
 518             "tablestyle": self.inner_table_style,
 519             "style": self.td_style,
 520             "thumbnail_width": self.thumbnail_width,
 521             "full": self.full[idx] + ',' + ','.join(self.full),
 522             "description": self.description[idx] + '!,!' + '!,!'.join(self.description),
 523             "exif_date": self.to_htmltext(self.exif_date[idx] + ',' +
 524                                          ','.join(self.exif_date)),
 525             "target": self.webimg[idx] + ',' + ','.join(self.webimg),
 526             "this_target": self.full[idx],
 527             "thumbnail": "%s%s" % (self.static_url, self.thumb[idx]),
 528             "show_tools_restricted":self.show_tools_restricted(this_image)
 529             }
 530 
 531         return text
 532 
 533     def show_alias_mode2(self, idx):
 534        if self.show_text == '1':
 535            return '''
 536             <td valign="top" width="%(text_width)s" %(style)s>
 537            %(this_alias)s
 538         </td>''' % {
 539         "this_alias":self.description[idx],
 540         "text_width":self.text_width,
 541         "style": ' align="left" style="padding:0px; margin:2px 2px; border-style:none"'}
 542        else:
 543           return ''
 544 
 545     def show_date_mode2(self, idx):
 546        if self.show_date == '1':
 547            return '''
 548                   <td%(style)s><p>%(this_exif_date)s</p></td>''' % {
 549                   "style": self.td_style,
 550                   "this_exif_date": self.to_htmltext(self.exif_date[idx]) }
 551        else:
 552             return ''
 553 
 554     def show_tools_mode2(self, idx):
 555         if self.show_tools == '1':
 556             return "<td align=""center""%(style)s> %(tools)s </td>" % {
 557                 "style":self.td_style,
 558                 "tools":self.tools_html(idx)}
 559         else:
 560             return ''
 561 
 562     def mode2_html(self, idx):
 563         text = '''
 564         <tr valign="center">
 565         <form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data">
 566             <td align="center" valign="center" width="%(thumbnail_width)s"
 567             %(tdstyle)s>
 568                 <input type="hidden" name="action" value="gallery2image">
 569                 <input type="hidden" name="do" value="VS">
 570                 <input type="hidden" name="full" value='%(full)s'>
 571                 <input type="hidden" name="alias" value='%(description)s'>
 572                 <input type="hidden" name="exif_date" value='%(exif_date)s'>
 573                 <input type="hidden" name="target" value='%(target)s'>
 574                 <input type="image" value="submit" src="%(thumbnail)s">
 575             </td>
 576         </form>
 577             %(alias_html)s 
 578     </tr>
 579     <tr>%(tools_html)s%(date_html)s</tr>''' % {
 580      "tdstyle": self.td_style,
 581      "baseurl": self.request.getScriptname(),
 582      "pagename": self.quoted_pagename,
 583      "thumbnail_width": self.thumbnail_width,
 584      "full": self.full[idx] + ',' + ','.join(self.full),
 585      "description": self.description[idx] + '!,!' + '!,!'.join(self.description),
 586      "exif_date": self.to_htmltext(self.exif_date[idx] + ',' +
 587                                   ','.join(self.exif_date)),
 588      "target": self.webimg[idx] + ',' + ','.join(self.webimg),
 589      "thumbnail": "%s%s" % (self.static_url, self.thumb[idx]),
 590      "tools_html": self.show_tools_mode2(idx),
 591      "date_html": self.show_date_mode2(idx),
 592      "alias_html": self.show_alias_mode2(idx)
 593      }
 594 
 595         return text
 596 
 597     def show_tools_mode1(self, idx):
 598         if self.show_tools == '1':
 599             text = "<tr><td align=""center""%(style)s>%(tools)s </td></tr>" % {
 600                 "style":self.td_style,
 601                 "tools":self.tools_html(idx)}
 602         else:
 603             text = ''
 604         return text
 605 
 606     def show_date_mode1(self, idx):
 607        if self.show_date == '1':
 608            return '''
 609         <TR>
 610         <td%(style)s>%(this_exif_date)s</td>
 611     </TR>''' % {
 612     "style":self.td_style,
 613     "this_exif_date": self.to_htmltext(self.exif_date[idx])}
 614        else:
 615            return ''
 616 
 617     def show_alias_mode1(self, idx):
 618        if self.show_text == '1':
 619            return '''
 620         <TR>
 621         <td width="%(thumbnail_width)s" %(style)s> %(this_alias)s</td>
 622     </TR>''' % {
 623     "thumbnail_width": self.thumbnail_width,
 624     "style": ' align="left" style="padding:0em; margin:2px 2px; border-style:none"',
 625     "this_alias": self.description[idx]}
 626        else:
 627            return ''
 628 
 629     def mode1_html(self, idx):
 630         text = '''
 631     <table width="%(thumbnail_width)s" align="center" valign="center"%(style)s>
 632     <TR align="center" valign="center">
 633         <form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data">
 634             <td align="center" valign="middle" width="%(thumbnail_width)s"
 635             %(tdstyle)s>
 636                 <input type="hidden" name="action" value="gallery2image">
 637                 <input type="hidden" name="do" value="VS">
 638                 <input type="hidden" name="full" value='%(full)s'>
 639                 <input type="hidden" name="alias" value='%(description)s'>
 640                 <input type="hidden" name="exif_date" value='%(exif_date)s'>
 641                 <input type="hidden" name="target" value='%(target)s'>
 642                 <input type="image" value="submit" src="%(thumbnail)s" >
 643             </td>
 644         </form>
 645     </TR>
 646       %(alias_html)s
 647       %(date_html)s
 648       %(tools_html)s
 649 </table>'''%       {
 650      "tdstyle": self.td_style,
 651      "style": self.inner_table_style,
 652      "baseurl": self.request.getScriptname(),
 653      "pagename": self.quoted_pagename,
 654      "full": self.full[idx] + ',' + ','.join(self.full),
 655      "description": self.description[idx] + '!,!' + '!,!'.join(self.description),
 656      "exif_date": self.to_htmltext(self.exif_date[idx] + ',' +
 657                                   ','.join(self.exif_date)),
 658      "target": self.webimg[idx] + ',' + ','.join(self.webimg),
 659      "thumbnail": "%s%s" % (self.static_url, self.thumb[idx]),
 660      "thumbnail_width": self.thumbnail_width,
 661      "tools_html": self.show_tools_mode1(idx),
 662      "date_html": self.show_date_mode1(idx),
 663      "alias_html": self.show_alias_mode1(idx)
 664      }
 665 
 666         return text
 667 
 668     def get_files(self, path, files, quotes):
 669         self.web = []
 670         self.full = []
 671         self.thumb = []
 672         self.exif_date = []
 673         self.imgtype = []
 674         self.description = []
 675 
 676         ddict = {}
 677         n = len(quotes['image'])
 678         if n > 0:
 679             i = 0
 680             for txt in quotes['image']:
 681                 ddict[txt] = quotes['alias'][i]
 682                 i += 1
 683 
 684         self.video_type = 'swf'
 685         self.source_type = ''
 686         for attfile in files:
 687             # only files not thumb or webnails
 688             if not attfile.startswith('tmp.') and attfile.find('thumbnail_') == -1 and attfile.find('webnail_') == -1:
 689             #previous naming left for compatibility
 690                 # only images
 691                 if wikiutil.isPicture(attfile):
 692                     self.description.append(ddict.get(attfile, attfile))
 693                     self.full.append(attfile)
 694 
 695                     fname, ext = os.path.splitext(attfile)
 696                     if ext in ('.gif', '.png'):
 697                         self.imgtype.append('PNG')
 698                         webnail = 'tmp.webnail_%s.png' % fname
 699                         thumbfile = 'tmp.thumbnail_%s.png' % fname
 700                         video_type = 'swf'
 701                         source_type = ext[1:]
 702                     else:
 703                         self.imgtype.append("JPEG")
 704                         webnail = 'tmp.webnail_%s.jpg' % fname
 705                         thumbfile = 'tmp.thumbnail_%s.jpg' % fname
 706                         video_type = 'swf'
 707                         source_type = 'jpg'
 708 
 709                     infile = os.path.join(path, attfile)
 710                     if os.path.exists(infile):
 711                          self.web.append(webnail)
 712                          self.thumb.append(thumbfile)
 713 
 714 
 715                     f = open(infile, 'rb')
 716                     tags = EXIF.process_file(f, 'DateTimeOriginal')
 717                     f.close()
 718                     if tags.has_key('EXIF DateTimeOriginal'):
 719                         date = str(tags['EXIF DateTimeOriginal'])
 720                         date = date.replace(':', '-', 2)
 721                     else:
 722                         date = '--'
 723 
 724                     self.exif_date.append(date)
 725 
 726 
 727     def to_htmltext(self, text):
 728         if text.find ("'"):
 729             text = text.split("'")
 730             text = '&#39;'.join(text)
 731         return text
 732 
 733     def to_wikiname(self, formatter, text):
 734         ##taken from MiniPage
 735         out = StringIO.StringIO()
 736         self.request.redirect(out)
 737         wikiizer = text_moin_wiki.Parser(text.strip(), self.request)
 738         wikiizer.format(formatter)
 739         result = out.getvalue()
 740         self.request.redirect()
 741         del out
 742 
 743         result = result.replace('<a id="line-1"></a>', '')
 744         result = result.replace('<p>', '')
 745         result = result.replace('</p>', '')
 746         result = result.strip()
 747         return result
 748 
 749 
 750     def get_quotes(self, formatter):
 751         quotes = self.raw.split('\n')
 752         quotes = [quote.strip() for quote in quotes]
 753         quotes = [quote[2:] for quote in quotes if quote.startswith('* ')]
 754 
 755         image = []
 756         text = []
 757 
 758         for line in quotes:
 759             im, na = line[1:-1].split(' ', 1)
 760             na = na.strip()
 761             na = self.to_htmltext(na)
 762             na = self.to_wikiname(formatter, na)
 763             text.append(na)
 764             image.append(im.strip())
 765 
 766         return {
 767             'alias': text,
 768             'image': image,
 769         }
 770 
 771     def print_help(self):
 772         self.request.write('''
 773 <br>
 774 {{{<br>
 775 #!Gallery2 [columns=columns],[filter=filter],[mode=mode],<br>
 776            [show_text=show_text],[show_date=show_date], [show_tools=show_tools],<br>
 777            [sort_by_name=sort_by_name],[sort_by_date=sort_by_date],[sort_by_alias=sort_by_alias]<br>
 778            [reverse_sort=reverse_sort],<br>
 779            [only_items=only_items],[template_itemlist=template_itemlist],<br>
 780            [album=album],[album_name=album_name],[front_image=front_image],<br>
 781            [thumbnail_width=thumbnail_width],[webnail_width=webnail_width],[text_width=text_width],<br>
 782            [image_for_webnail=image_for_webnail],<br>
 783            [sequence_name=sequence_name],[sequence_fps=sequence_fps]<br>
 784            [border_thick=border_thick],[renew=renew],[help=help]<br>
 785  * [image1.jpg alias]<br>
 786  * [image2.jpg alias]<br>
 787 }}}<br>''')
 788 
 789     def format(self, formatter):
 790         if self.help == '1':
 791             self.print_help()
 792             return
 793         Dict = {}
 794         quotes = self.get_quotes(formatter)
 795         current_pagename = formatter.page.page_name
 796         self.pagename = current_pagename
 797         self.quoted_pagename = wikiutil.quoteWikinameURL(self.pagename)
 798         attachment_path = AttachFile.getAttachDir(self.request, current_pagename, create=1)
 799 
 800         if hasattr(self.request.cfg, 'document_root'):
 801 
 802             self.static_path = "%(dir)s/tmp/Gallery2%(wiki_name)s/%(pagename)s" % {
 803                  "wiki_name": self.request.getScriptname(),
 804                  "pagename": self.pagename,
 805                  "dir": self.request.cfg.document_root,
 806                  }
 807             if os.path.exists(self.static_path) == 0:
 808                  os.makedirs(self.static_path)
 809 
 810             self.static_url = "%(prefix)s/tmp/Gallery2%(wiki_name)s/%(pagename)s/" % {
 811                  "prefix": self.request.cfg.url_prefix,
 812                  "wiki_name": self.request.getScriptname(),
 813                  "pagename": self.pagename,
 814                  }
 815         else:
 816             self.static_path = attachment_path
 817             self.static_url = AttachFile.getAttachUrl(self.pagename, '', self.request)
 818 
 819 
 820         if self.only_items == '1':
 821             all_files = quotes['image']
 822             result = []
 823             for attfile in all_files:
 824                 infile = os.path.join(attachment_path, attfile)
 825                 if os.path.exists(infile):
 826                    result.append(attfile)
 827             all_files = result
 828 
 829             if self.sort_by_alias == '1':
 830                 new_ordered_files = []
 831                 alias_text = quotes['alias']
 832 
 833                 i = 0
 834                 for attfile in all_files:
 835                     infile = os.path.join(attachment_path, attfile)
 836                     Dict[alias_text[i]] = attfile
 837                     i += 1
 838 
 839                 keys = Dict.keys()
 840                 keys.sort()
 841                 for txt in keys:
 842                     new_ordered_files.append(Dict[txt])
 843 
 844                 all_files = new_ordered_files
 845                 Dict.clear()
 846 
 847         else:
 848             all_files = os.listdir(attachment_path)
 849 
 850 
 851         if self.filter != '.':
 852             result = []
 853             for test in all_files:
 854                 if re.match(self.filter, test):
 855                   result.append(test)
 856 
 857             all_files = result
 858 
 859         if not all_files:
 860             self.request.write("<br><br><h1>No matching image file found!</h1>")
 861             return
 862 
 863         if self.sort_by_name == '1' and self.only_items == '0':
 864             all_files.sort()
 865 
 866         if self.sort_by_date == '1':
 867            for attfile in all_files:
 868                infile = os.path.join(attachment_path, attfile)
 869                ft_file = "%s%s" % (str(os.path.getmtime(infile)), str(randint(0, 65535)))
 870                Dict[ft_file] = attfile
 871 
 872            keys = Dict.keys()
 873            keys.sort()
 874            file_mdate = []
 875            for txt in keys:
 876                file_mdate.append(Dict[txt])
 877            all_files = file_mdate
 878            Dict.clear()
 879 
 880         if self.reverse_sort == '1':
 881              all_files.reverse()
 882 
 883         cells = []
 884         cell_name = []
 885         img = []
 886 
 887         self.get_files(attachment_path, all_files, quotes)
 888 
 889         if self.template_itemlist == '1':
 890             self.request.write('Copy the following listitems into the script. Replace alias with the label you want. Afterwards disable template_itemlist by setting it to 0:<BR>')
 891             for attfile in self.full:
 892                 self.request.write(' * [%(attfile)s %(date)s]<br>\n' % {
 893                                    'attfile': attfile,
 894                                    'date': 'alias'
 895                                     })
 896 
 897         i = 0
 898         z = 1
 899         cols = int(self.columns)
 900 
 901         n = len(self.full)
 902         if  self.album == '0':
 903             self.request.write("<table%s>" % self.outer_table_style)
 904             if self.mode == '1' or cols > 1:
 905                 self.request.write('<TR valign="top">')
 906                 self.request.write('<TD%s>' % self.td_style)
 907 
 908 
 909         if self.album == '1':
 910             if self.front_image == '':
 911                 front_image = self.full[0]
 912             else:
 913                 front_image = self.front_image
 914             ii = 0
 915             for tst in self.full:
 916                 if tst == front_image:
 917                     break
 918                 ii += 1
 919 
 920         for attfile in self.full:
 921             if  self.album == '1':
 922                 if tst == front_image:
 923                    i = ii
 924 
 925             this_description = self.description[i]
 926             this_exif_date = self.exif_date[i]
 927             this_webnail = self.web[i]
 928             this_imgtype = self.imgtype[i]
 929             this_thumbfile = self.thumb[i]
 930 
 931             thumbf = os.path.join(self.static_path, this_thumbfile)
 932             webf = os.path.join(self.static_path, this_webnail)
 933 
 934             if self.renew == '1':
 935                 if os.path.exists(thumbf):
 936                    os.unlink(thumbf)
 937                 if os.path.exists(webf):
 938                    os.unlink(webf)
 939 
 940             if not os.path.exists(webf) or not os.path.exists(thumbf):
 941                 infile = os.path.join(attachment_path, attfile)
 942                 im = Image.open(infile)
 943 
 944                 if not os.path.exists(webf):
 945                     im.thumbnail((int(self.webnail_width), int(self.webnail_width)), Image.ANTIALIAS)
 946                     if self.image_for_webnail == '1':
 947                        os.link(os.path.join(attachment_path, attfile), webf)
 948                     else:
 949                        im.save(webf, this_imgtype)
 950                 if not os.path.exists(thumbf):
 951                     im.thumbnail(((int(self.thumbnail_width)), ((int(self.thumbnail_width)))),
 952                                    Image.ANTIALIAS)
 953                     im.save(thumbf, this_imgtype)
 954 
 955             if self.image_for_webnail == '1':
 956                  this_webnailimg = attfile
 957                  self.webimg = self.full
 958             else:
 959                  this_webnailimg = this_webnail
 960                  self.webimg = self.web
 961 
 962             if self.mode == '1':
 963                 text = self.mode1_html(i)
 964                 self.request.write(''.join(text))
 965 
 966             if self.mode == '2':
 967                 text = self.mode2_html(i)
 968                 if cols > 1: self.request.write('<table valign="bottom">')
 969                 self.request.write(''.join(text))
 970                 if cols > 1: self.request.write('</table>')
 971 
 972             if self.mode == '1' or cols > 1:
 973                 if self.album == '0':
 974                     if  z < cols:
 975                         self.request.write('</TD>')
 976                         if z < n and  i < n - 1:
 977                             self.request.write('<TD%s>' % self.td_style)
 978                         if i == n - 1:
 979                             self.request.write('</TR>')
 980                     else:
 981                         self.request.write('</TD>')
 982                         self.request.write('</TR>')
 983                         if i < n - 1:
 984                             self.request.write('<TR valign="top">')
 985                             self.request.write('<TD%s>' % self.td_style)
 986 
 987             i += 1
 988             z += 1
 989             if z > cols:
 990                 z = 1
 991 
 992             if self.album == '1':
 993                 self.request.write("%(n)s images (%(album_name)s)" % {"n": str(n), "album_name": self.album_name})
 994                 break
 995 
 996         if self.album == '0':
 997             if i < n:
 998                 self.request.write('</TD>')
 999                 self.request.write('</TR>')
1000             self.request.write('</table>')
1001 
1002 
1003         if self.sequence_name != '':
1004             video_file = "%(file)s.%(ext)s" % {
1005                  "file": os.path.join(attachment_path, self.sequence_name),
1006                  "ext": 'swf'}
1007             if self.renew == '1':
1008                if os.path.exists(video_file):
1009                   os.unlink(video_file)
1010 
1011             cmd = ''
1012             if float(self.sequence_fps) < 1:
1013                 fps = 1
1014             else:
1015                 fps = round(float(self.sequence_fps))
1016 
1017             f_list = []
1018             for attfile in self.web:
1019                 file = os.path.join(self.static_path, attfile)
1020                 if os.path.exists(file):
1021                    f_list.append(file)
1022 
1023             if not os.path.exists(video_file):
1024                 width, height = self.images2swf(f_list, video_file, fps, self.description, self.exif_date)
1025             else:
1026                 swf = SWF.load(video_file)
1027                 for tag in swf.tags:
1028                     if tag.isImage():
1029                        width, height = tag.image.size
1030                        break
1031 
1032             if os.path.exists(video_file):
1033                   dict = {}
1034                   dict['src'] = AttachFile.getAttachUrl(current_pagename, '%(file)s.%(videotype)s'  % {
1035                      'file': self.sequence_name,
1036                      'videotype': 'swf',
1037                      }, self.request)
1038 
1039                   image_link = '%(file)s.%(videotype)s' % {'file':self.sequence_name, 'videotype': 'swf'}
1040                   if  self.eo_info == '1':
1041                       eo = "Or embed it into your wiki page by [[EmbedObject(%(file)s,width=%(width)s,height=%(height)s)]]." % {
1042                            'file': image_link,
1043                            'width': str(width),
1044                            'height': str(height)}
1045                   else:
1046                       eo = ''
1047 
1048                   self.request.write('<P>')
1049                   text = formatter.url(1, dict['src'] ) + image_link + formatter.url(0)
1050                   self.request.write('Download this image sequence %(text)s for your archive. %(EO)s' % {
1051                        'text': text,
1052                        'EO': eo
1053                        })
1054                   self.request.write('</P>')

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2006-08-06 08:57:54, 41.8 KB) [[attachment:EXIF.py]]
  • [get | view] (2005-03-24 20:14:37, 10.6 KB) [[attachment:Gallery2-1.3.3-1.py]]
  • [get | view] (2005-03-26 08:39:13, 11.6 KB) [[attachment:Gallery2-1.3.3-2.py]]
  • [get | view] (2005-03-26 12:41:49, 13.1 KB) [[attachment:Gallery2-1.3.3-3.py]]
  • [get | view] (2005-03-27 20:23:01, 19.0 KB) [[attachment:Gallery2-1.3.3-4.py]]
  • [get | view] (2005-08-03 19:30:10, 23.2 KB) [[attachment:Gallery2-1.3.3-5.py]]
  • [get | view] (2005-08-18 07:58:38, 31.9 KB) [[attachment:Gallery2-1.3.5-10.py]]
  • [get | view] (2005-09-02 19:55:13, 34.1 KB) [[attachment:Gallery2-1.3.5-11.py]]
  • [get | view] (2005-11-13 18:09:11, 35.4 KB) [[attachment:Gallery2-1.3.5-12.py]]
  • [get | view] (2005-11-18 20:13:04, 46.2 KB) [[attachment:Gallery2-1.3.5-13.py]]
  • [get | view] (2005-12-03 15:33:06, 46.6 KB) [[attachment:Gallery2-1.3.5-14.py]]
  • [get | view] (2006-01-01 09:20:19, 43.3 KB) [[attachment:Gallery2-1.3.5-15.py]]
  • [get | view] (2005-08-07 15:46:28, 26.9 KB) [[attachment:Gallery2-1.3.5-6.py]]
  • [get | view] (2005-08-13 15:13:59, 28.7 KB) [[attachment:Gallery2-1.3.5-7.py]]
  • [get | view] (2005-08-14 13:02:00, 27.5 KB) [[attachment:Gallery2-1.3.5-8.py]]
  • [get | view] (2005-08-14 14:38:32, 28.7 KB) [[attachment:Gallery2-1.3.5-9.py]]
  • [get | view] (2006-08-06 08:45:47, 41.8 KB) [[attachment:Gallery2-1.5.4-16.py]]
  • [get | view] (2006-08-22 20:29:39, 42.0 KB) [[attachment:Gallery2-1.5.4-18.py]]
  • [get | view] (2006-08-06 08:57:36, 514.8 KB) [[attachment:example.swf]]
  • [get | view] (2005-08-17 18:10:27, 11.3 KB) [[attachment:gallery2image_test.py]]
  • [get | view] (2005-08-10 16:49:16, 1.3 KB) [[attachment:patchpullfromdir.diff]]
  • [get | view] (2006-08-17 16:32:50, 41.9 KB) [[attachment:text_x_gallery2-1.6.0-17.py]]
  • [get | view] (2006-08-22 20:23:06, 42.1 KB) [[attachment:text_x_gallery2-1.6.0-18.py]]
  • [get | view] (2008-02-06 10:08:05, 42.2 KB) [[attachment:text_x_gallery2-1.6.0-19.py]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.