diff --git a/doc.md b/doc.md index 8cb9aea..8f929ac 100644 --- a/doc.md +++ b/doc.md @@ -797,17 +797,18 @@ 5.1 `download_python` - Download python portable interpreter from https://github.com/indygreg/python-build-standalone/releases. `python -m morebuiltins.download_python` λ python -m morebuiltins.download_python - View the rules: + [10:56:17] Checking https://api.github.com/repos/indygreg/python-build-standalone/releases/latest + [10:56:19] View the rules: https://gregoryszorc.com/docs/python-build-standalone/main/running.html#obtaining-distributions - Got 290 urls from github. + [10:56:19] Got 290 urls from github. [290] Enter keywords (can be int index or partial match, defaults to 0): 0. windows 1. linux 2. darwin - - Filt with keyword: "windows". 290 => 40 + 0 + [10:56:24] Filt with keyword: "windows". 290 => 40 [40] Enter keywords (can be int index or partial match, defaults to 0): 0. 3.12.3 @@ -816,30 +817,32 @@ 3. 3.9.19 4. 3.8.19 - Filt with keyword: "3.12.3". 40 => 8 + [10:56:25] Filt with keyword: "3.12.3". 40 => 8 [8] Enter keywords (can be int index or partial match, defaults to 0): 0. x86_64 1. i686 - Filt with keyword: "x86_64". 8 => 4 + [10:56:28] Filt with keyword: "x86_64". 8 => 4 [4] Enter keywords (can be int index or partial match, defaults to 0): 0. shared-pgo-full.tar.zst 1. shared-install_only.tar.gz 2. pgo-full.tar.zst 3. install_only.tar.gz - - Filt with keyword: "shared-pgo-full.tar.zst". 4 => 1 - Download URL: 40.4 MB - https://github.com/indygreg/python-build-standalone/releases/download/20240415/cpython-3.12.3%2B20240415-x86_64-pc-windows-msvc-shared-pgo-full.tar.zst - File path to save(defaults to `./cpython-3.12.3+20240415-x86_64-pc-windows-msvc-shared-pgo-full.tar.zst`)? + 3 + [10:56:33] Filt with keyword: "install_only.tar.gz". 4 => 1 + [10:56:33] Download URL: 39.1 MB + https://github.com/indygreg/python-build-standalone/releases/download/20240415/cpython-3.12.3%2B20240415-x86_64-pc-windows-msvc-install_only.tar.gz + File path to save(defaults to `./cpython-3.12.3+20240415-x86_64-pc-windows-msvc-install_only.tar.gz`)? or `q` to exit. - Start downloading... - https://github.com/indygreg/python-build-standalone/releases/download/20240415/cpython-3.12.3%2B20240415-x86_64-pc-windows-msvc-shared-pgo-full.tar.zst - D:\github\morebuiltins\cpython-3.12.3+20240415-x86_64-pc-windows-msvc-shared-pgo-full.tar.zst - [Downloading]: 2.21 / 40.44 MB | 5.47% + [10:56:38] Start downloading... + https://github.com/indygreg/python-build-standalone/releases/download/20240415/cpython-3.12.3%2B20240415-x86_64-pc-windows-msvc-install_only.tar.gz + D:\github\morebuiltins\morebuiltins\download_python\cpython-3.12.3+20240415-x86_64-pc-windows-msvc-install_only.tar.gz + [10:56:44] Downloading: 39.12 / 39.12 MB | 100.00% | 11.3 MB/s | 0s + [10:56:44] Download complete. + --- diff --git a/morebuiltins/download_python/main.py b/morebuiltins/download_python/main.py index 4856251..d7ecee5 100644 --- a/morebuiltins/download_python/main.py +++ b/morebuiltins/download_python/main.py @@ -1,7 +1,9 @@ import http.client import json +import time import traceback import urllib.request +from collections import deque from dataclasses import dataclass from pathlib import Path @@ -35,21 +37,26 @@ def get_assets(): return urls +def get_time(): + return time.strftime("%H:%M:%S") + + def download_python(): """Download python portable interpreter from https://github.com/indygreg/python-build-standalone/releases. `python -m morebuiltins.download_python` λ python -m morebuiltins.download_python - View the rules: + [10:56:17] Checking https://api.github.com/repos/indygreg/python-build-standalone/releases/latest + [10:56:19] View the rules: https://gregoryszorc.com/docs/python-build-standalone/main/running.html#obtaining-distributions - Got 290 urls from github. + [10:56:19] Got 290 urls from github. [290] Enter keywords (can be int index or partial match, defaults to 0): 0. windows 1. linux 2. darwin - - Filt with keyword: "windows". 290 => 40 + 0 + [10:56:24] Filt with keyword: "windows". 290 => 40 [40] Enter keywords (can be int index or partial match, defaults to 0): 0. 3.12.3 @@ -58,36 +65,42 @@ def download_python(): 3. 3.9.19 4. 3.8.19 - Filt with keyword: "3.12.3". 40 => 8 + [10:56:25] Filt with keyword: "3.12.3". 40 => 8 [8] Enter keywords (can be int index or partial match, defaults to 0): 0. x86_64 1. i686 - Filt with keyword: "x86_64". 8 => 4 + [10:56:28] Filt with keyword: "x86_64". 8 => 4 [4] Enter keywords (can be int index or partial match, defaults to 0): 0. shared-pgo-full.tar.zst 1. shared-install_only.tar.gz 2. pgo-full.tar.zst 3. install_only.tar.gz - - Filt with keyword: "shared-pgo-full.tar.zst". 4 => 1 - Download URL: 40.4 MB - https://github.com/indygreg/python-build-standalone/releases/download/20240415/cpython-3.12.3%2B20240415-x86_64-pc-windows-msvc-shared-pgo-full.tar.zst - File path to save(defaults to `./cpython-3.12.3+20240415-x86_64-pc-windows-msvc-shared-pgo-full.tar.zst`)? + 3 + [10:56:33] Filt with keyword: "install_only.tar.gz". 4 => 1 + [10:56:33] Download URL: 39.1 MB + https://github.com/indygreg/python-build-standalone/releases/download/20240415/cpython-3.12.3%2B20240415-x86_64-pc-windows-msvc-install_only.tar.gz + File path to save(defaults to `./cpython-3.12.3+20240415-x86_64-pc-windows-msvc-install_only.tar.gz`)? or `q` to exit. - Start downloading... - https://github.com/indygreg/python-build-standalone/releases/download/20240415/cpython-3.12.3%2B20240415-x86_64-pc-windows-msvc-shared-pgo-full.tar.zst - D:\github\morebuiltins\cpython-3.12.3+20240415-x86_64-pc-windows-msvc-shared-pgo-full.tar.zst - [Downloading]: 2.21 / 40.44 MB | 5.47%""" + [10:56:38] Start downloading... + https://github.com/indygreg/python-build-standalone/releases/download/20240415/cpython-3.12.3%2B20240415-x86_64-pc-windows-msvc-install_only.tar.gz + D:\github\morebuiltins\morebuiltins\download_python\cpython-3.12.3+20240415-x86_64-pc-windows-msvc-install_only.tar.gz + [10:56:44] Downloading: 39.12 / 39.12 MB | 100.00% | 11.3 MB/s | 0s + [10:56:44] Download complete. +""" + print( + f"[{get_time()}] Checking https://api.github.com/repos/indygreg/python-build-standalone/releases/latest", + flush=True, + ) assets = get_assets() print( - "View the rules:\nhttps://gregoryszorc.com/docs/python-build-standalone/main/running.html#obtaining-distributions\n", + f"[{get_time()}] View the rules:\nhttps://gregoryszorc.com/docs/python-build-standalone/main/running.html#obtaining-distributions\n", flush=True, ) - print(f"Got {len(assets)} urls from github.") + print(f"[{get_time()}] Got {len(assets)} urls from github.") def sort_key(s): try: @@ -119,7 +132,13 @@ def sort_key(s): assets = temp else: assets = [i for i in assets if arg in i.keywords[index]] - print(f'Filt with keyword: "{arg}".', old, "=>", len(assets), flush=True) + print( + f'[{get_time()}] Filt with keyword: "{arg}".', + old, + "=>", + len(assets), + flush=True, + ) while len(assets) > 1: names = "\n".join(i.name for i in assets) arg = input(f"Enter keyword to reduce the list (partial match):\n{names}\n") @@ -130,7 +149,11 @@ def sort_key(s): asset = assets[0] download_url = asset.url total_size = asset.size - print("Download URL:", round(total_size / 1024**2, 1), "MB") + print( + f"[{get_time()}] Download URL:", + round(total_size / 1024**2, 1), + "MB", + ) print(download_url, flush=True) target = ( input( @@ -142,18 +165,47 @@ def sort_key(s): return target_path = Path(target) target_path.unlink(missing_ok=True) - print("Start downloading...") + print(f"[{get_time()}] Start downloading...") print(download_url) print(target_path.absolute(), flush=True) + records = deque(maxlen=1000) def reporthook(blocknum, blocksize, totalsize): if totalsize < 0: totalsize = total_size - percent = (blocknum * blocksize * 100.0) / totalsize - done = blocknum * blocksize / 1024 / 1024 + _done = blocknum * blocksize + if not _done: + return + percent = 100.0 * _done / totalsize total = totalsize / 1024 / 1024 + done = _done / 1024 / 1024 or total + if percent > 100: + percent = 100 + now = time.time() + record = (now, _done) + records.appendleft(record) + timeleft = "-" + _speed = 0 + if len(records) >= 2: + for record in records: + if now - record[0] > 1: + break + time_diff = now - record[0] + if time_diff: + _speed = round((_done - record[1]) / time_diff, 1) + secs = (totalsize - _done) / _speed + if secs > 60: + timeleft = f"{int(secs / 60)}:{int(secs % 60):02}" + else: + timeleft = f"{int(secs)}s" + if _speed > 1024**2: + speed = f"{round(_speed / 1024**2, 1)} MB/s" + elif _speed > 1024: + speed = f"{round(_speed / 1024, 1)} KB/s" + else: + speed = f"{round(_speed, 1)} B/s" print( - f"[Downloading]: {done:.2f} / {total:.2f} MB | {percent:.2f}%{' ' * 10}", + f"[{get_time()}] Downloading: {done:.2f} / {total:.2f} MB | {percent:.2f}% | {speed} | {timeleft} {' ' * 10}", end="\r", flush=True, ) @@ -165,14 +217,17 @@ def reporthook(blocknum, blocksize, totalsize): download_url, temp_path.absolute().as_posix(), reporthook=reporthook ) temp_path.rename(target_path) - print("Download complete.", flush=True) + print( + f"\n[{get_time()}] Download complete.", + flush=True, + ) break except http.client.RemoteDisconnected: continue except KeyboardInterrupt: temp_path.unlink(missing_ok=True) print() - print("Download canceled.", flush=True) + print(f"\n[{get_time()}] Download canceled.", flush=True) return except Exception: print()