rich/examples/downloader.py

64 lines
1.7 KiB
Python
Raw Normal View History

2020-03-10 22:18:23 +00:00
"""
A rudimentary URL downloader (like wget or curl) to demonstrate Rich progress bars.
"""
2020-03-07 17:45:01 +00:00
from concurrent.futures import ThreadPoolExecutor
2020-03-08 16:49:36 +00:00
from functools import partial
2020-03-07 17:45:01 +00:00
import os.path
2020-03-08 16:49:36 +00:00
import sys
from typing import Iterable
2020-03-07 17:45:01 +00:00
from urllib.request import urlopen
2020-03-10 17:12:39 +00:00
from rich.progress import (
2020-03-10 18:16:55 +00:00
BarColumn,
2020-03-22 15:46:43 +00:00
DownloadColumn,
2020-03-10 18:16:55 +00:00
TransferSpeedColumn,
TimeRemainingColumn,
2020-03-10 17:12:39 +00:00
Progress,
TaskID,
)
progress = Progress(
"[bold blue]{task.fields[filename]}",
2020-03-22 15:46:43 +00:00
BarColumn(bar_width=None),
2020-03-10 17:12:39 +00:00
"[progress.percentage]{task.percentage:>3.0f}%",
"",
2020-03-22 15:46:43 +00:00
DownloadColumn(),
2020-03-10 17:12:39 +00:00
"",
2020-03-10 18:16:55 +00:00
TransferSpeedColumn(),
2020-03-10 17:12:39 +00:00
"",
2020-03-10 18:16:55 +00:00
TimeRemainingColumn(),
2020-03-10 17:12:39 +00:00
)
2020-03-07 17:45:01 +00:00
2020-03-08 16:49:36 +00:00
def copy_url(task_id: TaskID, url: str, path: str) -> None:
"""Copy data from a url to a local file."""
2020-03-07 17:45:01 +00:00
response = urlopen(url)
2020-03-10 22:18:23 +00:00
# This will break if the response doesn't contain content length
2020-03-08 16:49:36 +00:00
progress.update(task_id, total=int(response.info()["Content-length"]))
with open(path, "wb") as dest_file:
for data in iter(partial(response.read, 32768), b""):
dest_file.write(data)
progress.update(task_id, advance=len(data))
2020-03-07 17:45:01 +00:00
2020-03-08 16:49:36 +00:00
def download(urls: Iterable[str], dest_dir: str):
"""Download multuple files to the given directory."""
with progress:
with ThreadPoolExecutor(max_workers=4) as pool:
for url in urls:
filename = url.split("/")[-1]
dest_path = os.path.join(dest_dir, filename)
2020-03-10 22:18:23 +00:00
task_id = progress.add_task("download", filename=filename)
2020-03-08 16:49:36 +00:00
pool.submit(copy_url, task_id, url, dest_path)
2020-03-07 17:45:01 +00:00
2020-03-08 16:49:36 +00:00
if __name__ == "__main__":
if sys.argv[1:]:
download(sys.argv[1:], "./")
else:
2020-03-10 17:12:39 +00:00
print("Usage:\n\tpython downloader.py URL1 URL2 URL3 (etc)")