Commit 098a9c69 authored by Arnaud Fontaine's avatar Arnaud Fontaine

WIP: ZODB Components: Migrate ERP5OOo Product from filesystem.

OOoUtils + OOoTemplate
parent 421d7d98
...@@ -74,7 +74,7 @@ def getIdFromString(string): ...@@ -74,7 +74,7 @@ def getIdFromString(string):
return clean_id return clean_id
def convert(self, filename, data=None): def convert(self, filename, data=None):
from Products.ERP5OOo.OOoUtils import OOoParser from erp5.component.module.OOoUtils import OOoParser
OOoParser = OOoParser() OOoParser = OOoParser()
import_file = read(self, filename, data) import_file = read(self, filename, data)
......
...@@ -56,7 +56,7 @@ import ZPublisher.HTTPRequest ...@@ -56,7 +56,7 @@ import ZPublisher.HTTPRequest
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import FileUpload from Products.ERP5Type.tests.utils import FileUpload
from Products.ERP5Type.tests.utils import DummyLocalizer from Products.ERP5Type.tests.utils import DummyLocalizer
from Products.ERP5OOo.OOoUtils import OOoBuilder from erp5.component.module.OOoUtils import OOoBuilder
from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import newSecurityManager
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from Products.ERP5.Document.Document import NotConvertedError from Products.ERP5.Document.Document import NotConvertedError
......
from Products.ERP5OOo.OOoUtils import OOoParser from erp5.component.module.OOoUtils import OOoParser
import string import string
request = container.REQUEST request = container.REQUEST
......
...@@ -37,31 +37,30 @@ from Products.PageTemplates.PageTemplateFile import PageTemplateFile ...@@ -37,31 +37,30 @@ from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from zope.tal.talinterpreter import FasterStringIO from zope.tal.talinterpreter import FasterStringIO
from Products.ERP5Type import PropertySheet from Products.ERP5Type import PropertySheet
from urllib import quote from urllib import quote
from Products.ERP5Type.Globals import InitializeClass, DTMLFile, get_request from Products.ERP5Type.Globals import InitializeClass, DTMLFile
from Acquisition import aq_base from Acquisition import aq_base
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from OOoUtils import OOoBuilder from erp5.component.module.OOoUtils import OOoBuilder
from zipfile import ZipFile, ZIP_DEFLATED from zipfile import ZipFile, ZIP_DEFLATED
from cStringIO import StringIO from cStringIO import StringIO
import re import re
import itertools import itertools
try: try:
# pylint: disable=no-name-in-module,unused-import
from webdav.Lockable import ResourceLockedError from webdav.Lockable import ResourceLockedError
from webdav.WriteLockInterface import WriteLockInterface from webdav.WriteLockInterface import WriteLockInterface
SUPPORTS_WEBDAV_LOCKS = 1 SUPPORTS_WEBDAV_LOCKS = 1
except ImportError: except ImportError:
SUPPORTS_WEBDAV_LOCKS = 0 SUPPORTS_WEBDAV_LOCKS = 0
from Products.ERP5.Document.Document import ConversionError
from lxml import etree from lxml import etree
from lxml.etree import Element from lxml.etree import Element
# Constructors # Constructors
manage_addOOoTemplate = DTMLFile("dtml/OOoTemplate_add", globals()) manage_addOOoTemplate = DTMLFile("dtml/OOoTemplate_add", globals())
def addOOoTemplate(self, id, title="", xml_file_id="content.xml", REQUEST=None): def addOOoTemplate(self, id, title="", xml_file_id="content.xml", REQUEST=None): # pylint: disable=redefined-builtin
"""Add OOo template to folder. """Add OOo template to folder.
id -- the id of the new OOo template to add id -- the id of the new OOo template to add
...@@ -76,12 +75,12 @@ def addOOoTemplate(self, id, title="", xml_file_id="content.xml", REQUEST=None): ...@@ -76,12 +75,12 @@ def addOOoTemplate(self, id, title="", xml_file_id="content.xml", REQUEST=None):
file_ = REQUEST.form.get('file') file_ = REQUEST.form.get('file')
if file_.filename: if file_.filename:
# Get the template in the associated context and upload the file # Get the template in the associated context and upload the file
obj.pt_upload(REQUEST, file) obj.pt_upload(REQUEST, file_)
# respond to the add_and_edit button if necessary # respond to the add_and_edit button if necessary
add_and_edit(self, id, REQUEST) add_and_edit(self, id, REQUEST)
return '' return ''
def add_and_edit(self, id, REQUEST): def add_and_edit(self, id, REQUEST): # pylint: disable=redefined-builtin
"""Helper method to point to the object's management screen if """Helper method to point to the object's management screen if
'Add and Edit' button is pressed. 'Add and Edit' button is pressed.
id -- id of the object we just added id -- id of the object we just added
...@@ -97,14 +96,18 @@ def add_and_edit(self, id, REQUEST): ...@@ -97,14 +96,18 @@ def add_and_edit(self, id, REQUEST):
REQUEST.RESPONSE.redirect(u+'/manage_main') REQUEST.RESPONSE.redirect(u+'/manage_main')
class OOoTemplateStringIO(FasterStringIO): class OOoTemplateStringIO(FasterStringIO):
# pylint: disable=method-hidden
def write(self, s): def write(self, s):
if type(s) == unicode: if isinstance(s, unicode):
s = s.encode('utf-8') s = s.encode('utf-8')
FasterStringIO.write(self, s) FasterStringIO.write(self, s)
from Products.PageTemplates.Expressions import ZopeContext, createZopeEngine from Products.PageTemplates.Expressions import ZopeContext, createZopeEngine
# On recent Zope, we need an engine to decode non-unicode-strings for us # On recent Zope, we need an engine to decode non-unicode-strings for us
#
# evaluateCode():
# pylint: disable=abstract-method
class OOoContext(ZopeContext): class OOoContext(ZopeContext):
""" ZopeContext variant that ALWAYS converts standard strings through utf-8, """ ZopeContext variant that ALWAYS converts standard strings through utf-8,
as needed by OpenOffice, ignoring the preferred encodings in the request. as needed by OpenOffice, ignoring the preferred encodings in the request.
...@@ -117,9 +120,9 @@ class OOoContext(ZopeContext): ...@@ -117,9 +120,9 @@ class OOoContext(ZopeContext):
return ZopeContext._handleText(self, text, expr) return ZopeContext._handleText(self, text, expr)
def createOOoZopeEngine(): def createOOoZopeEngine():
e = createZopeEngine() e = createZopeEngine()
e._create_context = OOoContext e._create_context = OOoContext
return e return e
_engine = createOOoZopeEngine() _engine = createOOoZopeEngine()
...@@ -177,7 +180,7 @@ class OOoTemplate(Base, ZopePageTemplate): ...@@ -177,7 +180,7 @@ class OOoTemplate(Base, ZopePageTemplate):
__name__='formSettings') __name__='formSettings')
formSettings._owner = None formSettings._owner = None
def __init__(self, id, title='', *args, **kw): def __init__(self, id, title='', *args, **kw): # pylint: disable=redefined-builtin
ZopePageTemplate.__init__(self, id, title, *args, **kw) ZopePageTemplate.__init__(self, id, title, *args, **kw)
# we store the attachments of the uploaded document # we store the attachments of the uploaded document
self.OLE_documents_zipstring = None self.OLE_documents_zipstring = None
...@@ -190,12 +193,12 @@ class OOoTemplate(Base, ZopePageTemplate): ...@@ -190,12 +193,12 @@ class OOoTemplate(Base, ZopePageTemplate):
def pt_getEngine(self): def pt_getEngine(self):
return _engine return _engine
def pt_upload(self, REQUEST, file=''): def pt_upload(self, REQUEST, file=''): # pylint: disable=redefined-builtin,arguments-differ
"""Replace the document with the text in file.""" """Replace the document with the text in file."""
if SUPPORTS_WEBDAV_LOCKS and self.wl_isLocked(): if SUPPORTS_WEBDAV_LOCKS and self.wl_isLocked():
raise ResourceLockedError, "File is locked via WebDAV" raise ResourceLockedError, "File is locked via WebDAV"
if type(file) is not StringType: if not isinstance(file, StringType):
if not file: raise ValueError, 'File not specified' if not file: raise ValueError, 'File not specified'
file = file.read() file = file.read()
...@@ -217,7 +220,7 @@ class OOoTemplate(Base, ZopePageTemplate): ...@@ -217,7 +220,7 @@ class OOoTemplate(Base, ZopePageTemplate):
except RuntimeError: except RuntimeError:
zf = ZipFile(memory_file, mode='w') zf = ZipFile(memory_file, mode='w')
for attached_file in attached_files_list: for attached_file in attached_files_list:
zf.writestr(attached_file, builder.extract(attached_file) ) zf.writestr(attached_file, builder.extract(attached_file) )
zf.close() zf.close()
memory_file.seek(0) memory_file.seek(0)
self.OLE_documents_zipstring = memory_file.read() self.OLE_documents_zipstring = memory_file.read()
...@@ -225,20 +228,6 @@ class OOoTemplate(Base, ZopePageTemplate): ...@@ -225,20 +228,6 @@ class OOoTemplate(Base, ZopePageTemplate):
file = builder.prepareContentXml(self.getXmlFileId()) file = builder.prepareContentXml(self.getXmlFileId())
return ZopePageTemplate.pt_upload(self, REQUEST, file) return ZopePageTemplate.pt_upload(self, REQUEST, file)
if 'pt_edit' not in ZopePageTemplate.__dict__:
# Override it only for 2.8 !
# ZopePageTemplate v.2.8 inherate pt_edit from
# PageTemplate. If method is defined on ZopePageTemplate
# means we are under 2.12.
# Delete me when we drop support of 2.8
security.declareProtected('Change Page Templates', 'pt_edit')
def pt_edit(self, text, content_type):
if content_type:
self.content_type = str(content_type)
if hasattr(text, 'read'):
text = text.read()
self.write(text)
security.declareProtected('Change Page Templates', 'doSettings') security.declareProtected('Change Page Templates', 'doSettings')
def doSettings(self, REQUEST, title, xml_file_id, ooo_stylesheet, script_name=None): def doSettings(self, REQUEST, title, xml_file_id, ooo_stylesheet, script_name=None):
""" """
...@@ -262,7 +251,7 @@ class OOoTemplate(Base, ZopePageTemplate): ...@@ -262,7 +251,7 @@ class OOoTemplate(Base, ZopePageTemplate):
def renderIncludes(self, here, text, extra_context, request, sub_document=None): def renderIncludes(self, here, text, extra_context, request, sub_document=None):
attached_files_dict = {} attached_files_dict = {}
arguments_re = re.compile('''(\S+?)\s*=\s*('|")(.*?)\\2\s*''',re.DOTALL) arguments_re = re.compile(r'''(\S+?)\s*=\s*('|")(.*?)\\2\s*''',re.DOTALL)
def getLengthInfos( opts_dict, opts_names ): def getLengthInfos( opts_dict, opts_names ):
ret = [] ret = []
for opt_name in opts_names: for opt_name in opts_names:
...@@ -351,6 +340,7 @@ class OOoTemplate(Base, ZopePageTemplate): ...@@ -351,6 +340,7 @@ class OOoTemplate(Base, ZopePageTemplate):
if picture_type is None: if picture_type is None:
picture_type = picture.getContentType() picture_type = picture.getContentType()
# pylint: disable=unbalanced-tuple-unpacking
w, h, maxwidth, maxheight = getLengthInfos(options_dict, w, h, maxwidth, maxheight = getLengthInfos(options_dict,
('width', 'height', 'maxwidth', 'maxheight')) ('width', 'height', 'maxwidth', 'maxheight'))
...@@ -425,11 +415,13 @@ class OOoTemplate(Base, ZopePageTemplate): ...@@ -425,11 +415,13 @@ class OOoTemplate(Base, ZopePageTemplate):
office_include.getparent().replace(office_include, draw_object) office_include.getparent().replace(office_include, draw_object)
text = etree.tostring(xml_doc, encoding='utf-8', xml_declaration=True, text = etree.tostring(xml_doc, encoding='utf-8', xml_declaration=True,
pretty_print=False) pretty_print=False)
text = re.sub('<\s*office:include_img\s+(.*?)\s*/\s*>(?s)', replaceIncludesImg, text) text = re.sub(r'<\s*office:include_img\s+(.*?)\s*/\s*>(?s)', replaceIncludesImg, text)
return (text, attached_files_dict) return (text, attached_files_dict)
# Proxy method to PageTemplate # Proxy method to PageTemplate
def pt_render(self, source=0, extra_context={}): def pt_render(self, source=0, extra_context=None):
if extra_context is None:
extra_context = {}
if source: if source:
return ZopePageTemplate.pt_render(self, source=source, return ZopePageTemplate.pt_render(self, source=source,
extra_context=extra_context) extra_context=extra_context)
...@@ -448,14 +440,14 @@ class OOoTemplate(Base, ZopePageTemplate): ...@@ -448,14 +440,14 @@ class OOoTemplate(Base, ZopePageTemplate):
ooo_document = ooo_script(self.getOooStylesheet()) ooo_document = ooo_script(self.getOooStylesheet())
else: else:
ooo_document = getattr(here, self.getOooStylesheet()) ooo_document = getattr(here, self.getOooStylesheet())
format = request.get('format') format_ = request.get('format')
try: try:
# If style is dynamic, call it # If style is dynamic, call it
if getattr(aq_base(ooo_document), '__call__', None) is not None: if getattr(aq_base(ooo_document), '__call__', None) is not None:
request.set('format', None) request.set('format', None)
ooo_document = ooo_document() ooo_document = ooo_document()
finally: finally:
request.set('format', format) request.set('format', format_)
# Create a new builder instance # Create a new builder instance
ooo_builder = OOoBuilder(ooo_document) ooo_builder = OOoBuilder(ooo_document)
# Pass builder instance as extra_context # Pass builder instance as extra_context
...@@ -550,8 +542,8 @@ class OOoTemplate(Base, ZopePageTemplate): ...@@ -550,8 +542,8 @@ class OOoTemplate(Base, ZopePageTemplate):
filename=filename, filename=filename,
content_type=mimetype,) content_type=mimetype,)
format = opts.get('format', request.get('format', None)) format_ = opts.get('format', request.get('format', None))
if format: if format_:
# Performance improvement: # Performance improvement:
# We already have OOo format data, so we do not need to call # We already have OOo format data, so we do not need to call
# convertToBaseFormat(), but just copy it into base_data property. # convertToBaseFormat(), but just copy it into base_data property.
...@@ -561,19 +553,19 @@ class OOoTemplate(Base, ZopePageTemplate): ...@@ -561,19 +553,19 @@ class OOoTemplate(Base, ZopePageTemplate):
if request is not None and not batch_mode and not source: if request is not None and not batch_mode and not source:
return tmp_ooo.index_html(REQUEST=request, return tmp_ooo.index_html(REQUEST=request,
RESPONSE=request.RESPONSE, RESPONSE=request.RESPONSE,
format=format) format=format_)
return tmp_ooo.convert(format)[1] return tmp_ooo.convert(format_)[1]
def om_icons(self): def om_icons(self):
"""Return a list of icon URLs to be displayed by an ObjectManager""" """Return a list of icon URLs to be displayed by an ObjectManager"""
icons = ({'path': 'misc_/ERP5OOo/OOo.png', icons = ({'path': 'misc_/ERP5OOo/OOo.png',
'alt': self.meta_type, 'title': self.meta_type},) 'alt': self.meta_type, 'title': self.meta_type},)
if not self._v_cooked: if not self._v_cooked:
self._cook() self._cook()
if self._v_errors: if self._v_errors:
icons = icons + ({'path': 'misc_/PageTemplates/exclamation.gif', icons = icons + ({'path': 'misc_/PageTemplates/exclamation.gif',
'alt': 'Error', 'alt': 'Error',
'title': 'This template has an error'},) 'title': 'This template has an error'},)
return icons return icons
def _getFileName(self): def _getFileName(self):
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Module Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>OOoTemplate</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>Products.ERP5OOo.OOoTemplate</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>module.erp5.OOoTemplate</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Module Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -31,16 +31,12 @@ ...@@ -31,16 +31,12 @@
from Acquisition import Implicit from Acquisition import Implicit
from Products.PythonScripts.Utility import allow_class from Products.PythonScripts.Utility import allow_class
from ZPublisher.HTTPRequest import FileUpload from Products.ERP5Type.Globals import get_request
from xml.dom import Node
from AccessControl import ClassSecurityInfo
from Products.ERP5Type.Globals import InitializeClass, get_request
from zipfile import ZipFile, ZIP_DEFLATED from zipfile import ZipFile, ZIP_DEFLATED
from cStringIO import StringIO from cStringIO import StringIO
import imghdr import imghdr
import random import random
from Products.ERP5Type import Permissions from zLOG import LOG, DEBUG
from zLOG import LOG, INFO, DEBUG
from OFS.Image import Pdata from OFS.Image import Pdata
...@@ -142,7 +138,6 @@ class OOoBuilder(Implicit): ...@@ -142,7 +138,6 @@ class OOoBuilder(Implicit):
- indent the xml - indent the xml
""" """
content_xml = self.extract(ooo_xml_file_id) content_xml = self.extract(ooo_xml_file_id)
output = StringIO()
content_doc = etree.XML(content_xml) content_doc = etree.XML(content_xml)
root = content_doc.getroottree().getroot() root = content_doc.getroottree().getroot()
#Declare zope namespaces #Declare zope namespaces
...@@ -160,10 +155,10 @@ class OOoBuilder(Implicit): ...@@ -160,10 +155,10 @@ class OOoBuilder(Implicit):
def addFileEntry(self, full_path, media_type, content=None): def addFileEntry(self, full_path, media_type, content=None):
""" Add a file entry to the manifest and possibly is content """ """ Add a file entry to the manifest and possibly is content """
self.addManifest(full_path, media_type) self.addManifest(full_path, media_type)
if content: if content:
self.replace(full_path, content) self.replace(full_path, content)
def addManifest(self, full_path, media_type): def addManifest(self, full_path, media_type):
""" Add a path to the manifest """ """ Add a path to the manifest """
...@@ -176,9 +171,9 @@ class OOoBuilder(Implicit): ...@@ -176,9 +171,9 @@ class OOoBuilder(Implicit):
meta_infos = self.extract(MANIFEST_FILENAME) meta_infos = self.extract(MANIFEST_FILENAME)
# prevent some duplicates # prevent some duplicates
for meta_line in meta_infos.split('\n'): for meta_line in meta_infos.split('\n'):
for new_meta_line in self._manifest_additions_list: for new_meta_line in self._manifest_additions_list:
if meta_line.strip() == new_meta_line: if meta_line.strip() == new_meta_line:
self._manifest_additions_list.remove(new_meta_line) self._manifest_additions_list.remove(new_meta_line)
# add the new lines # add the new lines
self._manifest_additions_list.append('</manifest:manifest>') self._manifest_additions_list.append('</manifest:manifest>')
...@@ -186,7 +181,7 @@ class OOoBuilder(Implicit): ...@@ -186,7 +181,7 @@ class OOoBuilder(Implicit):
self.replace(MANIFEST_FILENAME, meta_infos) self.replace(MANIFEST_FILENAME, meta_infos)
self._manifest_additions_list = [] self._manifest_additions_list = []
def addImage(self, image, format='png', content_type=None): def addImage(self, image, format='png', content_type=None): # pylint: disable=redefined-builtin
""" """
Add an image to the current document and return its id Add an image to the current document and return its id
""" """
...@@ -334,7 +329,6 @@ class OOoParser(Implicit): ...@@ -334,7 +329,6 @@ class OOoParser(Implicit):
document = embedded.get('{%s}href' % embedded.nsmap['xlink']) document = embedded.get('{%s}href' % embedded.nsmap['xlink'])
if document: if document:
try: try:
object_content = etree.XML(self.oo_files[document[3:] + '/content.xml'])
find_path = './/{%s}table' % self.oo_content_dom.nsmap['table'] find_path = './/{%s}table' % self.oo_content_dom.nsmap['table']
table_list = self.oo_content_dom.findall(find_path) table_list = self.oo_content_dom.findall(find_path)
if table_list: if table_list:
...@@ -342,7 +336,7 @@ class OOoParser(Implicit): ...@@ -342,7 +336,7 @@ class OOoParser(Implicit):
spreadsheets.append(table) spreadsheets.append(table)
else: # XXX: insert the link to OLE document ? else: # XXX: insert the link to OLE document ?
pass pass
except XMLSyntaxError: except XMLSyntaxError: # pylint: disable=catching-non-exception
pass pass
return spreadsheets return spreadsheets
...@@ -383,7 +377,7 @@ class OOoParser(Implicit): ...@@ -383,7 +377,7 @@ class OOoParser(Implicit):
else: else:
lines_to_repeat = int(line_group_found) lines_to_repeat = int(line_group_found)
for i in range(lines_to_repeat): for _ in range(lines_to_repeat):
table_line = [] table_line = []
# Get all cells # Get all cells
...@@ -413,7 +407,7 @@ class OOoParser(Implicit): ...@@ -413,7 +407,7 @@ class OOoParser(Implicit):
cells_to_repeat = int(cell_group_found) cells_to_repeat = int(cell_group_found)
# Ungroup repeated cells # Ungroup repeated cells
for j in range(cells_to_repeat): for _ in range(cells_to_repeat):
# Get the cell content # Get the cell content
cell_data = None cell_data = None
attribute_type_mapping = {'date': 'date-value', attribute_type_mapping = {'date': 'date-value',
...@@ -433,7 +427,6 @@ class OOoParser(Implicit): ...@@ -433,7 +427,6 @@ class OOoParser(Implicit):
# instance <text:s/> for a space (or using <text:s text:c="3"/> # instance <text:s/> for a space (or using <text:s text:c="3"/>
# for multiple spaces) <text:tab/> for a tab and <text:line-break/> # for multiple spaces) <text:tab/> for a tab and <text:line-break/>
# for new line # for new line
text_ns = cell.nsmap['text']
def format_node(node): def format_node(node):
if node.tag == '{%s}table-cell' % node.nsmap['table']: if node.tag == '{%s}table-cell' % node.nsmap['table']:
return "\n".join(part for part in return "\n".join(part for part in
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Module Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>OOoUtils</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>Products.ERP5OOo.OOoUtils</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>module.erp5.OOoUtils</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Module Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -26,7 +26,7 @@ This scripts guarantees that the list of category info is sorted in such a ...@@ -26,7 +26,7 @@ This scripts guarantees that the list of category info is sorted in such a
way that parent always precedes their children. way that parent always precedes their children.
""" """
from Products.ERP5Type.Message import translateString from Products.ERP5Type.Message import translateString
from Products.ERP5OOo.OOoUtils import OOoParser from erp5.component.module.OOoUtils import OOoParser
parser = OOoParser() parser = OOoParser()
category_list_spreadsheet_mapping = {} category_list_spreadsheet_mapping = {}
error_list = [] error_list = []
......
...@@ -5,5 +5,7 @@ module.erp5.GeneratedAmountList ...@@ -5,5 +5,7 @@ module.erp5.GeneratedAmountList
module.erp5.Log module.erp5.Log
module.erp5.MovementCollectionDiff module.erp5.MovementCollectionDiff
module.erp5.MovementGroup module.erp5.MovementGroup
module.erp5.OOoTemplate
module.erp5.OOoUtils
module.erp5.TimeoutTransport module.erp5.TimeoutTransport
module.erp5.WebDAVSupport module.erp5.WebDAVSupport
\ No newline at end of file
...@@ -3161,7 +3161,7 @@ class TestAccountingExport(AccountingTestCase): ...@@ -3161,7 +3161,7 @@ class TestAccountingExport(AccountingTestCase):
quantity=200),)) quantity=200),))
ods_data = accounting_transaction.Base_viewAsODS( ods_data = accounting_transaction.Base_viewAsODS(
form_id='AccountingTransaction_view') form_id='AccountingTransaction_view')
from Products.ERP5OOo.OOoUtils import OOoParser from erp5.component.module.OOoUtils import OOoParser
parser = OOoParser() parser = OOoParser()
parser.openFromString(ods_data) parser.openFromString(ods_data)
content_xml = parser.oo_files['content.xml'] content_xml = parser.oo_files['content.xml']
......
...@@ -826,7 +826,7 @@ AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO ...@@ -826,7 +826,7 @@ AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
"output_encoding": "utf-8", "output_encoding": "utf-8",
"content_type": "text/html"} "content_type": "text/html"}
from Products.ERP5OOo.OOoTemplate import OOoTemplate from erp5.component.module.OOoTemplate import OOoTemplate
skin_folder._setObject(OOo_template_id, skin_folder._setObject(OOo_template_id,
OOoTemplate(OOo_template_id, OOo_template_data, content_type='')) OOoTemplate(OOo_template_id, OOo_template_data, content_type=''))
......
...@@ -37,7 +37,6 @@ from Products.DCWorkflow.DCWorkflow import ValidationFailed ...@@ -37,7 +37,6 @@ from Products.DCWorkflow.DCWorkflow import ValidationFailed
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import FileUpload from Products.ERP5Type.tests.utils import FileUpload
from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod
from Products.ERP5OOo.OOoUtils import OOoParser
from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import newSecurityManager
from DateTime import DateTime from DateTime import DateTime
from Acquisition import aq_parent from Acquisition import aq_parent
...@@ -1712,6 +1711,7 @@ class TestInvoice(TestInvoiceMixin): ...@@ -1712,6 +1711,7 @@ class TestInvoice(TestInvoiceMixin):
self.fail(''.join(err_list)) self.fail(''.join(err_list))
# the <draw:image> should not be present, because there's no logo # the <draw:image> should not be present, because there's no logo
from erp5.component.module.OOoUtils import OOoParser
parser = OOoParser() parser = OOoParser()
parser.openFromString(odt) parser.openFromString(odt)
style_xml = parser.oo_files['styles.xml'] style_xml = parser.oo_files['styles.xml']
......
...@@ -157,7 +157,7 @@ class TestOOoChart(ERP5TypeTestCase, ZopeTestCase.Functional): ...@@ -157,7 +157,7 @@ class TestOOoChart(ERP5TypeTestCase, ZopeTestCase.Functional):
# Test Validation Relax NG # Test Validation Relax NG
self._validate(body) self._validate(body)
from Products.ERP5OOo.OOoUtils import OOoParser from erp5.component.module.OOoUtils import OOoParser
parser = OOoParser() parser = OOoParser()
parser.openFromString(body) parser.openFromString(body)
content_xml_view = parser.oo_files['content.xml'] content_xml_view = parser.oo_files['content.xml']
...@@ -250,7 +250,7 @@ class TestOOoChart(ERP5TypeTestCase, ZopeTestCase.Functional): ...@@ -250,7 +250,7 @@ class TestOOoChart(ERP5TypeTestCase, ZopeTestCase.Functional):
# Test Validation Relax NG # Test Validation Relax NG
self._validate(body) self._validate(body)
from Products.ERP5OOo.OOoUtils import OOoParser from erp5.component.module.OOoUtils import OOoParser
parser = OOoParser() parser = OOoParser()
parser.openFromString(body) parser.openFromString(body)
content_xml_view = parser.oo_files['content.xml'] content_xml_view = parser.oo_files['content.xml']
......
This diff is collapsed.
OOo Template
An Zope object class to generate OOo documents dynamically.
OOo Template derives from Zope Page Templates. Simply define the content.xml
part of an OOo document in the edit tab. Then create a new File and upload
an existing OOo document (ex. default_ooo_template). Then set the stylesheet
property to the id of the uploaded OOo document (ex. default_ooo_template in this case).
Rendering consists in replacing content.xml of the original OOo document
with the content.xml generated by the OOo Template.
Special tags for including content:
- <office:include>
Allow you to include another document in the current template (as an OLE attachment)
You must specify at least the path (can be either a single name or a path name using "/").
The type of document must be specified in the embedded document itself as
a MIME type. Size parameters are defined, as in any ODF file,
within the <draw:frame> tag which encloses the <office:include> tag.
TODO: make sure it is useful or useless to pass x, y params (as before)
Example:
<draw:frame draw:style-name='gr1' svg:height='18.686cm' svg:width='27.367cm' draw:layer='layout'
svg:x='0cm' svg:y='0cm'
tal:attributes="svg:height height | string:18.686cm;
svg:width width | string:27.367cm">
<office:include path="ERP5Site_viewOwnerBarChart" xlink:type='simple'
xlink:actuate='onLoad' xlink:show='embed'/>
</draw:frame>
- <office:include_img>
Not unlike <office:include>, allows you to include a picture document, refer to
the <office:include> part for details.
The optional "type" attribute specifies the picture format ; you can either
pass a full value ("image/jpeg") or the short version ("jpeg").
You can also pass position parameters with "x" and "y" attributes.
The maxwidth and maxheight parameters are useful to set constraints.
The aspect ratio information try to be kept (if you set only one size
or if a constraint is applied).
Example:
<office:include_img x="5cm" y="1cm" path="foo" />
Tips:
- it is possible to embed images by calling oo_builder.addImage(image)
where oo_builder is a handle to OOo Template internals and
addImage a method to embed an image in the resulting document.
Example:
<draw:image draw:style-name="fr1" draw:name="Image1" text:anchor-type="as-char"
draw:z-index="0" xlink:href="#Pictures/0001.png"
xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"
tal:attributes="xlink:href python:request.oo_builder.addImage(image.index_html(None,None,display='medium'))"/>
Known Issues:
- content type must be set to text/html
- remove any dtd declaration such as:
<!DOCTYPE office:document-content PUBLIC "-//OpenOffice.org//DTD OfficeDocument
1.0//EN" "office.dtd">
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