ftw.zipexport

Zip export for Plone

Overview

ftw.zipexport provides a generic solution to export data from plone in a zip archive.

A user can export data with the "Export as Zip" action in document listings.

Install

Compatibility

For zipping files with a total size of over 4Gb python 2.7.4 is required.

Step-by-Step

  • Add ftw.zipexport to your buildout configuration
[instance]
eggs =
    ftw.zipexport
  • Run buildout
  • Install ftw.zipexport in portal_setup

Implementation

In a first step we have to collect all data to zip. Use the IZipRepresentation interface for this task.

The get_files function returns a list of tuples. The tuples consist of two values. First a relative path under which the file should show up in the zip. Second the data as eather a file or a stream.

System Message: WARNING/2 (<string>, line 43)

Cannot analyze code. Pygments package not found.

.. code:: python

        class IZipRepresentation(Interface):

            def get_files(path_prefix='', recursive=True, toplevel=True):

By default we support basic data-types like folder and files. More complex data-types require an own adapter for IZipRepresentation.

Feel free to extend one of the predefined adapters: Predefined representations

The data generated by our IZipRepresentation then gets delivered to the ZipGeneration helper class.

System Message: WARNING/2 (<string>, line 57)

Cannot analyze code. Pygments package not found.

.. code:: python

        class ZipGenerator(object):
                def add_file(file_path, file_pointer):
                        Zipps the file and adds it to the archive.
                        If large or many files are selected this function might take some time to execute.

                def generate():
                        returns a temp file holding the generated zip

Here is the sample code of the described steps:

System Message: WARNING/2 (<string>, line 69)

Cannot analyze code. Pygments package not found.

.. code:: python

        from zope.component import getMultiAdapter
        from ftw.zipexport.generation import ZipGenerator
        from ftw.zipexport.interfaces import IZipRepresentation

        ziprepresentation = getMultiAdapter((self.folder, self.request), interface=IZipRepresentation)
        with ZipGenerator() as zipgenerator:
                for file_path, file_pointer in ziprepresentation.get_files():
                        zipgenerator.add_file(file_path, file_pointer)
                generated_zip_pointer = zipgenerator.generate()


The download is handled in a standard BrowserView which plainly reads from the temp file. For details check out the code: zipexportview.py.

Current supported data-types

  • IFolderish
  • IFileContent
  • IDexterityItem with IPrimaryFieldInfo

Path Normalization

Paths are automatically using Plone's IFileNameNormalizer. If you want to use a custom normalization, you can pass it to the ZipGenerator:

System Message: WARNING/2 (<string>, line 99)

Cannot analyze code. Pygments package not found.

.. code:: python

    from ftw.zipexport.generation import ZipGenerator
    from Products.CMFPlone.utils import safe_unicode
    import re

    def normalize_path(path):
        path = safe_unicode(path).replace(u'\\', u'/')
        return re.sub(ur'[^\w\-.\/]', u'', path)

    with ZipGenerator(path_normalizer=normalize_path) as zipgenerator:
        ...

Pass None to disable normalization completely:

System Message: WARNING/2 (<string>, line 114)

Cannot analyze code. Pygments package not found.

.. code:: python

    from ftw.zipexport.generation import ZipGenerator

    with ZipGenerator(path_normalizer=None) as zipgenerator:
        ...




Nice to have

  • Multithreading

Changelog

1.6.3 (2018-04-17)

  • Allow IFolderish to specify a custom title via a property. [Rotonen]
  • Drop support for Plone 4.2. [mbaechtold]

1.6.2 (2017-11-29)

  • Remove wrong allowed check on context for zip selected view. [phgross]

1.6.1 (2017-09-06)

  • Fix encoding bug when zip filename contains umlauts. [phgross]

1.6.0 (2017-08-17)

  • Include empty folders by default and add possibility to deactivate this behavior. [elioschmutz]

1.5.0 (2016-12-15)

  • Drop official support for Python 2.6 [jone]

1.4.0 (2016-12-12)

  • Add events for the ZIP exports [Rotonen]

1.3.1 (2016-02-09)

  • Do not fail when exporting AT folders with titles containing umlauts [fRiSi]
  • Fall back to object.id in case filename is not set. [fRiSi]

1.3.0 (2015-05-05)

  • Normalize all paths added to the ZIP file. [jone]
  • Handle path encoding in ZIP. [jone]
  • Added check if fs has enough space to create the zip file. [lknoepfel]

1.2.2 (2015-03-25)

  • Fixed a bug in the file export which occurred if the file to be exported did not have a blob but an OFS file. [mbaechtold]

1.2.1 (2014-06-05)

  • Fixed metadata version in default profile. [lknoepfel]

1.2.0 (2014-05-26)

  • Added option to select multiple interfaces on which the export is available. [lknoepfel]
  • Added error message when the content is too big to zip. This happens when the ZIP64 isn't available and the content is bigger than 4GB. [lknoepfel]
  • Corrected error message when no zip-exportable content is selected. [lknoepfel]
  • Deny zipexport on unallowed content. [lknoepfel]
  • Include default AT image files. [jone]
  • Added French translation by I. Anthenien. [lknoepfel]

1.1.1 (2013-11-21)

  • Added handling for files with same filename. [lknoepfel]
  • Added a separate profile to install an additional zip-export document action. [deif]

1.1.0 (2013-10-14)

  • Added export limitation. [lknoepfel]
  • Fix encoding problem with nested folders containing umlauts in the title. [jone]

1.0.0 (2013-09-13)

  • Initial Development

Author name: 4teamwork AG

Author email: mailto:info@4teamwork.ch

Maintainer name: Lukas Knoepfel