view data/plugin/action/arnica_slides.py @ 45:81df8eb31218

arnica_slides: removed not used command
author Reimar Bauer <rb.proj AT googlemail DOT com>
date Tue, 03 Jun 2008 09:18:23 +0200
parents 4bc44b6b90ba
children 83078930ae66
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 log
logging = log.getLogger(__name__)

from MoinMoin import  caching, config, wikiutil
from MoinMoin.Page import Page
from MoinMoin.packages import packLine, unpackLine
from MoinMoin.action import AttachFile
from MoinMoin.formatter.text_html import Formatter
from MoinMoin.util import filesys, timefuncs
from MoinMoin.action import ActionBase

try:
    import Image
except ImportError:
    Image = None

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

def image_rotate(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
    """
    # image
    image_object = Image.open(file_name)
    os.remove(file_name)
    image_object.rotate(angle).save(file_name, img_type)

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

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

def html_js(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();

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];
   }
}

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(request, pagename, alias, exif_date, images, idx, image_for_webnail):
    """ 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 images: all images
    @param idx: index position of the image
    @param image_for_webnail: identifier for AttchFile or arnica_slides
    """
    if not image_for_webnail:
        url = getAttachUrl(request.getScriptname(), pagename, "")
    else:
        url = AttachFile.getAttachUrl(pagename, "", request)

    option_webnail = option_list(url + images[idx], pagename, images, request, image_for_webnail)
    inner_table_style = ' style="border-style:none; margin:10px;"'
    this_webnail_list = "".join(["%s%s|" % (url, name) for name in images])

    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>
     </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": packLine(images),
"this_alias_text": wikiutil.escape(alias[idx], quote=1),
"this_alias_list": wikiutil.escape(packLine(alias), quote=1),
"this_exif_date_text": wikiutil.escape(exif_date[idx], quote=1),
"this_exif_date_list": wikiutil.escape(packLine(exif_date), quote=1),

"this_image": url + images[idx],
"pagename": pagename,
"tablestyle": inner_table_style,
"option_webnails": option_webnail,
}
    return html

def option_list(this_image, pagename, text, request, image_for_webnail):
    """ 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:
        if not image_for_webnail:
            url = getAttachUrl(request.getScriptname(), pagename, filename)
        else:
            url = AttachFile.getAttachUrl(pagename, filename, request)

        if url == 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 getAttachUrl(base_url, pagename, filename):
    """ Get URL that points to cache of `filename` on page `pagename`. """
    url = "%(base_url)s/%(pagename)s?action=arnica_slides&do=view&target=%(filename)s" % {'base_url': base_url,
                                                                                          'pagename': pagename,
                                                                                          'filename': filename}
    return wikiutil.escape(url)

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 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 render(self):
        """ does execute the commands of the form data """
        _ = self.request.getText
        request = self.request
        pagename = self.pagename
        page = Page(request, pagename)
        arena_dir = caching.get_arena_dir(request, page, 'item')
        msg = None

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

        # View Slides
        if command == 'VS':
            web = {}
            images = request.form.get('images', [''])[0]
            images = unpackLine(images)
            images = (images[1:])

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

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

            # XXX Check that all lists have same length
            idx = images.index(target)

            image_for_webnail = int(request.form.get("image_for_webnail", [0])[0])

            if not image_for_webnail:
                web['src'] = getAttachUrl(request.getScriptname(), pagename, target)
            else:
                web['src']  = AttachFile.getAttachUrl(pagename, target, request)

            web['title'] = target

            mimetype = "text/html"
            request.emit_http_headers(["Content-Type: %s; charset=%s" % (mimetype, config.charset)])

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

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

        # view sends a cached attachment (thumbnail or webnail) to the browser
        elif command == 'view':
            if not request.user.may.read(pagename):
                msg = _('You are not allowed to view attachments of this page.')

            fpath = os.path.join(arena_dir, target)
            if not target or not os.path.exists(fpath) or not wikiutil.isPicture(fpath):
                msg = _("Attachment '%(filename)s' does not exist!") % {"filename": target}

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

            timestamp = timefuncs.formathttpdate(int(os.path.getmtime(fpath)))
            if request.if_modified_since == timestamp:
                request.emit_http_headers(["Status: 304 Not modified"])
            else:
                mt = wikiutil.MimeType(filename=target)
                content_type = mt.content_type()
                mime_type = mt.mime_type()

                content_dispo = 'inline'
                filename_enc = target.encode(config.charset)

                request.emit_http_headers([
                    'Content-Type: %s' % content_type,
                    'Last-Modified: %s' % timestamp,
                    'Content-Length: %d' % os.path.getsize(fpath),
                    'Content-Disposition: %s; filename="%s"' % (content_dispo, filename_enc),
                     ])

                # send data
                request.send_file(open(fpath, 'rb'))

        elif request.user.may.delete(pagename) and request.request_method == 'POST':
        # only users which are allowed to delete should use this tool
        # ToDo besides lots of refactoring, logig when what is needed has to be rechecked
            filename, ext = os.path.splitext(target)

            if ext in ('.gif', '.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}

            thumbf = os.path.join(arena_dir, thumbfile)
            webf = os.path.join(arena_dir, webnail)
            cache_web = caching.CacheEntry(request, page, webnail, scope='item', use_pickle=True)
            cache_thumb = caching.CacheEntry(request, page, thumbfile, scope='item', use_pickle=True)

            infile = os.path.join(attachment_path, target)

            # removes attachment (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})
                # removes cache files
                cache_web.remove()
                cache_thumb.remove()

                msg = _('%(target)s deleted, backup in place' % {
                      'target': target})
            # rotate left
            elif command == 'RL':
                image_rotate(infile, webf, thumbf, 90, img_type)
                msg = _('%(target)s rotated to left 90 degrees' % {'target': target})

            # rotate right
            elif command == 'RR':
                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. """
    _ = request.getText
    if not Image:
        msg = _('The action %(action)s needs python imaging library (PIL) installed' % {'action': action_name})
        request.theme.add_msg(msg, "error")
        Page(request, pagename).send_page()
        return

    return arnica_slides(request, pagename).render()