@glacier_connect
    @sdb_connect
    @log_class_call("Download an archive.",
                    "Download archive done.")
    def download(self, vault_name, archive_id, part_size,
                 out_file_name=None, overwrite=False):
        """
        Download a file from Glacier, and store it in out_file.
        If no out_file is given, the file will be dumped on stdout.
        """

        # Sanity checking on the input.
        self._check_vault_name(vault_name)
        self._check_id(archive_id, 'ArchiveId')

        # Check whether the requested file is available from Amazon Glacier.
        job_list = self.list_jobs(vault_name)
        job_id = None
        for job in job_list:
            if job['ArchiveId'] == archive_id:
                download_job = job
                if not job['Completed']:
                    raise CommunicationException(
                        "Archive retrieval request not completed yet. Please try again later.",
                        code='NotReady')
                self.logger.debug('Archive retrieval completed; archive is available for download now.')
                break

        else:
            raise InputException(
                "Requested archive not available. Please make sure \
your archive ID is correct, and start a retrieval job using \
'getarchive' if necessary.",
                code='IdError')

        # Check whether we can access the file the archive has to be written to.
        out_file = None
        if out_file_name:
            if os.path.isfile(out_file_name) and not overwrite:
                raise InputException(
                    "File exists already, aborting. Use the overwrite flag to overwrite existing file.",
                    code="FileError")
            try:
                out_file = open(out_file_name, 'w')
            except IOError as e:
                raise InputException(
                    "Cannot access the ouput file.",
                    cause=e,
                    code='FileError')

        # Sanity checking done; start downloading the file, part by part.
        total_size = download_job['ArchiveSizeInBytes']
        part_size_in_bytes = self._check_part_size(part_size, total_size) * 1024 * 1024
        start_bytes = downloaded_size = 0
        hash_list = []
        start_time = current_time = previous_time = time.time()

        # Log our pending action.
        if out_file:
            self.logger.debug('Starting download of archive to file %s.'% out_file_name)
        else:
            self.logger.debug('Starting download of archive to stdout.')

        # Download the data, one part at a time.
        while downloaded_size < total_size:

            # Read a part of data.
            from_bytes = downloaded_size
            to_bytes = min(downloaded_size + part_size_in_bytes, total_size)
            try:
                response = self.glacierconn.get_job_output(vault_name,
                                                            download_job['JobId'],
                                                            byte_range=(from_bytes, to_bytes-1))
                data = response.read()
            except boto.glacier.exceptions.UnexpectedHTTPResponseError as e:
                raise ResponseException(
                    'Failed to download archive %s.'% archive_id,
                    cause=self._decode_error_message(e.body),
                    code=e.code)

            hash_list.append(glaciercorecalls.chunk_hashes(data)[0])
            downloaded_size = to_bytes
            if out_file:
                try:
                    out_file.write(response.read())
                except IOError as e:
                    raise InputException(
                        "Cannot write data to the specified file.",
                        cause=e,
                        code='FileError')
            else:
                sys.stdout.write(response.read())
                sys.stdout.flush()

            # Calculate progress statistics.
            current_time = time.time()
            overall_rate = int((downloaded_size-start_bytes)/(current_time - start_time))
            current_rate = int(part_size_in_bytes/(current_time - previous_time))

            # Estimate finish time, based on overall transfer rate.
            time_left = (total_size - downloaded_size)/overall_rate
            eta_seconds = current_time + time_left
            if datetime.fromtimestamp(eta_seconds).day is not\
                    datetime.now().day:
                eta_template = "%a, %d %b, %H:%M:%S"
            else:
                eta_template = "%H:%M:%S"

            eta = time.strftime(eta_template, time.localtime(eta_seconds))
            msg = 'Read %s of %s (%s%%). Rate %s/s, average %s/s, ETA %s.' \
                  % (self._size_fmt(downloaded_size),
                     self._size_fmt(total_size),
                     self._bold(str(int(100 * downloaded_size/total_size))),
                     self._size_fmt(current_rate, 2),
                     self._size_fmt(overall_rate, 2),
                     eta)
            self._progress(msg)
            previous_time = current_time
            self.logger.debug(msg)

        if out_file:
            out_file.close()
        if glaciercorecalls.bytes_to_hex(glaciercorecalls.tree_hash(hash_list)) != download_job['SHA256TreeHash']:
            raise CommunicationException(
                "Downloaded data hash mismatch",
                code="DownloadError",
                cause=None)

        self.logger.debug('Download of archive finished successfully.')
        current_time = time.time()
        overall_rate = int(downloaded_size/(current_time - start_time))
        msg = 'Wrote %s. Rate %s/s.\n' % (self._size_fmt(downloaded_size),
                                            self._size_fmt(overall_rate, 2))
        self._progress(msg)
        self.logger.info(msg)
dataset/ETHPy150Open uskudnik/amazon-glacier-cmd-interface/glacier/GlacierWrapper.py/GlacierWrapper.download/original