Пример #1
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 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()
Пример #2
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()
Пример #3
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.0
        # 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
            path = parse_result[2]
            if path:
                # 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("/../", "")
                # 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)
                    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()