[Erp5-report] r24669 - /erp5/trunk/products/ERP5OOo/OOoTemplate.py
nobody at svn.erp5.org
nobody at svn.erp5.org
Fri Nov 21 19:51:23 CET 2008
Author: nicolas
Date: Fri Nov 21 19:51:23 2008
New Revision: 24669
URL: http://svn.erp5.org?rev=24669&view=rev
Log:
Refactor replaceInclude of office:include with native XML approach.
This patch allow user to pass some parameter inside XML structure,
given by marshaller xml.marshal.generic
dic = {'a':1, 'b':4}
<?xml version="1.0"?>
<marshal>
<dictionary id="i2">
<string>a</string>
<int>1</int>
<string>b</string>
<int>4</int>
</dictionary>
</marshal>
Modified:
erp5/trunk/products/ERP5OOo/OOoTemplate.py
Modified: erp5/trunk/products/ERP5OOo/OOoTemplate.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5OOo/OOoTemplate.py?rev=24669&r1=24668&r2=24669&view=diff
==============================================================================
--- erp5/trunk/products/ERP5OOo/OOoTemplate.py [utf8] (original)
+++ erp5/trunk/products/ERP5OOo/OOoTemplate.py [utf8] Fri Nov 21 19:51:23 2008
@@ -60,6 +60,14 @@
from Products.ERP5.Document.Document import ConversionError
import Products.ERP5Type.Document
+
+try:
+ from libxml2 import parseDoc, createOutputBuffer
+except ImportError:
+ LOG('OOoUtils', INFO, "Can't import libxml2.parseDoc")
+ class parseDoc:
+ def __init__(self, *args, **kw):
+ raise ImportError, "Sorry, it was not possible to import libxml2 library, python2.4-libxml2 is not installed"
# Constructors
manage_addOOoTemplate = DTMLFile("dtml/OOoTemplate_add", globals())
@@ -241,7 +249,7 @@
def _resolvePath(self, path):
return self.getPortalObject().unrestrictedTraverse(path)
- def renderIncludes(self, here, text, extra_context, sub_document=None):
+ def renderIncludes(self, here, text, extra_context, request, sub_document=None):
attached_files_dict = {}
arguments_re = re.compile('''(\S+?)\s*=\s*('|")(.*?)\\2\s*''',re.DOTALL)
def getLengthInfos( opts_dict, opts_names ):
@@ -257,21 +265,18 @@
ret.append(val)
return ret
- def replaceIncludes(match):
- # Build a dictionary with tag parameters
- options_dict = dict((x[0], x[2]) for x in arguments_re.findall(match.group(1)))
+ def replaceIncludes(path):
# Find the page template based on the path and remove path from dict
- document = self._resolvePath(options_dict['path'].encode())
+ document = self._resolvePath(path)
document_text = ZopePageTemplate.pt_render(document,
extra_context=extra_context)
- del options_dict['path']
# Find the type of the embedded document
document_type = document.content_type
# Prepare a subdirectory to store embedded objects
actual_idx = self.document_counter.next()
- dir_name = '%s%d'%(self._OLE_directory_prefix,actual_idx)
+ dir_name = '%s%d'%(self._OLE_directory_prefix, actual_idx)
if sub_document: # sub-document means sub-directory
dir_name = sub_document + '/' + dir_name
@@ -293,50 +298,18 @@
# Start recursion if necessary
sub_attached_files_dict = {}
if 'office:include' in document_text: # small optimisation to avoid recursion if possible
- (document_text, sub_attached_files_dict ) = self.renderIncludes(document_text, dir_name, extra_context)
-
- # Build settings document if necessary
- settings_text = None
- if 0:
- w = 10
- h = 10
- # View* = writer
- # Visible* = calc
- settings_text = """<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE office:document-settings PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "office.dtd">
-<office:document-settings xmlns:office="http://openoffice.org/2000/office"
-xmlns:xlink="http://www.w3.org/1999/xlink"
-xmlns:config="http://openoffice.org/2001/config" office:version="1.0">
-<office:settings>
-<config:config-item-set config:name="view-settings">
-<config:config-item config:name="ViewAreaTop" config:type="int">0</config:config-item>
-<config:config-item config:name="ViewAreaLeft" config:type="int">0</config:config-item>
-<config:config-item config:name="ViewAreaWidth" config:type="int">%(w)d</config:config-item>
-<config:config-item config:name="ViewAreaHeight" config:type="int">%(h)d</config:config-item>
-<config:config-item config:name="VisibleAreaTop" config:type="int">0</config:config-item>
-<config:config-item config:name="VisibleAreaLeft" config:type="int">0</config:config-item>
-<config:config-item config:name="VisibleAreaWidth" config:type="int">%(w)d</config:config-item>
-<config:config-item config:name="VisibleAreaHeight" config:type="int">%(h)d</config:config-item>
-</config:config-item-set>
-</office:settings>
-</office:document-settings>""" % dict( w=int(w*1000) , h=int(h*1000) ) # convert from 10^-2 (centimeters) to 10^-5
+ (document_text, sub_attached_files_dict ) = self.renderIncludes(document_text, dir_name, extra_context, request)
# Attach content, style and settings if any
attached_files_dict[dir_name] = dict(document=document_text,
doc_type=document_type,
stylesheet=stylesheet)
- if settings_text:
- attached_files_dict[dir_name + '/settings.xml'] = dict(document=settings_text,
- doc_type='text/xml')
+
attached_files_dict.update(sub_attached_files_dict)
# Build the new tag
- parameter_list = []
- for k, v in options_dict.items():
- parameter_list.append('%s="%s"' % (k, v))
- new_tag = '<draw:object xlink:href="./%s" %s/>' %\
- (dir_name.split('/')[-1], ' '.join(parameter_list))
- return new_tag
+ new_path = './%s' % dir_name.split('/')[-1]
+ return new_path
def replaceIncludesImg(match):
options_dict = { 'text:anchor-type': 'paragraph' }
@@ -428,18 +401,32 @@
replacement = '<text:p text:style-name="Standard">'+replacement+'</text:p>'
return replacement
- # NOTE: (?s) at the end is for including '\n' when matching '.'
- # It's an equivalent to DOTALL option passing (but sub can't get options parameter)
+ xml_doc = parseDoc(text)
+ draw_ns = xml_doc.getRootElement().searchNs(xml_doc, 'draw')
+ xlink_ns = xml_doc.getRootElement().searchNs(xml_doc, 'xlink')
+ for office_include in xml_doc.xpathEval('//*[name() = "office:include"]'):
+ marshal_list = office_include.xpathEval('./marshal')
+ if marshal_list:
+ from xml.marshal.generic import loads
+ arg_dict = loads(marshal_list[0].serialize('utf-8', 0))
+ extra_context.update(arg_dict)
+ request.other.update(arg_dict)
+ attr_path_list = office_include.xpathEval('./@path')
+ path = attr_path_list[0].content
+ new_path = replaceIncludes(path)
+ draw_object = xml_doc.newChild(draw_ns, 'object', None)
+ draw_object.setNsProp(xlink_ns, 'href', new_path)
+ draw_object.copyPropList(office_include)
+ office_include.replaceNode(draw_object)
+ text = xml_doc.serialize('utf-8', 0)
+ xml_doc.freeDoc()
text = re.sub('<\s*office:include_img\s+(.*?)\s*/\s*>(?s)', replaceIncludesImg, text)
- text = re.sub('<\s*office:include\s+(.*?)\s*/\s*>(?s)', replaceIncludes, text)
return (text, attached_files_dict)
# Proxy method to PageTemplate
def pt_render(self, source=0, extra_context={}):
# Get request
- request = extra_context.get('REQUEST', None)
- if request is None:
- request = self.REQUEST
+ request = extra_context.get('REQUEST', self.REQUEST)
# Get parent object (the one to render this template on)
here = getattr(self, 'aq_parent', None)
if here is None:
@@ -467,7 +454,8 @@
doc_xml = doc_xml.encode('utf-8')
# Replace the includes
- (doc_xml,attachments_dict) = self.renderIncludes(here, doc_xml, extra_context)
+ (doc_xml,attachments_dict) = self.renderIncludes(here, doc_xml,
+ extra_context, request)
try:
default_styles_text = ooo_builder.extract('styles.xml')
More information about the Erp5-report
mailing list