Will download a file from given URL (either local or external) to the
    desired path (or generate one if none is given). Local files are copied
    directly.

    The function will retry a number of times based on retry_count (default 10)
    parameter and sleeps a number of seconds based on given timeout
    (default 10.0 sec) after each failed request.

    Returns the path to the downloaded file if successful.
    Otherwise an exception is raised.

    Given a content_type and an external URL, the function will make sure
    that the desired content_type is equal to the content-type of returned
    file.

    @param url: where the file lives on the interwebs
    @type url: string

    @param content_type: desired content_type to check for in external URLs.
                         (optional)
    @type content_type: string

    @param download_to_file: where the file should live after download.
                             (optional)
    @type download_to_file: string

    @param retry_count: number of times to retry. Defaults to 10.
                        (optional)
    @type retry_count: int

    @param timeout: number of seconds to sleep between attempts.
                    Defaults to 10.0 seconds. (optional)
    @type timeout: float

    @return: the path of the downloaded/copied file
    @raise InvenioFileDownloadError: raised upon URL/HTTP errors, file errors or wrong format

def download_url(url, content_type=None, download_to_file=None,
                 retry_count=10, timeout=10.0):
    """
    Will download a file from given URL (either local or external) to the
    desired path (or generate one if none is given). Local files are copied
    directly.

    The function will retry a number of times based on retry_count (default 10)
    parameter and sleeps a number of seconds based on given timeout
    (default 10.0 sec) after each failed request.

    Returns the path to the downloaded file if successful.
    Otherwise an exception is raised.

    Given a content_type and an external URL, the function will make sure
    that the desired content_type is equal to the content-type of returned
    file.

    @param url: where the file lives on the interwebs
    @type url: string

    @param content_type: desired content_type to check for in external URLs.
                         (optional)
    @type content_type: string

    @param download_to_file: where the file should live after download.
                             (optional)
    @type download_to_file: string

    @param retry_count: number of times to retry. Defaults to 10.
                        (optional)
    @type retry_count: int

    @param timeout: number of seconds to sleep between attempts.
                    Defaults to 10.0 seconds. (optional)
    @type timeout: float

    @return: the path of the downloaded/copied file
    @raise InvenioFileDownloadError: raised upon URL/HTTP errors, file errors or wrong format
    """
    if not download_to_file:
        download_to_file = safe_mkstemp(suffix=".tmp",
                                        prefix="filedownloadutils_")

    try:
        if is_url_a_local_file(url):
            downloaded_file = download_local_file(url,
                                                  download_to_file)
        else:
            downloaded_file = download_external_url(url,
                                                    download_to_file,
                                                    content_type=content_type,
                                                    retry_count=retry_count,
                                                    timeout=timeout)
    except InvenioFileDownloadError:
        raise

    return downloaded_file