Attachment 'Gallery2-1.3.3-4.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 
  10     CALLING SEQUENCE:
  11       {{{
  12       #!Gallery2 [columns=columns],[filter=filter],[mode=mode],[show_text=show_text],
  13                  [show_date=show_date], [show_tools=show_tools],
  14                  [only_items=only_items],[border_thick=border_thick],[renew=renew]
  15       * [image1.jpg alias]
  16       * [image2.jpg alias]
  17       }}}
  18 
  19     KEYWORD PARAMETERS:
  20         columns:      number of columns for thumbnails
  21 	filter:       regex to select images
  22         show_text:    default is 1 description is shown
  23 	              any other means no description
  24 	show_date:    default is 1 date info from exif header if available is shown
  25                       any other means no description
  26 	show_tools:   default is 1 icon toolbar is show any other disables this
  27 	mode:         default is 1 this means description below the image
  28 	              any other number means description right of image
  29 	only_items:   default is 0 if it is set to 1 only images which are described in listitem are shown
  30 	border_thick: default is 1 this is the thickness in pixeln of the outer frame
  31 	renew:        default is 0 if set to 1 then all selected thumbnails_* and webnails_* removed.
  32 	              Afterwards they are new created.
  33 
  34     OPTIONAL INPUTS:
  35 	itemlist : if it is used and only_items is 1 then only the images in this list are ahown.
  36 	           The alias text is used as description of the image instead of the file name
  37 
  38 
  39     EXAMPLE:
  40 = GalleryTest =
  41 
  42 == all images shown, one is decribed ==
  43 {{{
  44 { { {
  45 #!Gallery2
  46 * [100_1185.JPG Bremen, SpaceCenter]
  47 } } }
  48 }}}
  49 
  50 Result: [[BR]]
  51  {{{
  52 #!Gallery2
  53 * [100_1185.JPG Bremen, SpaceCenter]
  54 }}}
  55 
  56 == only thumbnails and only_items ==
  57 {{{
  58 { { {
  59 #!Gallery2 show_text=0,show_tools=0,show_date=0,columns=2,only_items=1
  60  * [100_1185.JPG Bremen, SpaceCenter]
  61  * [100_1194.JPG Bremen]
  62 } } }
  63 }}}
  64 
  65 Result: [[BR]]
  66  {{{
  67 #!Gallery2 show_text=0,show_tools=0,show_date=0,columns=2,only_items=1
  68  * [100_1185.JPG Bremen, SpaceCenter]
  69  * [100_1194.JPG Bremen]
  70 }}}
  71 
  72 == only_items by two columns and text right ==
  73 
  74 {{{
  75 { { {
  76 #!Gallery2 mode=2,columns=2,only_items=1
  77  * [100_1185.JPG Bremen, SpaceCenter]
  78  * [100_1194.JPG Bremen]
  79 } } }
  80 }}}
  81 
  82 Result: [[BR]]
  83  {{{
  84 #!Gallery2 mode=2,columns=2,only_items=1
  85  * [100_1185.JPG Bremen, SpaceCenter]
  86  * [100_1194.JPG Bremen, behind SpaceCenter]
  87 }}}
  88 
  89 ----
  90 
  91 == only_items by two columns, date supressed ==
  92 
  93 {{{
  94 { { {
  95 #!Gallery2 columns=2,only_items=1,show_date=0
  96  * [100_1185.JPG Bremen, SpaceCenter]
  97  * [100_1194.JPG Bremen, behind SpaceCenter]
  98 } } }
  99 }}}
 100 
 101 Result: [[BR]]
 102  {{{
 103 #!Gallery2 columns=2,only_items=1,show_date=0
 104  * [100_1185.JPG Bremen, SpaceCenter]
 105  * [100_1194.JPG Bremen, behind SpaceCenter]
 106 }}}
 107 
 108 
 109 == filter regex used, mode 2, icons and date supressed, one column and border_thick=5 ==
 110 {{{
 111 { { {
 112 #!Gallery2 columns=1,filter=100_118[0-5],mode=2,show_date=0,show_tools=0,border_thick=5
 113 } } }
 114 }}}
 115 
 116 Result: [[BR]]
 117  {{{
 118 #!Gallery2 columns=1,filter=100_118[0-7],mode=2,show_date=0,show_tools=0,border_thick=5
 119 }}}
 120 
 121 == other macro calls ==
 122 {{{
 123 { { {
 124 #!Gallery2 only_items=1,show_date=0
 125  * [100_1189.JPG [[MiniPage(||Bremen||SpaceCenter||\n|| ||SpaceJump||)]]]
 126 } } }
 127 }}}
 128 
 129 Result: [[BR]]
 130  {{{
 131 #!Gallery2 only_items=1,show_date=0
 132  * [100_1189.JPG [[MiniPage(||Bremen||SpaceCenter||\n|| ||SpaceJump||)]]]
 133 }}}
 134 
 135 == renew means always new thumbnails and webnails of selection ==
 136 {{{
 137 { { {
 138 #!Gallery2 only_items=1,show_date=0,show_tools=0,renew=1
 139  * [100_1189.JPG [[MiniPage(||["Bremen"]||SpaceCenter||\n|| ||SpaceJump||)]]]
 140 } } }
 141 }}}
 142 
 143 Result: [[BR]]
 144  {{{
 145 #!Gallery2 only_items=1,show_date=0,renew=1
 146  * [100_1189.JPG [[MiniPage(||["Bremen"]||SpaceCenter||\n|| ||SpaceJump||)]]]
 147 }}}
 148 
 149 
 150 
 151     PROCEDURE:
 152       Download some images to a page and start with the examples.
 153       Aliasing of the filenames are done by adding an itemlist, see example.
 154 
 155       This routine requires the PIL (Python Imaging Library).
 156       And the EXIF routine from http://home.cfl.rr.com/genecash/digital_camera.html
 157 
 158 
 159       At the moment I have added the EXIF routine to the parsers dir.
 160       It's not the best place but during developing it is nice to have it there
 161       If you put it to another place you have to change the line
 162       from MoinMoin.parser import EXIF too.
 163 
 164       This routine requires the Action macro gallery2Image which is used to rotate or delete a selected image.
 165       Only users which have the rights to delete are able to execute this action macro.
 166       The icons of these are only shown if you have enough rights.
 167 
 168       The gallery2image macro does not take care on the EXIF header. This is lost by rotating.
 169       If a file is deleted by this macro it is moved to a bak file.
 170 
 171       Please remove the Version number from the code!
 172 
 173     RESTRICTIONS:
 174       The slideshow is not implemented at the moment. The implementation will be done in the acrion macro.
 175       This is not a quite big problem normally files with an EXIF header are right rotated.
 176 
 177     Required Images:
 178       I have put them to wiki/modern/img/ dir. The icons were created by me. License: GPL
 179 
 180     attachment:to_bak.png
 181     attachment:to_left.png
 182     attachment:to_right.png
 183     attachment:to_slide.png
 184     attachment:to_full.png
 185 
 186     HISTORY:
 187     While recognizing how to write MiniPage I got the idea to write a Gallery Parser.
 188     We have used in our wikis in the past the Gallery macro of SimonRyan.
 189     I have tried to modify it a bit to change it for 1.3 but my python skills weren't enough
 190     or it was easier to write it completly new.
 191     So this one shows now a way how a Gallery could be used by the parser and an action Macro.
 192     Probably it is a good example for others who like to know how to do this
 193 
 194     MODIFICATION HISTORY:
 195         Version 1.3.3.-1
 196         @copyright: 2005 by Reimar Bauer (R.Bauer@fz-juelich.de)
 197         @license: GNU GPL, see COPYING for details.
 198 	2005-03-26: Version 1.3.3-2 keyword renew added
 199 	            creation of thumnails and webnails in two calls splitted
 200                     Version 1.3.3-3 bug fixed if itemlist is given to describe only some of the images
 201 		                    but only_items is not set to 1
 202 				    Example code changed
 203         2005-03-27: Version 1.3.3-4 Action macro added and the form to call it. User which have rights to delete
 204                                     could use the functions of gallery2Image.
 205 
 206 """
 207 
 208 from MoinMoin.action import AttachFile
 209 from MoinMoin import wikiutil, config
 210 from MoinMoin.Page import Page
 211 import os,string,re,Image,StringIO
 212 from MoinMoin.parser import EXIF
 213 
 214 from MoinMoin.parser import wiki
 215 
 216 def ImageProcess(var):
 217     f=open('/tmp/workfile.txt', 'w')
 218     f.write(var)
 219     f.close()
 220 
 221 def get_quotes(self,formatter):
 222     quotes = self.raw.split('\n')
 223     quotes = [quote.strip() for quote in quotes]
 224     quotes = [quote[2:] for quote in quotes if quote.startswith('* ')]
 225 
 226     image=[]
 227     alias=[]
 228     for line in quotes:
 229         im,na=line[1:-1].split(' ',1)
 230 
 231         ##taken from MiniPage
 232 
 233         out=StringIO.StringIO()
 234         self.request.redirect(out)
 235         wikiizer = wiki.Parser(na.strip(),self.request)
 236         wikiizer.format(formatter)
 237         na=out.getvalue()
 238         self.request.redirect()
 239         del out
 240 
 241         alias.append(na)
 242         image.append(im.strip())
 243 
 244     result={}
 245     result['alias']=alias
 246     result['image']=image
 247 
 248     return(result)
 249 
 250 
 251 
 252 class Parser:
 253     def __init__(self, raw, request, **kw):
 254         self.raw = raw
 255         self.request = request
 256         self.form = request.form
 257         self._ = request.getText
 258         self.kw = {}
 259         self.kw['border_thick']='1'
 260         self.kw['columns']='4'
 261         self.kw['filter']='.'
 262         self.kw['mode']='1'
 263         self.kw['show_text']='1'
 264         self.kw['show_date']='1'
 265         self.kw['show_tools']='1'
 266         self.kw['only_items']='0'
 267         self.kw['renew']='0'
 268 
 269         for arg in kw.get('format_args','').split(','):
 270 
 271             if (arg.find('=') > -1):
 272                key=arg.split('=')
 273                self.kw[str(key[0])]=wikiutil.escape(string.join(key[1],''), quote=1)
 274 
 275 
 276     def format(self, formatter):
 277 
 278         kw=self.kw
 279         quotes=get_quotes(self,formatter)
 280 
 281         current_pagename=formatter.page.page_name
 282         attachment_path = AttachFile.getAttachDir(self.request,current_pagename,create=1)
 283 
 284         if (kw['only_items'] == '1'):
 285             all_files=quotes['image']
 286         else:
 287             all_files=os.listdir(attachment_path)
 288 
 289         result=[]
 290 
 291         for test in all_files:
 292            if re.match(kw['filter'], test):
 293               result.append(test)
 294 
 295         all_files=result
 296 
 297         if (len(all_files) == 0):
 298            self.request.write("<BR><BR><H1>No matching image file found!</H1>")
 299            return
 300 
 301 
 302         cells=[]
 303         big={}
 304         medium={}
 305         small={}
 306         cell_name=[]
 307         exif_date=[]
 308         big_image_url=[]
 309 
 310 	img=[]
 311 
 312         valid_img=0
 313 
 314         for attfile in all_files:
 315              # only files not thumb or webnails
 316             if ((string.find(string.join(attfile,''),'thumbnail_') == -1) and (string.find(string.join(attfile,''),'webnail_') == -1)) :
 317                 # only images
 318                 if wikiutil.isPicture(attfile):
 319 
 320                     file, ext = os.path.splitext(attfile)
 321 
 322                     if (ext == '.gif') or (ext == '.png'):
 323                         img_type='PNG'
 324                         thumbfile='thumbnail_'+file+".png"
 325                         webnail='webnail_'+file+".png"
 326                     else:
 327                         img_type="JPEG"
 328                         thumbfile='thumbnail_'+file+".jpg"
 329                         webnail='webnail_'+file+".jpg"
 330 
 331 
 332                     infile=attachment_path+'/'+attfile
 333                     # wikiutil.isPicture checks only the filename if it could be a picture
 334                     # it does not require to exist
 335                     if os.path.exists(infile):
 336                         img.append(attfile)
 337 
 338                         f=open(infile, 'rb')
 339                         tags=EXIF.process_file(f)
 340 
 341                         if tags.has_key('EXIF DateTimeOriginal'):
 342                              date=str(tags['EXIF DateTimeOriginal'])
 343                              date=string.replace(date,':','-',2)
 344                              exif_date.append(date)
 345                         else:
 346                             exif_date.append('--')
 347 
 348                         f.close()
 349 
 350                         thumb=attachment_path+'/'+thumbfile
 351                         webf=attachment_path+'/'+webnail
 352 
 353                         if (kw['renew'] == '1'):
 354                            if os.path.exists(thumb):
 355                               os.unlink(thumb)
 356                            if os.path.exists(webf):
 357                               os.unlink(webf)
 358 
 359                         valid_img=valid_img+1
 360 
 361                         im = Image.open(infile)
 362                         if not os.path.exists(webf):
 363                             im.thumbnail((640,640), Image.ANTIALIAS)
 364                             im.save(webf, img_type)
 365 
 366                         if not os.path.exists(thumb):
 367                             im.thumbnail((128, 128), Image.ANTIALIAS)
 368                             im.save(thumb, img_type)
 369 
 370 
 371 
 372                         big_image_url.append(AttachFile.getAttachUrl(current_pagename,
 373                                     attfile,self.request))
 374                         medium['src']=AttachFile.getAttachUrl(current_pagename,webnail,self.request)
 375 
 376                         small['title']=attfile
 377                         small['alt']=attfile
 378                         small['src']=AttachFile.getAttachUrl(current_pagename,thumbfile,self.request)
 379 
 380 
 381                         image_link=formatter.image(**small)
 382                     # collect images
 383                         cells.append(formatter.url(1,medium['src'] )+image_link+formatter.url(0))
 384                         cell_name.append(attfile)
 385 
 386 
 387         ##over all images
 388         n=len(cells)
 389         cols=int(kw['columns'])
 390 
 391 
 392         rows=n/cols
 393         first=0
 394         result=[]
 395         if (valid_img == 0):
 396            result.append('Image not found')
 397 
 398         if (valid_img > 1):
 399            result.append('<table border="'+kw['border_thick']+'">')
 400 
 401 
 402         icon={}
 403         icon['src']='/wiki/modern/img/idea.png'
 404         icon['title']='Load Image'
 405 
 406         z=1
 407         i=0
 408 
 409         ############################################
 410         ##TODO: syntax change to formatter - later #
 411         ############################################
 412 
 413         # fixed width because of better visualisation on different browsers
 414         for line in cells:
 415             if (z == 1):
 416                if (valid_img > 1):
 417                   if (kw['mode']=='1'):
 418                      result.append(formatter.table_cell(1))
 419                   else:
 420                       result.append('<td width="300" >')
 421             result.append('<table border="1">')
 422             result.append('<TR valign="top">')
 423             result.append('<td align="center" width="140">')
 424             result.append(line)
 425             result.append(formatter.table_cell(0))
 426             if (kw['show_text']=='1'):
 427                 if (kw['mode']=='1'):
 428                   result.append(formatter.table_row(0))
 429                   result.append(formatter.table_row(1))
 430 
 431                 if (kw['mode']=='1'):
 432                     result.append('<td width="140" >')
 433                 else:
 434                     result.append('<td width="140" >')
 435 
 436                 i_quote=0
 437                 found=0
 438                 for text in quotes['image'] :
 439                     if (text == cell_name[i]):
 440                         result.append(quotes['alias'][i_quote])
 441                         found=1
 442                     i_quote=i_quote+1
 443 
 444                 if (found == 0):
 445                     result.append(cell_name[i])
 446 
 447                 result.append(formatter.table_cell(0))
 448                 if (kw['mode']=='1'):
 449                     result.append(formatter.table_row(0))
 450 
 451 
 452             if (kw['show_date']=='1'):
 453                 if (kw['mode']=='1'):
 454                     result.append(formatter.table_row(1))
 455                     result.append(formatter.table_cell(1))
 456                     result.append(exif_date[i])
 457                     result.append(formatter.table_cell(0))
 458                     result.append(formatter.table_row(0))
 459             if (kw['show_tools'] == '1'):
 460 
 461                result.append(formatter.table_row(1))
 462                result.append('<td align="center">')
 463                result.append('<TABLE align="center">')
 464                result.append('<TR><td>')
 465                result.append('<FORM><TT>')
 466 
 467                result.append('<input type="hidden" name="action" value="AttachFile">')
 468                result.append('<input type="hidden" name="do" value=get>')
 469                result.append('<input type="hidden" name="target" value='+img[i]+'>')
 470                result.append('<input type="image" value="submit" src="wiki/modern/img/to_full.png" title="load image">')
 471                result.append('</TT></FONT></FORM>')
 472                result.append('</td><td>')
 473                result.append('<form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data"><TT>' % {
 474                              'baseurl': self.request.getScriptname(),
 475                              'pagename': wikiutil.quoteWikinameURL(current_pagename)})
 476 
 477                result.append('<input type="hidden" name="action" value="gallery2image">')
 478                result.append('<input type="hidden" name="do" value=PS>')
 479                result.append('<input type="hidden" name="target" value='+string.join(img,',')+'>')
 480                result.append('<input type="image" value="submit" src="wiki/modern/img/to_slide.png" title="slide_show">')
 481                result.append('</TT></FONT></FORM>')
 482                result.append('</td>')
 483 
 484                if self.request.user.may.delete(current_pagename):
 485                    result.append('<td>')
 486 
 487                    result.append('<form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data"><TT>' % {
 488                                  'baseurl': self.request.getScriptname(),
 489                                  'pagename': wikiutil.quoteWikinameURL(current_pagename)})
 490 
 491                    result.append('<input type="hidden" name="action" value="gallery2image">')
 492                    result.append('<input type="hidden" name="do" value=RL>')
 493                    result.append('<input type="hidden" name="target" value='+img[i]+'>')
 494                    result.append('<input type="image" value="submit" src="wiki/modern/img/to_left.png" title="rotate to left">')
 495                    result.append('</TT></FONT></FORM>')
 496                    result.append('</td><td>')
 497                    result.append('<form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data"><TT>' % {
 498                                 'baseurl': self.request.getScriptname(),
 499                                 'pagename': wikiutil.quoteWikinameURL(current_pagename)})
 500 
 501                    result.append('<input type="hidden" name="action" value="gallery2image">')
 502                    result.append('<input type="hidden" name="do" value=RR>')
 503                    result.append('<input type="hidden" name="target" value='+img[i]+'>')
 504                    result.append('<input type="image"  value="submit" src="wiki/modern/img/to_right.png" title="rotate to right">')
 505 
 506                    result.append('</TT></FONT></FORM>')
 507                    result.append('</td><td>')
 508                    result.append('<form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data"><TT>' % {
 509                                 'baseurl': self.request.getScriptname(),
 510                                 'pagename': wikiutil.quoteWikinameURL(current_pagename)})
 511 
 512                    result.append('<input type="hidden" name="action" value="gallery2image">')
 513                    result.append('<input type="hidden" name="do" value=RM>')
 514                    result.append('<input type="hidden" name="target" value='+img[i]+'>')
 515                    result.append('<input type="image" value="submit" src="wiki/modern/img/to_bak.png" title="move to bak">')
 516                    result.append('</TT></FONT></FORM>')
 517                    result.append('</TD>')
 518                result.append('</TR>')
 519                result.append('</TABLE>')
 520 
 521             result.append(formatter.table_cell(0))
 522             if (kw['show_date']=='1'):
 523                 if not (kw['mode']=='1'):
 524                     result.append(formatter.table_cell(1))
 525                     result.append(exif_date[i])
 526                     result.append(formatter.table_cell(0))
 527             if (kw['show_tools'] == '1'):
 528                result.append(formatter.table_row(0))
 529             result.append(formatter.table(0))
 530             if ((z != cols) and (i < n-1)):
 531                 result.append(formatter.table_cell(1))
 532             if (z == cols):
 533                 result.append(formatter.table_cell(0))
 534                 result.append(formatter.table_row(0))
 535             z=z+1
 536             i=i+1
 537             if (z > cols):
 538                z=1
 539         if (valid_img > 1):
 540            result.append(formatter.table(0))
 541 
 542         ##Output
 543         self.request.write(string.join(result,''))
 544         return()

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.