|
45 | 45 | 'objects.githubusercontent.com', |
46 | 46 | 'developer.apple.com', 'download.developer.apple.com', |
47 | 47 | 'updates.cdn-apple.com', 'swcdn.apple.com', |
48 | | - 'oclp-download.example.com' |
| 48 | + "apple.com","opensource.apple.com","swdist.apple.com" |
49 | 49 | } |
50 | 50 |
|
51 | 51 |
|
@@ -170,13 +170,14 @@ class NetworkUtilities: |
170 | 170 | """ |
171 | 171 |
|
172 | 172 | def __init__(self, url: str = None) -> None: |
173 | | - self.url: str = url |
174 | 173 | self.contents=constants.Constants() |
175 | 174 | self.trans=TranslateLanguage(self.contents).network_handler() |
176 | | - if self.contents.github_proxy_link=="Default": |
177 | | - self.url="https://www.github.com/" |
| 175 | + if url: |
| 176 | + self.url: str = url |
| 177 | + elif self.contents.github_proxy_link=="Default": |
| 178 | + self.url: str = "https://www.github.com/" |
178 | 179 | else: |
179 | | - self.url = "https://baidu.com/" |
| 180 | + self.url: str = "https://baidu.com/" |
180 | 181 |
|
181 | 182 |
|
182 | 183 |
|
@@ -419,6 +420,7 @@ def download(self, display_progress: bool = False, spawn_thread: bool = True, ve |
419 | 420 |
|
420 | 421 | """ |
421 | 422 | self.status = DownloadStatus.DOWNLOADING |
| 423 | + self.start_time = time.time() |
422 | 424 | logging.info(self.trans["Starting download: {0}"].format(self.filename)) |
423 | 425 | if spawn_thread: |
424 | 426 | if self.active_thread: |
@@ -486,13 +488,39 @@ def _populate_file_size(self) -> None: |
486 | 488 | """ |
487 | 489 |
|
488 | 490 | try: |
| 491 | + # Try HEAD request first |
489 | 492 | result = SESSION.head(self.url, allow_redirects=True, timeout=5) |
490 | 493 | if 'Content-Length' in result.headers: |
491 | 494 | self.total_file_size = float(result.headers['Content-Length']) |
492 | 495 | if self.size != None: |
493 | 496 | self.total_file_size = self.convert_size(self.size) |
494 | | - else: |
495 | | - raise Exception(self.trans["Content-Length missing from headers"]) |
| 497 | + return |
| 498 | + except Exception as e: |
| 499 | + logging.warning(self.trans["HEAD request failed for {0}: {1}"].format(self.url, str(e))) |
| 500 | + |
| 501 | + # Fallback: Try GET request with Range header (for Apple CDN and other servers that don't support HEAD with Content-Length) |
| 502 | + try: |
| 503 | + headers = {"Range": "bytes=0-0"} |
| 504 | + result = SESSION.get(self.url, stream=True, headers=headers, timeout=10, allow_redirects=True) |
| 505 | + if 'Content-Length' in result.headers: |
| 506 | + self.total_file_size = float(result.headers['Content-Length']) |
| 507 | + if self.size != None: |
| 508 | + self.total_file_size = self.convert_size(self.size) |
| 509 | + result.close() |
| 510 | + return |
| 511 | + elif 'Content-Range' in result.headers: |
| 512 | + # Content-Range format: "bytes 0-0/12345678" |
| 513 | + content_range = result.headers['Content-Range'] |
| 514 | + if '/' in content_range: |
| 515 | + total_size = content_range.split('/')[-1] |
| 516 | + if total_size != '*': |
| 517 | + self.total_file_size = float(total_size) |
| 518 | + if self.size != None: |
| 519 | + self.total_file_size = self.convert_size(self.size) |
| 520 | + result.close() |
| 521 | + return |
| 522 | + result.close() |
| 523 | + raise Exception(self.trans["Content-Length missing from headers"]) |
496 | 524 | except Exception as e: |
497 | 525 | logging.error(self.trans["Error determining file size {0}: {1}"].format(self.url, str(e))) |
498 | 526 | logging.error(self.trans["Assuming file size is 0"]) |
@@ -522,11 +550,13 @@ def _prepare_working_directory(self, path: Path) -> bool: |
522 | 550 |
|
523 | 551 | try: |
524 | 552 | if Path(path).exists(): |
525 | | - if self.resume_download: |
526 | | - # For resumable download, keep the existing file |
527 | | - self.downloaded_file_offset = Path(path).stat().st_size |
| 553 | + existing_size = Path(path).stat().st_size |
| 554 | + if self.resume_download and self.total_file_size > 0 and existing_size < self.total_file_size: |
| 555 | + # For resumable download, keep the existing file only if it's incomplete |
| 556 | + self.downloaded_file_offset = existing_size |
528 | 557 | logging.info(self.trans["Resuming download from {0}: {1}"].format(utilities.human_fmt(self.downloaded_file_offset), path)) |
529 | 558 | else: |
| 559 | + # Delete existing file if download is complete or resume is disabled |
530 | 560 | logging.info(self.trans["Deleting existing file: {0}"].format(path)) |
531 | 561 | Path(path).unlink() |
532 | 562 | return True |
@@ -861,11 +891,15 @@ def _download(self, display_progress: bool = False) -> None: |
861 | 891 | else: |
862 | 892 | self.download_complete = True |
863 | 893 | self._clear_progress() |
| 894 | + # If no new data was downloaded but file exists, use the file size on disk |
| 895 | + if self.downloaded_file_size == 0 and self.filepath.exists(): |
| 896 | + self.downloaded_file_size = self.filepath.stat().st_size |
864 | 897 | logging.info(self.trans["Download complete: {0}"].format(self.filename)) |
865 | 898 | logging.info(self.trans["Stats:"]) |
866 | 899 | logging.info(self.trans["- Downloaded size: {0}"].format(utilities.human_fmt(self.downloaded_file_size))) |
867 | 900 | logging.info(self.trans["- Time elapsed: {0:.2f} seconds"].format((time.time() - self.start_time))) |
868 | | - logging.info(self.trans["- Speed: {0}/s"].format(utilities.human_fmt(self.downloaded_file_size / (time.time() - self.start_time)))) |
| 901 | + if (time.time() - self.start_time) > 0: |
| 902 | + logging.info(self.trans["- Speed: {0}/s"].format(utilities.human_fmt(self.downloaded_file_size / (time.time() - self.start_time)))) |
869 | 903 | logging.info(self.trans["- Location: {0}"].format(self.filepath)) |
870 | 904 | except Exception as e: |
871 | 905 | self._save_progress() |
|
0 commit comments