示例#1
0
 def convert(self, orig, data, cache=None, filename=None, context=None, **kwargs):
   data = str(orig)
   doc = OOOdCommandTransform(context, filename, data, self.inputs[0])
   builder = OOoBuilder(doc)
   content = builder.extract('content.xml')
   if cache is not None:
     cache.setData(content)
     return cache
   else:
     stream = OOoDocumentDataStream()
     stream.setData(content)
     return stream
示例#2
0
  def test_01_dynamic(self):
    """
    Test applying stylesheet dynamically, using a Python Script with
    a stylesheet file name parameter.
    """
    request = self.app.REQUEST
    addOOoTemplate = self.getPortal().manage_addProduct['ERP5OOo'].addOOoTemplate
    addOOoTemplate(id='Dynamic_viewAsOdt', title='')
    Dynamic_viewAsOdt = self.getPortal().Dynamic_viewAsOdt
    # The stylesheet file 'Test_getODTStyleSheet' is not exist in this site.
    # So, the 'Base_getODTStyleSheet', a python script creates dynamically
    # exsited stylesheet file name.
    self.assertFalse(self.getPortal().hasObject('Test_getODTStyleSheet'))
    self.assertTrue(self.getPortal().hasObject('Test_getODTStyleSheet_ja'))
    self.assertTrue(self.getPortal().hasObject('Test_getODTStyleSheet_en'))
    Dynamic_viewAsOdt.doSettings(request, title='', xml_file_id='content.xml',
                                 ooo_stylesheet='Test_getODTStyleSheet',
                                 script_name='Base_getODTStyleSheetByLanguage')
    Dynamic_viewAsOdt.pt_edit(self.content, content_type='application/vnd.oasis.opendocument.text')

    # 1. test a normal case, language: ja
    self.getPortal().Localizer.changeLanguage('ja')
    response = self.publish('/' + self.getPortal().Dynamic_viewAsOdt.absolute_url(1))
    self.assertEqual('application/vnd.oasis.opendocument.text',
                     response.getHeader('content-type').split(';')[0])
    self.assertEqual('attachment; filename="Dynamic_viewAsOdt.odt"',
                     response.getHeader('content-disposition'))
    self._validate(response.getBody())
    self.assertEqual(200, response.getStatus())

    ooo_builder = OOoBuilder(response.getBody())
    styles_xml_body = ooo_builder.extract('styles.xml')
    self.assertTrue(len(styles_xml_body) > 0)
    # 'Style sheet ja' text is in the odt document header,
    # and the header is in the 'styles.xml'.
    self.assertTrue(styles_xml_body.find('Style sheet ja') > 0)

    # 2. test a normal case, change the language to 'en',
    #    so that the stylesheet changes dynamically.
    self.getPortal().Localizer = DummyLocalizer()
    self.getPortal().Localizer.changeLanguage('en')
    response = self.publish('/' + self.getPortal().Dynamic_viewAsOdt.absolute_url(1))
    self._validate(response.getBody())
    ooo_builder = OOoBuilder(response.getBody())
    styles_xml_body = ooo_builder.extract('styles.xml')
    self.assertTrue(styles_xml_body.find('Style sheet en') > 0)

    # 3. test a fail case, reset a not existed stylesheet
    Dynamic_viewAsOdt.doSettings(request, title='', xml_file_id='content.xml',
                                 ooo_stylesheet='NotFound_getODTStyleSheet',
                                 script_name='Base_getODTStyleSheet')
    self.assertFalse(self.getPortal().hasObject('NotFound_getODTStyleSheet'))
    self.assertFalse(self.getPortal().hasObject('NotFound_getODTStyleSheet_ja'))
    self.assertFalse(self.getPortal().hasObject('NotFound_getODTStyleSheet_en'))
    self.getPortal().Localizer.changeLanguage('en')
    response = self.publish('/' + self.getPortal().Dynamic_viewAsOdt.absolute_url(1))
    # then, it is not a zip stream
    self.assertFalse(response.getBody().startswith('PK'))
    self.assertEqual(500, response.getStatus())
示例#3
0
  def test_02_static(self):
    """
    Test applying stylesheet statically, using a stylesheet File object.
    """
    request = self.app.REQUEST
    addOOoTemplate = self.getPortal().manage_addProduct['ERP5OOo'].addOOoTemplate
    addOOoTemplate(id='Static_viewAsOdt', title='')
    Static_viewAsOdt = self.getPortal().Static_viewAsOdt
    # Test_getODTStyleSheet_ja is statically exist.
    self.assertTrue(self.getPortal().hasObject('Test_getODTStyleSheet_ja'))
    Static_viewAsOdt.doSettings(request, title='', xml_file_id='content.xml',
                                ooo_stylesheet='Test_getODTStyleSheet_ja', script_name='')
    Static_viewAsOdt.pt_edit(self.content, content_type='application/vnd.oasis.opendocument.text')

    # 1. test a normal case
    response = self.publish('/' + self.getPortal().Static_viewAsOdt.absolute_url(1))
    self.assertEqual(200, response.getStatus())
    self.assertEqual('application/vnd.oasis.opendocument.text',
                     response.getHeader('content-type').split(';')[0])
    self.assertEqual('attachment; filename="Static_viewAsOdt.odt"',
                     response.getHeader('content-disposition'))
    self._validate(response.getBody())
    ooo_builder = OOoBuilder(response.getBody())
    styles_xml_body = ooo_builder.extract('styles.xml')
    self.assertTrue(len(styles_xml_body) > 0)
    self.assertTrue(styles_xml_body.find('Style sheet ja') > 0)

    # 2. test a normal case, change the style sheet
    self.assertTrue(self.getPortal().hasObject('Test_getODTStyleSheet_en'))
    Static_viewAsOdt.doSettings(request, title='', xml_file_id='content.xml',
                                ooo_stylesheet='Test_getODTStyleSheet_en', script_name='')
    response = self.publish('/' + self.getPortal().Static_viewAsOdt.absolute_url(1))
    self.assertEqual(200, response.getStatus())
    self._validate(response.getBody())
    ooo_builder = OOoBuilder(response.getBody())
    styles_xml_body = ooo_builder.extract('styles.xml')
    self.assertTrue(len(styles_xml_body) > 0)
    self.assertTrue(styles_xml_body.find('Style sheet en') > 0)

    # 3. test a fail case
    self.assertFalse(self.getPortal().hasObject('NotFound_getODTStyleSheet'))
    Static_viewAsOdt.doSettings(request, title='', xml_file_id='content.xml',
                                ooo_stylesheet='NotFound_getODTStyleSheet', script_name='')
    response = self.publish('/' + self.getPortal().Static_viewAsOdt.absolute_url(1))
    self.assertFalse(response.getBody().startswith('PK'))
    self.assertEqual(500, response.getStatus())
示例#4
0
  def render(self, extra_context={}):
    """Render a odf document, form as a content, template as a template.

    Keyword arguments:
    extra_context -- a dictionary, expected:
      'here' : where it call
      'printout_template' : the template object, tipically a OOoTemplate
      'container' : the object which has a form printout object
      'form' : the form as a content
    """
    here = extra_context['here']
    if here is None:
      raise ValueError('Can not create a ODF Document without a parent acquisition context')
    form = extra_context['form']
    if not extra_context.has_key('printout_template') or \
        extra_context['printout_template'] is None:
      raise ValueError('Can not create a ODF Document without a printout template')

    odf_template = extra_context['printout_template']

    # First, render the Template if it has a pt_render method
    ooo_document = None
    if hasattr(odf_template, 'pt_render'):
      ooo_document = odf_template.pt_render(here, extra_context=extra_context)
    else:
      # File object can be a template
      ooo_document = odf_template

    # Create a new builder instance
    ooo_builder = OOoBuilder(ooo_document)
    self.odf_existent_name_list = ooo_builder.getNameList()

    # content.xml
    self._replaceContentXml(ooo_builder, extra_context)
    # styles.xml
    self._replaceStylesXml(ooo_builder, extra_context)
    # meta.xml is not supported yet
    # ooo_builder = self._replaceMetaXml(ooo_builder=ooo_builder, extra_context=extra_context)

    # Update the META information
    ooo_builder.updateManifest()

    ooo = ooo_builder.render()
    return ooo
示例#5
0
    def includeImageList(self, data):
        """Include Images in ODF archive

    - data: zipped archive content
    """
        builder = OOoBuilder(data)
        content = builder.extract('content.xml')
        xml_doc = etree.XML(content)
        image_tag_list = xml_doc.xpath('//*[name() = "draw:image"]')
        SVG_NAMESPACE = 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0'
        XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink'
        ratio_px_cm = 2.54 / 100.
        # Flag to enable modification of OOoBuilder
        odt_content_modified = False
        for image_tag in image_tag_list:
            frame = image_tag.getparent()
            #Try to get image file from ZODB
            href_attribute_list = image_tag.xpath(
                './/@*[name() = "xlink:href"]')
            url = href_attribute_list[0]
            parse_result = urlparse(unquote(url))
            # urlparse return a 6-tuple: scheme, netloc, path, params, query, fragment
            netloc = parse_result[1]
            path = parse_result[2]
            if path and netloc in ('', None):
                # it makes sense to include only relative to current site images not remote ones which can be taken by OOo
                # OOo corrupt relative Links inside HTML content during odt conversion
                # <img src="REF.TO.IMAGE" ... /> become <draw:image xlink:href="../REF.TO.IMAGE" ... />
                # So remove "../" added by OOo
                path = CLEAN_RELATIVE_PATH.sub('', path)
                # in some cases like Web Page content "/../" can be contained in image URL which will break
                # restrictedTraverse calls, our best guess is to remove it
                path = path.replace('/../', '')
                # remove occurencies of '//' or '///' in path (happens with web pages) and leave
                # a traversable relative URL
                path = '/'.join(
                    [x for x in path.split('/') if x.strip() != ''])
                # retrieve http parameters and use them to convert image
                query_parameter_string = parse_result[4]
                image_parameter_dict = dict(parse_qsl(query_parameter_string))
                try:
                    image = self.context.restrictedTraverse(path)
                except (AttributeError, KeyError):
                    #Image not found, this image is probably not hosted by ZODB. Do nothing
                    image = None
                if image is not None:
                    odt_content_modified = True
                    content_type = image.getContentType()
                    format = image_parameter_dict.pop('format', None)
                    # convert API accepts only a certail range of arguments
                    for key, value in ensure_list(
                            image_parameter_dict.items()):
                        if key not in (
                                'format',
                                'display',
                                'quality',
                                'resolution',
                        ):
                            image_parameter_dict.pop(key)
                    if getattr(image, 'convert', None) is not None:
                        # The document support conversion so perform conversion
                        # according given parameters
                        mime, image_data = image.convert(
                            format, **image_parameter_dict)
                        # wrapp converted data into OFSImage in order to compute metadatas
                        # on converted result
                        image = OFSImage(image.getId(), image.getTitle(),
                                         image_data)

                    # image should be OFSImage
                    data = str(image.data)
                    width = image.width
                    height = image.height
                    if height:
                        frame.attrib.update({
                            '{%s}height' % SVG_NAMESPACE:
                            '%.3fcm' % (height * ratio_px_cm)
                        })
                    if width:
                        frame.attrib.update({
                            '{%s}width' % SVG_NAMESPACE:
                            '%.3fcm' % (width * ratio_px_cm)
                        })
                    if not format:
                        mimetype_list = self.context.getPortalObject(
                        ).mimetypes_registry.lookup(content_type)
                        # guess a format with help of mimetypes_registry
                        for mimetype_object in mimetype_list:
                            if mimetype_object.extensions:
                                format = mimetype_object.extensions[0]
                                break
                            elif mimetype_object.globs:
                                format = mimetype_object.globs[0].strip('*.')
                                break
                    new_path = builder.addImage(data, format=format)
                    image_tag.attrib.update(
                        {'{%s}href' % XLINK_NAMESPACE: new_path})
        if odt_content_modified:
            builder.replace(
                'content.xml',
                etree.tostring(xml_doc,
                               encoding='utf-8',
                               xml_declaration=True,
                               pretty_print=False))
        return builder.render()
示例#6
0
    def test_04_ProxyField(self):
        """
    Check it's possible to use an odg document to map proxyfields
    """
        portal = self.getPortal()
        foo_module = self.portal.foo_module
        if foo_module._getOb('test1', None) is None:
            foo_module.newContent(id='test1', portal_type='Foo')
        test1 = foo_module.test1
        test1.setTitle('Foo title!')
        self.tic()

        style_dict = {
            '{urn:oasis:names:tc:opendocument:xmlns:text:1.0}span': {
                '{urn:oasis:names:tc:opendocument:xmlns:text:1.0}style-name':
                'T2'
            },
            '{urn:oasis:names:tc:opendocument:xmlns:text:1.0}p': {}
        }

        # test target
        foo_printout = portal.foo_module.test1.Foo_viewProxyFieldAsODGPrintout
        original_file_content = self.getODFDocumentFromPrintout(foo_printout)
        self._validate(original_file_content)

        # extract content.xml from original odg document
        original_doc_builder = OOoBuilder(original_file_content)
        original_content_xml = original_doc_builder.extract("content.xml")
        # get style of the title in the orignal test document
        original_document_style_dict = self.getStyleDictFromFieldName(
            original_content_xml, 'my_title')

        # check the style is good before the odg generation
        self.assertEqual(original_document_style_dict, style_dict)

        request = self.app.REQUEST
        # 1. Normal case: "my_title" field to the "my_title" reference in the ODF document
        odf_document = foo_printout.index_html(request)
        self.assertTrue(odf_document is not None)
        builder = OOoBuilder(odf_document)
        content_xml = builder.extract("content.xml")
        final_document_style_dict = self.getStyleDictFromFieldName(
            content_xml, 'my_title')

        # check the style is keept after the odg generation
        self.assertEqual(final_document_style_dict, style_dict)

        self.assertTrue(content_xml.find("Foo title!") > 0)
        self.assertEqual(request.RESPONSE.getHeader('content-type'),
                         'application/vnd.oasis.opendocument.graphics')
        self.assertEqual(
            request.RESPONSE.getHeader('content-disposition'),
            'inline;filename="Foo_viewProxyFieldAsODGPrintout.odg"')
        self._validate(odf_document)

        # 2. Normal case: change the field value and check again the ODF document
        test1.setTitle("Changed Title!")
        #foo_form.my_title.set_value('default', "Changed Title!")
        odf_document = foo_printout.index_html(request)
        self.assertTrue(odf_document is not None)
        builder = OOoBuilder(odf_document)
        content_xml = builder.extract("content.xml")
        self.assertTrue(content_xml.find("Changed Title!") > 0)
        self._validate(odf_document)

        # 3. False case: change the field name
        test1.setTitle("you cannot find")
        # rename id 'my_title' to 'xxx_title', then does not match in the ODF document
        foo_form = portal.foo_module.test1.Foo_viewProxyField
        foo_form.manage_renameObject('my_title', 'xxx_title', REQUEST=request)
        odf_document = foo_printout.index_html(request)
        self.assertTrue(odf_document is not None)
        builder = OOoBuilder(odf_document)
        content_xml = builder.extract("content.xml")
        self.assertFalse(content_xml.find("you cannot find") > 0)
        self._validate(odf_document)
        # put back
        foo_form.manage_renameObject('xxx_title', 'my_title', REQUEST=request)

        ## 4. False case: does not set a ODF template
        self.assertTrue(foo_printout.template == 'Foo_getODGStyleSheet')
        tmp_template = foo_printout.template
        foo_printout.template = None
        self.assertRaises(ValueError, foo_printout.index_html, request)
        # put back
        foo_printout.template = tmp_template

        # 5. Normal case: just call a FormPrintout object
        request.RESPONSE.setHeader('Content-Type', 'text/html')
        test1.setTitle("call!")
        odf_document = foo_printout(request)  # call
        self.assertTrue(odf_document is not None)
        builder = OOoBuilder(odf_document)
        content_xml = builder.extract("content.xml")
        self.assertTrue(content_xml.find("call!") > 0)
        self.assertEqual(request.RESPONSE.getHeader('content-type'),
                         'application/vnd.oasis.opendocument.graphics')
        self._validate(odf_document)

        # 5. Normal case: utf-8 string
        test1.setTitle("Français")
        odf_document = foo_printout(request)
        self.assertTrue(odf_document is not None)
        builder = OOoBuilder(odf_document)
        content_xml = builder.extract("content.xml")
        self.assertTrue(content_xml.find("Français") > 0)
        self._validate(odf_document)

        # 6. Normal case: unicode string
        test1.setTitle(u'Français test2')
        odf_document = foo_printout(request)
        self.assertTrue(odf_document is not None)
        builder = OOoBuilder(odf_document)
        content_xml = builder.extract("content.xml")
        self.assertTrue(content_xml.find("Français test2") > 0)
        self._validate(odf_document)
示例#7
0
    def test_03_Image(self):
        """
    Mapping an ImageField to odg document.
    Check it's possible to use an odg document to map an image with a
    form.ImageField
    """
        # create a new person
        request = self.portal.REQUEST
        person_module = self.portal.getDefaultModule('Person')
        if person_module._getOb('person1', None) is None:
            person_module.newContent(id='person1', portal_type='Person')
        person1 = person_module.person1

        # add an image to this person
        current_dir = os.path.dirname(__file__)
        parent_dir = os.path.dirname(current_dir)
        image_path = os.path.join(parent_dir, 'www', 'form_printout_icon.png')
        file_data = FileUpload(image_path)
        image = person1.newContent(portal_type='Embedded File')
        image.edit(file=file_data)

        foo_printout = image.Foo_viewAsODGPrintout
        foo_form = image.Foo_view
        # add an image_field to Foo_view if there is not
        if foo_form._getOb("image_view", None) is None:
            foo_form.manage_addField('image_view', 'logo', 'ImageField')
        image_view_field = foo_form.image_view
        # set the image on the field
        image_view_field.values['default'] = image.absolute_url_path()

        # 01 - Normal image mapping
        odf_document = foo_printout(request)
        self.assertTrue(odf_document is not None)
        self._validate(odf_document)
        builder = OOoBuilder(odf_document)
        content_xml = builder.extract("content.xml")
        content = etree.XML(content_xml)
        image_element_list = content.xpath('//draw:image',
                                           namespaces=content.nsmap)
        self.assertTrue(len(image_element_list) > 0)

        # check the image is in the odg file
        try:
            image_path = image_element_list[0].get(
                '{http://www.w3.org/1999/xlink}href')
            image_data = builder.extract(image_path)
        except KeyError:
            self.fail('image %r not found in odg document' % image_path)
        self.assertEqual(image.getData(), image_data,
                         '%s != %s' % (len(image.getData()), len(image_data)))
        image_frame_xpath = '//draw:frame[@draw:name="image_view"]'
        image_frame_list = content.xpath(image_frame_xpath,
                                         namespaces=content.nsmap)
        self.assertTrue(len(image_frame_list) > 0)
        image_frame = image_frame_list[0]
        # Check the image size.
        # as the test image (form_printout_icon.png) is a square, proportions
        # should be keept, so heigh and width should be same and equal to the
        # height of the original image in the original odf test document.
        self.assertEqual(
            image_frame.attrib['{%s}height' % content.nsmap['svg']], '1.206cm')
        self.assertEqual(
            image_frame.attrib['{%s}width' % content.nsmap['svg']], '1.206cm')

        # 02: No image defined
        image_view_field.values['default'] = ''
        odf_document = foo_printout(request)
        self.assertTrue(odf_document is not None)
        builder = OOoBuilder(odf_document)
        content_xml = builder.extract("content.xml")
        # confirming the image was removed
        content = etree.XML(content_xml)
        image_element_list = content.xpath('//draw:image',
                                           namespaces=content.nsmap)
        self.assertFalse(len(image_element_list) > 0)
        self._validate(odf_document)
示例#8
0
    def test_02_TextFieldWithMultiLines(self):
        """
    mapping a field containing many lines ('\n') to a textbox
    """
        portal = self.getPortal()

        # add a description field in the form
        foo_form = self.portal.foo_module.test1.Foo_view
        if foo_form._getOb("my_description", None) is None:
            foo_form.manage_addField('my_description', 'Description',
                                     'TextAreaField')
        foo_module = self.portal.foo_module
        if foo_module._getOb('test1', None) is None:
            foo_module.newContent(id='test1', portal_type='Foo')
        test1 = foo_module.test1
        test1.setDescription('A text a bit more longer\n\nWith a newline !')
        self.tic()

        style_dict = {
            '{urn:oasis:names:tc:opendocument:xmlns:text:1.0}line-break': {},
            '{urn:oasis:names:tc:opendocument:xmlns:text:1.0}p': {},
            '{urn:oasis:names:tc:opendocument:xmlns:text:1.0}span': {
                '{urn:oasis:names:tc:opendocument:xmlns:text:1.0}style-name':
                'T4'
            }
        }

        # test target
        foo_printout = portal.foo_module.test1.Foo_viewAsODGPrintout
        original_file_content = self.getODFDocumentFromPrintout(foo_printout)
        self._validate(original_file_content)

        # extract content.xml from original odg document
        original_doc_builder = OOoBuilder(original_file_content)
        original_content_xml = original_doc_builder.extract("content.xml")
        # get style of the title in the orignal test document
        original_document_style_dict = self.getStyleDictFromFieldName(
            original_content_xml, 'my_description')

        # check the style is good before the odg generation
        self.assertEqual(original_document_style_dict, style_dict)

        request = self.app.REQUEST
        # 1. Normal case: "my_title" field to the "my_title" reference in the ODF document
        odf_document = foo_printout.index_html(request)
        self.assertTrue(odf_document is not None)
        # validate the generated document
        self._validate(odf_document)
        builder = OOoBuilder(odf_document)
        content_xml = builder.extract("content.xml")
        content = etree.XML(content_xml)
        final_document_style_dict = self.getStyleDictFromFieldName(
            content_xml, 'my_description')

        # check the style is keept after the odg generation
        self.assertEqual(final_document_style_dict, style_dict)

        # check the two lines are prensent in the generated document
        self.assertTrue(content_xml.find('A text a bit more longer') > 0)
        self.assertTrue(content_xml.find('With a newline !') > 0)

        # check there is two line-break in the element my_description
        text_xpath = '//draw:frame[@draw:name="my_description"]//text:line-break'
        node_list = content.xpath(text_xpath, namespaces=content.nsmap)
        self.assertEqual(len(node_list), 2)