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

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.