Commit a5d14b11 authored by Nicolas Delaby's avatar Nicolas Delaby

Add support of Image & Css inclusions in Html conversion

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@21869 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent e1d4f879
from Products.PortalTransforms.libtransforms.commandtransform import commandtransform from Products.PortalTransforms.libtransforms.commandtransform import commandtransform
from Products.PortalTransforms.interfaces import idatastream from Products.PortalTransforms.interfaces import idatastream
from Products.ERP5Type.Document import newTempOOoDocument from Products.ERP5Type.Document import newTempOOoDocument
from Products.CMFCore.utils import getToolByName
try:
from Products.ERP5OOo.OOoUtils import OOoBuilder
import re
from libxml2 import parseDoc, parserError
import_succeed = 1
except ImportError:
import_succeed = 0
from zLOG import LOG from zLOG import LOG
REMOTE_URL_PATTERN = '^((?P<protocol>http(s)?://)(?P<domain>[.a-zA-Z0-9]+)+)?(?P<port>:\d{4})?(?P<path>/?\S*)'
class TransformError(Exception): class TransformError(Exception):
pass pass
...@@ -46,13 +56,102 @@ class OOOdCommandTransform(commandtransform): ...@@ -46,13 +56,102 @@ class OOOdCommandTransform(commandtransform):
commandtransform.__init__(self, name) commandtransform.__init__(self, name)
if name: if name:
self.__name__ = name self.__name__ = name
self.data = data
self.context = context
self.mimetype = mimetype self.mimetype = mimetype
self.context = context
if import_succeed and self.mimetype == 'text/html':
data = self.includeExternalCssList(data)
self.data = data
def name(self): def name(self):
return self.__name__ return self.__name__
def includeImageList(self, data):
"""
Include Images in ODF archive
"""
builder = OOoBuilder(data)
content = builder.extract('content.xml')
xml_doc = parseDoc(content)
image_tag_list = xml_doc.xpathEval('//*[name() = "draw:image"]')
svg_ns = xml_doc.getRootElement().searchNs(xml_doc, 'svg')
ratio_px_cm = 2.54 / 100.
for image_tag in image_tag_list:
frame = image_tag.parent
#Try to get image file from ZODB
href_attribute_list = image_tag.xpathEval('.//@*[name() = "xlink:href"]')
href_attribute = href_attribute_list[0]
url = href_attribute.get_content()
matching = re.match(REMOTE_URL_PATTERN, url)
if matching is not None:
path = matching.groupdict().get('path')
try:
image = self.context.restrictedTraverse(path)
except AttributeError:
#Image not found, this image is probably not hosted by ZODB. Do nothing
image = None
if image is not None:
content_type = image.getContentType()
mimetype_list = getToolByName(self.context,
'mimetypes_registry').lookup(content_type)
#Need to improve default format handling
format = 'png'
if mimetype_list:
format = mimetype_list[0].minor()
try:
#ERP5 API
data = image.getData()
height = image.getHeight()
width = image.getWidth()
except AttributeError:
#OFS API
data = image.data
height = image.height
width = image.width
if height:
frame.setNsProp(svg_ns, 'height', '%.3fcm' % (height * ratio_px_cm))
if width:
frame.setNsProp(svg_ns, 'width', '%.3fcm' % (width * ratio_px_cm))
new_path = builder.addImage(data, format=format)
href_attribute.setContent(new_path)
builder.replace('content.xml', xml_doc.serialize('utf-8', 0))
xml_doc.freeDoc()
return builder.render()
def includeExternalCssList(self, data):
"""
Replace external Css link by style Element
"""
try:
xml_doc = parseDoc(data)
except parserError:
#If not valid xhtml do nothing
return data
xpath = '//*[local-name() = "link"][@type = "text/css"]'
css_link_tag_list = xml_doc.xpathEval(xpath)
for css_link_tag in css_link_tag_list:
#Try to get css from ZODB
href_attribute_list = css_link_tag.xpathEval('.//@href')
href_attribute = href_attribute_list[0]
url = href_attribute.get_content()
matching = re.match(REMOTE_URL_PATTERN, url)
if matching is not None:
path = matching.groupdict().get('path')
try:
css = self.context.restrictedTraverse(path)
except AttributeError:
#Image not found, this image is probably not hosted by ZODB. Do nothing
css = None
if css is not None:
css_as_text = css(client=self.context.getPortalObject())
style_node = xml_doc.newChild(None, 'style', css_as_text)
style_node.setProp('type', 'text/css')
css_link_tag.replaceNode(style_node)
#omit xml-declaration
data = xml_doc.serialize('utf-8', 0)\
.replace('<?xml version="1.0" encoding="utf-8"?>\n', '')
xml_doc.freeDoc()
return data
def convert(self): def convert(self):
tmp_ooo = newTempOOoDocument(self.context, self.name) tmp_ooo = newTempOOoDocument(self.context, self.name)
tmp_ooo.edit( base_data=self.data, tmp_ooo.edit( base_data=self.data,
...@@ -65,6 +164,11 @@ class OOOdCommandTransform(commandtransform): ...@@ -65,6 +164,11 @@ class OOOdCommandTransform(commandtransform):
def convertTo(self, format): def convertTo(self, format):
if self.ooo.isTargetFormatAllowed(format): if self.ooo.isTargetFormatAllowed(format):
mime, data = self.ooo.convert(format) mime, data = self.ooo.convert(format)
if import_succeed and self.mimetype == 'text/html':
builder = OOoBuilder(data)
content = builder.extract('content.xml')
xml_doc = parseDoc(content)
data = self.includeImageList(data)
return data return data
else: else:
raise TransformError raise TransformError
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment