def do_replaceunderlayattachment(self, zipname, filename, pagename, author=u"Scripting Subsystem", comment=u""): """ overwrite underlay attachments @param pagename: Page where the file is attached. Or in 2.0, the file itself. @param zipname: Filename of the attachment from the zip file @param filename: Filename of the attachment (just applicable for MoinMoin < 2.0) """ if self.request.user.may.write(pagename): _ = self.request.getText filename = wikiutil.taintfilename(filename) zipname = wikiutil.taintfilename(zipname) page = PageEditor(self.request, pagename, do_editor_backup=0, uid_override=author) pagedir = page.getPagePath(use_underlay=1, check_create=1) attachments = os.path.join(pagedir, 'attachments') if not os.path.exists(attachments): os.mkdir(attachments) target = os.path.join(attachments, filename) self._extractToFile(zipname, target) if os.path.exists(target): filesys.chmod(target, 0666 & config.umask) else: self.msg += u"action replace underlay attachment: not enough rights - nothing done \n"
def do_copythemefile(self, filename, ftype, target): """ Copies a theme-related file (CSS, PNG, etc.) into a directory of the current theme. @param filename: name of the file in this package @param ftype: the subdirectory of the theme directory, e.g. "css" @param target: filename, e.g. "screen.css" """ _ = self.request.getText if self.themename is None: raise RuntimeScriptException(_("The theme name is not set.")) from MoinMoin.web.static import STATIC_FILES_PATH as htdocs_dir if not os.access(htdocs_dir, os.W_OK): raise RuntimeScriptException( _("Theme files not installed! Write rights missing for %s.") % htdocs_dir) theme_file = os.path.join(htdocs_dir, self.themename, wikiutil.taintfilename(ftype), wikiutil.taintfilename(target)) theme_dir = os.path.dirname(theme_file) if not os.path.exists(theme_dir): os.makedirs(theme_dir) self._extractToFile(filename, theme_file)
def do_addattachment(self, zipname, filename, pagename, author=u"Scripting Subsystem", comment=u""): """ Installs an attachment @param pagename: Page where the file is attached. Or in 2.0, the file itself. @param zipname: Filename of the attachment from the zip file @param filename: Filename of the attachment (just applicable for MoinMoin < 2.0) """ if self.request.user.may.write(pagename): _ = self.request.getText attachments = Page(self.request, pagename).getPagePath("attachments", check_create=1) filename = wikiutil.taintfilename(filename) zipname = wikiutil.taintfilename(zipname) target = os.path.join(attachments, filename) page = PageEditor(self.request, pagename, do_editor_backup=0, uid_override=author) rev = page.current_rev() path = page.getPagePath(check_create=0) if not os.path.exists(target): self._extractToFile(zipname, target) if os.path.exists(target): os.chmod(target, config.umask ) action = 'ATTNEW' edit_logfile_append(self, pagename, path, rev, action, logname='edit-log', comment=u'%(filename)s' % {"filename": filename}, author=author) self.msg += u"%(filename)s attached \n" % {"filename": filename} else: self.msg += u"%(filename)s not attached \n" % {"filename": filename} else: self.msg += u"action add attachment: not enough rights - nothing done \n"
def _do_attachment_move(pagename, request): _ = request.getText if 'cancel' in request.form: return _('Move aborted!') if not wikiutil.checkTicket(request, request.form.get('ticket', '')): return _('Please use the interactive user interface to use action %(actionname)s!') % {'actionname': 'AttachFile.move' } if not request.user.may.delete(pagename): return _('You are not allowed to move attachments from this page.') if 'newpagename' in request.form: new_pagename = request.form.get('newpagename') else: upload_form(pagename, request, msg=_("Move aborted because new page name is empty.")) if 'newattachmentname' in request.form: new_attachment = request.form.get('newattachmentname') if new_attachment != wikiutil.taintfilename(new_attachment): upload_form(pagename, request, msg=_("Please use a valid filename for attachment '%(filename)s'.") % { 'filename': new_attachment}) return else: upload_form(pagename, request, msg=_("Move aborted because new attachment name is empty.")) attachment = request.form.get('oldattachmentname') if attachment != wikiutil.taintfilename(attachment): upload_form(pagename, request, msg=_("Please use a valid filename for attachment '%(filename)s'.") % { 'filename': attachment}) return move_file(request, pagename, new_pagename, attachment, new_attachment)
def do_addattachment(self, zipname, filename, pagename, author=u"Scripting Subsystem", comment=u""): """ Installs an attachment @param pagename: Page where the file is attached. Or in 2.0, the file itself. @param zipname: Filename of the attachment from the zip file @param filename: Filename of the attachment (just applicable for MoinMoin < 2.0) """ if self.request.user.may.write(pagename): _ = self.request.getText attachments = Page(self.request, pagename).getPagePath("attachments", check_create=1) filename = wikiutil.taintfilename(filename) zipname = wikiutil.taintfilename(zipname) target = os.path.join(attachments, filename) page = PageEditor(self.request, pagename, do_editor_backup=0, uid_override=author) rev = page.current_rev() path = page.getPagePath(check_create=0) if not os.path.exists(target): self._extractToFile(zipname, target) if os.path.exists(target): filesys.chmod(target, 0666 & config.umask) action = 'ATTNEW' edit_logfile_append(self, pagename, path, rev, action, logname='edit-log', comment=u'%(filename)s' % {"filename": filename}, author=author) self.msg += u"%(filename)s attached \n" % { "filename": filename } else: self.msg += u"%(filename)s not attached \n" % { "filename": filename } else: self.msg += u"action add attachment: not enough rights - nothing done \n"
def add_attachment(request, pagename, target, filecontent, overwrite=0): """ save <filecontent> to an attachment <target> of page <pagename> filecontent can be either a str (in memory file content), or an open file object (file content in e.g. a tempfile). """ # replace illegal chars target = wikiutil.taintfilename(target) # get directory, and possibly create it attach_dir = getAttachDir(request, pagename, create=1) fpath = os.path.join(attach_dir, target).encode(config.charset) exists = os.path.exists(fpath) if exists: if overwrite: remove_attachment(request, pagename, target) else: raise AttachmentAlreadyExists # save file stream = open(fpath, 'wb') try: _write_stream(filecontent, stream) finally: stream.close() _addLogEntry(request, 'ATTNEW', pagename, target) filesize = os.path.getsize(fpath) event = FileAttachedEvent(request, pagename, target, filesize) send_event(event) return target, filesize
def attachment_inlined(self, url, text, **kw): from MoinMoin.action import AttachFile import os _ = self.request.getText pagename, filename = AttachFile.absoluteName(url, self.page.page_name) fname = wikiutil.taintfilename(filename) fpath = AttachFile.getFilename(self.request, pagename, fname) ext = os.path.splitext(filename)[1] Parser = wikiutil.getParserForExtension(self.request.cfg, ext) if Parser is not None: try: content = file(fpath, "r").read() # Try to decode text. It might return junk, but we don't # have enough information with attachments. content = wikiutil.decodeUnknownInput(content) if ".csv" in getattr(Parser, "extensions", list()): colorizer = Parser(content, self.request, filename=filename, format_args=kw.get("format_args", "")) else: colorizer = Parser(content, self.request, filename=filename) colorizer.format(self) except IOError: pass return self.attachment_link(1, url) + self.text(text) + self.attachment_link(0)
def xmlrpc_putAttachment(self, pagename, attachname, data): """ Set attachname associated with pagename to data @param pagename: pagename (utf-8) @param attachname: attachment name (utf-8) @param data: file data (base64) @rtype boolean @return True if attachment was set """ pagename = self._instr(pagename) # User may read page? if not self.request.user.may.read(pagename): return self.notAllowedFault() # also check ACLs if not self.request.user.may.write(pagename): return xmlrpclib.Fault(1, "You are not allowed to edit this page") attachname = wikiutil.taintfilename(attachname) filename = AttachFile.getFilename(self.request, pagename, attachname) if os.path.exists(filename) and not os.path.isfile(filename): return self.noSuchPageFault() open(filename, 'wb+').write(data.data) AttachFile._addLogEntry(self.request, 'ATTNEW', pagename, filename) return xmlrpclib.Boolean(1)
def do_delattachment(self, filename, pagename, author=u"Scripting Subsystem", comment=u""): """ Removes an attachment @param pagename: Page where the file is attached. Or in 2.0, the file itself. @param filename: Filename of the attachment (just applicable for MoinMoin < 2.0) """ if self.request.user.may.write(pagename): _ = self.request.getText attachments = Page(self.request, pagename).getPagePath("attachments", check_create=1) filename = wikiutil.taintfilename(filename) target = os.path.join(attachments, filename) page = PageEditor(self.request, pagename, do_editor_backup=0, uid_override=author) rev = page.current_rev() path = page.getPagePath(check_create=0) if os.path.exists(target): os.remove(target) action = 'ATTDEL' edit_logfile_append(self, pagename, path, rev, action, logname='edit-log', comment=u'%(filename)s' % {"filename": filename}, author=author) self.msg += u"%(filename)s removed \n" % {"filename": filename} else: self.msg += u"%(filename)s does not exist \n" % {"filename": filename} else: self.msg += u"action delete attachment: not enough rights - nothing done \n"
def xmlrpc_putAttachment(self, pagename, attachname, data): """ Store <data> as content of attachment <attachname> of page <pagename>. @param pagename: pagename (utf-8) @param attachname: attachment name (utf-8) @param data: file data (base64) @rtype: bool @return: True if attachment was successfully stored """ pagename = self._instr(pagename) # User may read page? if not self.request.user.may.read(pagename): return self.notAllowedFault() # also check ACLs if not self.request.user.may.write(pagename): return xmlrpclib.Fault(1, "You are not allowed to edit this page") attachname = wikiutil.taintfilename(self._instr(attachname)) filename = AttachFile.getFilename(self.request, pagename, attachname) if os.path.exists(filename) and not os.path.isfile(filename): return self.noSuchPageFault() open(filename, 'wb+').write(data.data) AttachFile._addLogEntry(self.request, 'ATTNEW', pagename, attachname) return xmlrpclib.Boolean(1)
def attachment_inlined(self, url, text, **kw): from MoinMoin.action import AttachFile import os _ = self.request.getText pagename, filename = AttachFile.absoluteName(url, self.page.page_name) fname = wikiutil.taintfilename(filename) fpath = AttachFile.getFilename(self.request, pagename, fname) ext = os.path.splitext(filename)[1] Parser = wikiutil.getParserForExtension(self.request.cfg, ext) if Parser is not None: try: content = file(fpath, 'r').read() # Try to decode text. It might return junk, but we don't # have enough information with attachments. content = wikiutil.decodeUnknownInput(content) if '.csv' in getattr(Parser, 'extensions', list()): colorizer = Parser(content, self.request, filename=filename, format_args=kw.get('format_args', '')) else: colorizer = Parser(content, self.request, filename=filename) colorizer.format(self) except IOError: pass return (self.attachment_link(1, url) + self.text(text) + self.attachment_link(0))
def package(self): """ Calls collectpackage() with the arguments specified. """ _ = self.request.getText # Get new name from form and normalize. pagelist = self.request.values.get('pagelist', u'') packagename = self.request.values.get('packagename', u'') include_attachments = self.request.values.get('include_attachments', False) if not self.request.values.get('submit'): self.request.theme.add_msg(self.makeform(), "dialog") raise ActionError target = wikiutil.taintfilename(packagename) if not target: self.request.theme.add_msg(self.makeform(_('Invalid filename "%s"!') % wikiutil.escape(packagename)), "error") raise ActionError request = self.request filelike = cStringIO.StringIO() package = self.collectpackage(unpackLine(pagelist, ","), filelike, target, include_attachments) request.headers['Content-Type'] = 'application/zip' request.headers['Content-Length'] = filelike.tell() request.headers['Content-Disposition'] = 'inline; filename="%s"' % target request.write(filelike.getvalue()) filelike.close()
def attachment_inlined(self, url, text, **kw): from MoinMoin.action import AttachFile import os _ = self.request.getText pagename, filename = AttachFile.absoluteName(url, self.page.page_name) fname = wikiutil.taintfilename(filename) fpath = AttachFile.getFilename(self.request, pagename, fname) ext = os.path.splitext(filename)[1] Parser = wikiutil.getParserForExtension(self.request.cfg, ext) if Parser is not None: try: # rU: universal newline support so that even a \r is considered a valid line separator. # CSV exported by office (on Mac?) has \r line separators. content = file(fpath, 'rU').read() # Try to decode text. It might return junk, but we don't # have enough information with attachments. content = wikiutil.decodeUnknownInput(content) colorizer = Parser(content, self.request, filename=filename) colorizer.format(self) except IOError: pass return (self.attachment_link(1, url) + self.text(text) + self.attachment_link(0))
def package(self): """ Calls collectpackage() with the arguments specified. """ _ = self.request.getText # Get new name from form and normalize. pagelist = self.request.values.get('pagelist', u'') packagename = self.request.values.get('packagename', u'') include_attachments = self.request.values.get('include_attachments', False) if not self.request.values.get('submit'): self.request.theme.add_msg(self.makeform(), "dialog") raise ActionError target = wikiutil.taintfilename(packagename) if not target: self.request.theme.add_msg( self.makeform( _('Invalid filename "%s"!') % wikiutil.escape(packagename)), "error") raise ActionError request = self.request filelike = cStringIO.StringIO() package = self.collectpackage(unpackLine(pagelist, ","), filelike, target, include_attachments) request.headers['Content-Type'] = 'application/zip' request.headers['Content-Length'] = filelike.tell() request.headers[ 'Content-Disposition'] = 'inline; filename="%s"' % target request.write(filelike.getvalue()) filelike.close()
def gedit_drawing(self, url, text, **kw): # This is called for displaying a drawing image by gui editor. _ = self.request.getText # TODO: this 'text' argument is kind of superfluous, replace by using alt=... kw arg # ToDo: make this clickable for the gui editor if 'alt' not in kw or not kw['alt']: kw['alt'] = text # we force the title here, needed later for html>wiki converter kw['title'] = "drawing:%s" % wikiutil.quoteWikinameURL(url) pagename, drawing = AttachFile.absoluteName(url, self.page.page_name) containername = wikiutil.taintfilename(drawing) drawing_url = AttachFile.getAttachUrl(pagename, containername, self.request) ci = AttachFile.ContainerItem(self.request, pagename, containername) if not ci.exists(): title = _( 'Create new drawing "%(filename)s (opens in new window)"') % { 'filename': self.text(containername) } img = self.icon( 'attachimg' ) # TODO: we need a new "drawimg" in similar grey style and size css = 'nonexistent' return self.url(1, drawing_url, css=css, title=title) + img + self.url(0) kw['src'] = ci.member_url('drawing.png') return self.image(**kw)
def do_installpackage(self, pagename, filename): """ Installs a package. @param pagename: Page where the file is attached. Or in 2.0, the file itself. @param filename: Filename of the attachment (just applicable for MoinMoin < 2.0) """ _ = self.request.getText attachments = Page(self.request, pagename).getPagePath("attachments", check_create=0) package = ZipPackage( self.request, os.path.join(attachments, wikiutil.taintfilename(filename))) if package.isPackage(): if not package.installPackage(): raise RuntimeScriptException( _("Installation of '%(filename)s' failed.") % {'filename': filename} + "\n" + package.msg) else: raise RuntimeScriptException( _('The file %s is not a MoinMoin package file.') % filename) self.msg += package.msg
def attachment_drawing(self, url, text, **kw): _ = self.request.getText pagename = self.page.page_name image = url + u'.png' fname = wikiutil.taintfilename(image) fpath = AttachFile.getFilename(self.request, pagename, fname) return self.image( title="drawing:%s" % wikiutil.quoteWikinameURL(url), src=AttachFile.getAttachUrl(pagename, image, self.request, addts=1))
def attachment_link(self, on, url=None, **kw): assert on in (0, 1, False, True) # make sure we get called the new way, not like the 1.5 api was # we do not output a "upload link" when outputting docbook if on: pagename, filename = AttachFile.absoluteName(url, self.page.page_name) fname = wikiutil.taintfilename(filename) target = AttachFile.getAttachUrl(pagename, filename, self.request) return self.url(1, target, title="attachment:%s" % url) else: return self.url(0)
def getAttachUrl(pagename, filename, request, addts=0, escaped=0, do='get', drawing='', upload=False): """ Get URL that points to attachment `filename` of page `pagename`. """ if upload: if not drawing: url = attachUrl(request, pagename, filename, rename=wikiutil.taintfilename(filename), action=action_name) else: url = attachUrl(request, pagename, filename, rename=wikiutil.taintfilename(filename), drawing=drawing, action=action_name) else: if not drawing: url = attachUrl(request, pagename, filename, target=filename, action=action_name, do=do) else: url = attachUrl(request, pagename, filename, drawing=drawing, action=action_name) if escaped: url = wikiutil.escape(url) return url
def check_attachfile(request, pagename, aname): # Check that the attach dir exists getAttachDir(request, pagename, create=1) aname = wikiutil.taintfilename(aname) fpath = getFilename(request, pagename, aname) # Trying to make sure the target is a regular file if os.path.isfile(fpath) and not os.path.islink(fpath): return fpath, True return fpath, False
def addAttachment(self, name, content): """add image to attachment""" if os.path.splitext(name)[1].lower() not in \ ['.' + x for x in self.image_extenstions]: name += '.jpg' # if the url didn't contain a image extention AttachFile.add_attachment(self.request, self.pagename, name, content, True) return wikiutil.taintfilename(name)
def attachment_image(self, url, **kw): _ = self.request.getText pagename, filename = AttachFile.absoluteName(url, self.page.page_name) fname = wikiutil.taintfilename(filename) fpath = AttachFile.getFilename(self.request, pagename, fname) if not os.path.exists(fpath): return self.text("[attachment:%s]" % url) else: return self.image( title="attachment:%s" % url, src=AttachFile.getAttachUrl(pagename, filename, self.request, addts=1))
def attachment_link(self, url, text, **kw): _ = self.request.getText pagename, filename = AttachFile.absoluteName(url, self.page.page_name) fname = wikiutil.taintfilename(filename) fpath = AttachFile.getFilename(self.request, pagename, fname) target = AttachFile.getAttachUrl(pagename, filename, self.request) if not os.path.exists(fpath): return self.text("[attachment:%s]" % url) else: return (self.url(1, target, title="attachment:%s" % url) + self.text(text) + self.url(0))
def loadSession(key, path=s_path, prefix=s_prefix): """ Loads a particular session from the directory. The key needs to be the session id. """ key = key.lower() filename = os.path.join(path, prefix + wikiutil.taintfilename(key)) try: f = open(filename, "rb") except IOError, e: if e.errno == 2: return None # session does not exist else: raise
def attachment_drawing(self, url, text, **kw): _ = self.request.getText pagename, filename = AttachFile.absoluteName(url, self.page.page_name) fname = wikiutil.taintfilename(filename) drawing = fname fname = fname + ".png" filename = filename + ".png" fpath = AttachFile.getFilename(self.request, pagename, fname) if not os.path.exists(fpath): return self.text("{{drawing:%s}}" % url) else: src = AttachFile.getAttachUrl(pagename, filename, self.request, addts=1) return self.image(alt=drawing, src=src, html_class="drawing")
def attachment_link(self, on, url=None, **kw): assert on in ( 0, 1, False, True ) # make sure we get called the new way, not like the 1.5 api was # we do not output a "upload link" when outputting docbook if on: pagename, filename = AttachFile.absoluteName( url, self.page.page_name) fname = wikiutil.taintfilename(filename) target = AttachFile.getAttachUrl(pagename, filename, self.request) return self.url(1, target, title="attachment:%s" % url) else: return self.url(0)
def macro_ThumbnailGallery(macro, page=None, regex=None, height=200, width=None, link=True): _ = macro.request.getText formatter = macro.formatter pagename = page or macro.formatter.page.page_name output = [] if not regex: regex = re.compile(".*\.(jpg|jpeg|png|gif)$") else: regex = re.compile(regex) if not macro.request.user.may.read(pagename): return _('You are not allowed to view attachments of this page.') for attachment in AttachFile._get_files(macro.request, pagename): if regex.match(attachment) is None: continue pagename, filename = AttachFile.absoluteName(attachment, pagename) fname = wikiutil.taintfilename(filename) if width: size, dimension = width, "w" else: size, dimension = height, "h" if AttachFile.exists(macro.request, pagename, fname): url = AttachFile.getAttachUrl(pagename, fname, macro.request, do='get') output.extend([ macro.formatter.url(True, url) if link else "", macro.formatter.image( macro.request.href( pagename, { "target": fname, "action": "Thumbnail", "do": "tc:{},{}".format(size, dimension) })), macro.formatter.url(False) if link else "", " ", ]) return "".join(output)
def execute(pagename, request): target = request.values.get('target') target = wikiutil.taintfilename(target) twd = TwikiDraw(request, pagename, target) do = request.values.get('do') if do == 'save': msg = twd.save() else: msg = twd.render() if msg: request.theme.add_msg(msg, 'error') do_show(pagename, request)
def do_copythemefile(self, filename, ftype, target): """ Copies a theme-related file (CSS, PNG, etc.) into a directory of the current theme. @param filename: name of the file in this package @param ftype: the subdirectory of the theme directory, e.g. "css" @param target: filename, e.g. "screen.css" """ _ = self.request.getText if self.themename is None: raise RuntimeScriptException(_("The theme name is not set.")) from MoinMoin.web.static import STATIC_FILES_PATH as htdocs_dir if not os.access(htdocs_dir, os.W_OK): raise RuntimeScriptException(_("Theme files not installed! Write rights missing for %s.") % htdocs_dir) theme_file = os.path.join(htdocs_dir, self.themename, wikiutil.taintfilename(ftype), wikiutil.taintfilename(target)) theme_dir = os.path.dirname(theme_file) if not os.path.exists(theme_dir): os.makedirs(theme_dir) self._extractToFile(filename, theme_file)
def do_installplugin(self, filename, visibility, ptype, target): """ Installs a python code file into the appropriate directory. @param filename: name of the file in this package @param visibility: 'local' will copy it into the plugin folder of the current wiki. 'global' will use the folder of the MoinMoin python package. @param ptype: the type of the plugin, e.g. "parser" @param target: the filename of the plugin, e.g. wiki.py """ visibility = visibility.lower() ptype = wikiutil.taintfilename(ptype.lower()) if visibility == 'global': basedir = os.path.dirname(__import__("MoinMoin").__file__) elif visibility == 'local': basedir = self.request.cfg.plugin_dir target = os.path.join(basedir, ptype, wikiutil.taintfilename(target)) self._extractToFile(filename, target) wikiutil._wiki_plugins = {}
def attachment_drawing(self, url, text, **kw): # This is called for displaying a clickable drawing image by text_html formatter. # XXX text arg is unused! _ = self.request.getText pagename, drawing = AttachFile.absoluteName(url, self.page.page_name) containername = wikiutil.taintfilename(drawing) drawing_url = AttachFile.getAttachUrl(pagename, containername, self.request, do='modify') ci = AttachFile.ContainerItem(self.request, pagename, containername) if not ci.exists(): title = _('Create new drawing "%(filename)s (opens in new window)"') % {'filename': self.text(containername)} img = self.icon('attachimg') # TODO: we need a new "drawimg" in similar grey style and size css = 'nonexistent' return self.url(1, drawing_url, css=css, title=title) + img + self.url(0) title = _('Edit drawing %(filename)s (opens in new window)') % {'filename': self.text(containername)} kw['src'] = src = ci.member_url('drawing.png') kw['css'] = 'drawing' try: mapfile = ci.get('drawing.map') map = mapfile.read() mapfile.close() map = map.decode(config.charset) except (KeyError, IOError, OSError): map = u'' if map: # we have a image map. inline it and add a map ref to the img tag # we have also to set a unique ID mapid = u'ImageMapOf%s%s' % (self.request.uid_generator(pagename), drawing) map = map.replace(u'%MAPNAME%', mapid) # add alt and title tags to areas map = re.sub(ur'href\s*=\s*"((?!%TWIKIDRAW%).+?)"', ur'href="\1" alt="\1" title="\1"', map) map = map.replace(u'%TWIKIDRAW%"', u'%s" alt="%s" title="%s"' % ( wikiutil.escape(drawing_url, 1), title, title)) # unxml, because 4.01 concrete will not validate /> map = map.replace(u'/>', u'>') title = _('Clickable drawing: %(filename)s') % {'filename': self.text(containername)} if 'title' not in kw: kw['title'] = title if 'alt' not in kw: kw['alt'] = kw['title'] kw['usemap'] = '#'+mapid return self.url(1, drawing_url) + map + self.image(**kw) + self.url(0) else: if 'title' not in kw: kw['title'] = title if 'alt' not in kw: kw['alt'] = kw['title'] return self.url(1, drawing_url) + self.image(**kw) + self.url(0)
def do_copythemefile(self, filename, ftype, target): """ Copies a theme-related file (CSS, PNG, etc.) into a directory of the current theme. @param filename: name of the file in this package @param ftype: the subdirectory of the theme directory, e.g. "css" @param target: filename, e.g. "screen.css" """ _ = self.request.getText if self.themename is None: raise RuntimeScriptException(_("The theme name is not set.")) sa = getattr(self.request, "sareq", None) if sa is None: raise RuntimeScriptException(_("Installing theme files is only supported " "for standalone type servers.")) htdocs_dir = sa.server.htdocs theme_file = os.path.join(htdocs_dir, self.themename, wikiutil.taintfilename(ftype), wikiutil.taintfilename(target)) theme_dir = os.path.dirname(theme_file) if not os.path.exists(theme_dir): os.makedirs(theme_dir) self._extractToFile(filename, theme_file)
def execute(pagename, request): target = request.values.get('target') target = wikiutil.taintfilename(target) awd = AnyWikiDraw(request, pagename, target) do = request.values.get('do') if do == 'save': msg = awd.save() else: msg = awd.render() if msg: request.theme.add_msg(wikiutil.escape(msg), 'error') do_show(pagename, request)
def attachment_move(pagename, request): _ = request.getText if request.form.has_key('newpagename'): new_pagename = request.form.get('newpagename')[0] else: upload_form(pagename, request, msg=_("Move aborted because empty page name")) if request.form.has_key('newattachmentname'): new_attachment = request.form.get('newattachmentname')[0] if new_attachment != wikiutil.taintfilename(new_attachment): upload_form(pagename, request, msg=_("Please use proper signs in attachment '%(filename)s'.") % { 'filename': new_attachment}) return else: upload_form(pagename, request, msg=_("Move aborted because empty attachment name")) attachment = request.form.get('oldattachmentname')[0] move_file(request, pagename, new_pagename, attachment, new_attachment)
def xmlrpc_getAttachment(self, pagename, attachname): """ Get attachname associated with pagename @param pagename: pagename (utf-8) @param attachname: attachment name (utf-8) @rtype base64 @return base64 data """ pagename = self._instr(pagename) # User may read page? if not self.request.user.may.read(pagename): return self.notAllowedFault() filename = wikiutil.taintfilename(self._instr(attachname)) filename = AttachFile.getFilename(self.request, pagename, filename) if not os.path.isfile(filename): return self.noSuchPageFault() return self._outlob(open(filename, 'rb').read())
def xmlrpc_deleteAttachment(self, pagename, attachname): """ Deletes attachment <attachname> of page <pagename>. @param pagename: pagename (utf-8) @param attachname: attachment name (utf-8) @rtype: bool @return: True on success """ pagename = self._instr(pagename) if not self.request.user.may.delete(pagename): return xmlrpclib.Fault(1, 'You are not allowed to delete attachments on this page.') attachname = wikiutil.taintfilename(self._instr(attachname)) filename = AttachFile.getFilename(self.request, pagename, attachname) AttachFile.remove_attachment(self.request, pagename, attachname) return xmlrpclib.Boolean(1)
def do_delattachment(self, filename, pagename, author=u"Scripting Subsystem", comment=u""): """ Removes an attachment @param pagename: Page where the file is attached. Or in 2.0, the file itself. @param filename: Filename of the attachment (just applicable for MoinMoin < 2.0) """ if self.request.user.may.write(pagename): _ = self.request.getText attachments = Page(self.request, pagename).getPagePath("attachments", check_create=1) filename = wikiutil.taintfilename(filename) target = os.path.join(attachments, filename) page = PageEditor(self.request, pagename, do_editor_backup=0, uid_override=author) rev = page.current_rev() path = page.getPagePath(check_create=0) if os.path.exists(target): os.remove(target) action = 'ATTDEL' edit_logfile_append(self, pagename, path, rev, action, logname='edit-log', comment=u'%(filename)s' % {"filename": filename}, author=author) self.msg += u"%(filename)s removed \n" % {"filename": filename} else: self.msg += u"%(filename)s does not exist \n" % { "filename": filename } else: self.msg += u"action delete attachment: not enough rights - nothing done \n"
def xmlrpc_getAttachment(self, pagename, attachname): """ Get contents of attachment <attachname> of page <pagename> @param pagename: pagename (utf-8) @param attachname: attachment name (utf-8) @rtype: base64 @return: base64 data """ pagename = self._instr(pagename) # User may read page? if not self.request.user.may.read(pagename): return self.notAllowedFault() attachname = wikiutil.taintfilename(self._instr(attachname)) filename = AttachFile.getFilename(self.request, pagename, attachname) if not os.path.isfile(filename): return self.noSuchPageFault() return self._outlob(open(filename, 'rb').read())
def xmlrpc_deleteAttachment(self, pagename, attachname): """ Deletes attachment <attachname> of page <pagename>. @param pagename: pagename (utf-8) @param attachname: attachment name (utf-8) @rtype: bool @return: True on success """ pagename = self._instr(pagename) if not self.request.user.may.delete(pagename): return xmlrpclib.Fault( 1, 'You are not allowed to delete attachments on this page.') attachname = wikiutil.taintfilename(self._instr(attachname)) filename = AttachFile.getFilename(self.request, pagename, attachname) AttachFile.remove_attachment(self.request, pagename, attachname) return xmlrpclib.Boolean(1)
def attachment_image(self, url, **kw): """ Figures out the absolute path to the image and then hands over to the image function. Any title is also handed over, and an additional title suggestion is made based on filename. The image function will use the suggestion if no other text alternative is found. If the file is not found, then a simple text will replace it. """ _ = self.request.getText pagename, filename = AttachFile.absoluteName(url, self.page.page_name) fname = wikiutil.taintfilename(filename) fpath = AttachFile.getFilename(self.request, pagename, fname) if not os.path.exists(fpath): return self.text(u"[attachment:%s]" % url) else: return self.image( src=AttachFile.getAttachUrl(pagename, filename, self.request, addts=1), attachment_title=url, **kw )
def _do_box(pagename, request): _ = request.getText pagename, filename, fpath = _access_file(pagename, request) if not request.user.may.read(pagename): return _('You are not allowed to get attachments from this page.') if not filename: return # error msg already sent in _access_file timestamp = datetime.datetime.fromtimestamp(os.path.getmtime(fpath)) if_modified = request.if_modified_since if if_modified and if_modified >= timestamp: request.status_code = 304 else: ci = ContainerItem(request, pagename, filename) filename = wikiutil.taintfilename(request.values['member']) mt = wikiutil.MimeType(filename=filename) content_type = mt.content_type() mime_type = mt.mime_type() # TODO: fix the encoding here, plain 8 bit is not allowed according to the RFCs # There is no solution that is compatible to IE except stripping non-ascii chars filename_enc = filename.encode(config.charset) # for dangerous files (like .html), when we are in danger of cross-site-scripting attacks, # we just let the user store them to disk ('attachment'). # For safe files, we directly show them inline (this also works better for IE). dangerous = mime_type in request.cfg.mimetypes_xss_protect content_dispo = dangerous and 'attachment' or 'inline' now = time.time() request.headers['Date'] = http_date(now) request.headers['Content-Type'] = content_type request.headers['Last-Modified'] = http_date(timestamp) request.headers['Expires'] = http_date(now - 365 * 24 * 3600) #request.headers['Content-Length'] = os.path.getsize(fpath) content_dispo_string = '%s; filename="%s"' % (content_dispo, filename_enc) request.headers['Content-Disposition'] = content_dispo_string # send data request.send_file(ci.get(filename))
def do_installpackage(self, pagename, filename): """ Installs a package. @param pagename: Page where the file is attached. Or in 2.0, the file itself. @param filename: Filename of the attachment (just applicable for MoinMoin < 2.0) """ _ = self.request.getText attachments = Page(self.request, pagename).getPagePath("attachments", check_create=0) package = ZipPackage(self.request, os.path.join(attachments, wikiutil.taintfilename(filename))) if package.isPackage(): if not package.installPackage(): raise RuntimeScriptException(_("Installation of '%(filename)s' failed.") % { 'filename': filename} + "\n" + package.msg) else: raise RuntimeScriptException(_('The file %s is not a MoinMoin package file.') % filename) self.msg += package.msg
def gedit_drawing(self, url, text, **kw): # This is called for displaying a drawing image by gui editor. _ = self.request.getText # TODO: this 'text' argument is kind of superfluous, replace by using alt=... kw arg # ToDo: make this clickable for the gui editor if 'alt' not in kw or not kw['alt']: kw['alt'] = text # we force the title here, needed later for html>wiki converter kw['title'] = "drawing:%s" % wikiutil.quoteWikinameURL(url) pagename, drawing = AttachFile.absoluteName(url, self.page.page_name) containername = wikiutil.taintfilename(drawing) drawing_url = AttachFile.getAttachUrl(pagename, containername, self.request) ci = AttachFile.ContainerItem(self.request, pagename, containername) if not ci.exists(): title = _('Create new drawing "%(filename)s (opens in new window)"') % {'filename': self.text(containername)} img = self.icon('attachimg') # TODO: we need a new "drawimg" in similar grey style and size css = 'nonexistent' return self.url(1, drawing_url, css=css, title=title) + img + self.url(0) kw['src'] = ci.member_url('drawing.png') return self.image(**kw)
def attachment_image(self, url, **kw): """ Figures out the absolute path to the image and then hands over to the image function. Any title is also handed over, and an additional title suggestion is made based on filename. The image function will use the suggestion if no other text alternative is found. If the file is not found, then a simple text will replace it. """ _ = self.request.getText pagename, filename = AttachFile.absoluteName(url, self.page.page_name) fname = wikiutil.taintfilename(filename) fpath = AttachFile.getFilename(self.request, pagename, fname) if not os.path.exists(fpath): return self.text("{{attachment:%s}}" % url) else: return self.image(src=AttachFile.getAttachUrl(pagename, filename, self.request, addts=1), attachment_title=url, **kw)
def macro_Thumbnail(macro, attachment, height=200, width=None, link=True): _ = macro.request.getText formatter = macro.formatter pagename, filename = AttachFile.absoluteName(attachment, formatter.page.page_name) fname = wikiutil.taintfilename(filename) if not macro.request.user.may.read(pagename): return _('You are not allowed to view attachments of this page.') if width: size, dimension = width, "w" else: size, dimension = height, "h" if AttachFile.exists(macro.request, pagename, fname): url = AttachFile.getAttachUrl(pagename, fname, macro.request, do='get') output = [ formatter.url(True, url) if link else "", formatter.image( macro.request.href( pagename, { "target": fname, "action": "Thumbnail", "do": "tc:{},{}".format(size, dimension) })), formatter.url(False) if link else "", ] else: output = [ formatter.span(True, style="color: red"), "No Image: {}".format(attachment), formatter.span(False), ] return "".join(output)
def _do_attachment_move(pagename, request): _ = request.getText if 'cancel' in request.form: return _('Move aborted!') if not wikiutil.checkTicket(request, request.form.get('ticket', '')): return _( 'Please use the interactive user interface to use action %(actionname)s!' ) % { 'actionname': 'AttachFile.move' } if not request.user.may.delete(pagename): return _('You are not allowed to move attachments from this page.') if 'newpagename' in request.form: new_pagename = request.form.get('newpagename') else: upload_form(pagename, request, msg=_("Move aborted because new page name is empty.")) if 'newattachmentname' in request.form: new_attachment = request.form.get('newattachmentname') if new_attachment != wikiutil.taintfilename(new_attachment): upload_form( pagename, request, msg= _("Please use a valid filename for attachment '%(filename)s'.") % {'filename': new_attachment}) return else: upload_form( pagename, request, msg=_("Move aborted because new attachment name is empty.")) attachment = request.form.get('oldattachmentname') move_file(request, pagename, new_pagename, attachment, new_attachment)
def remove_attachment(request, pagename, target): """ remove attachment <target> of page <pagename> """ # replace illegal chars target = wikiutil.taintfilename(target) # get directory, do not create it attach_dir = getAttachDir(request, pagename, create=0) # remove file fpath = os.path.join(attach_dir, target).encode(config.charset) try: filesize = os.path.getsize(fpath) os.remove(fpath) except: # either it is gone already or we have no rights - not much we can do about it filesize = 0 else: _addLogEntry(request, 'ATTDEL', pagename, target) event = FileRemovedEvent(request, pagename, target, filesize) send_event(event) return target, filesize
def _access_file(pagename, request): """ Check form parameter `target` and return a tuple of `(pagename, filename, filepath)` for an existing attachment. Return `(pagename, None, None)` if an error occurs. """ _ = request.getText error = None if not request.values.get('target'): error = _("Filename of attachment not specified!") else: filename = wikiutil.taintfilename(request.values['target']) fpath = getFilename(request, pagename, filename) if os.path.isfile(fpath): return (pagename, filename, fpath) error = _("Attachment '%(filename)s' does not exist!") % { 'filename': filename } error_msg(pagename, request, error) return (pagename, None, None)
def execute(self): request = self.request _ = request.getText pagename = request.page.page_name if not request.user.may.read(pagename): fault = _(u'Can not read page') + u'\n' if self.inline: request.write(request.formatter.text(fault)) return request.content_type = 'text/plain' request.write(fault) return form = values_to_form(request.values) self.formargs(form) if self.help or not self.attachment: enter_page(request, pagename, 'View .gv attachment') self.sendForm() if self.help: # This is the URL addition to the nodes that have graph data self.urladd = url_parameters(form) self.urladd = self.urladd.replace('&help=Inline', '') request.write('<<ViewDot(' + self.urladd + ')>>') exit_page(request, pagename) return if not self.attachment[:10].lower() == 'attachment': fault = _(u'No attachment defined') + u'\n' if self.inline: request.write(request.formatter.text(fault)) return request.content_type = 'text/plain' request.write(fault) return self.attachment = self.attachment[11:] pagename, filename = AttachFile.absoluteName(self.attachment, self.pagename) if not request.user.may.read(pagename): fault = _(u'Can not read attachment page') + u'\n' if self.inline: request.write(request.formatter.text(fault)) return request.content_type = 'text/plain' request.write(fault) return fname = wikiutil.taintfilename(filename) fpath = AttachFile.getFilename(request, pagename, fname) try: data = file(fpath, 'r').read() except IOError: fault = _(u'Can not read attachment') + u'\n' if self.inline: request.write(request.formatter.text(fault)) return request.content_type = 'text/plain' request.write(fault) return if not gv_found: fault = _(u"ERROR: Graphviz Python extensions not installed. " +\ u"Not performing layout.") if self.inline: request.write(request.formatter.text(fault)) return request.content_type = 'text/plain' request.write(fault) return self.cache_key = cache_key(self.request, [data, self.graphengine, self.format]) key = "%s-%s" % (self.cache_key, self.format) if self.format in ['zgr', 'svg']: formatcontent = 'svg+xml' else: formatcontent = self.format if not cache_exists(request, key): graphviz = Graphviz(engine=self.graphengine, string=data) data = self.getLayoutInFormat(graphviz, self.format) cache.put(self.request, key, data, content_type=formatcontent) if self.format in ['zgr', 'svg']: # Display zgr graphs as applets if self.format == 'zgr': image_p = lambda url, text: \ '<applet code="net.claribole.zgrviewer.ZGRApplet.class"'+ \ ' archive="%s/gwikicommon/zgrviewer/zvtm.jar,' % \ (self.request.cfg.url_prefix_static) + \ '%s/gwikicommon/zgrviewer/zgrviewer.jar" ' % \ (self.request.cfg.url_prefix_static) + \ 'width="%s" height="%s">' % (form_escape(self.width), form_escape(self.height))+\ '<param name="type" ' + \ 'value="application/x-java-applet;version=1.4" />' + \ '<param name="scriptable" value="false" />' + \ '<param name="svgURL" value="%s" />' % (url) + \ '<param name="title" value="ZGRViewer - Applet" />'+ \ '<param name="appletBackgroundColor" value="#DDD" />' + \ '<param name="graphBackgroundColor" value="#DDD" />' + \ '<param name="highlightColor" value="red" />' + \ ' </applet><br>\n' else: image_p = lambda url, text: \ '<object data="%s" alt="%s" ' % (url, text) + \ 'type="image/svg+xml">\n' + \ '<embed src="%s" alt="%s" ' % (url, text) + \ 'type="image/svg+xml"/>\n</object>' else: image_p = lambda url, text: \ '<img src="%s" alt="%s">\n' % (url, text) image_uri = cache.url(self.request, key) if not self.inline: if self.format == 'zgr': request.write('<html><body>') request.write(image_p(image_uri, _('visualisation'))) if not self.inline and self.format == 'zgr': request.write('</html></body>') else: pass # No footer
def execute(macro, args): request = macro.request _ = request.getText formatter = macro.formatter kwAllowed = ['width', 'height', 'alt'] pp, pp_count, kw, kw_count = explore_args(args, kwAllowed) if not pp_count or pp_count and not pp[0]: msg = 'Not enough arguments given to ImageLink macro! Try <<ImageLink(example.png, WikiName, width=200)>>.' return "%s%s%s" % (formatter.sysmsg(1), formatter.text(msg), formatter.sysmsg(0)) image = pp[0] if pp_count >= 2 and pp[1]: target = pp[1] if target.startswith('attachment:') or target.startswith('inline:'): if target.startswith('attachment:'): target = (target.split('attachment:'))[1] pagename, attname = AttachFile.absoluteName( target, formatter.page.page_name) target = AttachFile.getAttachUrl(pagename, target, request) elif target.startswith('inline:'): target = (target.split('inline:'))[1] pagename, attname = AttachFile.absoluteName( target, formatter.page.page_name) target = AttachFile.getAttachUrl(pagename, target, request, do='view') if not AttachFile.exists(request, pagename, attname): linktext = _('Upload new attachment "%(filename)s"', formatted=False) return wikiutil.link_tag(request, ('%s?action=AttachFile&rename=%s' % (wikiutil.quoteWikinameURL(pagename), wikiutil.url_quote_plus(attname))), linktext % {'filename': attname}) kw['src'] = AttachFile.getAttachUrl(pagename, image, request) elif pp_count == 1: pagename, attname = AttachFile.absoluteName(image, formatter.page.page_name) target = AttachFile.getAttachUrl(pagename, image, request) else: target = None if _is_URL(image): kw['src'] = image else: pagename, attname = AttachFile.absoluteName(image, formatter.page.page_name) kw['src'] = AttachFile.getAttachUrl(pagename, attname, request) if not AttachFile.exists(request, pagename, attname): linktext = _('Upload new attachment "%(filename)s"', formatted=False) return wikiutil.link_tag(request, ('%s?action=AttachFile&rename=%s' % (wikiutil.quoteWikinameURL(pagename), wikiutil.url_quote_plus(attname))), linktext % {'filename': attname}) if 'alt' not in kw: if target is None or _is_URL(target): if _is_URL(image): # Get image name http://here.com/dir/image.png -> image.png kw['alt'] = wikiutil.taintfilename( formatter.text(image.split('/')[-1])) else: kw['alt'] = attname else: kw['alt'] = target if target is None: target = kw['src'] if pp_count == 1: return "%s%s%s" % (formatter.url( 1, kw['src']), formatter.image(**kw), formatter.url(0)) if _is_URL( target ) or 'action=AttachFile&do=get&target=' in target or 'action=AttachFile&do=view&target=' in target: return "%s%s%s" % (formatter.url( 1, target), formatter.image(**kw), formatter.url(0)) else: if ":" in target: if target.startswith('wiki:'): target = target[5:] wikitag, wikiurl, wikitail, error = wikiutil.resolve_wiki( request, target) url = wikiurl + wikiutil.quoteWikinameURL(wikitail) return "%s%s%s" % (formatter.url( 1, url), formatter.image(**kw), formatter.url(0)) else: return "%s%s%s" % (formatter.pagelink( 1, target), formatter.image(**kw), formatter.pagelink(0))
def do_setthemename(self, themename): """ Sets the name of the theme which will be altered next. """ self.themename = wikiutil.taintfilename(str(themename))