Download from start_byte to end of file.
(
self, url: str, file_path: Path, start_byte: int, total_size: int
)
| 86 | return None |
| 87 | |
| 88 | def _download_range( |
| 89 | self, url: str, file_path: Path, start_byte: int, total_size: int |
| 90 | ) -> None: |
| 91 | """Download from start_byte to end of file.""" |
| 92 | import urllib.request |
| 93 | |
| 94 | # Create range request |
| 95 | headers: dict[str, str] = {} |
| 96 | if start_byte > 0: |
| 97 | headers["Range"] = f"bytes={start_byte}-" |
| 98 | |
| 99 | req = urllib.request.Request(url, headers=headers) |
| 100 | |
| 101 | # Open file in append mode if resuming, write mode if starting fresh |
| 102 | mode = "ab" if start_byte > 0 else "wb" |
| 103 | |
| 104 | with urllib.request.urlopen(req, timeout=30) as response: |
| 105 | with open(file_path, mode) as f: |
| 106 | downloaded = start_byte |
| 107 | |
| 108 | while True: |
| 109 | chunk = response.read(self.chunk_size) |
| 110 | if not chunk: |
| 111 | break |
| 112 | |
| 113 | f.write(chunk) |
| 114 | downloaded += len(chunk) |
| 115 | |
| 116 | # Progress reporting |
| 117 | if total_size > 0: |
| 118 | progress = downloaded / total_size * 100 |
| 119 | mb_downloaded = downloaded / (1024 * 1024) |
| 120 | mb_total = total_size / (1024 * 1024) |
| 121 | print( |
| 122 | f"\rProgress: {progress:.1f}% ({mb_downloaded:.1f}/{mb_total:.1f} MB)", |
| 123 | end="", |
| 124 | flush=True, |
| 125 | ) |
| 126 | else: |
| 127 | mb_downloaded = downloaded / (1024 * 1024) |
| 128 | print( |
| 129 | f"\rDownloaded: {mb_downloaded:.1f} MB", end="", flush=True |
| 130 | ) |
| 131 | |
| 132 | print() # New line after progress |