Attachment 'ImageMap.py'

Download

   1 # -*- coding: iso-8859-1 -*-
   2 """
   3     MoinMoin - ImageMap Parser
   4 
   5     This parser is used to create clickable image maps.
   6     
   7     Syntax:
   8     
   9     {{{#!ImageMap
  10     picsrc[;width=".."][;height=".."][;alt=".."][;title=".."] 
  11     link_area1;shape="rect|circle|poly";coords="..";alt=".."[;title=".."]
  12     link_area2;shape="rect|circle|poly";coords="..";alt=".."[;title=".."]
  13     }}}
  14 
  15     For a detailed explanation of the syntax see:
  16     http://moinmoin.wikiwikiweb.de/ParserMarket/ImageMap
  17 
  18     Please note: Image maps are not accessible by blind people. Do also have a
  19     look at the best-practise-examples for using image maps
  20     on http://moinmoin.wikiwikiweb.de/ParserMarket/ImageMap.
  21     
  22     Example:
  23 
  24     {{{#!ImageMap
  25     picture.jpg;width="345";height="312";alt="Clickable Organizational Chart" 
  26     FrontPage;shape="rect";coords="11,10,59,29";alt="Area1"
  27     http://www.xyz.com/;shape="circle";coords="42,36,96";alt="Area2"
  28     FrontPage/SubPage;shape="poly";coords="48,311,105,248,96,210";alt="Area3"
  29     Another Site in This Wiki;shape="rect";coords="88,10,59,29";alt="Area4"
  30     InterWiki:RemotePage;shape="rect";coords="181,120,59,29";alt="Area5"
  31     }}}
  32 
  33     ImageMap Parser is partly based on ImageLink Macro
  34     ImageLink Macro
  35     @copyright: 2001 by Jeff Kunce,
  36                 2004 by Marcin Zalewski,
  37                 2004-2006 by Reimar Bauer,
  38                 2006 by Thomas Waldmann
  39     @license: GNU GPL, see COPYING for details.
  40 
  41     ImageMap Parser
  42     @copyright: 2006,2007 by Oliver Siemoneit
  43     @license: GNU GPL, see COPYING for details.
  44 
  45     Changes:
  46 
  47     Version 1.1
  48     * Made code PEP8 compatible.
  49     * Parameter checking and stripping added to prevent inserting of malicious
  50       code in html page via parser call.
  51 
  52     Version 1.2
  53     * Fixed ouput abstraction violations: on other formatters than html-formatter
  54       just the specified image is output via formatter.image and map information
  55       dropped.
  56     * In case of missing alt texts: "alt" ist set to alt="" (for the whole map)
  57       and to alt="area_url" (for the different clickable areas). 
  58     * Now also "title" supported to generate tooltips for the map areas.
  59     * Interwiki links can also be specified in "wiki:MoinMoin/Page" syntax now.
  60     
  61 """
  62 
  63 import os, random
  64 from MoinMoin import wikiutil, config
  65 from MoinMoin.action import AttachFile
  66 
  67 
  68 def _is_URL(text):
  69     return '://' in text
  70 
  71 def _is_InterWiki(text):
  72     return ':' in text
  73 
  74 def _is_allowed_Para(para, allowed_paras):
  75     found = False
  76     for p in allowed_paras:
  77         if para.startswith(p):
  78             found = True
  79     return found
  80 
  81 def _strip_Para(para):
  82     _para = wikiutil.escape(para)
  83     if para.count('"') < 2:
  84         return _para
  85     shortend_para = _para[0:_para.find('"')+1]
  86     cut_para = _para[_para.find('"')+1:len(_para)]
  87     shortend_para += cut_para[0:cut_para.find('"')+1]
  88     return shortend_para
  89 
  90 
  91 class Parser:
  92 
  93     def __init__(self, raw, request, **kw):
  94         self.raw = raw
  95         self.request = request
  96 
  97     def format(self, formatter):
  98         request = self.request
  99         _ = request.getText
 100         row = self.raw.split('\n')
 101                
 102         # Produce <img ...> html-code stuff
 103         paras = row[0].split(';')
 104         image = wikiutil.escape(paras[0])
 105         mapname = '%s_%s' % ([image, image[:15]][(len(image) > 14)], str(random.randint(1, 999999)))
 106         
 107         if _is_URL(image):
 108             imgurl = image
 109         elif _is_InterWiki(image):
 110             if image.startswith('wiki:'):
 111                 image = image[5:]
 112             wikitag, wikiurl, wikitail, err = wikiutil.resolve_wiki(request, image)
 113             imgurl = wikiutil.join_wiki(wikiurl, wikitail)
 114         else:
 115             pagename, attname = AttachFile.absoluteName(image, formatter.page.page_name)
 116             imgurl = AttachFile.getAttachUrl(pagename, attname, request)
 117             attachment_fname = AttachFile.getFilename(request, pagename, attname)
 118 
 119             if not os.path.exists(attachment_fname):
 120                 linktext = _('Upload new attachment "%(filename)s"')
 121                 output = wikiutil.link_tag(request,
 122                                          ('%s?action=AttachFile&rename=%s' % (
 123                                              wikiutil.quoteWikinameURL(pagename),
 124                                              wikiutil.url_quote_plus(attname))),
 125                                           text=linktext % {'filename': attname},
 126                                           formatter=formatter)
 127                 request.write(output)
 128                 return
 129         
 130         html = '''
 131 <img src="%s"''' % imgurl
 132         paras.pop(0)
 133 
 134         kw = {}
 135         kw['src'] = imgurl
 136         for p in paras:
 137             # Prevent attacks like: pic.png;height="10" onmouseover="ExecuteBadCode()";alt="..";
 138             # and: pic.png;height="10&#34; onmouseover=&#34;ExecuteBadCode()";alt="..";
 139             # and: pic.png;height=&#34;10&#34; onmouseover="ExecuteBadCode()";alt="..";
 140             p = _strip_Para(p)
 141             if _is_allowed_Para(p, ['width="', 'height="', 'alt="', 'title="']): 
 142                 html += ' %s' % p
 143                 # Prepare dict for formatter.image if formatter.rawHTML call fails
 144                 key, value = p.split('=', 1)
 145                 kw[str(key.lower())] = value.strip('"')
 146 
 147         # If there is no alt provided, create one
 148         if not 'alt' in kw:
 149             kw['alt'] = image
 150             html += ' alt=""'
 151 
 152         html += ' usemap="#%s"> ' % mapname
 153         row.pop(0)
 154         
 155         # Produce <map ..> html-code stuff
 156         html += '''
 157 <map name="%s">''' % mapname
 158 
 159         for p in row:
 160             paras = p.split(';')
 161             paras[0] = wikiutil.escape(paras[0])
 162 
 163             if _is_URL(paras[0]):
 164                 area_url = paras[0]
 165             elif _is_InterWiki(paras[0]):
 166                 if paras[0].startswith('wiki:'):
 167                     paras[0] = paras[0][5:]
 168                 wikitag, wikiurl, wikitail, err = wikiutil.resolve_wiki(request, paras[0])
 169                 area_url = wikiutil.join_wiki(wikiurl, wikitail)
 170             else:
 171                 area_url = wikiutil.quoteWikinameURL(paras[0])
 172             paras.pop(0)
 173             
 174             html += '''
 175     <area href="%s"''' % area_url
 176 
 177             for i in paras:
 178                 # Prevent attacks like: FrontPage;shape="rect" onmouseover="ExecuteBadCode()";coords="..";
 179                 # and: FrontPage;shape="rect&#34; onmouseover=&#34;ExecuteBadCode()";coords="..";
 180                 # and: FrontPage;shape=&#34;rect&#34; onmouseover="ExecuteBadCode()";coords="..";
 181                 i = _strip_Para(i) 
 182                 if _is_allowed_Para(i, ['shape="', 'coords="', 'alt="', 'title="']): 
 183                     html += ' %s' % i
 184             # If there is no alt provided at all, set alt to area_url
 185             if p.lower().find('alt="') == -1:
 186                 html += ' alt="%s"' % area_url
 187 
 188             html += '>'
 189 
 190         html += '''
 191 </map>
 192 '''
 193         # If current formatter is a HTML formatter, output image map with formatter.rawHTML().
 194         # Otherwise just output image with formatter.image()
 195         try:
 196             request.write(formatter.rawHTML(html))
 197         except:
 198             request.write(formatter.image(**kw))

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.
  • [get | view] (2007-07-05 17:59:14, 7.1 KB) [[attachment:ImageMap.py]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.