Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / common / extensions / docs / server2 / directory_zipper.py
blob6d162258fc70b96ee89b025d78d3fa4c0fa7a993
1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 from io import BytesIO
6 import posixpath
7 from zipfile import ZipFile
9 from compiled_file_system import SingleFile
12 class DirectoryZipper(object):
13 '''Creates zip files of whole directories.
14 '''
16 def __init__(self, compiled_fs_factory, file_system):
17 self._file_system = file_system
18 self._zip_cache = compiled_fs_factory.Create(file_system,
19 self._MakeZipFile,
20 DirectoryZipper)
22 # NOTE: It's ok to specify SingleFile here even though this method reads
23 # multiple files. All files are underneath |base_dir|. If any file changes its
24 # stat will change, so the stat of |base_dir| will also change.
25 @SingleFile
26 def _MakeZipFile(self, base_dir, files):
27 base_dir = base_dir.strip('/')
28 zip_bytes = BytesIO()
29 with ZipFile(zip_bytes, mode='w') as zip_file:
30 futures_with_name = [
31 (file_name,
32 self._file_system.ReadSingle(posixpath.join(base_dir, file_name)))
33 for file_name in files]
34 for file_name, future in futures_with_name:
35 file_contents = future.Get()
36 if isinstance(file_contents, unicode):
37 # Data is sometimes already cached as unicode.
38 file_contents = file_contents.encode('utf8')
39 # We want e.g. basic.zip to expand to basic/manifest.json etc, not
40 # chrome/common/extensions/.../basic/manifest.json, so only use the
41 # end of the path component when writing into the zip file.
42 dir_name = posixpath.basename(base_dir)
43 zip_file.writestr(posixpath.join(dir_name, file_name), file_contents)
44 return zip_bytes.getvalue()
46 def Zip(self, path):
47 '''Creates a new zip file from the recursive contents of |path| as returned
48 by |_zip_cache|.
50 Paths within the zip file will be relative to and include the last
51 component of |path|, such that when zipping foo/bar containing baf.txt and
52 qux.txt will return a zip file which unzips to bar/baz.txt and bar/qux.txt.
53 '''
54 return self._zip_cache.GetFromFileListing(path)