Source code for veditor.utils.download_utils

# coding: utf-8
import os
import sys
import time
import urllib
import urllib.request
from typing import Callable, Optional

from ._colorings import toBLUE, toGREEN, toRED
from .generic_utils import readable_bytes

# Use Specific Opener
opener = urllib.request.build_opener()
opener.addheaders = [
    (
        "User-Agent",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1941.0 Safari/537.36",
    )
]
urllib.request.install_opener(opener)


[docs]def progress_reporthook_create( filename: str = "", bar_width: int = 20, verbose: bool = True, ) -> Callable[[int, int, int], None]: """Create Progress reporthook for ``urllib.request.urlretrieve`` Args: filename (str, optional) : A downloading filename. Defaults to ``""``. bar_width (int, optional) : The maximum width of progress bar.. Defaults to ``20``. verbose (bool, optional) : Whether to show progress or not. Returns: Callable[[int,int,int],None]: The ``reporthook`` which is a callable that accepts a ``block number``, a ``read size``, and the ``total file size`` of the URL target. Examples: >>> import urllib >>> from veditor.utils import progress_reporthook_create >>> urllib.request.urlretrieve(url="hoge.zip", filename="hoge.zip", reporthook=progress_reporthook_create(filename="hoge.zip")) hoge.zip 1.5%[--------------------] 21.5[s] 8.0[GB/s] eta 1415.1[s] """ def progress_reporthook_verbose(block_count: int, block_size: int, total_size: int): global _reporthook_start_time if block_count == 0: _reporthook_start_time = time.time() return progress_size = block_count * block_size percentage = min(1.0, progress_size / total_size) progress_bar = ("#" * int(percentage * bar_width)).ljust(bar_width, "-") duration = time.time() - _reporthook_start_time speed = progress_size / duration eta = (total_size - progress_size) / speed speed, speed_unit = readable_bytes(speed) sys.stdout.write( f"\r{filename}\t{percentage:.1%}[{progress_bar}] {duration:.1f}[s] {speed:.1f}[{speed_unit}/s]\teta {eta:.1f}[s]" ) if progress_size >= total_size: print() def progress_reporthook_non_verbose(block_count, block_size, total_size): pass return progress_reporthook_verbose if verbose else progress_reporthook_non_verbose
[docs]def download_file( url: str, dirname: str = ".", filename: Optional[str] = None, bar_width: int = 20, verbose: bool = True, ) -> str: """Download a file from ``url`` Args: url (str) : URL where the data is located. dirname (str, optional) : The directory where downloaded data will be saved.. Defaults to ``"."``. filename (Optional[str], optional) : The name of the file you want to download. Saved with this name. Defaults to ``None``. bar_width (int, optional) : The maximum width of progress bar. Defaults to ``20``. verbose (bool, optional) : Whether to show progress or not. Defaults to ``True``. Returns: str: The path to a downloaded file. Examples: >>> from veditor.utils import download_file >>> download_file(url="https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_eye.xml") Download a file from https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_eye.xml * Content-Encoding : None * Content-Length : (333.404296875, 'MB') * Content-Type : text/plain; charset=utf-8 * Save Destination : ./haarcascade_eye.xml haarcascade_eye.xml 100.0%[####################] 0.1[s] 5.5[GB/s] eta -0.0[s] './haarcascade_eye.xml' """ try: with urllib.request.urlopen(url) as web_file: # Get Information from webfile header headers = dict(web_file.headers._headers) content_encoding = headers.get("Content-Encoding") content_length, unit = readable_bytes(int(headers.get("Content-Length", 0))) content_length = f"{content_length:.1f} [{unit}]" content_type = headers.get("Content-Type") filename = filename or url.split("/")[-1] if not os.path.exists(dirname): os.makedirs(name=dirname) path = os.path.join(dirname, filename) if verbose: print( f"""Download a file from {toBLUE(url)} * Content-Encoding : {toGREEN(content_encoding)} * Content-Length : {toGREEN(content_length)} * Content-Type : {toGREEN(content_type)} * Save Destination : {toBLUE(path)}""" ) _, res = urllib.request.urlretrieve( url=url, filename=path, reporthook=progress_reporthook_create( filename=filename, bar_width=bar_width, verbose=verbose ), ) except urllib.error.URLError as e: print(f"{toRED(e)} : url={toBLUE(url)}") return path