Load requested file, downloading it if needed or requested.

    Parameters
    ----------
    url: string
        The url of file to be downloaded.
    file_name: string
        Name, along with the path, of where downloaded file will be saved.
    resume: bool, optional
        If true, try to resume partially downloaded files.
    hash_ : str | None
        The hash of the file to check. If None, no checking is
        performed.
    timeout : float
        The URL open timeout.
    verbose : bool
        Whether to print download status.

def _fetch_file(url, file_name, resume=True,
                hash_=None, timeout=10., progressbar=True, verbose=True):
    """Load requested file, downloading it if needed or requested.

    Parameters
    ----------
    url: string
        The url of file to be downloaded.
    file_name: string
        Name, along with the path, of where downloaded file will be saved.
    resume: bool, optional
        If true, try to resume partially downloaded files.
    hash_ : str | None
        The hash of the file to check. If None, no checking is
        performed.
    timeout : float
        The URL open timeout.
    verbose : bool
        Whether to print download status.
    """
    # Adapted from NISL and MNE-python:
    # https://github.com/nisl/tutorial/blob/master/nisl/datasets.py
    # https://martinos.org/mne
    if hash_ is not None and (not isinstance(hash_, string_types) or
                              len(hash_) != 32):
        raise ValueError('Bad hash value given, should be a 32-character '
                         'string:\n%s' % (hash_,))
    temp_file_name = file_name + ".part"

    try:
        if 'dropbox.com' in url:
            # Use requests to handle cookies.
            # XXX In the future, we should probably use requests everywhere.
            # Unless we want to minimize dependencies.
            try:
                import requests
            except ModuleNotFoundError:
                raise ValueError('To download Dropbox links, you need to '
                                 'install the `requests` module.')
            resp = requests.get(url)
            chunk_size = 8192  # 2 ** 13
            with open(temp_file_name, 'wb') as ff:
                for chunk in resp.iter_content(chunk_size=chunk_size):
                    if chunk:  # filter out keep-alive new chunks
                        ff.write(chunk)
        else:
            # Check file size and displaying it alongside the download url
            u = urllib.request.urlopen(url, timeout=timeout)
            u.close()
            # this is necessary to follow any redirects
            url = u.geturl()
            u = urllib.request.urlopen(url, timeout=timeout)
            try:
                file_size = int(u.headers.get('Content-Length', '1').strip())
            finally:
                u.close()
                del u
            if verbose:
                tqdm.write('Downloading data from %s (%s)\n'
                           % (url, sizeof_fmt(file_size)))

            # Triage resume
            if not os.path.exists(temp_file_name):
                resume = False
            if resume:
                with open(temp_file_name, 'rb', buffering=0) as local_file:
                    local_file.seek(0, 2)
                    initial_size = local_file.tell()
                del local_file
            else:
                initial_size = 0
            # This should never happen if our functions work properly
            if initial_size > file_size:
                raise RuntimeError('Local file (%s) is larger than remote '
                                   'file (%s), cannot resume download'
                                   % (sizeof_fmt(initial_size),
                                      sizeof_fmt(file_size)))

            scheme = urllib.parse.urlparse(url).scheme
            fun = _get_http if scheme in ('http', 'https') else _get_ftp
            fun(url, temp_file_name, initial_size, file_size, verbose,
                progressbar, ncols=80)

            # check md5sum
            if hash_ is not None:
                if verbose:
                    tqdm.write('Verifying download hash.')
                md5 = md5sum(temp_file_name)
                if hash_ != md5:
                    raise RuntimeError('Hash mismatch for downloaded file %s, '
                                       'expected %s but got %s'
                                       % (temp_file_name, hash_, md5))
        shutil.move(temp_file_name, file_name)
    except Exception as ee:
        raise RuntimeError('Error while fetching file %s.'
                           ' Dataset fetching aborted.\nError: %s' % (url, ee))