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.You are not allowed to attach a file to this page.