1# Copyright 2015 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.
4
5import os
6
7from dependency_manager import exceptions
8from dependency_manager import dependency_manager_util
9
10
11class ArchiveInfo(object):
12
13  def __init__(self, archive_file, unzip_path, path_within_archive):
14    """ Container for the information needed to unzip a downloaded archive.
15
16    Args:
17        archive_path: Path to the archive file.
18        unzip_path: Path to unzip the archive into. Assumes that this path
19            is unique for the archive.
20        path_within_archive: Specify if and how to handle zip archives
21            downloaded from cloud_storage. Expected values:
22                None: Do not unzip the file downloaded from cloud_storage.
23                '.': Unzip the file downloaded from cloud_storage. The
24                    unzipped file/folder is the expected dependency.
25                file_path: Unzip the file downloaded from cloud_storage.
26                    |file_path| is the path to the expected dependency,
27                    relative to the unzipped archive path.
28    """
29    self._archive_file = archive_file
30    self._unzip_path = unzip_path
31    self._path_within_archive = path_within_archive
32    self._dependency_path = os.path.join(
33        self._unzip_path, self._path_within_archive)
34    if not self._has_minimum_data:
35      raise ValueError(
36          'Not enough information specified to initialize an archive info.'
37          ' %s' % self)
38
39  def GetUnzippedPath(self):
40    if self.ShouldUnzipArchive():
41      # TODO(aiolos): Replace UnzipFile with zipfile.extractall once python
42      # version 2.7.4 or later can safely be assumed.
43      dependency_manager_util.UnzipArchive(
44          self._archive_file, self._unzip_path)
45      if self.ShouldUnzipArchive():
46        raise exceptions.ArchiveError(
47            "Expected path '%s' was not extracted from archive '%s'." %
48            (self._dependency_path, self._archive_file))
49    return self._dependency_path
50
51  def ShouldUnzipArchive(self):
52    if not self._has_minimum_data:
53      raise exceptions.ArchiveError(
54          'Missing needed info to unzip archive. Known data: %s',
55          self.data_string)
56    return not os.path.exists(self._dependency_path)
57
58  @property
59  def _has_minimum_data(self):
60    return all([self._archive_file, self._unzip_path,
61                self._dependency_path])
62
63  def __repr__(self):
64    return (
65        'ArchiveInfo(archive_file=%s, unzip_path=%s, path_within_archive=%s, '
66        'dependency_path =%s)' % (
67            self._archive_file, self._unzip_path, self._path_within_archive,
68            self._dependency_path))
69
70