# -*- coding: iso-8859-1 -*-
"""
    MoinMoin - Gallery2 parser

    PURPOSE:
        This parser is used to visualize a couple of images as a thumbnail gallery.
	Optional a description of an image could be added including WikiName.
	On default the image name and it's creation date is shown.

    CALLING SEQUENCE:
      {{{
      #!Gallery2 [columns=columns],[filter=filter],[mode=mode],[show_text=show_text],
                 [show_date=show_date], [show_tools=show_tools],
                 [only_items=only_items],[border_thick=border_thick],[renew=renew]
      * [image1.jpg alias]
      * [image2.jpg alias]
      }}}

    KEYWORD PARAMETERS:
        columns:      number of columns for thumbnails
	filter:       regex to select images
        show_text:    default is 1 description is shown
	              any other means no description
	show_date:    default is 1 date info from exif header if available is shown
                      any other means no description
	show_tools:   default is 1 icon toolbar is show any other disables this
	mode:         default is 1 this means description below the image
	              any other number means description right of image
	only_items:   default is 0 if it is set to 1 only images which are described in listitem are shown
	border_thick: default is 1 this is the thickness in pixeln of the outer frame
	renew:        default is 0 if set to 1 then all selected thumbnails_* and webnails_* removed.
	              Afterwards they are new created.

    OPTIONAL INPUTS:
	itemlist : if it is used and only_items is 1 then only the images in this list are ahown.
	           The alias text is used as description of the image instead of the file name


    EXAMPLE:
= GalleryTest =

== all images shown, one is decribed ==
{{{
{ { {
#!Gallery2
* [100_1185.JPG Bremen, SpaceCenter]
} } }
}}}

Result: [[BR]]
 {{{
#!Gallery2
* [100_1185.JPG Bremen, SpaceCenter]
}}}

== only thumbnails and only_items ==
{{{
{ { {
#!Gallery2 show_text=0,show_tools=0,show_date=0,columns=2,only_items=1
 * [100_1185.JPG Bremen, SpaceCenter]
 * [100_1194.JPG Bremen]
} } }
}}}

Result: [[BR]]
 {{{
#!Gallery2 show_text=0,show_tools=0,show_date=0,columns=2,only_items=1
 * [100_1185.JPG Bremen, SpaceCenter]
 * [100_1194.JPG Bremen]
}}}

== only_items by two columns and text right ==

{{{
{ { {
#!Gallery2 mode=2,columns=2,only_items=1
 * [100_1185.JPG Bremen, SpaceCenter]
 * [100_1194.JPG Bremen]
} } }
}}}

Result: [[BR]]
 {{{
#!Gallery2 mode=2,columns=2,only_items=1
 * [100_1185.JPG Bremen, SpaceCenter]
 * [100_1194.JPG Bremen, behind SpaceCenter]
}}}

----

== only_items by two columns, date supressed ==

{{{
{ { {
#!Gallery2 columns=2,only_items=1,show_date=0
 * [100_1185.JPG Bremen, SpaceCenter]
 * [100_1194.JPG Bremen, behind SpaceCenter]
} } }
}}}

Result: [[BR]]
 {{{
#!Gallery2 columns=2,only_items=1,show_date=0
 * [100_1185.JPG Bremen, SpaceCenter]
 * [100_1194.JPG Bremen, behind SpaceCenter]
}}}


== filter regex used, mode 2, icons and date supressed, one column and border_thick=5 ==
{{{
{ { {
#!Gallery2 columns=1,filter=100_118[0-5],mode=2,show_date=0,show_tools=0,border_thick=5
} } }
}}}

Result: [[BR]]
 {{{
#!Gallery2 columns=1,filter=100_118[0-7],mode=2,show_date=0,show_tools=0,border_thick=5
}}}

== other macro calls ==
{{{
{ { {
#!Gallery2 only_items=1,show_date=0
 * [100_1189.JPG [[MiniPage(||Bremen||SpaceCenter||\n|| ||SpaceJump||)]]]
} } }
}}}

Result: [[BR]]
 {{{
#!Gallery2 only_items=1,show_date=0
 * [100_1189.JPG [[MiniPage(||Bremen||SpaceCenter||\n|| ||SpaceJump||)]]]
}}}

== renew means always new thumbnails and webnails of selection ==
{{{
{ { {
#!Gallery2 only_items=1,show_date=0,show_tools=0,renew=1
 * [100_1189.JPG [[MiniPage(||["Bremen"]||SpaceCenter||\n|| ||SpaceJump||)]]]
} } }
}}}

Result: [[BR]]
 {{{
#!Gallery2 only_items=1,show_date=0,renew=1
 * [100_1189.JPG [[MiniPage(||["Bremen"]||SpaceCenter||\n|| ||SpaceJump||)]]]
}}}



    PROCEDURE:
      Download some images to a page and start with the examples.
      Aliasing of the filenames are done by adding an itemlist, see example.

      This routine requires the PIL (Python Imaging Library).
      And the EXIF routine from http://home.cfl.rr.com/genecash/digital_camera.html


      At the moment I have added the EXIF routine to the parsers dir.
      It's not the best place but during developing it is nice to have it there
      If you put it to another place you have to change the line
      from MoinMoin.parser import EXIF too.

      This routine requires the Action macro gallery2Image which is used to rotate or delete a selected image.
      Only users which have the rights to delete are able to execute this action macro.
      The icons of these are only shown if you have enough rights.

      The gallery2image macro does not take care on the EXIF header. This is lost by rotating.
      If a file is deleted by this macro it is moved to a bak file.

      Please remove the Version number from the code!

    RESTRICTIONS:
      The slideshow is not implemented at the moment. The implementation will be done in the acrion macro.
      This is not a quite big problem normally files with an EXIF header are right rotated.

    Required Images:
      I have put them to wiki/modern/img/ dir. The icons were created by me. License: GPL

    attachment:to_bak.png
    attachment:to_left.png
    attachment:to_right.png
    attachment:to_slide.png
    attachment:to_full.png

    HISTORY:
    While recognizing how to write MiniPage I got the idea to write a Gallery Parser.
    We have used in our wikis in the past the Gallery macro of SimonRyan.
    I have tried to modify it a bit to change it for 1.3 but my python skills weren't enough
    or it was easier to write it completly new.
    So this one shows now a way how a Gallery could be used by the parser and an action Macro.
    Probably it is a good example for others who like to know how to do this

    MODIFICATION HISTORY:
        Version 1.3.3.-1
        @copyright: 2005 by Reimar Bauer (R.Bauer@fz-juelich.de)
        @license: GNU GPL, see COPYING for details.
	2005-03-26: Version 1.3.3-2 keyword renew added
	            creation of thumnails and webnails in two calls splitted
                    Version 1.3.3-3 bug fixed if itemlist is given to describe only some of the images
		                    but only_items is not set to 1
				    Example code changed
        2005-03-27: Version 1.3.3-4 Action macro added and the form to call it. User which have rights to delete
                                    could use the functions of gallery2Image.

"""

from MoinMoin.action import AttachFile
from MoinMoin import wikiutil, config
from MoinMoin.Page import Page
import os,string,re,Image,StringIO
from MoinMoin.parser import EXIF

from MoinMoin.parser import wiki

def ImageProcess(var):
    f=open('/tmp/workfile.txt', 'w')
    f.write(var)
    f.close()

def get_quotes(self,formatter):
    quotes = self.raw.split('\n')
    quotes = [quote.strip() for quote in quotes]
    quotes = [quote[2:] for quote in quotes if quote.startswith('* ')]

    image=[]
    alias=[]
    for line in quotes:
        im,na=line[1:-1].split(' ',1)

        ##taken from MiniPage

        out=StringIO.StringIO()
        self.request.redirect(out)
        wikiizer = wiki.Parser(na.strip(),self.request)
        wikiizer.format(formatter)
        na=out.getvalue()
        self.request.redirect()
        del out

        alias.append(na)
        image.append(im.strip())

    result={}
    result['alias']=alias
    result['image']=image

    return(result)



class Parser:
    def __init__(self, raw, request, **kw):
        self.raw = raw
        self.request = request
        self.form = request.form
        self._ = request.getText
        self.kw = {}
        self.kw['border_thick']='1'
        self.kw['columns']='4'
        self.kw['filter']='.'
        self.kw['mode']='1'
        self.kw['show_text']='1'
        self.kw['show_date']='1'
        self.kw['show_tools']='1'
        self.kw['only_items']='0'
        self.kw['renew']='0'

        for arg in kw.get('format_args','').split(','):

            if (arg.find('=') > -1):
               key=arg.split('=')
               self.kw[str(key[0])]=wikiutil.escape(string.join(key[1],''), quote=1)


    def format(self, formatter):

        kw=self.kw
        quotes=get_quotes(self,formatter)

        current_pagename=formatter.page.page_name
        attachment_path = AttachFile.getAttachDir(self.request,current_pagename,create=1)

        if (kw['only_items'] == '1'):
            all_files=quotes['image']
        else:
            all_files=os.listdir(attachment_path)

        result=[]

        for test in all_files:
           if re.match(kw['filter'], test):
              result.append(test)

        all_files=result

        if (len(all_files) == 0):
           self.request.write("<BR><BR><H1>No matching image file found!</H1>")
           return


        cells=[]
        big={}
        medium={}
        small={}
        cell_name=[]
        exif_date=[]
        big_image_url=[]

	img=[]

        valid_img=0

        for attfile in all_files:
             # only files not thumb or webnails
            if ((string.find(string.join(attfile,''),'thumbnail_') == -1) and (string.find(string.join(attfile,''),'webnail_') == -1)) :
                # only images
                if wikiutil.isPicture(attfile):

                    file, ext = os.path.splitext(attfile)

                    if (ext == '.gif') or (ext == '.png'):
                        img_type='PNG'
                        thumbfile='thumbnail_'+file+".png"
                        webnail='webnail_'+file+".png"
                    else:
                        img_type="JPEG"
                        thumbfile='thumbnail_'+file+".jpg"
                        webnail='webnail_'+file+".jpg"


                    infile=attachment_path+'/'+attfile
                    # wikiutil.isPicture checks only the filename if it could be a picture
                    # it does not require to exist
                    if os.path.exists(infile):
                        img.append(attfile)

                        f=open(infile, 'rb')
                        tags=EXIF.process_file(f)

                        if tags.has_key('EXIF DateTimeOriginal'):
                             date=str(tags['EXIF DateTimeOriginal'])
                             date=string.replace(date,':','-',2)
                             exif_date.append(date)
                        else:
                            exif_date.append('--')

                        f.close()

                        thumb=attachment_path+'/'+thumbfile
                        webf=attachment_path+'/'+webnail

                        if (kw['renew'] == '1'):
                           if os.path.exists(thumb):
                              os.unlink(thumb)
                           if os.path.exists(webf):
                              os.unlink(webf)

                        valid_img=valid_img+1

                        im = Image.open(infile)
                        if not os.path.exists(webf):
                            im.thumbnail((640,640), Image.ANTIALIAS)
                            im.save(webf, img_type)

                        if not os.path.exists(thumb):
                            im.thumbnail((128, 128), Image.ANTIALIAS)
                            im.save(thumb, img_type)



                        big_image_url.append(AttachFile.getAttachUrl(current_pagename,
                                    attfile,self.request))
                        medium['src']=AttachFile.getAttachUrl(current_pagename,webnail,self.request)

                        small['title']=attfile
                        small['alt']=attfile
                        small['src']=AttachFile.getAttachUrl(current_pagename,thumbfile,self.request)


                        image_link=formatter.image(**small)
                    # collect images
                        cells.append(formatter.url(1,medium['src'] )+image_link+formatter.url(0))
                        cell_name.append(attfile)


        ##over all images
        n=len(cells)
        cols=int(kw['columns'])


        rows=n/cols
        first=0
        result=[]
        if (valid_img == 0):
           result.append('Image not found')

        if (valid_img > 1):
           result.append('<table border="'+kw['border_thick']+'">')


        icon={}
        icon['src']='/wiki/modern/img/idea.png'
        icon['title']='Load Image'

        z=1
        i=0

        ############################################
        ##TODO: syntax change to formatter - later #
        ############################################

        # fixed width because of better visualisation on different browsers
        for line in cells:
            if (z == 1):
               if (valid_img > 1):
                  if (kw['mode']=='1'):
                     result.append(formatter.table_cell(1))
                  else:
                      result.append('<td width="300" >')
            result.append('<table border="1">')
            result.append('<TR valign="top">')
            result.append('<td align="center" width="140">')
            result.append(line)
            result.append(formatter.table_cell(0))
            if (kw['show_text']=='1'):
                if (kw['mode']=='1'):
                  result.append(formatter.table_row(0))
                  result.append(formatter.table_row(1))

                if (kw['mode']=='1'):
                    result.append('<td width="140" >')
                else:
                    result.append('<td width="140" >')

                i_quote=0
                found=0
                for text in quotes['image'] :
                    if (text == cell_name[i]):
                        result.append(quotes['alias'][i_quote])
                        found=1
                    i_quote=i_quote+1

                if (found == 0):
                    result.append(cell_name[i])

                result.append(formatter.table_cell(0))
                if (kw['mode']=='1'):
                    result.append(formatter.table_row(0))


            if (kw['show_date']=='1'):
                if (kw['mode']=='1'):
                    result.append(formatter.table_row(1))
                    result.append(formatter.table_cell(1))
                    result.append(exif_date[i])
                    result.append(formatter.table_cell(0))
                    result.append(formatter.table_row(0))
            if (kw['show_tools'] == '1'):

               result.append(formatter.table_row(1))
               result.append('<td align="center">')
               result.append('<TABLE align="center">')
               result.append('<TR><td>')
               result.append('<FORM><TT>')

               result.append('<input type="hidden" name="action" value="AttachFile">')
               result.append('<input type="hidden" name="do" value=get>')
               result.append('<input type="hidden" name="target" value='+img[i]+'>')
               result.append('<input type="image" value="submit" src="wiki/modern/img/to_full.png" title="load image">')
               result.append('</TT></FONT></FORM>')
               result.append('</td><td>')
               result.append('<form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data"><TT>' % {
                             'baseurl': self.request.getScriptname(),
                             'pagename': wikiutil.quoteWikinameURL(current_pagename)})

               result.append('<input type="hidden" name="action" value="gallery2image">')
               result.append('<input type="hidden" name="do" value=PS>')
               result.append('<input type="hidden" name="target" value='+string.join(img,',')+'>')
               result.append('<input type="image" value="submit" src="wiki/modern/img/to_slide.png" title="slide_show">')
               result.append('</TT></FONT></FORM>')
               result.append('</td>')

               if self.request.user.may.delete(current_pagename):
                   result.append('<td>')

                   result.append('<form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data"><TT>' % {
                                 'baseurl': self.request.getScriptname(),
                                 'pagename': wikiutil.quoteWikinameURL(current_pagename)})

                   result.append('<input type="hidden" name="action" value="gallery2image">')
                   result.append('<input type="hidden" name="do" value=RL>')
                   result.append('<input type="hidden" name="target" value='+img[i]+'>')
                   result.append('<input type="image" value="submit" src="wiki/modern/img/to_left.png" title="rotate to left">')
                   result.append('</TT></FONT></FORM>')
                   result.append('</td><td>')
                   result.append('<form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data"><TT>' % {
                                'baseurl': self.request.getScriptname(),
                                'pagename': wikiutil.quoteWikinameURL(current_pagename)})

                   result.append('<input type="hidden" name="action" value="gallery2image">')
                   result.append('<input type="hidden" name="do" value=RR>')
                   result.append('<input type="hidden" name="target" value='+img[i]+'>')
                   result.append('<input type="image"  value="submit" src="wiki/modern/img/to_right.png" title="rotate to right">')

                   result.append('</TT></FONT></FORM>')
                   result.append('</td><td>')
                   result.append('<form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data"><TT>' % {
                                'baseurl': self.request.getScriptname(),
                                'pagename': wikiutil.quoteWikinameURL(current_pagename)})

                   result.append('<input type="hidden" name="action" value="gallery2image">')
                   result.append('<input type="hidden" name="do" value=RM>')
                   result.append('<input type="hidden" name="target" value='+img[i]+'>')
                   result.append('<input type="image" value="submit" src="wiki/modern/img/to_bak.png" title="move to bak">')
                   result.append('</TT></FONT></FORM>')
                   result.append('</TD>')
               result.append('</TR>')
               result.append('</TABLE>')

            result.append(formatter.table_cell(0))
            if (kw['show_date']=='1'):
                if not (kw['mode']=='1'):
                    result.append(formatter.table_cell(1))
                    result.append(exif_date[i])
                    result.append(formatter.table_cell(0))
            if (kw['show_tools'] == '1'):
               result.append(formatter.table_row(0))
            result.append(formatter.table(0))
            if ((z != cols) and (i < n-1)):
                result.append(formatter.table_cell(1))
            if (z == cols):
                result.append(formatter.table_cell(0))
                result.append(formatter.table_row(0))
            z=z+1
            i=i+1
            if (z > cols):
               z=1
        if (valid_img > 1):
           result.append(formatter.table(0))

        ##Output
        self.request.write(string.join(result,''))
        return()


