view data/plugin/macro/pdf2svg.py @ 548:9e59fdd04742

macro.pdf2svg: keyword added for converting an attachment
author Reimar Bauer <rb.proj AT googlemail DOT com>
date Fri, 25 Feb 2011 11:02:00 +0100
parents 983196519144
children e75fc2c81653
line wrap: on
line source
# -*- coding: iso-8859-1 -*-
"""
    MoinMoin - pdf2svg converts pdf files to svg and shows rendered svg

    Features:
    * fetches pdf files from urls and converts them to svg,
      The new svg image is stored and rendered from its cachefile
    * can also be used for an attached pdf file 

    Requires posix platform and pdf2svg

    @copyright: 2011 MoinMoin:ReimarBauer
    @license: GNU GPL, see COPYING for details.
"""

from MoinMoin import log
logging = log.getLogger(__name__)

import os
import tempfile
import urllib2

from MoinMoin import caching
from MoinMoin.util.SubProcess import exec_cmd
from MoinMoin.action import AttachFile, cache
from MoinMoin.Page import Page

CACHE_ARENA = 'sendcache'
CACHE_SCOPE = 'wiki'

def get_svg_key(request, url, pageno):
    """
    gets the key needed for the svg cache file 
    """
    return cache.key(request, itemname="SVG", content="%s.%s.SVG" % (url, pageno))

def prepare_svg_cache(request, url, pageno):
    """
    prepares the svg cache file and returns its file name
    """
    key = get_svg_key(request, url, pageno)
    cache.put(request, key, "<svg></svg>",
              content_type="image/svg+xml")
    data_cache = caching.CacheEntry(request, CACHE_ARENA, key+'.data', CACHE_SCOPE, do_locking=False)
    return data_cache._fname

def fetch_pdf_item(request, url):
    """
    fetches the pdf item and stores it as cache file 
    """
    key = cache.key(request, itemname="PDF", content=url)
    try:
        item = urllib2.urlopen(url)
    except (IOError, urllib2.HTTPError, ValueError), err:
        logging.info(url)
        logging.debug("%s: %s" % (url, err))
        return ""
    else:
        cache.put(request, key, item.read(),
                  content_type="application/pdf")
        item.close()
        data_cache = caching.CacheEntry(request, CACHE_ARENA, key+'.data', CACHE_SCOPE, do_locking=False)
        return data_cache._fname

def macro_pdf2svg(macro, attachment='', url='', width=1200, height=800, pageno=1):
    """
    converts pdf from urls to svg files using MoinMoins cache and renders from there
    """
    request = macro.request
    pagename = request.page.page_name
    content_type = 'image/svg+xml'
    template_cmd = "pdf2svg %(pdf_file)s %(svg_file)s %(pageno)s"
    pdf_file = None

    if os.name == 'posix':
        key = get_svg_key(request, attachment or url, pageno)
        if not cache.exists(request, key):
            if attachment and attachment.lower().endswith('.pdf') and AttachFile.exists(request, pagename, attachment):
                pdf_file = os.path.join(AttachFile.getAttachDir(request, pagename), attachment)
            elif url:
                #TODO: a mimetype check is needed beforehand 
                pdf_file = fetch_pdf_item(request, url)
            if pdf_file:
                svg_file = prepare_svg_cache(request, url, pageno)
                cmd = template_cmd % {"pdf_file": pdf_file,
                                      "svg_file": svg_file,
                                      "pageno": pageno
                                      }
                data, errors, rc = exec_cmd(cmd, timeout=300)
                logging.debug("Command '%s', rc: %d, stdout: %d bytes, stderr: %s" % (cmd, rc, len(data), errors))
                if not errors:
                    svg_image = open(svg_file, 'rb')
                    cache.put(request, key, svg_image.read(),
                              content_type="image/svg+xml")
                    svg_image.close()

        if cache.exists(request, key):
            cache_url = "%s%s%s" % (request.getQualifiedURL(), Page(request, pagename).url(request), cache.url(request, key))
            from MoinMoin import macro as _macro
            from MoinMoin.parser.text import Parser
            _macro.formatter = request.html_formatter
            parser = Parser("##\n", request)
            m = _macro.Macro(parser)
            html_object = m.execute('EmbedObject', u'width=%s, height=%s, target=%s, url_mimetype=%s' % (width, height, cache_url, content_type))
            if not url:
                url = AttachFile.getAttachUrl(pagename, attachment, request, addts=0, do='get')
                name = attachment
                return '<B>Preview for:</B> "<a href=%s>%s</a>"<hr>%s<br>' % (url, name, html_object)
            else:
                name = url
                return '<B>Converted from:</B> "<a href=%s>%s</a>" <b>to SVG</b><hr>%s<br>' % (url, name, html_object)
        else:
             return ""