def __init__(self, item, revno): if revno != 0: raise NoSuchRevisionError( 'Item %r has no revision %d (attachments just have revno 0)!' % (item.name, revno)) StoredRevision.__init__(self, item, revno) attpath = item._fs_attachpath editlog = item._fs_editlog try: editlog_data = editlog.find_attach(item._fs_attachname) except KeyError: editlog_data = { # make something up MTIME: os.path.getmtime(attpath), ACTION: u'SAVE', } meta = editlog_data meta['__size'] = 0 # not needed for converter # attachments in moin 1.9 were protected by their "parent" page's acl if item._fs_parent_acl is not None: meta[ ACL] = item._fs_parent_acl # XXX not needed for acl_hierarchic meta[MIMETYPE] = unicode( wikiutil.MimeType(filename=item._fs_attachname).mime_type()) hash_name, hash_digest = hash_hexdigest(open(attpath, 'rb')) meta[hash_name] = hash_digest if item._syspages: meta[IS_SYSITEM] = True meta[SYSITEM_VERSION] = item._syspages self._fs_meta = meta self._fs_data_fname = attpath self._fs_data_file = None
def contentfilter(self, filename): """ Get a filter for content of filename and return unicode content. @param filename: name of the file """ mt = wikiutil.MimeType(filename=filename) return mt.mime_type( ), u'not implemented' # XXX see moin 1.9 code about how it was done there
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 contentfilter(self, filename): """ Get a filter for content of filename and return unicode content. @param filename: name of the file """ request = self.request mt = wikiutil.MimeType(filename=filename) for modulename in mt.module_name(): try: execute = wikiutil.importPlugin(request.cfg, 'filter', modulename) break except wikiutil.PluginMissingError: pass else: logging.info("Cannot load filter for mimetype %s" % modulename) try: data = execute(self, filename) logging.debug("Filter %s returned %d characters for file %s" % (modulename, len(data), filename)) except (OSError, IOError), err: data = '' logging.exception("Filter %s threw error '%s' for file %s" % (modulename, str(err), filename))
def macro_EmbedObject( macro, target=wikiutil.required_arg(unicode), pagename=None, width=wikiutil.UnitArgument(None, float, ['px', 'em', 'pt', 'in', 'mm', '%'], defaultunit='px'), height=wikiutil.UnitArgument(None, float, ['px', 'em', 'pt', 'in', 'mm', '%'], defaultunit='px'), alt=u'', play=False, stop=True, loop=False, quality=(u'high', u'low', u'medium'), op=True, repeat=False, autostart=False, align=(u'middle', u'top', u'bottom'), hidden=False, menu=True, wmode=u'transparent', url_mimetype=None): """ This macro is used to embed an object into a wiki page """ # Join unit arguments with their units if width: if width[1] == 'px': width = '%dpx' % int(width[0]) else: width = '%g%s' % width if height: if height[1] == 'px': height = '%dpx' % int(height[0]) else: height = '%g%s' % height request = macro.request _ = macro.request.getText fmt = macro.formatter # AttachFile calls always with pagename. Users can call the macro from a different page as the attachment is saved. if not pagename: pagename = fmt.page.page_name if not wikiutil.is_URL(target): pagename, fname = AttachFile.absoluteName(target, pagename) if not AttachFile.exists(request, pagename, fname): linktext = _('Upload new attachment "%(filename)s"') % { 'filename': fname } target = AttachFile.getAttachUrl(pagename, fname, request, do='upload_form') return (fmt.url(1, target) + fmt.text(linktext) + fmt.url(0)) url = AttachFile.getAttachUrl(pagename, fname, request) mt = wikiutil.MimeType(filename=fname) else: if not url_mimetype: return fmt.text( _('%(extension_name)s %(extension_type)s: Required argument %(argument_name)s missing.' ) % { "extension_name": extension_name, "extension_type": extension_type, "argument_name": "url_mimetype", }) else: url = target mt = wikiutil.MimeType() # initialize dict try: mt.major, mt.minor = url_mimetype.split('/') except ValueError: return fmt.text( _('%(extension_name)s %(extension_type)s: Invalid %(argument_name)s=%(argument_value)s!' ) % { "extension_name": extension_name, "extension_type": extension_type, "argument_name": "url_mimetype", "argument_value": str(url_mimetype), }) mime_type = "%s/%s" % ( mt.major, mt.minor, ) dangerous = mime_type in request.cfg.mimetypes_xss_protect if not mime_type in request.cfg.mimetypes_embed or dangerous: return "%s: %s%s%s" % (fmt.text( _("Current configuration does not allow embedding of the file %(file)s because of its mimetype %(mimetype)s." ) % { "mimetype": mime_type, "file": target }), fmt.url(1, url), fmt.text(target), fmt.url(0)) if not alt: alt = "%(text)s %(mime_type)s" % { 'text': _("Embedded"), 'mime_type': mime_type } embed_src = '' if mt.major == 'video': if not width and not height: width = '400px' height = '400px' embed_src = ''' <object %(ob_data)s %(ob_type)s %(ob_width)s %(ob_height)s %(ob_align)s %(ob_standby)s %(ob_stop)s> %(wmode)s%(movie)s%(play)s%(stop)s%(repeat)s%(autostart)s%(op)s%(menu)s <p>%(alt)s</p> </object>''' % { "ob_data": _check_object_value("data", url), "ob_type": _check_object_value("type", mime_type), "ob_width": _check_object_value("width", width), "ob_height": _check_object_value("height", height), "ob_align": _check_object_value("align", align), "ob_standby": _check_object_value("standby", alt), "ob_stop": _check_object_value("stop", stop), "wmode": _check_param_value("wmode", wmode, "data"), "movie": _check_param_value("movie", url, "data"), "play": _check_param_value("play", play, "data"), "stop": _check_param_value("stop", stop, "data"), "repeat": _check_param_value("repeat", repeat, "data"), "autostart": _check_param_value("autostart", autostart, "data"), "op": _check_param_value("op", op, "data"), "menu": _check_param_value("menu", menu, "data"), "alt": wikiutil.escape(alt), } elif mt.major in ['image', 'chemical', 'x-world']: embed_src = ''' <object %(ob_data)s %(ob_type)s %(ob_width)s %(ob_height)s %(ob_align)s> %(name)s <p>%(alt)s</p> </object>''' % { "mime_type": mime_type, "ob_data": _check_object_value("data", url), "ob_width": _check_object_value("width", width), "ob_height": _check_object_value("height", height), "ob_type": _check_object_value("type", mime_type), "ob_align": _check_object_value("align", align), "name": _check_param_value("name", url, "data"), "alt": wikiutil.escape(alt), } elif mt.major == 'audio': if not width and not height: width = '400px' height = '100px' embed_src = ''' <object %(ob_data)s %(ob_type)s %(ob_width)s %(ob_height)s %(ob_align)s> %(audio)s%(repeat)s%(autostart)s%(op)s%(play)s%(stop)s%(hidden)s<p>%(alt)s</p> </object>''' % { "ob_data": _check_object_value("data", url), "ob_width": _check_object_value("width", width or "60"), "ob_height": _check_object_value("height", height or "20"), "ob_type": _check_object_value("type", mime_type), "ob_align": _check_object_value("align", align), "audio": _check_param_value("audio", url, "data"), "repeat": _check_param_value("repeat", repeat, "data"), "autostart": _check_param_value("autostart", autostart, "data"), "op": _check_param_value("op", op, "data"), "play": _check_param_value("play", play, "data"), "stop": _check_param_value("stop", stop, "data"), "hidden": _check_param_value("hidden", hidden, "data"), "alt": wikiutil.escape(alt), } elif mt.major == 'application': # workaround for the acroread browser plugin not knowing the size to embed # we use a width of 100% for the case that there is no width given. # A height of 100% gives a fullscreen pdf file view without embedding it into the wikicontent. if mt.minor == 'pdf': width = width or '100%' height = height or '800px' embed_src = ''' <object %(ob_data)s %(ob_type)s %(ob_width)s %(ob_height)s %(ob_align)s> <p>%(alt)s</p> </object>''' % { "ob_data": _check_object_value("data", url), "ob_width": _check_object_value("width", width), "ob_height": _check_object_value("height", height), "ob_type": _check_object_value("type", mime_type), "ob_align": _check_object_value("align", align), "alt": wikiutil.escape(alt), } else: embed_src = ''' <object %(ob_data)s %(ob_type)s %(ob_width)s %(ob_height)s %(ob_align)s> %(movie)s%(quality)s%(wmode)s%(autostart)s%(play)s%(loop)s%(menu)s<p>%(alt)s</p> </object>''' % { "ob_data": _check_object_value("data", url), "ob_width": _check_object_value("width", width), "ob_height": _check_object_value("height", height), "ob_type": _check_object_value("type", mime_type), "ob_align": _check_object_value("align", align), "movie": _check_param_value("movie", url, "data"), "quality": _check_param_value("quality", quality, "data"), "wmode": _check_param_value("wmode", wmode, "data"), "autostart": _check_param_value("autostart", autostart, "data"), "play": _check_param_value("play", play, "data"), "loop": _check_param_value("loop", loop, "data"), "menu": _check_param_value("menu", menu, "data"), "alt": wikiutil.escape(alt), } return fmt.rawHTML(embed_src)
with open(fpath) as fp: img = Image.open(fp) for action in request.values.getlist("do"): action = action.split(":") args = action[1].split(",") if len(action) > 1 else [] try: img = action_map[action[0]](img, *args) except Exception, e: request.status_code = 400 request.write("Error: {}".format(e)) return mt = wikiutil.MimeType(filename=filename) request.headers['Content-Type'] = mt.content_type() data = img.tostring('jpeg', img.mode) try: cache.lock("w") cache.open(mode="w") cache.write(data) cache.close() except Exception, e: request.status_code = 500 request.write("Error: {}".format(e)) return finally: cache.unlock() request.write(data)
def __init__(self, item, revno): FileDirRevision.__init__(self, item, revno) mimetype = wikiutil.MimeType(filename=self._fs_data_fname).mime_type() self._fs_meta.update({ MIMETYPE: mimetype, })
def _build_filelist(request, pagename, showheader, readonly, mime_type='*'): _ = request.getText fmt = request.html_formatter # access directory attach_dir = getAttachDir(request, pagename) files = _get_files(request, pagename) if mime_type != '*': files = [ fname for fname in files if mime_type == mimetypes.guess_type(fname)[0] ] html = [] if files: if showheader: html.append( fmt.rawHTML( _( "To refer to attachments on a page, use '''{{{attachment:filename}}}''', \n" "as shown below in the list of files. \n" "Do '''NOT''' use the URL of the {{{[get]}}} link, \n" "since this is subject to change and can break easily.", wiki=True))) label_del = _("del") label_move = _("move") label_get = _("get") label_edit = _("edit") label_view = _("view") label_unzip = _("unzip") label_install = _("install") may_read = request.user.may.read(pagename) may_write = request.user.may.write(pagename) may_delete = request.user.may.delete(pagename) html.append(fmt.bullet_list(1)) for file in files: mt = wikiutil.MimeType(filename=file) fullpath = os.path.join(attach_dir, file).encode(config.charset) st = os.stat(fullpath) base, ext = os.path.splitext(file) parmdict = { 'file': wikiutil.escape(file), 'fsize': "%.1f" % (float(st.st_size) / 1024), 'fmtime': request.user.getFormattedDateTime(st.st_mtime), } links = [] if may_delete and not readonly: links.append( fmt.url(1, getAttachUrl(pagename, file, request, do='del')) + fmt.text(label_del) + fmt.url(0)) if may_delete and not readonly: links.append( fmt.url(1, getAttachUrl(pagename, file, request, do='move')) + fmt.text(label_move) + fmt.url(0)) links.append( fmt.url(1, getAttachUrl(pagename, file, request)) + fmt.text(label_get) + fmt.url(0)) links.append( fmt.url(1, getAttachUrl(pagename, file, request, do='view')) + fmt.text(label_view) + fmt.url(0)) if may_write and not readonly: edit_url = getAttachUrl(pagename, file, request, do='modify') if edit_url: links.append( fmt.url(1, edit_url) + fmt.text(label_edit) + fmt.url(0)) try: is_zipfile = zipfile.is_zipfile(fullpath) if is_zipfile and not readonly: is_package = packages.ZipPackage(request, fullpath).isPackage() if is_package and request.user.isSuperUser(): links.append( fmt.url( 1, getAttachUrl( pagename, file, request, do='install')) + fmt.text(label_install) + fmt.url(0)) elif (not is_package and mt.minor == 'zip' and may_read and may_write and may_delete): links.append( fmt.url( 1, getAttachUrl( pagename, file, request, do='unzip')) + fmt.text(label_unzip) + fmt.url(0)) except RuntimeError: # We don't want to crash with a traceback here (an exception # here could be caused by an uploaded defective zip file - and # if we crash here, the user does not get a UI to remove the # defective zip file again). # RuntimeError is raised by zipfile stdlib module in case of # problems (like inconsistent slash and backslash usage in the # archive). logging.exception( "An exception within zip file attachment handling occurred:" ) html.append(fmt.listitem(1)) html.append("[%s]" % " | ".join(links)) html.append(" (%(fmtime)s, %(fsize)s KB) [[attachment:%(file)s]]" % parmdict) html.append(fmt.listitem(0)) html.append(fmt.bullet_list(0)) else: if showheader: html.append(fmt.paragraph(1)) html.append( fmt.text( _("No attachments stored for %(pagename)s") % {'pagename': pagename})) html.append(fmt.paragraph(0)) return ''.join(html)
def send_viewfile(pagename, request): _ = request.getText fmt = request.html_formatter pagename, filename, fpath = _access_file(pagename, request) if not filename: return request.write('<h2>' + _("Attachment '%(filename)s'") % {'filename': filename} + '</h2>') # show a download link above the content label = _('Download') link = (fmt.url(1, getAttachUrl(pagename, filename, request, do='get'), css_class="download") + fmt.text(label) + fmt.url(0)) request.write('%s<br><br>' % link) if filename.endswith('.tdraw') or filename.endswith('.adraw'): request.write(fmt.attachment_drawing(filename, '')) return mt = wikiutil.MimeType(filename=filename) # destinguishs if browser need a plugin in place if mt.major == 'image' and mt.minor in config.browser_supported_images: url = getAttachUrl(pagename, filename, request) request.write('<img src="%s" alt="%s">' % (wikiutil.escape(url, 1), wikiutil.escape(filename, 1))) return elif mt.major == 'text': ext = os.path.splitext(filename)[1] Parser = wikiutil.getParserForExtension(request.cfg, ext) if Parser is not None: try: content = file(fpath, 'r').read() content = wikiutil.decodeUnknownInput(content) colorizer = Parser(content, request, filename=filename) colorizer.format(request.formatter) return except IOError: pass request.write(request.formatter.preformatted(1)) # If we have text but no colorizing parser we try to decode file contents. content = open(fpath, 'r').read() content = wikiutil.decodeUnknownInput(content) content = wikiutil.escape(content) request.write(request.formatter.text(content)) request.write(request.formatter.preformatted(0)) return try: package = packages.ZipPackage(request, fpath) if package.isPackage(): request.write( "<pre><b>%s</b>\n%s</pre>" % (_("Package script:"), wikiutil.escape(package.getScript()))) return if zipfile.is_zipfile(fpath) and mt.minor == 'zip': zf = zipfile.ZipFile(fpath, mode='r') request.write("<pre>%-46s %19s %12s\n" % (_("File Name"), _("Modified") + " " * 5, _("Size"))) for zinfo in zf.filelist: date = "%d-%02d-%02d %02d:%02d:%02d" % zinfo.date_time request.write( wikiutil.escape("%-46s %s %12d\n" % (zinfo.filename, date, zinfo.file_size))) request.write("</pre>") return except RuntimeError: # We don't want to crash with a traceback here (an exception # here could be caused by an uploaded defective zip file - and # if we crash here, the user does not get a UI to remove the # defective zip file again). # RuntimeError is raised by zipfile stdlib module in case of # problems (like inconsistent slash and backslash usage in the # archive). logging.exception( "An exception within zip file attachment handling occurred:") return from MoinMoin import macro from MoinMoin.parser.text import Parser macro.request = request macro.formatter = request.html_formatter p = Parser("##\n", request) m = macro.Macro(p) # use EmbedObject to view valid mime types if mt is None: request.write( '<p>' + _("Unknown file type, cannot display this attachment inline.") + '</p>') link = (fmt.url(1, getAttachUrl(pagename, filename, request)) + fmt.text(filename) + fmt.url(0)) request.write('For using an external program follow this link %s' % link) return request.write( m.execute('EmbedObject', u'target="%s", pagename="%s"' % (filename, pagename))) return