Download a URL.

    This will download a file and store it in a '~/data/` folder,
    creating directories if need be. It will also work for zip
    files, in which case it will unzip all of the files to the
    desired location.

    Parameters
    ----------
    url : string
        The url of the file to download. This may be a dropbox
        or google drive "share link", or a regular URL. If it
        is a share link, then it should point to a single file and
        not a folder. To download folders, zip them first.
    path : string
        The path where the downloaded file will be stored. If ``zipfile``
        is True, then this must be a folder into which files will be zipped.
    kind : one of ['file', 'zip', 'tar', 'tar.gz']
        The kind of file to be downloaded. If not 'file', then the file
        contents will be unpackaged according to the kind specified. Package
        contents will be placed in ``root_destination/<name>``.
    progressbar : bool
        Whether to display a progress bar during file download.
    replace : bool
        If True and the URL points to a single file, overwrite the
        old file if possible.
    timeout : float
        The URL open timeout.
    verbose : bool
        Whether to print download status to the screen.

    Returns
    -------
    out_path : string
        A path to the downloaded file (or folder, in the case of
        a zip file).

def download(url, path, kind='file',
             progressbar=True, replace=False, timeout=10., verbose=True):
    """Download a URL.

    This will download a file and store it in a '~/data/` folder,
    creating directories if need be. It will also work for zip
    files, in which case it will unzip all of the files to the
    desired location.

    Parameters
    ----------
    url : string
        The url of the file to download. This may be a dropbox
        or google drive "share link", or a regular URL. If it
        is a share link, then it should point to a single file and
        not a folder. To download folders, zip them first.
    path : string
        The path where the downloaded file will be stored. If ``zipfile``
        is True, then this must be a folder into which files will be zipped.
    kind : one of ['file', 'zip', 'tar', 'tar.gz']
        The kind of file to be downloaded. If not 'file', then the file
        contents will be unpackaged according to the kind specified. Package
        contents will be placed in ``root_destination/<name>``.
    progressbar : bool
        Whether to display a progress bar during file download.
    replace : bool
        If True and the URL points to a single file, overwrite the
        old file if possible.
    timeout : float
        The URL open timeout.
    verbose : bool
        Whether to print download status to the screen.

    Returns
    -------
    out_path : string
        A path to the downloaded file (or folder, in the case of
        a zip file).
    """
    if kind not in ALLOWED_KINDS:
        raise ValueError('`kind` must be one of {}, got {}'.format(
            ALLOWED_KINDS, kind))

    # Make sure we have directories to dump files
    path = op.expanduser(path)

    if len(path) == 0:
        raise ValueError('You must specify a path. For current directory use .')

    download_url = _convert_url_to_downloadable(url)

    if replace is False and op.exists(path):
        msg = ('Replace is False and data exists, so doing nothing. '
               'Use replace==True to re-download the data.')
    elif kind in ZIP_KINDS:
        # Create new folder for data if we need it
        if not op.isdir(path):
            if verbose:
                tqdm.write('Creating data folder...')
            os.makedirs(path)

        # Download the file to a temporary folder to unzip
        path_temp = _TempDir()
        path_temp_file = op.join(path_temp, "tmp.{}".format(kind))
        _fetch_file(download_url, path_temp_file, timeout=timeout,
                    verbose=verbose)

        # Unzip the file to the out path
        if verbose:
            tqdm.write('Extracting {} file...'.format(kind))
        if kind == 'zip':
            zipper = ZipFile
        elif kind == 'tar':
            zipper = tarfile.open
        elif kind == 'tar.gz':
            zipper = partial(tarfile.open, mode='r:gz')
        with zipper(path_temp_file) as myobj:
            myobj.extractall(path)
        msg = 'Successfully downloaded / unzipped to {}'.format(path)
    else:
        if not op.isdir(op.dirname(path)):
            os.makedirs(op.dirname(path))
        _fetch_file(download_url, path, timeout=timeout, verbose=verbose)
        msg = 'Successfully downloaded file to {}'.format(path)
    if verbose:
        tqdm.write(msg)
    return path