view data/plugin/action/arnica_slides.py @ 12:39ca17464e9c

arnica_slides: fixed definition of do_action_finish
author Reimar Bauer <rb.proj AT googlemail DOT com>
date Sun, 09 Mar 2008 18:50:41 +0100
parents 7d73f63ca30e
children cd19dc74d179
line wrap: on
line source
# -*- coding: iso-8859-1 -*-
"""
    MoinMoin - arnica_slides Action macro
    This action macro is used to rotate, move to bak or to slide through the images from arnica

    based on gallery2image by ReimarBauer 2005-2008
    
    @copyright: 2008 by MoinMoin:ReimarBauer
    @license: GNU GPL, see COPYING for details.
"""
Dependencies = []
import os
from MoinMoin import  wikiutil
from MoinMoin.Page import Page
from MoinMoin.action import AttachFile
from MoinMoin.formatter.text_html import Formatter
from MoinMoin.util import filesys
from MoinMoin.action import ActionBase

try:
    import Image
except ImportError:
    Image = None

action_name = __name__.split('.')[-1]

class arnica_slides(ActionBase):
    """ arnica_slides page action

    Note: the action name is the class name
    """
    def __init__(self, request, pagename):
        ActionBase.__init__(self, pagename, request)
        self.request = request
        self.pagename = pagename
        self.page = Page(request, pagename)
        self.method = 'POST'
        self.enctype = 'multipart/form-data'

    def is_excluded(self):
        """ Return True if action is excluded """
        return self.actionname in self.cfg.actions_excluded

    def is_allowed(self):
        """ Return True if read access is allowed """
        may = self.request.user.may
        return may.read(self.pagename)

    def get_path_url(self, request, pagename, attachment_path):
        """ Returns attachment path and it's url 
        @param request: request object
        @pagename: pagename of attachments
        @attachment_path: path to attachment
        """
        url = AttachFile.getAttachUrl(pagename, '', request)
        # xxx fix this at the right place!
        url = url.replace('//', '/')
        return attachment_path, url

    def option_list(self, this_image, pagename, text, request):
        """ generates the pulldown option list
        @param this_image: selected image  on top
        @param pagename: pagename of attachments
        @param text: array of filenames
        @param request: request object
        """
        txt = ''

        for filename in text:
            name = AttachFile.getAttachUrl(pagename, filename, request)
            if name == this_image:
                txt += '<option selected value="%(name)s">%(alias)s' % {
                    "name": this_image,
                    "alias": filename.replace('tmp.', '')}
            else:
                txt += '<option value="%(name)s">%(alias)s' % {
                    "name": this_image,
                    "alias": filename.replace('tmp.', '')}

        return txt

    def html_js(self, request, counter):
        """ javscript for the slides 
        @param request: request object
        @param this_image:  url of image to start
        @param counter: index position of this_image
        """

        html = '''
<SCRIPT LANGUAGE="JavaScript">
<!-- Original:  Ricocheting (ricocheting@hotmail.com) -->
<!-- Web Site:  http://www.ricocheting.com -->

<!-- This script and many more are available free online at -->
<!-- The JavaScript Source!! http://javascript.internet.com -->

<!-- Modifications by MoinMoin:ReimarBauer -->
<!-- 2005-10-29 -->
<!-- Many thanks to Ricocheting, it is much easier as my own one. I like it -->
<!-- Some code added and replaced for the MoinMoin:arnica parser-->


<!-- Begin 

var rotate_delay = 5; // delay in milliseconds (5000 = 5 secs)
var current = %(counter)s;
var theImages = new Array();
var thewebImages =  new Array();

function arnica_preload() {
   var list = document.slideform.webnail_list.value;
   var value = list.split(","); 
   var n = value.length;
   
   for (i = 0; i <  n-1; i++){
       theImages[i] = new Image();
       theImages[i].src = value[i];
   }   
   thewebImages = theImages;
} 

function arnica_getserver() {
     var value = document.URL;
     var text = value.split("/");
     return text[0]+'//'+text[2];
}     

function arnica_show_image(image) {
    return arnica_getserver() + '%(htdocs)s' + '/common/arnica/' + image;
} 

function arnica_add_comments() {
  var alias_text = document.slideform.alias.value;
  var exif_date_text = document.slideform.exif_date.value;
  var index = document.slideform.slide.selectedIndex;
  var alias = alias_text.split("!,!");
  var exif = exif_date_text.split(",");
  document.getElementById("arnica_alias_text").innerHTML = alias[index];
  document.getElementById("arnica_exif_date_text").innerHTML = exif[index];
}

function arnica_next_slide() {
   if (document.slideform.slide[current+1]) {
      document.images.show.src = theImages[current+1].src;
      document.slideform.slide.selectedIndex = ++current;
      arnica_add_comments();
   }
   else arnica_first_slide();
   document.getElementById("arnica_first_slide").innerHTML = '<img src="'+arnica_show_image('arnica_first.png')+'" onclick="arnica_first_slide();" name="fs"  title="first slide" >';
   document.getElementById("arnica_last_slide").innerHTML = '<img src="'+arnica_show_image('arnica_last.png')+'" onclick="arnica_last_slide();" name="fs"  title="last slide" >';
}

function arnica_previous_slide() {
   if (current-1 >= 0) {
      document.images.show.src = theImages[current-1].src;  
      document.slideform.slide.selectedIndex = --current;
      arnica_add_comments(); 
   }
   else arnica_last_slide();
   document.getElementById("arnica_first_slide").innerHTML = '<img src="'+arnica_show_image('arnica_first.png')+'" onclick="arnica_first_slide();" name="fs"  title="first slide" >';
   document.getElementById("arnica_last_slide").innerHTML = '<img src="'+arnica_show_image('arnica_last.png')+'" onclick="arnica_last_slide();" name="fs"  title="last slide" >';
}

function arnica_first_slide() {
   current = 0;
   document.images.show.src = theImages[0].src;  
   document.slideform.slide.selectedIndex = 0;
   arnica_add_comments();
   document.getElementById("arnica_first_slide").innerHTML = '<img src="'+arnica_show_image('arnica_first_disabled.png')+'" title="first slide" >';
   document.getElementById("arnica_last_slide").innerHTML = '<img src="'+arnica_show_image('arnica_last.png')+'" onclick="arnica_last_slide();" name="fs"  title="last slide" >';
}

function arnica_last_slide() {
   current = document.slideform.slide.length-1;
   document.images.show.src = theImages[current].src; 
   document.slideform.slide.selectedIndex = current;
   arnica_add_comments();
   document.getElementById("arnica_first_slide").innerHTML = '<img src="'+arnica_show_image('arnica_first.png')+'" onclick="arnica_first_slide();" name="fs"  title="first slide" >';
   document.getElementById("arnica_last_slide").innerHTML = '<img src="'+arnica_show_image('arnica_last_disabled.png')+'" title="last slide" >';
}

function arnica_ap(text) {
   document.slideform.slidebutton.value = (text == "Stop") ? "Start" : "Stop";
   arnica_rotate();
}

function arnica_change() {
   current = document.slideform.slide.selectedIndex;
   document.images.show.src = theImages[current].src; 
   arnica_add_comments(); 
   document.getElementById("arnica_first_slide").innerHTML = '<img src="'+arnica_show_image('arnica_first.png') +'" onclick="arnica_first_slide();" name="fs"  title="first slide" >';
   document.getElementById("arnica_last_slide").innerHTML = '<img src="'+arnica_show_image('arnica_last.png')+'" onclick="arnica_last_slide();" name="fs"  title="last slide" >';
}

function arnica_rotate() {
   if (document.slideform.slidebutton.value == "Stop") {
      current = (current == document.slideform.slide.length-1) ? 0 : current+1;
      document.images.show.src = theImages[current].src; 
      document.slideform.slide.selectedIndex = current;
      arnica_add_comments(); 
      document.getElementById("arnica_first_slide").innerHTML = '<img src="'+arnica_show_image('arnica_first.png')+'" onclick="arnica_first_slide();" name="fs"  title="first slide" >';
      document.getElementById("arnica_last_slide").innerHTML = '<img src="'+arnica_show_image('arnica_last.png')+'" onclick="arnica_last_slide();" name="fs"  title="last slide" >';
      rotate_delay = document.slideform.duration.value * 1000.;
      window.setTimeout("arnica_rotate()", rotate_delay);
   }
}
//  End -->
</script> ''' % {
  'htdocs': request.cfg.url_prefix_static,
  'counter': counter}

        return html

    def html_slideform(self, request, pagename, alias, exif_date, target, idx):
        """ html code for the slideform
        @param request: request object
        @param pagename: pagename where the attachments are located
        @param url_wiki_page: 
        @param alias: text alias for filename
        @param exif_date:  date information 
        @param target: all images 
        @param idx:  index position of the image
        """

        attachment_path = AttachFile.getAttachDir(request, pagename)
        static_path, static_url = self.get_path_url(request, pagename, attachment_path )

        option_webnail = self.option_list(static_url + target[idx], pagename, target, request)
        static_path, static_url = self.get_path_url(request, pagename, attachment_path)

        inner_table_style = ' style="border-style:none; margin:10px;"'

        this_webnail_list = ''
        for name in target:
            this_webnail_list += static_url + name + ','
            html = '''
<form name=slideform method="POST">
   <input type="hidden" name="flag" value="webnail">
   <input type="hidden" name="webnail_list" value='%(this_webnail_list)s'>
   <input type="hidden" name="webnail_name" value='%(this_webnail_name)s'>
   <input type="hidden" name="alias" value='%(this_alias_list)s'>
   <input type="hidden" name="exif_date" value='%(this_exif_date_list)s'>
   <BR>
   <table%(tablestyle)s>
    <tr>
     <td style="border-style:none" bgcolor="#C0C0C0"><strong>Slide: </strong></td>
     <td style="border-style:none" bgcolor="#C0C0C0">
       <select name="slide" onChange="arnica_change();" >
         %(option_webnails)s
       </select>
     </td>
     <td style="border-style:none" bgcolor="#C0C0C0">
      <input type="button" name="slidebutton" onClick="arnica_ap(this.value);" value="Start" title="AutoPlay">
     </td>
     <td style="border-style:none" bgcolor="#C0C0C0">
      <strong>Duration (sec): </strong>
     </td>
     <td style="border-style:none" bgcolor="#C0C0C0">
      <input type="input" name="duration" value="3.0" size="3">
     </td>
   </tr>
   <tr>
     <td style="border-style:none" colspan="5" align="center" bgcolor="#C0C0C0">
     <SPAN id="arnica_first_slide"><img src="%(server)s%(htdocs)s/common/arnica/arnica_first.png" onclick="arnica_first_slide();" name="fs"  title="first slide" ></SPAN>
     <img src="%(server)s%(htdocs)s/common/arnica/arnica_previous.png" onclick="arnica_previous_slide();"  title="previous slide" >
     <img src="%(server)s%(htdocs)s/common/arnica/arnica_next.png" onClick="arnica_next_slide();"  title="next slide" >
     <SPAN id="arnica_last_slide"><img src="%(server)s%(htdocs)s/common/arnica/arnica_last.png" onClick="arnica_last_slide();"  title="last slide" ></SPAN>
     <input type="image" value="submit" src="%(server)s%(htdocs)s/common/arnica/arnica_back.png" title="return to %(pagename)s">
     </td>
   </tr>
   <tr>
    <td style="border-style:none" colspan="5" align="center" bgcolor="#C0C0C0">
     <img src="%(server)s/%(this_image)s" name="show">
    </td>
   </tr>
   <tr valign="center">
    <td style="border-style:none"colspan="5" bgcolor="#C0C0C0" align="left">
     <P><SPAN id="arnica_alias_text">%(this_alias_text)s</SPAN></P>
    </td></tr>
   <tr valign="center">
    <td style="border-style:none" colspan="5" bgcolor="#C0C0C0" align="left">  
     <P><SPAN id="arnica_exif_date_text">%(this_exif_date_text)s</SPAN></P>
    </td>
  </tr>
</table>
</form>
''' % {
"server": request.getQualifiedURL(),
"htdocs": request.cfg.url_prefix_static,
"base_url": request.getScriptname(),
"this_webnail_list": this_webnail_list,
"this_webnail_name": ','.join(target),
"this_alias_text": wikiutil.escape(alias[idx], quote=1),
"this_alias_list": wikiutil.escape('!,!'.join(alias), quote=1),
"this_exif_date_text": wikiutil.escape(exif_date[idx], quote=1),
"this_exif_date_list": wikiutil.escape(','.join(exif_date), quote=1),

"this_image": static_url + target[idx], # AttachFile.getAttachUrl(pagename, target[idx], request),
"pagename": pagename,
"tablestyle": inner_table_style,
"option_webnails": option_webnail,
}
        return html

    def do_action(self):
        """ Do the action and either return error msg or None, if there was no error. """
        return None

    def do_action_finish(self, success):
        """ Do the action and either return error msg or None, if there was no error. """
        return None

    def image_rotate(self, file_name, webf, thumbf, angle, img_type):
        """ rotates the image and dependent images
        
        @param file: the name of the attachment
        @param webf: the name of the webnail
        @param thumbf: the name of the thumbnail
        @param angle: the angle to rotate to
        @param img_type: type of image PNG or JPEG
        """
        _ = self.request.getText
        if not Image:
            msg = _('The action %(action)s needs python imaging library (PIL) installed' % {'action': action_name})
            self.request.theme.add_msg(msg, "error")
            Page(self.request, self.pagename).send_page()
            return
        # image
        im = Image.open(file_name)
        os.remove(file_name)
        im.rotate(angle).save(file_name, img_type)

        # image becomes webnail
        nim = Image.open(file_name)
        nim.thumbnail((640, 640), Image.ANTIALIAS)
        os.remove(webf)
        nim.save(webf, img_type)

        # image becomes thumbnail based on webnail
        nim.thumbnail((128, 128), Image.ANTIALIAS)
        os.remove(thumbf)
        nim.save(thumbf, img_type)

    def render(self):
        """ does execute the commands of the form data """
        _ = self.request.getText
        request = self.request
        pagename = self.pagename

        if not Image:
            msg = _('The action %(action)s needs python imaging library (PIL) installed' % {'action': action_name})
            request.theme.add_msg(msg, "error")
            self.page.send_page()
            return

        request.formatter = Formatter(request)
        attachment_path = AttachFile.getAttachDir(request, self.pagename)
        command = request.form.get('do', ['none'])[0]

        if command == 'VS':
            web = {}
            images = request.form.get('target', [''])[0]
            images = images.split(',')
            target = images[0]
            images = (images[1:])

            all_description = request.form.get('alias', [''])[0]
            all_description = all_description.split('!,!')
            #this_description = all_description[0]
            all_description = (all_description[1:])

            all_exif_date = request.form.get('exif_date', [''])[0]
            all_exif_date = all_exif_date.split(',')
            all_exif_date = (all_exif_date[1:])

           # XXX Check that all lists have same length
            z = 0
            for img in images:
                if target == img:
                    idx = z
                z += 1

            attachment_path = AttachFile.getAttachDir(request, pagename)

            static_path, static_url = self.get_path_url(request, pagename, attachment_path)

            web['src'] = static_url+target #AttachFile.getAttachUrl(pagename, target, request)
            web['title'] = target

            request.theme.send_title(pagename,
                                 pagename=pagename,
                                 body_onload="arnica_preload();",
                                 html_head=self.html_js(request, idx))

            request.write(request.formatter.startContent("content"))
            html = self.html_slideform(request, pagename, all_description, all_exif_date, images, idx)
            request.write(html)
            request.write(request.formatter.endContent())
            request.write(request.theme.send_footer(pagename))
            msg = None

        elif command == 'PS':
            msg = None

        elif command == 'BS':
            msg = "gone back" 

        elif request.user.may.delete(pagename):
        # only users which are allowed to delete should use this tool

            target = request.form.get('target', [''])[0]
            filename, ext = os.path.splitext(target)

            if ext == '.gif'  or  ext == '.png':
                img_type = 'PNG'
                thumbfile = "tmp.thumbnail_%(file)s.png" % {"file": filename}
                webnail = "tmp.webnail_%(file)s.png" % {"file": filename}
            else:
                img_type = "JPEG"
                thumbfile = "tmp.thumbnail_%(file)s.jpg"  % {"file": filename}
                webnail = "tmp.webnail_%(file)s.jpg"  % {"file": filename}

            static_path, static_url = self.get_path_url(request, pagename, attachment_path)

            thumbf = os.path.join(static_path, thumbfile)
            webf = os.path.join(static_path, webnail)
            infile = os.path.join(attachment_path, target)

            msg = None
            # removes (moves to bak)
            if command == 'RM':
                if os.path.exists(infile + '.bak'):
                    os.unlink("%(file)s.bak" % {"file": infile})
                filesys.rename(infile, "%(file)s.bak" % {"file": infile})
                msg = _('%(target)s deleted, backup in place' % {
                      'target':target})
            # rotate left
            elif command == 'RL':
                self.image_rotate(infile, webf, thumbf, 90, img_type)
                msg = _('%(target)s rotated to left 90 degrees' % {'target':target})

            # rotate right
            elif command == 'RR':
                self.image_rotate(infile, webf, thumbf, 270, img_type)
                msg = _('%(target)s rotated to right 90 degrees' % {'target':target})
            else:
                # fallback
                msg = _('action not implemented: %s') % (command, )
        else:
            msg = _('Your are not allowed to change attachments on this page: %s') % (pagename,)

        if msg:
            request.theme.add_msg(msg, "info")
            self.page.send_page()

def execute(pagename, request):
    """ Main dispatcher for the arnica_slides action.
    """
    return arnica_slides(request, pagename).render()