download_utils.py raw
1 #!/usr/bin/env python3
2 #
3 # Copyright (c) The Bitcoin Core developers
4 # Distributed under the MIT software license, see the accompanying
5 # file COPYING or https://opensource.org/license/mit/.
6
7 import sys
8 import time
9 import urllib.request
10
11
12 def download_from_url(url, archive):
13 print(f"Fetching: {url}")
14 last_print_time = time.time()
15
16 def progress_hook(progress_bytes, total_size):
17 nonlocal last_print_time
18 now = time.time()
19 percent = min(100, (progress_bytes * 100) / total_size)
20 bar_length = 40
21 filled_length = int(bar_length * percent / 100)
22 bar = '#' * filled_length + '-' * (bar_length - filled_length)
23 if now - last_print_time >= 1 or percent >= 100:
24 print(f'\rDownloading: [{bar}] {percent:.1f}%', flush=True, end="")
25 last_print_time = now
26
27 with urllib.request.urlopen(url) as response:
28 if response.status != 200:
29 raise RuntimeError(f"HTTP request failed with status code: {response.status}")
30
31 sock_info = response.fp.raw._sock.getpeername()
32 print(f"Connected to {sock_info[0]}")
33
34 total_size = int(response.getheader("Content-Length"))
35 progress_bytes = 0
36
37 with open(archive, 'wb') as file:
38 while True:
39 chunk = response.read(8192)
40 if not chunk:
41 break
42 file.write(chunk)
43 progress_bytes += len(chunk)
44 progress_hook(progress_bytes, total_size)
45
46 if progress_bytes < total_size:
47 raise RuntimeError(f"Download incomplete: expected {total_size} bytes, got {progress_bytes} bytes")
48
49 print('\n', flush=True, end="") # Flush to avoid error output on the same line.
50
51
52 def download_script_assets(script_assets_dir):
53 script_assets_dir.mkdir(parents=True, exist_ok=True)
54 script_assets = script_assets_dir / "script_assets_test.json"
55 url = "https://github.com/bitcoin-core/qa-assets/raw/main/unit_test_data/script_assets_test.json"
56 try:
57 download_from_url(url, script_assets)
58 except Exception as e:
59 print(f"\nDownload failed: {e}", file=sys.stderr)
60 print("Retrying download after failure ...", file=sys.stderr)
61 time.sleep(12)
62 try:
63 download_from_url(url, script_assets)
64 except Exception as e2:
65 sys.exit(e2)
66