diff --git a/product/ERP5OOo/Document/OOoDocument.py b/product/ERP5OOo/Document/OOoDocument.py index 78fcec11ad7e9bbeacb4f1f79b837e14a54d7171..66950f90cf62e9f44e1ca559aebf54ec08ca9e0e 100644 --- a/product/ERP5OOo/Document/OOoDocument.py +++ b/product/ERP5OOo/Document/OOoDocument.py @@ -373,7 +373,7 @@ class OOoDocument(File, ConversionCacheMixin): if display is None or original_format not in STANDARD_IMAGE_FORMAT_LIST: self.setConversion(data, mime, format=format) else: - temp_image = self.portal_contributions.newContent( + self.portal_contributions.newContent( portal_type='Image', temp_object=1) temp_image._setData(data) diff --git a/product/ERP5OOo/OOoTemplate.py b/product/ERP5OOo/OOoTemplate.py index 00e820cd804e33544d6cd202ab22921e19382fdc..7d6848fc45f779f3e2626578c3363e9b0701028b 100644 --- a/product/ERP5OOo/OOoTemplate.py +++ b/product/ERP5OOo/OOoTemplate.py @@ -51,6 +51,8 @@ try: except ImportError: SUPPORTS_WEBDAV_LOCKS = 0 +from Products.ERP5.Document.Document import ConversionError + # Constructors manage_addOOoTemplate = DTMLFile("dtml/OOoTemplate_add", globals()) @@ -63,11 +65,12 @@ def addOOoTemplate(self, id, title="", REQUEST=None): """ # add actual object id = self._setObject(id, OOoTemplate(id, title)) - file = REQUEST.form.get('file') - if file.filename: - # Get the template in the associated context and upload the file - getattr(self,id).pt_upload(REQUEST, file) - # respond to the add_and_edit button if necessary + if REQUEST is not None: + file = REQUEST.form.get('file') + if file.filename: + # Get the template in the associated context and upload the file + getattr(self,id).pt_upload(REQUEST, file) + # respond to the add_and_edit button if necessary add_and_edit(self, id, REQUEST) return '' @@ -394,9 +397,8 @@ xmlns:config="http://openoffice.org/2001/config" office:version="1.0"> def pt_render(self, source=0, extra_context={}): # Get request request = extra_context.get('REQUEST', None) - if not request: - request = get_request() - + if request is None: + request = self.REQUEST # Get parent object (the one to render this template on) here = getattr(self, 'aq_parent', None) if here is None: @@ -413,6 +415,7 @@ xmlns:config="http://openoffice.org/2001/config" office:version="1.0"> ooo_builder = OOoBuilder(ooo_document) # Pass builder instance as extra_context extra_context['ooo_builder'] = ooo_builder + # And render page template doc_xml = ZopePageTemplate.pt_render(self, source=source, extra_context=extra_context) @@ -423,6 +426,7 @@ xmlns:config="http://openoffice.org/2001/config" office:version="1.0"> default_styles_text = ooo_builder.extract('styles.xml') except AttributeError: default_styles_text = None + # Add the associated files for dir_name, document_dict in attachments_dict.iteritems(): # Special case : the document is an OOo one @@ -441,9 +445,6 @@ xmlns:config="http://openoffice.org/2001/config" office:version="1.0"> ooo_builder.addFileEntry(full_path=dir_name, media_type=document_dict['doc_type'], content = document_dict['document'] ) - # Get request and batch_mode - batch_mode = extra_context.get('batch_mode', 0) - # Debug mode if request.get('debug',0): return doc_xml @@ -457,6 +458,12 @@ xmlns:config="http://openoffice.org/2001/config" office:version="1.0"> except AttributeError: self.OLE_documents_zipstring = None + # Convert if necessary + opts = extra_context.get("options", None) + + # Get request and batch_mode + batch_mode = opts.get('batch_mode', None) + # If the file has embedded OLE documents, restore it if self.OLE_documents_zipstring: additional_builder = OOoBuilder( self.OLE_documents_zipstring ) @@ -467,24 +474,22 @@ xmlns:config="http://openoffice.org/2001/config" office:version="1.0"> ooo_builder.updateManifest() # Produce final result - ooo = ooo_builder.render(self.title or self.id) - - # Convert if necessary - opts = extra_context.get("options", None) + ooo = ooo_builder.render(name=self.title or self.id) + if opts is not None: format = opts.get('format', request.get('format', None)) if format: - return self._asFormat(ooo, format, request) + return self._asFormat(ooo, format, request, batch_mode) - # Do not send a RESPONSE if in batch_mode - if request and not batch_mode: + if format is None and not batch_mode: request.RESPONSE.setHeader('Content-Type','%s;; charset=utf-8' % self.content_type) - request.RESPONSE.setHeader('Content-Length',len(ooo)) - request.RESPONSE.setHeader('Content-Disposition','inline;filename=%s' % - self.title_or_id()) - + request.RESPONSE.setHeader('Content-disposition', 'inline;filename=%s' % self.title_or_id()) + else: + request.RESPONSE.setHeader('Content-Type','%s;; charset=utf-8' % 'text/html') + request.RESPONSE.setHeader('Content-disposition', 'inline;filename=%s' % self.title_or_id()) + return ooo - + def om_icons(self): """Return a list of icon URLs to be displayed by an ObjectManager""" icons = ({'path': 'misc_/ERP5OOo/OOo.png', @@ -503,8 +508,8 @@ xmlns:config="http://openoffice.org/2001/config" office:version="1.0"> """ return self._asFormat(ooo, 'pdf', REQUEST) - def _asFormat(self, ooo, format, REQUEST=None): - # now create a temp OOoDocument to convert data to pdf + def _asFormat(self, ooo, format, REQUEST=None, batch_mode=0): + # Now create a temp OOoDocument to convert data to pdf from Products.ERP5Type.Document import newTempOOoDocument tmp_ooo = newTempOOoDocument(self, self.title_or_id()) tmp_ooo.edit(base_data=ooo, @@ -512,30 +517,30 @@ xmlns:config="http://openoffice.org/2001/config" office:version="1.0"> source_reference=self.title_or_id(), base_content_type=self.content_type,) tmp_ooo.oo_data = ooo - - if format == 'pdf': - # slightly different implementation + if format == 'pdf' and not batch_mode: + # Slightly different implementation # now convert it to pdf tgts = [x[1] for x in tmp_ooo.getTargetFormatItemList() if x[1].endswith('pdf')] if len(tgts) > 1: - raise ValueError, 'multiple pdf formats found - this shouldnt happen' + REQUEST.RESPONSE.setHeader('Content-type', 'text/html') + REQUEST.RESPONSE.setHeader('Content-disposition', 'inline;filename=%s.pdf' % self.title_or_id()) + raise ValueError, 'multiple pdf formats found - this shouldnt happen' if len(tgts) == 0: - raise ValueError, 'no pdf format found' + REQUEST.RESPONSE.setHeader('Content-type', 'text/html') + REQUEST.RESPONSE.setHeader('Content-disposition', 'inline;filename=%s.pdf' % self.title_or_id()) + raise ValueError, 'no pdf format found' fmt = tgts[0] mime, data = tmp_ooo.convert(fmt) if REQUEST is not None: - REQUEST.RESPONSE.setHeader('Content-type', 'application/pdf') - REQUEST.RESPONSE.setHeader('Content-disposition', - 'attachment;; filename="%s.pdf"' % self.title_or_id()) + REQUEST.RESPONSE.setHeader('Content-type', 'application/pdf') + REQUEST.RESPONSE.setHeader('Content-disposition', 'attachment;filename=%s.pdf' % self.title_or_id()) return data - - mime, data = tmp_ooo.convert(format) + mime , data = tmp_ooo.convert(format) if REQUEST is not None: REQUEST.RESPONSE.setHeader('Content-type', mime) - REQUEST.RESPONSE.setHeader('Content-disposition', - 'attachment;; filename="%s.%s"' % (self.title_or_id(),format)) - # FIXME the above lines should return zip format when html was requested + REQUEST.RESPONSE.setHeader('Content-disposition', 'attachment;filename=%s.%s' % (self.title_or_id(),format)) + # FIXME the above lines should return zip format when html was requested return data InitializeClass(OOoTemplate) diff --git a/product/ERP5OOo/OOoUtils.py b/product/ERP5OOo/OOoUtils.py index a41d2312b9e3e5ab6148ab1a55c461ed2556ea13..a45d2555239ccd7404d9cd3c73a417695722c080 100644 --- a/product/ERP5OOo/OOoUtils.py +++ b/product/ERP5OOo/OOoUtils.py @@ -176,7 +176,6 @@ class OOoBuilder: """ Add a path to the manifest """ MANIFEST_FILENAME = 'META-INF/manifest.xml' meta_infos = self.extract(MANIFEST_FILENAME) - # prevent some duplicates for meta_line in meta_infos.split('\n'): for new_meta_line in self._manifest_additions_list: @@ -207,9 +206,9 @@ class OOoBuilder: returns the OOo document """ request = get_request() - request.response.setHeader('Content-type', OOo_mimeType_dict.get(extension, 'application/vnd.sun.xml.writer')) if name: - request.response.setHeader('Content-Disposition', 'attachment; filename=%s.%s' % (name, extension)) + request.response.setHeader('Content-Disposition', 'inline; filename=%s.%s' % (name, extension)) + self._document.seek(0) return self._document.read() diff --git a/product/ERP5OOo/tests/PersonSpreadsheetStylesheet b/product/ERP5OOo/tests/PersonSpreadsheetStylesheet new file mode 100644 index 0000000000000000000000000000000000000000..34e59f79b5bbf0ae0a05b7ad92abda2a5fa766c6 Binary files /dev/null and b/product/ERP5OOo/tests/PersonSpreadsheetStylesheet differ diff --git a/product/ERP5OOo/tests/testOOoBatchMode.py b/product/ERP5OOo/tests/testOOoBatchMode.py new file mode 100644 index 0000000000000000000000000000000000000000..b345797a7cdf8be4bd7637463bbf3c09a2793374 --- /dev/null +++ b/product/ERP5OOo/tests/testOOoBatchMode.py @@ -0,0 +1,124 @@ +############################################################################## +# +# Copyright (c) 2004, 2005, 2006 Nexedi SARL and Contributors. +# All Rights Reserved. +## +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsability of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# garantees and support are strongly adviced to contract a Free Software +# Service Company +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +############################################################################## + +import os +import sys +import Zope +from AccessControl.SecurityManagement import newSecurityManager +from Testing import ZopeTestCase +from Products.PageTemplates.GlobalTranslationService import setGlobalTranslationService +from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase +from Testing.makerequest import makerequest +from Products.ERP5.Document.Document import ConversionError +from App.config import getConfiguration + +class TestOoodResponse(ERP5TypeTestCase): + + manager_username = 'rie' + manager_password = 'rie' + quiet = 1 + run_all_test = 1 + + def getTitle(self): + return "TestOOoBatchMode" + + def login(self, quiet=0, run=run_all_test): + uf = self.getPortal().acl_users + uf._doAddUser(self.manager_username, self.manager_password, ['Manager'], []) + user = uf.getUserById(self.manager_username).__of__(uf) + newSecurityManager(None, user) + + def getBusinessTemplateList(self): + return () + + def afterSetUp(self): + self.login() + portal_skins = self.getSkinsTool() + portal_skins.custom.REQUEST.RESPONSE.setHeader('content-type', 'text/html') + try: + import_file_path = os.path.join(getConfiguration().instancehome, + 'Products', + 'ERP5OOo', + 'tests', + 'PersonSpreadsheetStylesheet' ) + except IOError: + import_file_path = os.path.join(getConfiguration().softwarehome, + 'Products', + 'ERP5OOo', + 'tests', + 'PersonSpreadsheetStylesheet') + + import_file = open(import_file_path) + addStyleSheet = portal_skins.custom.manage_addProduct['OFSP'].manage_addFile + addStyleSheet(id='Base_getODTStyleSheet', file=import_file, title='', precondition='', content_type='application/vnd.oasis.opendocument.text') + addOOoTemplate = portal_skins.custom.manage_addProduct['ERP5OOo'].addOOoTemplate + addOOoTemplate(id='ERP5Site_viewNothingAsOdt', title='') + portal_skins.changeSkin(skinname=None) + ERP5Site_viewNothingAsOdt = self.getPortal().ERP5Site_viewNothingAsOdt + text = "<office:document-content xmlns:draw='urn:oasis:names:tc:opendocument:xmlns:drawing:1.0' xmlns:office='urn:oasis:names:tc:opendocument:xmlns:office:1.0' xmlns:text='urn:oasis:names:tc:opendocument:xmlns:text:1.0' xmlns:ooo='http://openoffice.org/2004/office' xmlns:number='urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0' xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:meta='urn:oasis:names:tc:opendocument:xmlns:meta:1.0' xmlns:table='urn:oasis:names:tc:opendocument:xmlns:table:1.0' xmlns:dr3d='urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0' xmlns:fo='urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0' xmlns:style='urn:oasis:names:tc:opendocument:xmlns:style:1.0' xmlns:xforms='http://www.w3.org/2002/xforms' xmlns:form='urn:oasis:names:tc:opendocument:xmlns:form:1.0' xmlns:script='urn:oasis:names:tc:opendocument:xmlns:script:1.0' xmlns:ooow='http://openoffice.org/2004/writer' xmlns:svg='urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0' xmlns:chart='urn:oasis:names:tc:opendocument:xmlns:chart:1.0' xmlns:dom='http://www.w3.org/2001/xml-events' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:oooc='http://openoffice.org/2004/calc' xmlns:math='http://www.w3.org/1998/Math/MathML' xmlns:tal='http://xml.zope.org/namespaces/tal'></office:document-content>" + content_type = 'application/vnd.oasis.opendocument.text' + ERP5Site_viewNothingAsOdt.pt_edit(text, content_type) + + def test_01_noExcNoFormatNoBatchMode(self): + portal_skins = self.getSkinsTool() + portal_skins.custom.REQUEST.RESPONSE.setHeader('content-type', 'text/html') + ERP5Site_viewNothingAsOdt = self.getPortal().ERP5Site_viewNothingAsOdt + ERP5Site_viewNothingAsOdt(batch_mode=0) + self.assertEqual('application/vnd.oasis.opendocument.text', portal_skins.custom.REQUEST.RESPONSE.getHeader('content-type').split(';')[0]) + self.assertEqual('inline;filename=ERP5Site_viewNothingAsOdt', portal_skins.custom.REQUEST.RESPONSE.getHeader('content-disposition')) + + def test_02_noExcNoFormatBatchMode(self): + portal_skins = self.getSkinsTool() + portal_skins.custom.REQUEST.RESPONSE.setHeader('content-type', 'text/html') + ERP5Site_viewNothingAsOdt = self.getPortal().ERP5Site_viewNothingAsOdt + ERP5Site_viewNothingAsOdt(batch_mode=1) + self.assertEqual('text/html', portal_skins.custom.REQUEST.RESPONSE.getHeader('content-type').split(';')[0]) + + def test_03_excPdfFormatNoBatchMode(self): + portal_skins = self.getSkinsTool() + portal_skins.custom.REQUEST.RESPONSE.setHeader('content-type', 'text/html') + ERP5Site_viewNothingAsOdt = self.getPortal().ERP5Site_viewNothingAsOdt + self.assertRaises(ConversionError, ERP5Site_viewNothingAsOdt, batch_mode=0, format='pdf') + self.assertEqual('text/html', portal_skins.custom.REQUEST.RESPONSE.getHeader('content-type').split(';')[0]) + + def test_04_excPdfFormatBatchMode(self): + portal_skins = self.getSkinsTool() + portal_skins.custom.REQUEST.RESPONSE.setHeader('content-type', 'text/html') + ERP5Site_viewNothingAsOdt = self.getPortal().ERP5Site_viewNothingAsOdt + self.assertRaises(ConversionError, ERP5Site_viewNothingAsOdt, batch_mode=1, format='pdf') + self.assertEqual('text/html', portal_skins.custom.REQUEST.RESPONSE.getHeader('content-type').split(';')[0]) + +if __name__ == '__main__': + framework() +else: + import unittest + def test_suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(TestOoodResponse)) + return suite +