Back to index

moin  1.9.0~rc2
twikidraw.py
Go to the documentation of this file.
00001 # -*- coding: iso-8859-1 -*-
00002 """
00003     MoinMoin - twikidraw
00004 
00005     This action is used to call twikidraw
00006 
00007     @copyright: 2001 by Ken Sugino (sugino@mediaone.net),
00008                 2001-2004 by Juergen Hermann <jh@web.de>,
00009                 2005 MoinMoin:AlexanderSchremmer,
00010                 2005 DiegoOngaro at ETSZONE (diego@etszone.com),
00011                 2007-2008 MoinMoin:ThomasWaldmann,
00012                 2005-2009 MoinMoin:ReimarBauer,
00013     @license: GNU GPL, see COPYING for details.
00014 """
00015 import os, re
00016 
00017 from MoinMoin import log
00018 logging = log.getLogger(__name__)
00019 
00020 from MoinMoin import wikiutil, config
00021 from MoinMoin.action import AttachFile, do_show
00022 from MoinMoin.action.AttachFile import _write_stream
00023 from MoinMoin.security.textcha import TextCha
00024 
00025 action_name = __name__.split('.')[-1]
00026 
00027 
00028 def gedit_drawing(self, url, text, **kw):
00029     # This is called for displaying a drawing image by gui editor.
00030     _ = self.request.getText
00031     # TODO: this 'text' argument is kind of superfluous, replace by using alt=... kw arg
00032     # ToDo: make this clickable for the gui editor
00033     if 'alt' not in kw or not kw['alt']:
00034         kw['alt'] = text
00035     # we force the title here, needed later for html>wiki converter
00036     kw['title'] = "drawing:%s" % wikiutil.quoteWikinameURL(url)
00037     pagename, drawing = AttachFile.absoluteName(url, self.page.page_name)
00038     containername = wikiutil.taintfilename(drawing)
00039     drawing_url = AttachFile.getAttachUrl(pagename, containername, self.request)
00040     ci = AttachFile.ContainerItem(self.request, pagename, containername)
00041     if not ci.exists():
00042         title = _('Create new drawing "%(filename)s (opens in new window)"') % {'filename': self.text(containername)}
00043         img = self.icon('attachimg')  # TODO: we need a new "drawimg" in similar grey style and size
00044         css = 'nonexistent'
00045         return self.url(1, drawing_url, css=css, title=title) + img + self.url(0)
00046     kw['src'] = ci.member_url('drawing.png')
00047     return self.image(**kw)
00048 
00049 
00050 def attachment_drawing(self, url, text, **kw):
00051     # This is called for displaying a clickable drawing image by text_html formatter.
00052     # XXX text arg is unused!
00053     _ = self.request.getText
00054     pagename, drawing = AttachFile.absoluteName(url, self.page.page_name)
00055     containername = wikiutil.taintfilename(drawing)
00056 
00057     drawing_url = AttachFile.getAttachUrl(pagename, containername, self.request, do='modify')
00058     ci = AttachFile.ContainerItem(self.request, pagename, containername)
00059     if not ci.exists():
00060         title = _('Create new drawing "%(filename)s (opens in new window)"') % {'filename': self.text(containername)}
00061         img = self.icon('attachimg')  # TODO: we need a new "drawimg" in similar grey style and size
00062         css = 'nonexistent'
00063         return self.url(1, drawing_url, css=css, title=title) + img + self.url(0)
00064 
00065     title = _('Edit drawing %(filename)s (opens in new window)') % {'filename': self.text(containername)}
00066     kw['src'] = src = ci.member_url('drawing.png')
00067     kw['css'] = 'drawing'
00068 
00069     try:
00070         mapfile = ci.get('drawing.map')
00071         map = mapfile.read()
00072         mapfile.close()
00073         map = map.decode(config.charset)
00074     except (KeyError, IOError, OSError):
00075         map = u''
00076     if map:
00077         # we have a image map. inline it and add a map ref to the img tag
00078         # we have also to set a unique ID
00079         mapid = u'ImageMapOf%s%s' % (self.request.uid_generator(pagename), drawing)
00080         map = map.replace(u'%MAPNAME%', mapid)
00081         # add alt and title tags to areas
00082         map = re.sub(ur'href\s*=\s*"((?!%TWIKIDRAW%).+?)"', ur'href="\1" alt="\1" title="\1"', map)
00083         map = map.replace(u'%TWIKIDRAW%"', u'%s" alt="%s" title="%s"' % (
00084             wikiutil.escape(drawing_url, 1), title, title))
00085         # unxml, because 4.01 concrete will not validate />
00086         map = map.replace(u'/>', u'>')
00087         title = _('Clickable drawing: %(filename)s') % {'filename': self.text(containername)}
00088         if 'title' not in kw:
00089             kw['title'] = title
00090         if 'alt' not in kw:
00091             kw['alt'] = kw['title']
00092         kw['usemap'] = '#'+mapid
00093         return self.url(1, drawing_url) + map + self.image(**kw) + self.url(0)
00094     else:
00095         if 'title' not in kw:
00096             kw['title'] = title
00097         if 'alt' not in kw:
00098             kw['alt'] = kw['title']
00099         return self.url(1, drawing_url) + self.image(**kw) + self.url(0)
00100 
00101 
00102 class TwikiDraw(object):
00103     """ twikidraw action """
00104     def __init__(self, request, pagename, target):
00105         self.request = request
00106         self.pagename = pagename
00107         self.target = target
00108 
00109     def save(self):
00110         request = self.request
00111         _ = request.getText
00112         pagename = self.pagename
00113         target = self.target
00114         if not request.user.may.write(pagename):
00115             return _('You are not allowed to save a drawing on this page.')
00116         if not target:
00117             return _("Empty target name given.")
00118 
00119         file_upload = request.files.get('filepath')
00120         if not file_upload:
00121             # This might happen when trying to upload file names
00122             # with non-ascii characters on Safari.
00123             return _("No file content. Delete non ASCII characters from the file name and try again.")
00124 
00125         filename = request.form['filename']
00126         basepath, basename = os.path.split(filename)
00127         basename, ext = os.path.splitext(basename)
00128         ci = AttachFile.ContainerItem(request, pagename, target)
00129         filecontent = file_upload.stream
00130         content_length = None
00131         if ext == '.draw': # TWikiDraw POSTs this first
00132             AttachFile._addLogEntry(request, 'ATTDRW', pagename, target)
00133             ci.truncate()
00134             filecontent = filecontent.read() # read file completely into memory
00135             filecontent = filecontent.replace("\r", "")
00136         elif ext == '.map':
00137             # touch attachment directory to invalidate cache if new map is saved
00138             attach_dir = AttachFile.getAttachDir(request, pagename)
00139             os.utime(attach_dir, None)
00140             filecontent = filecontent.read() # read file completely into memory
00141             filecontent = filecontent.strip()
00142         else:
00143             #content_length = file_upload.content_length
00144             # XXX gives -1 for wsgiref :( If this is fixed, we could use the file obj,
00145             # without reading it into memory completely:
00146             filecontent = filecontent.read()
00147 
00148         ci.put('drawing' + ext, filecontent, content_length)
00149 
00150 
00151     def render(self):
00152         request = self.request
00153         _ = request.getText
00154         pagename = self.pagename
00155         target = self.target
00156         if not request.user.may.read(pagename):
00157             return _('You are not allowed to view attachments of this page.')
00158         if not target:
00159             return _("Empty target name given.")
00160 
00161         ci = AttachFile.ContainerItem(request, pagename, target)
00162         if ci.exists():
00163             drawurl = ci.member_url('drawing.draw')
00164             pngurl = ci.member_url('drawing.png')
00165         else:
00166             drawurl = 'drawing.draw'
00167             pngurl = 'drawing.png'
00168         pageurl = request.href(pagename)
00169         saveurl = request.href(pagename, action=action_name, do='save', target=target)
00170         helpurl = request.href("HelpOnActions/AttachFile")
00171 
00172         html = """
00173 <p>
00174 <applet code="CH.ifa.draw.twiki.TWikiDraw.class"
00175         archive="%(htdocs)s/applets/TWikiDrawPlugin/twikidraw.jar" width="640" height="480">
00176     <param name="drawpath" value="%(drawurl)s">
00177     <param name="pngpath"  value="%(pngurl)s">
00178     <param name="savepath" value="%(saveurl)s">
00179     <param name="basename" value="%(basename)s">
00180     <param name="viewpath" value="%(pageurl)s">
00181     <param name="helppath" value="%(helpurl)s">
00182     <strong>NOTE:</strong> You need a Java enabled browser to edit the drawing.
00183 </applet>
00184 </p>
00185 """ % dict(
00186     htdocs=request.cfg.url_prefix_static,
00187     basename=wikiutil.escape(target, 1),
00188     drawurl=wikiutil.escape(drawurl, 1),
00189     pngurl=wikiutil.escape(pngurl, 1),
00190     pageurl=wikiutil.escape(pageurl, 1),
00191     saveurl=wikiutil.escape(saveurl, 1),
00192     helpurl=wikiutil.escape(helpurl, 1),
00193 )
00194 
00195         title = "%s %s:%s" % (_("Edit drawing"), pagename, target)
00196         request.theme.send_title(title, page=request.page, pagename=pagename)
00197         request.write(request.formatter.startContent("content"))
00198         request.write(request.formatter.rawHTML(html))
00199         request.write(request.formatter.endContent())
00200         request.theme.send_footer(pagename)
00201         request.theme.send_closing_html()
00202 
00203 
00204 def execute(pagename, request):
00205     target = request.values.get('target')
00206     twd = TwikiDraw(request, pagename, target)
00207 
00208     do = request.values.get('do')
00209     if do == 'save':
00210         msg = twd.save()
00211     else:
00212         msg = twd.render()
00213     if msg:
00214         request.theme.add_msg(msg, 'error')
00215         do_show(pagename, request)
00216 
00217