WebKitTools/ChangeLog

 12010-12-12 James Kozianski <koz@chromium.org>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 Add remote zip file handling to webkitpy.
 6 https://bugs.webkit.org/show_bug.cgi?id=50901
 7
 8 * Scripts/webkitpy/common/diraszip.py: Added.
 9 * Scripts/webkitpy/common/net/remotezip.py: Added.
 10
1112010-12-12 Alejandro G. Castro <alex@igalia.com>
212
313 Reviewed by Eric Seidel.

WebKitTools/Scripts/webkitpy/common/diraszip.py

 1#!/usr/bin/env python
 2# Copyright (C) 2010 Google Inc. All rights reserved.
 3#
 4# Redistribution and use in source and binary forms, with or without
 5# modification, are permitted provided that the following conditions
 6# are met:
 7#
 8# 1. Redistributions of source code must retain the above copyright
 9# notice, this list of conditions and the following disclaimer.
 10# 2. Redistributions in binary form must reproduce the above copyright
 11# notice, this list of conditions and the following disclaimer in the
 12# documentation and/or other materials provided with the distribution.
 13#
 14# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 15# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 16# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 17# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 18# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 19# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 20# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 21# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 23# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24
 25from __future__ import with_statement
 26
 27import os
 28import shutil
 29
 30from webkitpy.common.net.remotezip import ZipFileHandle
 31from webkitpy.common.system.filesystem import FileSystem
 32import webkitpy.common.system.ospath as ospath
 33
 34
 35class DirAsZip(object):
 36 """Provides a zipfile-like interface to a local directory"""
 37 def __init__(self, path, filesystem=None):
 38 self._path = path
 39 self._filesystem = filesystem if filesystem != None else FileSystem()
 40 if not self._path.endswith(os.path.sep):
 41 self._path += os.path.sep
 42
 43 def _full_path(self, filename):
 44 assert self._is_under(self._path, filename)
 45 return os.path.join(self._path, filename)
 46
 47 def _drop_directory_prefix(self, path):
 48 return path[len(self._path):]
 49
 50 def _files_in_directory(self):
 51 """Returns a list of all the files in the directory, including the path
 52 to the directory"""
 53 return [os.path.join(path, filename)
 54 for (path, _, filenames) in os.walk(self._path)
 55 for filename in filenames]
 56
 57 def _is_under(self, dir, filename):
 58 return ospath.relpath(os.path.join(dir, filename), dir) is not None
 59
 60 def open(self, filename):
 61 return ZipFileHandle(self, filename)
 62
 63 def namelist(self):
 64 return map(self._drop_directory_prefix, self._files_in_directory())
 65
 66 def read(self, filename):
 67 return self._filesystem.read_text_file(self._full_path(filename))
 68
 69 def extract(self, filename, path):
 70 """Extracts a file from this 'zip archive' to the specified directory."""
 71 src = self._full_path(filename)
 72 dest = os.path.join(path, filename)
 73 # As filename may have slashes in it, we must ensure that the same
 74 # directory heirarchy exists at the output path.
 75 self._filesystem.maybe_make_directory(os.path.split(dest)[0])
 76 self._filesystem.copyfile(src, dest)
 77
 78 def delete(self, filename):
 79 filename = self._full_path(filename)
 80 self._filesystem.remove(filename)

WebKitTools/Scripts/webkitpy/common/net/remotezip.py

 1#!/usr/bin/env python
 2# Copyright (C) 2010 Google Inc. All rights reserved.
 3#
 4# Redistribution and use in source and binary forms, with or without
 5# modification, are permitted provided that the following conditions
 6# are met:
 7#
 8# 1. Redistributions of source code must retain the above copyright
 9# notice, this list of conditions and the following disclaimer.
 10# 2. Redistributions in binary form must reproduce the above copyright
 11# notice, this list of conditions and the following disclaimer in the
 12# documentation and/or other materials provided with the distribution.
 13#
 14# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 15# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 16# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 17# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 18# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 19# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 20# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 21# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 23# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24
 25from webkitpy.common.net.networktransaction import NetworkTransaction
 26from webkitpy.common.system.filesystem import FileSystem
 27import os
 28import urllib
 29import zipfile
 30
 31
 32class RemoteZip(object):
 33 """A zip file that resides at a URL (local or remote)"""
 34 def __init__(self, zip_url, filesystem=None):
 35 self._zip_url = zip_url
 36 self._zip_file = None
 37 self._filesystem = filesystem if filesystem != None else FileSystem()
 38
 39 def _load(self):
 40 if self._zip_file is None:
 41 temp_file = NetworkTransaction().run(lambda: urllib.urlretrieve(self._zip_url)[0])
 42 self._zip_file = zipfile.ZipFile(temp_file)
 43
 44 def open(self, filename):
 45 return ZipFileHandle(self, filename)
 46
 47 def namelist(self):
 48 self._load()
 49 return self._zip_file.namelist()
 50
 51 def read(self, filename):
 52 self._load()
 53 return self._zip_file.read(filename)
 54
 55 def extract(self, filename, path):
 56 self._load()
 57 return self._zip_file.extract(filename, path)
 58
 59 def delete(self, filename):
 60 raise Exception("Can't delete from a RemoteZip.")
 61
 62
 63class ZipFileHandle:
 64 """Points to a file that resides in a RemoteZip"""
 65 def __init__(self, zip_file, filename):
 66 self._filename = filename
 67 self._zip_file = zip_file
 68 self._contents = None
 69
 70 def __str__(self):
 71 return "%s:%s" % (self._zip_file, self._filename)
 72
 73 def contents(self):
 74 if self._contents is None:
 75 self._contents = self._zip_file.read(self._filename)
 76 return self._contents
 77
 78 def save_to(self, path, filename=None):
 79 if filename is None:
 80 self._zip_file.extract(self._filename, path)
 81 else:
 82 with self._filesystem.mkdtemp() as temp_dir:
 83 self._zip_file.extract(self._filename, temp_dir)
 84
 85 src = os.path.join(temp_dir, self._filename)
 86 dest = os.path.join(path, filename)
 87 self._filesystem.copyfile(src, dest)
 88
 89 def delete(self):
 90 self._zip_file.delete(self._filename)
 91
 92 def name(self):
 93 return self._filename
 94
 95 def splitext(self):
 96 return os.path.splitext(self.name())