1 | import os |
---|
2 | import time |
---|
3 | from tarfile import TarInfo, DIRTYPE |
---|
4 | from StringIO import StringIO |
---|
5 | |
---|
6 | # TarballExportContext don't write dirs in tarball and we need to fix this |
---|
7 | |
---|
8 | #security.declareProtected( ManagePortal, 'writeDataFile' ) |
---|
9 | def writeDataFile( self, filename, text, content_type, subdir=None ): |
---|
10 | |
---|
11 | """ See IExportContext. |
---|
12 | """ |
---|
13 | mod_time = time.time() |
---|
14 | if subdir is not None: |
---|
15 | elements = subdir.split('/') |
---|
16 | parents = filter(None, elements) |
---|
17 | while parents: |
---|
18 | dirname = os.path.join(*parents) |
---|
19 | try: |
---|
20 | self._archive.getmember(dirname+'/') |
---|
21 | except KeyError: |
---|
22 | info = TarInfo(dirname) |
---|
23 | info.size = 0 |
---|
24 | info.mode = 509 |
---|
25 | info.mtime = mod_time |
---|
26 | info.type = DIRTYPE |
---|
27 | self._archive.addfile(info, StringIO()) |
---|
28 | parents = parents[:-1] |
---|
29 | |
---|
30 | filename = '/'.join( ( subdir, filename ) ) |
---|
31 | |
---|
32 | stream = StringIO( text ) |
---|
33 | info = TarInfo( filename ) |
---|
34 | info.size = len( text ) |
---|
35 | info.mode = 436 |
---|
36 | info.mtime = mod_time |
---|
37 | self._archive.addfile( info, stream ) |
---|
38 | |
---|
39 | from Products.GenericSetup.context import TarballExportContext |
---|
40 | TarballExportContext.writeDataFile = writeDataFile |
---|
41 | |
---|
42 | from Products.GenericSetup.context import SKIPPED_FILES, SKIPPED_SUFFIXES |
---|
43 | |
---|
44 | def listDirectory(self, path, skip=SKIPPED_FILES, |
---|
45 | skip_suffixes=SKIPPED_SUFFIXES): |
---|
46 | |
---|
47 | """ See IImportContext. |
---|
48 | """ |
---|
49 | if path is None: # root is special case: no leading '/' |
---|
50 | path = '' |
---|
51 | elif path: |
---|
52 | if not self.isDirectory(path): |
---|
53 | return None |
---|
54 | |
---|
55 | if not path.endswith('/'): |
---|
56 | path = path + '/' |
---|
57 | |
---|
58 | pfx_len = len(path) |
---|
59 | |
---|
60 | names = [] |
---|
61 | for name in self._archive.getnames(): |
---|
62 | if name == path or not name.startswith(path): |
---|
63 | continue |
---|
64 | name = name[pfx_len:] |
---|
65 | if name.count('/') > 1: |
---|
66 | continue |
---|
67 | if '/' in name and not name.endswith('/'): |
---|
68 | continue |
---|
69 | if name in skip: |
---|
70 | continue |
---|
71 | if [s for s in skip_suffixes if name.endswith(s)]: |
---|
72 | continue |
---|
73 | # directories have trailing '/' character and we need to remove it |
---|
74 | name = name.rstrip('/') |
---|
75 | names.append(name) |
---|
76 | |
---|
77 | return names |
---|
78 | |
---|
79 | from Products.GenericSetup.context import TarballImportContext |
---|
80 | TarballImportContext.listDirectory = listDirectory |
---|