|
|
import sys, time |
|
|
|
|
|
|
|
|
_start_time = None |
|
|
_last_time = None |
|
|
_last_downloaded = 0 |
|
|
_speed_history = [] |
|
|
_update_interval = 0.5 |
|
|
|
|
|
def progress_hook(block_num, block_size, total_size, filename=None): |
|
|
""" |
|
|
Simple progress bar hook for urlretrieve |
|
|
|
|
|
Args: |
|
|
block_num: Number of blocks downloaded so far |
|
|
block_size: Size of each block in bytes |
|
|
total_size: Total size of the file in bytes |
|
|
filename: Name of the file being downloaded (optional) |
|
|
""" |
|
|
global _start_time, _last_time, _last_downloaded, _speed_history, _update_interval |
|
|
|
|
|
current_time = time.time() |
|
|
downloaded = block_num * block_size |
|
|
|
|
|
|
|
|
if _start_time is None or block_num == 0: |
|
|
_start_time = current_time |
|
|
_last_time = current_time |
|
|
_last_downloaded = 0 |
|
|
_speed_history = [] |
|
|
|
|
|
|
|
|
speed = 0 |
|
|
if current_time - _last_time >= _update_interval: |
|
|
if _last_time > 0: |
|
|
current_speed = (downloaded - _last_downloaded) / (current_time - _last_time) |
|
|
_speed_history.append(current_speed) |
|
|
|
|
|
if len(_speed_history) > 5: |
|
|
_speed_history.pop(0) |
|
|
|
|
|
speed = sum(_speed_history) / len(_speed_history) |
|
|
|
|
|
_last_time = current_time |
|
|
_last_downloaded = downloaded |
|
|
elif _speed_history: |
|
|
|
|
|
speed = sum(_speed_history) / len(_speed_history) |
|
|
|
|
|
def format_bytes(bytes_val): |
|
|
for unit in ['B', 'KB', 'MB', 'GB']: |
|
|
if bytes_val < 1024: |
|
|
return f"{bytes_val:.1f}{unit}" |
|
|
bytes_val /= 1024 |
|
|
return f"{bytes_val:.1f}TB" |
|
|
|
|
|
file_display = filename if filename else "Unknown file" |
|
|
|
|
|
if total_size <= 0: |
|
|
|
|
|
speed_str = f" @ {format_bytes(speed)}/s" if speed > 0 else "" |
|
|
line = f"\r{file_display}: {format_bytes(downloaded)}{speed_str}" |
|
|
|
|
|
sys.stdout.write(line.ljust(80)) |
|
|
sys.stdout.flush() |
|
|
return |
|
|
|
|
|
downloaded = block_num * block_size |
|
|
percent = min(100, (downloaded / total_size) * 100) |
|
|
|
|
|
|
|
|
bar_length = 40 |
|
|
filled = int(bar_length * percent / 100) |
|
|
bar = '█' * filled + '░' * (bar_length - filled) |
|
|
|
|
|
|
|
|
def format_bytes(bytes_val): |
|
|
for unit in ['B', 'KB', 'MB', 'GB']: |
|
|
if bytes_val < 1024: |
|
|
return f"{bytes_val:.1f}{unit}" |
|
|
bytes_val /= 1024 |
|
|
return f"{bytes_val:.1f}TB" |
|
|
|
|
|
speed_str = f" @ {format_bytes(speed)}/s" if speed > 0 else "" |
|
|
|
|
|
|
|
|
line = f"\r{file_display}: [{bar}] {percent:.1f}% ({format_bytes(downloaded)}/{format_bytes(total_size)}){speed_str}" |
|
|
|
|
|
sys.stdout.write(line.ljust(100)) |
|
|
sys.stdout.flush() |
|
|
|
|
|
|
|
|
if percent >= 100: |
|
|
print() |
|
|
|
|
|
|
|
|
def create_progress_hook(filename): |
|
|
"""Creates a progress hook with the filename included""" |
|
|
global _start_time, _last_time, _last_downloaded, _speed_history |
|
|
|
|
|
_start_time = None |
|
|
_last_time = None |
|
|
_last_downloaded = 0 |
|
|
_speed_history = [] |
|
|
|
|
|
def hook(block_num, block_size, total_size): |
|
|
return progress_hook(block_num, block_size, total_size, filename) |
|
|
return hook |
|
|
|
|
|
|
|
|
|