def install_package(tar_url, folder, md5_url='<STR_LIT>',<EOL>on_download=lambda: None, on_complete=lambda: None):
data_file = join(folder, basename(tar_url))<EOL>md5_url = md5_url.format(tar_url=tar_url)<EOL>try:<EOL><INDENT>remote_md5 = download(md5_url).decode('<STR_LIT:utf-8>').split('<STR_LIT:U+0020>')[<NUM_LIT:0>]<EOL><DEDENT>except (UnicodeDecodeError, URLError):<EOL><INDENT>raise ValueError('<STR_LIT>' + md5_url)<EOL><DEDENT>if remote_md5 != calc_md5(data_file):<EOL><INDENT>on_download()<EOL>if isfile(data_file):<EOL><INDENT>try:<EOL><INDENT>with tarfile.open(data_file) as tar:<EOL><INDENT>for i in reversed(list(tar)):<EOL><INDENT>try:<EOL><INDENT>os.remove(join(folder, i.path))<EOL><DEDENT>except OSError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT><DEDENT>except (OSError, EOFError):<EOL><INDENT>pass<EOL><DEDENT><DEDENT>download_extract_tar(tar_url, folder, data_file)<EOL>on_complete()<EOL>if remote_md5 != calc_md5(data_file):<EOL><INDENT>raise ValueError('<STR_LIT>' + md5_url)<EOL><DEDENT>return True<EOL><DEDENT>return False<EOL>
Install or update a tar package that has an md5

Args:
    tar_url (str): URL of package to download
    folder (str): Location to extract tar. Will be created if doesn't exist
    md5_url (str): URL of md5 to use to check for updates
    on_download (Callable): Function that gets called when downloading a new update
    on_complete (Callable): Function that gets called when a new download is complete

Returns:
    bool: Whether the package was updated