Ejemplo n.º 1
0
 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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
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))
Ejemplo n.º 4
0
    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))
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
 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,
     })
Ejemplo n.º 8
0
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]" % "&nbsp;| ".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)
Ejemplo n.º 9
0
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