~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/export/zip_exporter.py

Merge bzr.dev, update to use new hooks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
 
"""Export a Tree to a non-versioned directory.
 
17
"""Export a Tree to a zip file.
18
18
"""
19
19
 
20
20
import os
21
21
import stat
 
22
import sys
22
23
import time
23
24
import zipfile
24
25
 
26
27
    osutils,
27
28
    )
28
29
from bzrlib.export import _export_iter_entries
29
 
from bzrlib.filters import (
30
 
    ContentFilterContext,
31
 
    filtered_output_bytes,
32
 
    )
33
30
from bzrlib.trace import mutter
34
31
 
35
32
 
36
 
# Windows expects this bit to be set in the 'external_attr' section
37
 
# Or it won't consider the entry a directory
 
33
# Windows expects this bit to be set in the 'external_attr' section,
 
34
# or it won't consider the entry a directory.
38
35
ZIP_DIRECTORY_BIT = (1 << 4)
39
36
FILE_PERMISSIONS = (0644 << 16)
 
37
DIR_PERMISSIONS = (0755 << 16)
40
38
 
41
39
_FILE_ATTR = stat.S_IFREG | FILE_PERMISSIONS
42
 
_DIR_ATTR = stat.S_IFDIR | ZIP_DIRECTORY_BIT
43
 
 
44
 
 
45
 
def zip_exporter(tree, dest, root, subdir, filtered=False,
46
 
                 per_file_timestamps=False):
 
40
_DIR_ATTR = stat.S_IFDIR | ZIP_DIRECTORY_BIT | DIR_PERMISSIONS
 
41
 
 
42
 
 
43
def zip_exporter_generator(tree, dest, root, subdir=None,
 
44
    force_mtime=None, fileobj=None):
47
45
    """ Export this tree to a new zip file.
48
46
 
49
47
    `dest` will be created holding the contents of this tree; if it
50
48
    already exists, it will be overwritten".
51
49
    """
52
 
    mutter('export version %r', tree)
53
 
 
54
 
    now = time.localtime()[:6]
55
50
 
56
51
    compression = zipfile.ZIP_DEFLATED
 
52
    if fileobj is not None:
 
53
        dest = fileobj
 
54
    elif dest == "-":
 
55
        dest = sys.stdout
57
56
    zipf = zipfile.ZipFile(dest, "w", compression)
58
 
 
59
57
    try:
60
 
        for dp, ie in _export_iter_entries(tree, subdir):
 
58
        for dp, tp, ie in _export_iter_entries(tree, subdir):
61
59
            file_id = ie.file_id
62
60
            mutter("  export {%s} kind %s to %s", file_id, ie.kind, dest)
63
61
 
64
62
            # zipfile.ZipFile switches all paths to forward
65
63
            # slashes anyway, so just stick with that.
66
 
            if per_file_timestamps:
67
 
                mtime = tree.get_file_mtime(ie.file_id, dp)
 
64
            if force_mtime is not None:
 
65
                mtime = force_mtime
68
66
            else:
69
 
                mtime = now
 
67
                mtime = tree.get_file_mtime(ie.file_id, tp)
 
68
            date_time = time.localtime(mtime)[:6]
70
69
            filename = osutils.pathjoin(root, dp).encode('utf8')
71
70
            if ie.kind == "file":
72
71
                zinfo = zipfile.ZipInfo(
73
72
                            filename=filename,
74
 
                            date_time=mtime)
 
73
                            date_time=date_time)
75
74
                zinfo.compress_type = compression
76
75
                zinfo.external_attr = _FILE_ATTR
77
 
                if filtered:
78
 
                    chunks = tree.get_file_lines(file_id)
79
 
                    filters = tree._content_filter_stack(dp)
80
 
                    context = ContentFilterContext(dp, tree, ie)
81
 
                    contents = filtered_output_bytes(chunks, filters, context)
82
 
                    content = ''.join(contents)
83
 
                else:
84
 
                    content = tree.get_file_text(file_id)
 
76
                content = tree.get_file_text(file_id, tp)
85
77
                zipf.writestr(zinfo, content)
86
78
            elif ie.kind == "directory":
87
79
                # Directories must contain a trailing slash, to indicate
89
81
                # not just empty files.
90
82
                zinfo = zipfile.ZipInfo(
91
83
                            filename=filename + '/',
92
 
                            date_time=mtime)
 
84
                            date_time=date_time)
93
85
                zinfo.compress_type = compression
94
86
                zinfo.external_attr = _DIR_ATTR
95
 
                zipf.writestr(zinfo,'')
 
87
                zipf.writestr(zinfo, '')
96
88
            elif ie.kind == "symlink":
97
89
                zinfo = zipfile.ZipInfo(
98
90
                            filename=(filename + '.lnk'),
99
 
                            date_time=mtime)
 
91
                            date_time=date_time)
100
92
                zinfo.compress_type = compression
101
93
                zinfo.external_attr = _FILE_ATTR
102
 
                zipf.writestr(zinfo, ie.symlink_target)
 
94
                zipf.writestr(zinfo, tree.get_symlink_target(file_id, tp))
 
95
            yield
103
96
 
104
97
        zipf.close()
105
98