Get the next chunk of the download. Args: num_retries: Integer, number of times to retry with randomized exponential backoff. If all retries fail, the raised HttpError represents the last request. If zero (default), we attempt the re
(self, num_retries=0)
| 714 | |
| 715 | @util.positional(1) |
| 716 | def next_chunk(self, num_retries=0): |
| 717 | """Get the next chunk of the download. |
| 718 | |
| 719 | Args: |
| 720 | num_retries: Integer, number of times to retry with randomized |
| 721 | exponential backoff. If all retries fail, the raised HttpError |
| 722 | represents the last request. If zero (default), we attempt the |
| 723 | request only once. |
| 724 | |
| 725 | Returns: |
| 726 | (status, done): (MediaDownloadProgress, boolean) |
| 727 | The value of 'done' will be True when the media has been fully |
| 728 | downloaded or the total size of the media is unknown. |
| 729 | |
| 730 | Raises: |
| 731 | googleapiclient.errors.HttpError if the response was not a 2xx. |
| 732 | httplib2.HttpLib2Error if a transport error has occurred. |
| 733 | """ |
| 734 | headers = self._headers.copy() |
| 735 | headers["range"] = "bytes=%d-%d" % ( |
| 736 | self._progress, |
| 737 | self._progress + self._chunksize - 1, |
| 738 | ) |
| 739 | http = self._request.http |
| 740 | |
| 741 | resp, content = _retry_request( |
| 742 | http, |
| 743 | num_retries, |
| 744 | "media download", |
| 745 | self._sleep, |
| 746 | self._rand, |
| 747 | self._uri, |
| 748 | "GET", |
| 749 | headers=headers, |
| 750 | ) |
| 751 | |
| 752 | if resp.status in [200, 206]: |
| 753 | if "content-location" in resp and resp["content-location"] != self._uri: |
| 754 | self._uri = resp["content-location"] |
| 755 | self._progress += len(content) |
| 756 | self._fd.write(content) |
| 757 | |
| 758 | if "content-range" in resp: |
| 759 | content_range = resp["content-range"] |
| 760 | length = content_range.rsplit("/", 1)[1] |
| 761 | self._total_size = int(length) |
| 762 | elif "content-length" in resp: |
| 763 | self._total_size = int(resp["content-length"]) |
| 764 | |
| 765 | if self._total_size is None or self._progress == self._total_size: |
| 766 | self._done = True |
| 767 | return MediaDownloadProgress(self._progress, self._total_size), self._done |
| 768 | elif resp.status == 416: |
| 769 | # 416 is Range Not Satisfiable |
| 770 | # This typically occurs with a zero byte file |
| 771 | content_range = resp["content-range"] |
| 772 | length = content_range.rsplit("/", 1)[1] |
| 773 | self._total_size = int(length) |