Attachment 'Gallery2-1.3.5-6.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 abel to toggle to 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],
16 [only_items=only_items],[template_itemlist=template_itemlist],
17 [thumbnail_width=thumbnail_width],[webnail_width=webnail_width],[text_width=text_width],
18 [image_for_webnail=image_for_webnail],
19 [border_thick=border_thick],[renew=renew],[help=help]
20 * [image1.jpg alias]
21 * [image2.jpg alias]
22 }}}
23
24 KEYWORD PARAMETERS:
25 columns: number of columns for thumbnails
26 filter: regex to select images
27 show_text: default is 1 description is shown
28 any other means no description
29 show_date: default is 1 date info from exif header if available is shown
30 show_tools: default is 1 icon toolbar is show any other disables this
31 sort_by_name: default is 1, the images are sorted by name, but not if only_items is 1
32 sort_by_date: default is 0, if set to 1 the images are sorted to the modification time
33 reverse_sort: default is 0, if set to 1 the file list is reversed
34 any other means no description
35 mode: default is 1 this means description below the image
36 any other number means description right of image
37 only_items: default is 0 if it is set to 1 only images which are described in listitem are shown
38 dependend on the order of the items
39 template_itemlist: default is 0, if set to 1 an item list is shown which could be copied into the script.
40 border_thick: default is 1 this is the thickness in pixeln of the outer frame
41 renew: default is 0 if set to 1 then all selected thumbnails_* and webnails_* removed.
42 Afterwards they are new created.
43 thumbnail_width: default is 128
44 webnail_width: default is 640
45 text_width: default is 140
46 image_for_webnail default is 0 if set to 1 then the image is shown as preview and not the webnail
47 help: default is 0 if set a copy of the CALLING SEQUENCE is shown,
48 (there are some new ideas around to show help to an user so this will be later replaced)
49
50 OPTIONAL INPUTS:
51 itemlist : if it is used and only_items is 1 then only the images in this list are ahown.
52 The alias text is used as description of the image instead of the file name
53
54
55 EXAMPLE:
56 = GalleryTest =
57
58 == all images shown, one is decribed ==
59 {{{
60 { { {
61 #!Gallery2
62 * [100_1185.JPG Bremen, SpaceCenter]
63 } } }
64 }}}
65
66 Result: [[BR]]
67 {{{
68 #!Gallery2
69 * [100_1185.JPG Bremen, SpaceCenter]
70 }}}
71
72 == only thumbnails and only_items ==
73 {{{
74 { { {
75 #!Gallery2 show_text=0,show_tools=0,show_date=0,columns=2,only_items=1
76 * [100_1185.JPG Bremen, SpaceCenter]
77 * [100_1194.JPG Bremen]
78 } } }
79 }}}
80
81 Result: [[BR]]
82 {{{
83 #!Gallery2 show_text=0,show_tools=0,show_date=0,columns=2,only_items=1
84 * [100_1185.JPG Bremen, SpaceCenter]
85 * [100_1194.JPG Bremen]
86 }}}
87
88 == only_items by two columns and text right ==
89
90 {{{
91 { { {
92 #!Gallery2 mode=2,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 mode=2,columns=2,only_items=1
101 * [100_1185.JPG Bremen, SpaceCenter]
102 * [100_1194.JPG Bremen, behind SpaceCenter]
103 }}}
104
105 ----
106
107 == only_items by two columns, date supressed ==
108
109 {{{
110 { { {
111 #!Gallery2 columns=2,only_items=1,show_date=0
112 * [100_1185.JPG Bremen, SpaceCenter]
113 * [100_1194.JPG Bremen, behind SpaceCenter]
114 } } }
115 }}}
116
117 Result: [[BR]]
118 {{{
119 #!Gallery2 columns=2,only_items=1,show_date=0
120 * [100_1185.JPG Bremen, SpaceCenter]
121 * [100_1194.JPG Bremen, behind SpaceCenter]
122 }}}
123
124
125 == filter regex used, mode 2, icons and date supressed, one column and border_thick=5 ==
126 {{{
127 { { {
128 #!Gallery2 columns=1,filter=100_118[0-5],mode=2,show_date=0,show_tools=0,border_thick=5
129 } } }
130 }}}
131
132 Result: [[BR]]
133 {{{
134 #!Gallery2 columns=1,filter=100_118[0-7],mode=2,show_date=0,show_tools=0,border_thick=5
135 }}}
136
137 == other macro calls ==
138 {{{
139 { { {
140 #!Gallery2 only_items=1,show_date=0
141 * [100_1189.JPG [[MiniPage(||Bremen||SpaceCenter||\n|| ||SpaceJump||)]]]
142 } } }
143 }}}
144
145 Result: [[BR]]
146 {{{
147 #!Gallery2 only_items=1,show_date=0
148 * [100_1189.JPG [[MiniPage(||Bremen||SpaceCenter||\n|| ||SpaceJump||)]]]
149 }}}
150
151 == renew means always new thumbnails and webnails of selection ==
152 {{{
153 { { {
154 #!Gallery2 only_items=1,show_date=0,show_tools=0,renew=1
155 * [100_1189.JPG [[MiniPage(||["Bremen"]||SpaceCenter||\n|| ||SpaceJump||)]]]
156 } } }
157 }}}
158
159 Result: [[BR]]
160 {{{
161 #!Gallery2 only_items=1,show_date=0,renew=1
162 * [100_1189.JPG [[MiniPage(||["Bremen"]||SpaceCenter||\n|| ||SpaceJump||)]]]
163 }}}
164
165 == template_itemlist ==
166 {{{
167 { { {
168 #!Gallery2 template_itemlist=1
169 * [100_1185.JPG Bremen, SpaceCenter]
170 } } }
171 }}}
172
173 Result: [[BR]]
174 {{{
175 #!Gallery2 template_itemlist=1
176 * [100_1185.JPG Bremen, SpaceCenter]
177 }}}
178
179 == help to show Calling Sequence ==
180 {{{
181 { { {
182 #!Gallery2 help=1
183 } } }
184 }}}
185
186 Result: [[BR]]
187 {{{
188 #!Gallery2 help=1
189 }}}
190
191
192 PROCEDURE:
193 Download some images to a page and start with the examples.
194 Aliasing of the filenames are done by adding an itemlist, see example.
195
196 This routine requires the PIL (Python Imaging Library).
197 And the EXIF routine from http://home.cfl.rr.com/genecash/digital_camera.html
198
199
200 At the moment I have added the EXIF routine to the parsers dir.
201 It's not the best place but during developing it is nice to have it there
202 If you put it to another place you have to change the line
203 from MoinMoin.parser import EXIF too.
204
205 This routine requires the Action macro gallery2Image which is used to rotate or delete a selected image.
206 Only users which have the rights to delete are able to execute this action macro.
207 The icons of these are only shown if you have enough rights.
208
209 The gallery2image macro does not take care on the EXIF header. This is lost by rotating.
210 If a file is deleted by this macro it is moved to a bak file.
211
212 Please remove the Version number from the code!
213
214 RESTRICTIONS:
215 The movie mode is not implemented at the moment. The implementation will be done in the action macro.
216
217
218 If you rotate an image #at the moment the exif is destroyed. PIL ignores the exif header.
219 This is not a quite big problem normally files with an EXIF header are right rotated.
220
221 Required Images:
222 I have put them to wiki/modern/img/ dir. The icons were created by me. License: GPL
223
224 attachment:to_bak.png
225 attachment:to_left.png
226 attachment:to_right.png
227 attachment:to_slide.png
228 attachment:to_full.png
229
230 HISTORY:
231 While recognizing how to write MiniPage I got the idea to write a Gallery Parser.
232 We have used in our wikis in the past the Gallery macro of SimonRyan.
233 I have tried to modify it a bit to change it for 1.3 but my python skills weren't enough
234 or it was easier to write it completly new.
235 So this one shows now a way how a Gallery could be used by the parser and an action Macro.
236 Probably it is a good example for others who like to know how to do this
237
238 MODIFICATION HISTORY:
239 Version 1.3.3.-1
240 @copyright: 2005 by Reimar Bauer (R.Bauer@fz-juelich.de)
241 @license: GNU GPL, see COPYING for details.
242 2005-03-26: Version 1.3.3-2 keyword renew added
243 creation of thumbnails and webnails in two calls splitted
244 Version 1.3.3-3 bug fixed if itemlist is given to describe only some of the images
245 but only_items is not set to 1
246 Example code changed
247 2005-03-27: Version 1.3.3-4 Action macro added and the form to call it. User which have rights to delete
248 could use the functions of gallery2Image.
249 2005-08-03: Version 1.3.3-5 theme path for icons corrected and a platform independent path joining
250 os.unlink removed as suggested by CraigJohnson
251 sort_by_name is default if not only_items is 1
252 optional sort_by_date could be used
253 keyword template_itemlist added
254 keyword help added
255 extra frame by mode=2 removed
256 2005-08-06: Version 1.3.5-6 slideshow mode added
257 keyword image_for_webnail added
258
259
260
261 """
262 Dependencies = []
263 from MoinMoin.action import AttachFile
264 from MoinMoin import wikiutil, config
265 from MoinMoin.Page import Page
266 import os,string,re,Image,StringIO
267 from MoinMoin.parser import EXIF
268
269 from MoinMoin.parser import wiki
270
271 #def ImageProcess(var):
272 # f=open('/tmp/workfile.txt', 'w')
273 # f.write(var)
274 # f.close()
275
276 def get_quotes(self,formatter):
277 quotes = self.raw.split('\n')
278 quotes = [quote.strip() for quote in quotes]
279 quotes = [quote[2:] for quote in quotes if quote.startswith('* ')]
280
281 image=[]
282 alias=[]
283 for line in quotes:
284 im,na=line[1:-1].split(' ',1)
285
286 ##taken from MiniPage
287
288 out=StringIO.StringIO()
289 self.request.redirect(out)
290 wikiizer = wiki.Parser(na.strip(),self.request)
291 wikiizer.format(formatter)
292 na=out.getvalue()
293 self.request.redirect()
294 del out
295
296 alias.append(na)
297 image.append(im.strip())
298
299 result={}
300 result['alias']=alias
301 result['image']=image
302
303 return(result)
304
305
306
307 class Parser:
308 def __init__(self, raw, request, **kw):
309 self.raw = raw
310 self.request = request
311 self.form = request.form
312 self._ = request.getText
313 self.kw = {}
314 self.kw['sort_by_date']='0' # nor implemented at the moment
315 self.kw['sort_by_name']='1'
316 self.kw['template_itemlist']='0'
317 self.kw['reverse_sort']='0'
318 self.kw['border_thick']='1'
319 self.kw['columns']='4'
320 self.kw['filter']='.'
321 self.kw['mode']='1'
322 self.kw['help']='0'
323 self.kw['show_text']='1'
324 self.kw['show_date']='1'
325 self.kw['show_tools']='1'
326 self.kw['only_items']='0'
327 self.kw['image_for_webnail']='0'
328 self.kw['renew']='0'
329 self.kw['thumbnail_width']='128'
330 self.kw['webnail_width']='640'
331 self.kw['text_width']='140'
332
333
334
335 for arg in kw.get('format_args','').split(','):
336
337 if (arg.find('=') > -1):
338 key=arg.split('=')
339 self.kw[str(key[0])]=wikiutil.escape(string.join(key[1],''), quote=1)
340
341 self.kw['width']=str((int(self.kw['thumbnail_width'])+int(self.kw['text_width'])))
342
343
344 def format(self, formatter):
345
346 kw=self.kw
347 Dict = {}
348 quotes=get_quotes(self,formatter)
349
350 current_pagename=formatter.page.page_name
351
352 attachment_path = AttachFile.getAttachDir(self.request,current_pagename,create=1)
353
354 if (kw['help'] == '1'):
355
356 self.request.write('<BR>')
357 self.request.write('{{{<BR>')
358 self.request.write('#!Gallery2 [columns=columns],[filter=filter],[mode=mode],<BR>')
359 self.request.write(' [show_text=show_text],[show_date=show_date], [show_tools=show_tools],<BR>')
360 self.request.write(' [sort_by_name=sort_by_name],[sort_by_date=sort_by_date],<BR>')
361 self.request.write(' [only_items=only_items],[template_itemlist=template_itemlist],<BR>')
362 self.request.write(' [thumbnail_width=thumbnail_width],[webnail_width=webnail_width],[text_width=text_width],<BR>')
363 self.request.write(' [image_for_webnail=image_for_webnail],<BR>')
364 self.request.write(' [border_thick=border_thick],[renew=renew],[help=help]<BR>')
365 self.request.write(' * [image1.jpg alias]<BR>')
366 self.request.write(' * [image2.jpg alias]<BR>')
367 self.request.write('}}}<BR>')
368 return
369
370 if (kw['only_items'] == '1'):
371 all_files=quotes['image']
372 else:
373 all_files=os.listdir(attachment_path)
374
375 result=[]
376
377 for test in all_files:
378 if re.match(kw['filter'], test):
379 result.append(test)
380
381 all_files=result
382
383 if (len(all_files) == 0):
384 self.request.write("<BR><BR><H1>No matching image file found!</H1>")
385 return
386
387 if ((kw['sort_by_name']=='1') and (kw['only_items'] == '0')):
388 all_files.sort()
389
390 if (kw['sort_by_date']=='1'):
391
392 for attfile in all_files:
393 infile=os.path.join(attachment_path,attfile)
394 ft_file=str(os.path.getmtime(infile))+os.tmpnam()
395 Dict[ft_file]=attfile
396
397 file_mdate=[]
398 keys = Dict.keys()
399 keys.sort()
400 for txt in keys:
401 file_mdate.append(Dict[txt])
402
403 all_files=file_mdate
404
405 if (kw['reverse_sort']=='1'):
406 all_files.reverse()
407
408
409 cells=[]
410 big={}
411 medium={}
412 small={}
413 cell_name=[]
414 exif_date=[]
415
416 big_image_url=[]
417
418 img=[]
419 web=[]
420
421 valid_img=0
422 if (kw['template_itemlist'] == '1'):
423 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>')
424
425
426 #preliminary solution to get all webnail files for the slide show
427 #I have to think on how to pass meta data to the action macro
428
429 for attfile in all_files:
430 # only files not thumb or webnails
431 if ((string.find(string.join(attfile,''),'thumbnail_') == -1) and (string.find(string.join(attfile,''),'webnail_') == -1)) :
432 # only images
433 if wikiutil.isPicture(attfile):
434 if (kw['image_for_webnail']=='1'):
435 webnail=attfile
436 else:
437 file, ext = os.path.splitext(attfile)
438 if (ext == '.gif') or (ext == '.png'):
439 img_type='PNG'
440 webnail='webnail_'+file+".png"
441 else:
442 img_type="JPEG"
443 webnail='webnail_'+file+".jpg"
444
445 infile=os.path.join(attachment_path,attfile)
446 if os.path.exists(infile):
447 web.append(webnail)
448
449 ########################################################################
450
451 for attfile in all_files:
452 # only files not thumb or webnails
453 if ((string.find(string.join(attfile,''),'thumbnail_') == -1) and (string.find(string.join(attfile,''),'webnail_') == -1)) :
454 # only images
455 if wikiutil.isPicture(attfile):
456 if (kw['image_for_webnail']=='1'):
457 webnail=attfile
458 file, ext = os.path.splitext(attfile)
459
460 if (ext == '.gif') or (ext == '.png'):
461 img_type='PNG'
462 thumbfile='thumbnail_'+file+".png"
463 else:
464 img_type="JPEG"
465 thumbfile='thumbnail_'+file+".jpg"
466 else:
467 file, ext = os.path.splitext(attfile)
468
469 if (ext == '.gif') or (ext == '.png'):
470 img_type='PNG'
471 thumbfile='thumbnail_'+file+".png"
472 webnail='webnail_'+file+".png"
473 else:
474 img_type="JPEG"
475 thumbfile='thumbnail_'+file+".jpg"
476 webnail='webnail_'+file+".jpg"
477
478
479
480
481 infile=os.path.join(attachment_path,attfile)
482 # wikiutil.isPicture checks only the filename if it could be a picture
483 # it does not require to exist
484 if os.path.exists(infile):
485 img.append(attfile)
486 #web.append(webnail)
487
488 f=open(infile, 'rb')
489
490 tags=EXIF.process_file(f)
491
492 if tags.has_key('EXIF DateTimeOriginal'):
493 date=str(tags['EXIF DateTimeOriginal'])
494 date=string.replace(date,':','-',2)
495 exif_date.append(date)
496 else:
497 date='--'
498 exif_date.append(date)
499
500
501 f.close()
502 if (kw['template_itemlist'] == '1'):
503 self.request.write(' * [%(attfile)s %(date)s]<BR>' % {
504 'attfile' : attfile,
505 'date' : 'alias'
506 })
507
508 thumb=os.path.join(attachment_path,thumbfile)
509 webf=os.path.join(attachment_path,webnail)
510
511 if (kw['renew'] == '1'):
512 if os.path.exists(thumb):
513 os.unlink(thumb)
514 if os.path.exists(webf):
515 os.unlink(webf)
516
517 valid_img=valid_img+1
518
519 im = Image.open(infile)
520 if not os.path.exists(webf):
521 im.thumbnail(((int(kw['webnail_width'])),((int(kw['webnail_width'])))), Image.ANTIALIAS)
522 im.save(webf, img_type)
523
524 if not os.path.exists(thumb):
525 im.thumbnail(((int(kw['thumbnail_width'])),((int(kw['thumbnail_width'])))),
526 Image.ANTIALIAS)
527 im.save(thumb, img_type)
528
529
530
531 big_image_url.append(AttachFile.getAttachUrl(current_pagename,
532 attfile,self.request))
533 medium['src']=AttachFile.getAttachUrl(current_pagename,webnail,self.request)
534
535 small['title']=attfile
536 small['alt']=attfile
537 small['src']=AttachFile.getAttachUrl(current_pagename,thumbfile,self.request)
538
539
540 image_link=formatter.image(**small)
541
542 webn_url="%(pagename)s?action=gallery2image&do=VS&target=%(webnail)s " % {
543 "pagename":current_pagename,
544 "webnail":webnail+","+string.join(web,',')}
545 text=image_link
546 url=webn_url
547 webn_url=wikiutil.link_tag(self.request, url, text=text,
548 formatter=formatter)
549 cells.append(webn_url)
550 cell_name.append(attfile)
551
552
553 ##over all images
554 n=len(cells)
555 cols=int(kw['columns'])
556
557 rows=n/cols
558 first=0
559 result=[]
560 if (valid_img == 0):
561 result.append('Image not found')
562
563 #if (valid_img > 1):
564 result.append('<table border="'+kw['border_thick']+'" valign="bottom">')
565
566 z=1
567 i=0
568
569 ############################################
570 ##TODO: syntax change to formatter - later #
571 ############################################
572
573 # fixed width because of better visualisation on different browsers
574 for line in cells:
575 if (z == 1):
576 if (cols > 1) and (n > 1):
577 if (kw['mode']=='1'):
578 result.append('<td width="'+kw['thumbnail_width']+'" >')
579 #result.append(formatter.table_cell(1))
580 else:
581 result.append('<td width="'+kw['width']+'" >')
582 if n > 1 and cols > 1:
583 result.append('<table border="1" valign="center">')
584
585 result.append('<TR valign="center">')
586 # image align center
587 result.append('<td align="center" valign="center" width="'+kw['thumbnail_width']+'">')
588 result.append(line)
589 result.append(formatter.table_cell(0))
590
591 if (kw['show_text']=='1'):
592 if (kw['mode']=='1'):
593 result.append(formatter.table_row(0))
594 result.append(formatter.table_row(1))
595 # text aligned left in mode 1
596 result.append('<td align="left" width="'+kw['thumbnail_width']+'" >')
597 else:
598 # text aligned on top in mode 2
599 result.append('<td valign="top" width="'+kw['text_width']+'" >')
600
601 i_quote=0
602 found=0
603 for text in quotes['image'] :
604 if (text == cell_name[i]):
605 result.append(quotes['alias'][i_quote])
606 found=1
607 i_quote=i_quote+1
608
609 if (found == 0):
610 result.append(cell_name[i])
611
612 result.append(formatter.table_cell(0))
613 if (kw['mode']=='1'):
614 result.append(formatter.table_row(0))
615
616
617 if (kw['show_date']=='1'):
618 if (kw['mode']=='1'):
619 result.append(formatter.table_row(1))
620 result.append(formatter.table_cell(1))
621 result.append(exif_date[i])
622 result.append(formatter.table_cell(0))
623 result.append(formatter.table_row(0))
624
625 if (kw['show_tools'] == '1'):
626 result.append(formatter.table_row(1))
627 # tool bar centriert
628 result.append('<td align="center">')
629 result.append('<TABLE align="center">')
630 result.append('<TR><td>')
631 result.append('<FORM><TT>')
632
633 result.append('<input type="hidden" name="action" value="AttachFile">')
634 result.append('<input type="hidden" name="do" value=get>')
635 result.append('<input type="hidden" name="target" value='+img[i]+'>')
636 result.append('<input type="image" value="submit" src="/wiki/modern/img/to_full.png" title="load image">')
637 result.append('</TT></FONT></FORM>')
638 result.append('</td><td>')
639 result.append('<form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data"><TT>' % {
640 'baseurl': self.request.getScriptname(),
641 'pagename': wikiutil.quoteWikinameURL(current_pagename)})
642
643 result.append('<input type="hidden" name="action" value="gallery2image">')
644 result.append('<input type="hidden" name="do" value=PS>')
645 result.append('<input type="hidden" name="target" value='+string.join(img,',')+'>')
646 result.append('<input type="image" value="submit" src="/wiki/modern/img/to_slide.png" title="slide_show">')
647 result.append('</TT></FONT></FORM>')
648 result.append('</td>')
649
650 if self.request.user.may.delete(current_pagename):
651 result.append('<td>')
652
653 result.append('<form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data"><TT>' % {
654 'baseurl': self.request.getScriptname(),
655 'pagename': wikiutil.quoteWikinameURL(current_pagename)})
656
657 result.append('<input type="hidden" name="action" value="gallery2image">')
658 result.append('<input type="hidden" name="do" value=RL>')
659 result.append('<input type="hidden" name="target" value='+img[i]+'>')
660 result.append('<input type="image" value="submit" src="/wiki/modern/img/to_left.png" title="rotate to left">')
661 result.append('</TT></FONT></FORM>')
662 result.append('</td><td>')
663 result.append('<form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data"><TT>' % {
664 'baseurl': self.request.getScriptname(),
665 'pagename': wikiutil.quoteWikinameURL(current_pagename)})
666
667 result.append('<input type="hidden" name="action" value="gallery2image">')
668 result.append('<input type="hidden" name="do" value=RR>')
669 result.append('<input type="hidden" name="target" value='+img[i]+'>')
670 result.append('<input type="image" value="submit" src="/wiki/modern/img/to_right.png" title="rotate to right">')
671
672 result.append('</TT></FONT></FORM>')
673 result.append('</td><td>')
674 result.append('<form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data"><TT>' % {
675 'baseurl': self.request.getScriptname(),
676 'pagename': wikiutil.quoteWikinameURL(current_pagename)})
677
678 result.append('<input type="hidden" name="action" value="gallery2image">')
679 result.append('<input type="hidden" name="do" value=RM>')
680 result.append('<input type="hidden" name="target" value='+img[i]+'>')
681 result.append('<input type="image" value="submit" src="/wiki/modern/img/to_bak.png" title="move to bak">')
682 result.append('</TT></FONT></FORM>')
683 result.append('</TD>')
684 result.append('</TR>')
685 result.append('</TABLE>')
686
687 result.append(formatter.table_cell(0))
688 if (kw['show_date']=='1'):
689 if not (kw['mode']=='1'):
690 result.append(formatter.table_cell(1))
691 result.append(exif_date[i])
692 result.append(formatter.table_cell(0))
693 if (kw['show_tools'] == '1'):
694 result.append(formatter.table_row(0))
695 if n > 1 and cols > 1:
696 result.append(formatter.table(0))
697 if ((z != cols) and (i < n-1)):
698 result.append(formatter.table_cell(1))
699 if (z == cols):
700 result.append(formatter.table_cell(0))
701 result.append(formatter.table_row(0))
702 z=z+1
703 i=i+1
704 if (z > cols):
705 z=1
706
707 result.append(formatter.table(0))
708 ##Output
709 self.request.write(string.join(result,''))
710
711 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.You are not allowed to attach a file to this page.