def download_latest_git_files_from_github_to_winecache(
        wine_prefix: Union[str, pathlib.Path] = configmagick_linux.
    get_path_home_dir_current_user() / '.wine',
        username: str = configmagick_linux.get_current_username(),
        force_download: bool = False,
        quiet: bool = False) -> None:
    """
    >>> install_wine_machine.create_wine_test_prefixes()
    >>> download_latest_git_files_from_github_to_winecache(wine_prefix = 'wine_test_32', force_download=True, quiet=False)
    >>> download_latest_git_files_from_github_to_winecache(wine_prefix = 'wine_test_64', force_download=False, quiet=False)
    """
    wine_prefix = lib_wine.get_and_check_wine_prefix(wine_prefix, username)
    wine_arch = lib_wine.get_wine_arch_from_wine_prefix(
        wine_prefix=wine_prefix, username=username)

    lib_log_utils.log_verbose(
        'Download latest Portable Git from Github to Wine Cache', quiet=quiet)
    git_download_link = get_git_portable_download_link_from_github(
        wine_arch=wine_arch)
    git_exe_filename = pathlib.Path(git_download_link.rsplit('/', 1)[1])

    if lib_wine.is_file_in_wine_cache(filename=git_exe_filename,
                                      username=username) or force_download:
        if force_download:
            lib_wine.remove_file_from_winecache(filename=git_exe_filename,
                                                username=username)
            lib_wine.download_file_to_winecache(
                download_link=git_download_link,
                filename=git_exe_filename,
                username=username)
    else:
        lib_wine.download_file_to_winecache(download_link=git_download_link,
                                            filename=git_exe_filename,
                                            username=username)
Beispiel #2
0
def install_mono_latest(wine_prefix: Union[
    str, pathlib.Path] = configmagick_linux.get_path_home_dir_current_user() /
                        '.wine',
                        username: str = configmagick_linux.
                        get_current_username(),
                        quiet: bool = False) -> None:
    """
    install the latest mono version from github

    >>> install_wine_machine.create_wine_test_prefixes()
    >>> install_mono_latest('wine_test_32', quiet=True)
    >>> install_mono_latest('wine_test_64', quiet=True)

    """
    wine_prefix = lib_wine.get_and_check_wine_prefix(wine_prefix, username)
    wine_arch = lib_wine.get_wine_arch_from_wine_prefix(
        wine_prefix=wine_prefix, username=username)
    mono_download_link = get_wine_mono_download_link_from_github()
    mono_msi_filename = pathlib.Path(mono_download_link.rsplit('/', 1)[1])
    wine_cache_directory = lib_wine.get_path_wine_cache_for_user(
        username=username)
    lib_log_utils.banner_verbose(
        'Installing Wine Mono :\n'
        'WINEPREFIX="{wine_prefix}"\n'
        'WINEARCH="{wine_arch}"\n'
        'mono_msi_filename="{mono_msi_filename}"\n'
        'wine_cache_directory="{wine_cache_directory}"'.format(
            wine_prefix=wine_prefix,
            wine_arch=wine_arch,
            wine_cache_directory=wine_cache_directory,
            mono_msi_filename=mono_msi_filename),
        quiet=quiet)

    download_latest_mono_msi_files_from_github(username=username,
                                               force_download=False,
                                               quiet=quiet)

    lib_log_utils.log_verbose(
        'Install "{mono_msi_filename}" on WINEPREFIX="{wine_prefix}"'.format(
            mono_msi_filename=mono_msi_filename, wine_prefix=wine_prefix),
        quiet=quiet)

    command = 'WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" wine msiexec /i "{wine_cache_directory}/{mono_msi_filename}"'\
        .format(wine_prefix=wine_prefix,
                wine_arch=wine_arch,
                wine_cache_directory=wine_cache_directory,
                mono_msi_filename=mono_msi_filename)
    lib_shell.run_shell_command(command,
                                shell=True,
                                run_as_user=username,
                                pass_stdout_stderr_to_sys=True,
                                quiet=quiet)
    lib_wine.fix_wine_permissions(
        wine_prefix=wine_prefix,
        username=username)  # it is cheap, just in case
    lib_log_utils.banner_success(
        'Wine Mono "{mono_msi_filename}" installed'.format(
            mono_msi_filename=mono_msi_filename))
Beispiel #3
0
def download_gecko_msi_files(wine_prefix: Union[str, pathlib.Path],
                             username: str,
                             quiet: bool = False) -> None:

    wine_arch = lib_wine.get_wine_arch_from_wine_prefix(wine_prefix, username)
    if wine_arch == 'win32' or wine_arch == 'win64':
        download_gecko_32_msi_files(wine_prefix, username, quiet=quiet)
    if wine_arch == 'win64':
        download_gecko_64_msi_files(wine_prefix, username, quiet=quiet)
    lib_wine.fix_permissions_winecache(username=username)
Beispiel #4
0
def install_mono_recommended(wine_prefix: Union[
    str, pathlib.Path] = configmagick_linux.get_path_home_dir_current_user() /
                             '.wine',
                             username: str = configmagick_linux.
                             get_current_username(),
                             quiet: bool = False) -> None:
    """ Installs the mono version stated in appwiz.cpl - might be not the newest version, se we should prefer to install the latest wine-mono from github
    Mono version can only be extracted from wine prefixes created with wine version 4.18 upwards, on older version this does not work

    >>> install_wine_machine.create_wine_test_prefixes()
    >>> install_mono_recommended('wine_test_32', quiet=True)
    >>> install_mono_recommended('wine_test_64', quiet=True)

    """
    wine_prefix = lib_wine.get_and_check_wine_prefix(wine_prefix, username)
    wine_arch = lib_wine.get_wine_arch_from_wine_prefix(
        wine_prefix=wine_prefix, username=username)
    mono_msi_filename = get_mono_msi_filename_from_appwiz(
        wine_prefix=wine_prefix, username=username)
    wine_cache_directory = lib_wine.get_path_wine_cache_for_user(
        username=username)
    lib_log_utils.banner_verbose(
        'Installing Wine Mono :\n'
        'WINEPREFIX="{wine_prefix}"\n'
        'WINEARCH="{wine_arch}"\n'
        'mono_msi_filename="{mono_msi_filename}"\n'
        'wine_cache_directory="{wine_cache_directory}"'.format(
            wine_prefix=wine_prefix,
            wine_arch=wine_arch,
            wine_cache_directory=wine_cache_directory,
            mono_msi_filename=mono_msi_filename),
        quiet=quiet)

    download_mono_msi_files_from_appwiz(wine_prefix=wine_prefix,
                                        username=username,
                                        force_download=False,
                                        quiet=quiet)

    command = 'WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" wine msiexec /i "{wine_cache_directory}/{mono_msi_filename}"'\
        .format(wine_prefix=wine_prefix,
                wine_arch=wine_arch,
                wine_cache_directory=wine_cache_directory,
                mono_msi_filename=mono_msi_filename)

    lib_shell.run_shell_command(command,
                                shell=True,
                                run_as_user=username,
                                pass_stdout_stderr_to_sys=True,
                                quiet=quiet)
    lib_wine.fix_wine_permissions(
        wine_prefix=wine_prefix,
        username=username)  # it is cheap, just in case
Beispiel #5
0
def get_gecko_64_filename_from_appwiz(
    wine_prefix: Union[str, pathlib.Path],
    username: str = configmagick_linux.get_current_username()
) -> pathlib.Path:
    """ Gecko 64 Bit Filename can only be read from a 64 Bit Wine Prefix
    Gecko Filename can only be extracted from wine prefixes created with wine version 4.18 upwards,
    on older version this does not work and we assume gecko-2.47


    >>> import unittest
    >>> install_wine_machine.create_wine_test_prefixes()
    >>> wine_prefix = lib_wine.get_and_check_wine_prefix('wine_test_32')
    >>> unittest.TestCase().assertRaises(RuntimeError, get_gecko_64_filename_from_appwiz, wine_prefix)

    >>> wine_prefix = lib_wine.get_and_check_wine_prefix('wine_test_64')
    >>> path_gecko_64_filename = get_gecko_64_filename_from_appwiz(wine_prefix)
    >>> assert str(path_gecko_64_filename).startswith('wine_gecko-') and str(path_gecko_64_filename).endswith('-x86_64.msi')
    """
    wine_arch = lib_wine.get_wine_arch_from_wine_prefix(
        wine_prefix=wine_prefix, username=username)
    if wine_arch == 'win32':
        raise RuntimeError(
            'can not determine Gecko 64 Bit msi Filename from a 32 Bit Wine Machine'
        )
    else:
        path_appwiz = pathlib.Path(
            wine_prefix) / 'drive_c/windows/system32/appwiz.cpl'

    if not path_appwiz.is_file():
        raise RuntimeError(
            'can not determine Gecko MSI Filename, File "{path_appwiz}" does not exist'
            .format(path_appwiz=path_appwiz))

    try:
        response = lib_shell.run_shell_command(
            'strings -d --bytes=12 --encoding=s "{path_appwiz}" | fgrep "wine_gecko" | fgrep "x86_64.msi"'
            .format(path_appwiz=path_appwiz),
            shell=True,
            quiet=True,
            use_sudo=True)
        gecko_64_filename = response.stdout
    except (subprocess.CalledProcessError, RuntimeError):
        # this happens on old wine versions, the wine_gecko-2.47-x86.msi is not present in the appwiz.cpl
        lib_log_utils.log_warning(
            'Can not determine Gecko Version from appwiz.cpl - assuming "wine_gecko-2.47-x86_64.msi"'
        )
        gecko_64_filename = 'wine_gecko-2.47-x86_64.msi'

    path_gecko_64_filename = pathlib.Path(gecko_64_filename)
    return path_gecko_64_filename
Beispiel #6
0
def install_gecko(wine_prefix: Union[
    str, pathlib.Path] = configmagick_linux.get_path_home_dir_current_user() /
                  '.wine',
                  username: str = configmagick_linux.get_current_username(),
                  quiet: bool = False) -> None:
    """
    install 32 Bit Gecko for 32/64 Bit Wine, and 64 Bit Gecko for 64 Bit Wine

    >>> install_wine_machine.create_wine_test_prefixes()
    >>> install_gecko(wine_prefix='wine_test_32', quiet=True)
    >>> install_gecko(wine_prefix='wine_test_64', quiet=True)

    """
    lib_log_utils.banner_verbose(
        'Install Gecko on WINEPREFIX="{wine_prefix}"'.format(
            wine_prefix=wine_prefix),
        quiet=quiet)
    wine_prefix = lib_wine.get_and_check_wine_prefix(
        wine_prefix, username)  # prepend /home/user if needed
    download_gecko_msi_files(wine_prefix=wine_prefix,
                             username=username,
                             quiet=True)
    wine_arch = lib_wine.get_wine_arch_from_wine_prefix(wine_prefix, username)

    if wine_arch == 'win32' or wine_arch == 'win64':
        lib_log_utils.log_verbose(
            'Install Gecko 32 Bit on WINEPREFIX="{wine_prefix}"'.format(
                wine_prefix=wine_prefix),
            quiet=quiet)
        install_gecko_32(wine_prefix=wine_prefix,
                         username=username,
                         quiet=quiet)

    if wine_arch == 'win64':
        lib_log_utils.log_verbose(
            'Install Gecko 64 Bit on WINEPREFIX="{wine_prefix}"'.format(
                wine_prefix=wine_prefix),
            quiet=quiet)
        install_gecko_64(wine_prefix=wine_prefix,
                         username=username,
                         quiet=quiet)

    lib_wine.fix_wine_permissions(
        wine_prefix=wine_prefix,
        username=username)  # it is cheap, just in case
    lib_log_utils.banner_success('Wine Gecko installed')
Beispiel #7
0
def install_gecko_by_architecture(wine_prefix: Union[str, pathlib.Path],
                                  username: str,
                                  path_gecko_msi_filename: pathlib.Path,
                                  quiet: bool = False) -> None:
    path_wine_cache = lib_wine.get_path_wine_cache_for_user(username)
    wine_arch = lib_wine.get_wine_arch_from_wine_prefix(wine_prefix, username)

    command = 'WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" wine msiexec /i "{path_wine_cache}/{path_gecko_msi_filename}"'.format(
        wine_prefix=wine_prefix,
        wine_arch=wine_arch,
        path_wine_cache=path_wine_cache,
        path_gecko_msi_filename=path_gecko_msi_filename)

    lib_shell.run_shell_command(command,
                                shell=True,
                                run_as_user=username,
                                pass_stdout_stderr_to_sys=True,
                                quiet=quiet)
def install_python_setuptools(wine_prefix: Union[
    str, pathlib.Path] = configmagick_linux.get_path_home_dir_current_user() /
                              '.wine',
                              username: str = configmagick_linux.
                              get_current_username(),
                              quiet: bool = False) -> None:

    wine_prefix = lib_wine.get_and_check_wine_prefix(wine_prefix, username)
    wine_arch = lib_wine.get_wine_arch_from_wine_prefix(
        wine_prefix=wine_prefix, username=username)
    wine_cache_directory = lib_wine.get_path_wine_cache_for_user(
        username=username)
    download_get_pip(username=username)
    command = 'WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" wine python "{wine_cache_directory}/get-pip.py"'.format(
        wine_prefix=wine_prefix,
        wine_arch=wine_arch,
        wine_cache_directory=wine_cache_directory)
    lib_shell.run_shell_command(command,
                                run_as_user=username,
                                quiet=True,
                                shell=True)
Beispiel #9
0
def get_mono_msi_filename_from_appwiz(
    wine_prefix: Union[str, pathlib.Path],
    username: str = configmagick_linux.get_current_username()
) -> pathlib.Path:
    """
    >>> install_wine_machine.create_wine_test_prefixes()
    >>> path_mono_msi_filename = get_mono_msi_filename_from_appwiz(wine_prefix='wine_test_32')
    >>> assert str(path_mono_msi_filename).startswith('wine-mono-') and str(path_mono_msi_filename).endswith('.msi')
    >>> path_mono_msi_filename = get_mono_msi_filename_from_appwiz(wine_prefix='wine_test_64')
    >>> assert str(path_mono_msi_filename).startswith('wine-mono-') and str(path_mono_msi_filename).endswith('.msi')
    """
    wine_prefix = lib_wine.get_and_check_wine_prefix(wine_prefix, username)
    wine_arch = lib_wine.get_wine_arch_from_wine_prefix(
        wine_prefix=wine_prefix, username=username)
    if wine_arch == 'win32':
        path_appwiz = wine_prefix / 'drive_c/windows/system32/appwiz.cpl'
    else:
        path_appwiz = wine_prefix / 'drive_c/windows/syswow64/appwiz.cpl'

    if not path_appwiz.is_file():
        raise RuntimeError(
            'can not determine Mono MSI Filename, File "{path_appwiz}" does not exist'
            .format(path_appwiz=path_appwiz))

    # this fails from unknown reason on travis xenial !
    response = lib_shell.run_shell_command(
        'strings -d --bytes=12 --encoding=s "{path_appwiz}" | fgrep "wine-mono-" | fgrep ".msi"'
        .format(path_appwiz=path_appwiz),
        shell=True,
        quiet=True,
        use_sudo=True)
    mono_msi_filename = response.stdout

    if not mono_msi_filename:
        raise RuntimeError(
            'can not determine Mono MSI Filename from WINEPREFIX="{wine_prefix}"'
            .format(wine_prefix=wine_prefix))
    path_mono_msi = pathlib.Path(mono_msi_filename)
    return path_mono_msi
def install_git(wine_prefix: Union[
    str, pathlib.Path] = configmagick_linux.get_path_home_dir_current_user() /
                '.wine',
                username: str = configmagick_linux.get_current_username(),
                quiet: bool = False) -> None:
    """ install git on wine

    >>> install_wine_machine.create_wine_test_prefixes()
    >>> install_git(wine_prefix='wine_test_32', quiet=True)
    >>> install_git(wine_prefix='wine_test_64', quiet=True)

    """
    configmagick_linux.full_update_and_upgrade(quiet=quiet)
    configmagick_linux.install_linux_package('p7zip-full', quiet=quiet)
    wine_prefix = lib_wine.get_and_check_wine_prefix(wine_prefix, username)
    wine_arch = lib_wine.get_wine_arch_from_wine_prefix(
        wine_prefix=wine_prefix, username=username)
    wine_cache_directory = lib_wine.get_path_wine_cache_for_user(
        username=username)
    path_git_filename = get_path_git_filename(wine_arch=wine_arch)
    lib_log_utils.banner_verbose(
        'Installing Git Portable :\n'
        'WINEPREFIX="{wine_prefix}"\n'
        'WINEARCH="{wine_arch}"\n'
        'git_filename="{path_git_filename}"\n'
        'wine_cache_directory="{wine_cache_directory}"'.format(
            wine_prefix=wine_prefix,
            wine_arch=wine_arch,
            path_git_filename=path_git_filename,
            wine_cache_directory=wine_cache_directory),
        quiet=quiet)

    download_latest_git_files_from_github_to_winecache(wine_prefix=wine_prefix,
                                                       username=username,
                                                       quiet=quiet)
    lib_log_utils.log_verbose(
        'Install "{path_git_filename}" on WINEPREFIX="{wine_prefix}"'.format(
            path_git_filename=path_git_filename, wine_prefix=wine_prefix),
        quiet=quiet)

    path_git_install_dir = wine_prefix / 'drive_c/Program Files/PortableGit'

    lib_shell.run_shell_command('rm -Rf "{path_git_install_dir}"'.format(
        path_git_install_dir=path_git_install_dir),
                                quiet=True,
                                use_sudo=True,
                                shell=True)
    # remove old installation if exists
    configmagick_linux.force_remove_directory_recursive(path_git_install_dir)
    command = '7z e {wine_cache_directory}/{path_git_filename} -o"{path_git_install_dir}" -y -bd'.format(
        wine_cache_directory=wine_cache_directory,
        path_git_filename=path_git_filename,
        path_git_install_dir=path_git_install_dir)
    lib_shell.run_shell_command(command,
                                shell=True,
                                run_as_user=username,
                                pass_stdout_stderr_to_sys=True,
                                quiet=quiet)
    lib_wine.fix_wine_permissions(
        wine_prefix=wine_prefix,
        username=username)  # it is cheap, just in case
    lib_wine.prepend_path_to_wine_registry_path(
        path_to_add='C:\\Program Files\\PortableGit',
        wine_prefix=wine_prefix,
        username=username)
    # we need to use wineconsole here
    command = 'WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" wineconsole git --version'.format(
        wine_prefix=wine_prefix, wine_arch=wine_arch)
    try:
        lib_shell.run_shell_command(command,
                                    run_as_user=username,
                                    quiet=True,
                                    shell=True)
        lib_log_utils.banner_success('Git installed')
    except subprocess.CalledProcessError:
        raise RuntimeError(
            'can not install git portable on WINEPREFIX="{wine_prefix}"'.
            format(wine_prefix=wine_prefix))
def install_python_nuget(wine_prefix: Union[
    str, pathlib.Path] = configmagick_linux.get_path_home_dir_current_user() /
                         '.wine',
                         username: str = configmagick_linux.
                         get_current_username(),
                         quiet: bool = False) -> None:
    """ install python on wine, using the nuget installer
        wine stable 4.0.2 : not working
        wine devel  4.19  : working
        wine staging 4.19 : working

    >>> install_wine_machine.create_wine_test_prefixes()
    >>> install_python_nuget(wine_prefix='wine_test_32', quiet=True)
    >>> install_python_nuget(wine_prefix='wine_test_64', quiet=True)

    >>> # test python 32 Bit installed
    >>> wine_prefix = lib_wine.get_and_check_wine_prefix(wine_prefix='wine_test_32')
    >>> wine_arch = lib_wine.get_wine_arch_from_wine_prefix(wine_prefix=wine_prefix)
    >>> command = 'WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" wine '
    >>> result = lib_shell.run_shell_command('WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" wine python --version'
    ...                                      .format(wine_prefix=wine_prefix, wine_arch=wine_arch), shell=True, quiet=True)
    >>> assert result.stdout.startswith('Python')
    >>> assert '.' in result.stdout

    >>> # test python 64 Bit installed
    >>> wine_prefix = lib_wine.get_and_check_wine_prefix(wine_prefix='wine_test_64')
    >>> wine_arch = lib_wine.get_wine_arch_from_wine_prefix(wine_prefix=wine_prefix)
    >>> command = 'WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" wine '
    >>> result = lib_shell.run_shell_command('WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" wine python --version'
    ...                                      .format(wine_prefix=wine_prefix, wine_arch=wine_arch), shell=True, quiet=True)
    >>> assert result.stdout.startswith('Python')
    >>> assert '.' in result.stdout

    """
    wine_prefix = lib_wine.get_and_check_wine_prefix(wine_prefix, username)
    wine_arch = lib_wine.get_wine_arch_from_wine_prefix(
        wine_prefix=wine_prefix, username=username)
    if wine_arch == 'win32':
        python_version = 'pythonx86'
    else:
        python_version = 'python'

    wine_cache_directory = lib_wine.get_path_wine_cache_for_user(
        username=username)
    path_nuget_filename = pathlib.Path('nuget.exe')
    lib_log_utils.banner_verbose(
        'Installing Python :\n'
        'WINEPREFIX="{wine_prefix}"\n'
        'WINEARCH="{wine_arch}"\n'
        'wine_cache_directory="{wine_cache_directory}"'.format(
            wine_prefix=wine_prefix,
            wine_arch=wine_arch,
            wine_cache_directory=wine_cache_directory),
        quiet=quiet)

    download_nuget(username=username)

    lib_log_utils.log_verbose(
        'Install Python on WINEPREFIX="{wine_prefix}"'.format(
            wine_prefix=wine_prefix),
        quiet=quiet)

    command = 'DISPLAY="{display}" WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" '\
              'wineconsole "{wine_cache_directory}/{path_nuget_filename}" '\
              'install {python_version} -ExcludeVersion -OutputDirectory "C:\\Program Files"'\
        .format(display=configmagick_linux.get_env_display(),
                wine_prefix=wine_prefix,
                wine_arch=wine_arch,
                wine_cache_directory=wine_cache_directory,
                path_nuget_filename=path_nuget_filename,
                python_version=python_version)

    lib_shell.run_shell_command(command,
                                shell=True,
                                run_as_user=username,
                                pass_stdout_stderr_to_sys=True,
                                quiet=quiet)
    lib_wine.fix_wine_permissions(wine_prefix=wine_prefix, username=username)
    lib_wine.prepend_path_to_wine_registry_path(
        'C:\\Program Files\\{python_version}\\tools'.format(
            python_version=python_version),
        wine_prefix=wine_prefix,
        username=username)

    command = 'WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" wine python --version'.format(
        wine_prefix=wine_prefix, wine_arch=wine_arch)
    try:
        result = lib_shell.run_shell_command(command,
                                             run_as_user=username,
                                             quiet=True,
                                             shell=True)
        assert result.stdout.startswith('Python')
        lib_log_utils.banner_success('{python_version} installed OK'.format(
            python_version=result.stdout))
    except (subprocess.CalledProcessError, AssertionError):
        raise RuntimeError(
            'can not install Python on WINEPREFIX="{wine_prefix}"'.format(
                wine_prefix=wine_prefix))
def install_python(wine_prefix: Union[
    str, pathlib.Path] = configmagick_linux.get_path_home_dir_current_user() /
                   '.wine',
                   username: str = configmagick_linux.get_current_username(),
                   python_version: str = 'latest',
                   quiet: bool = False) -> None:
    """ install python on wine, using the normal installer - unfortunately this does not work on travis

    Parameter:
        python_version : 'latest' or valid Version number, like '3.8.0'

    >>> install_wine_machine.create_wine_test_prefixes()
    >>> install_python(wine_prefix='wine_test_32', quiet=True)
    >>> install_python(wine_prefix='wine_test_64', quiet=True)

    >>> # test python 32 Bit installed
    >>> wine_prefix = lib_wine.get_and_check_wine_prefix(wine_prefix='wine_test_32')
    >>> wine_arch = lib_wine.get_wine_arch_from_wine_prefix(wine_prefix=wine_prefix)
    >>> command = 'WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" wine '
    >>> result = lib_shell.run_shell_command('WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" wine python --version'
    ...                                      .format(wine_prefix=wine_prefix, wine_arch=wine_arch), shell=True, quiet=True)
    >>> assert result.stdout.startswith('Python')
    >>> assert '.' in result.stdout

    >>> # test python 64 Bit installed
    >>> wine_prefix = lib_wine.get_and_check_wine_prefix(wine_prefix='wine_test_64')
    >>> wine_arch = lib_wine.get_wine_arch_from_wine_prefix(wine_prefix=wine_prefix)
    >>> command = 'WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" wine '
    >>> result = lib_shell.run_shell_command('WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" wine python --version'
    ...                                      .format(wine_prefix=wine_prefix, wine_arch=wine_arch), shell=True, quiet=True)
    >>> assert result.stdout.startswith('Python')
    >>> assert '.' in result.stdout

    """
    wine_prefix = lib_wine.get_and_check_wine_prefix(wine_prefix, username)
    wine_arch = lib_wine.get_wine_arch_from_wine_prefix(
        wine_prefix=wine_prefix, username=username)
    if python_version == 'latest':
        python_version = get_latest_python_version()
    path_python_filename = get_path_python_exe_filename(version=python_version,
                                                        arch=wine_arch)
    wine_cache_directory = lib_wine.get_path_wine_cache_for_user(
        username=username)
    lib_log_utils.banner_verbose(
        'Installing Python :\n'
        'WINEPREFIX="{wine_prefix}"\n'
        'WINEARCH="{wine_arch}"\n'
        'python_filename="{path_python_filename}"\n'
        'wine_cache_directory="{wine_cache_directory}"'.format(
            wine_prefix=wine_prefix,
            wine_arch=wine_arch,
            wine_cache_directory=wine_cache_directory,
            path_python_filename=path_python_filename),
        quiet=quiet)

    download_python_exe_file(python_version=python_version,
                             wine_prefix=wine_prefix,
                             username=username)

    lib_log_utils.log_verbose(
        'Install "{path_python_filename}" on WINEPREFIX="{wine_prefix}"'.
        format(path_python_filename=path_python_filename,
               wine_prefix=wine_prefix),
        quiet=quiet)

    command = 'DISPLAY="{display}" WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" '\
              'wineconsole "{wine_cache_directory}/{path_python_filename}" '\
              '/quiet InstallAllUsers=1 PrependPath=1 Include_test=0'\
        .format(wine_prefix=wine_prefix,
                wine_arch=wine_arch,
                wine_cache_directory=wine_cache_directory,
                path_python_filename=path_python_filename,
                display=configmagick_linux.get_env_display())

    lib_shell.run_shell_command(command,
                                shell=True,
                                run_as_user=username,
                                pass_stdout_stderr_to_sys=True,
                                quiet=quiet)
    lib_wine.fix_wine_permissions(wine_prefix=wine_prefix, username=username)

    command = 'WINEPREFIX="{wine_prefix}" WINEARCH="{wine_arch}" wine python --version'.format(
        wine_prefix=wine_prefix, wine_arch=wine_arch)
    try:
        result = lib_shell.run_shell_command(command,
                                             run_as_user=username,
                                             quiet=True,
                                             shell=True)
        assert result.stdout.startswith('Python')
        lib_log_utils.banner_success('{python_version} installed OK'.format(
            python_version=result.stdout))
    except (subprocess.CalledProcessError, AssertionError):
        raise RuntimeError(
            'can not install Python on WINEPREFIX="{wine_prefix}"'.format(
                wine_prefix=wine_prefix))
def download_python_exe_file(
        python_version: str,
        wine_prefix: Union[str, pathlib.Path],
        username: str = configmagick_linux.get_current_username(),
        force_download: bool = False) -> None:
    """ Downloads the Python Exe File to the WineCache directory

    >>> install_wine_machine.create_wine_test_prefixes()
    >>> wine_prefix = configmagick_linux.get_path_home_dir_current_user() / 'wine_test_32'
    >>> wine_arch = lib_wine.get_wine_arch_from_wine_prefix(wine_prefix=wine_prefix)
    >>> username = configmagick_linux.get_current_username()
    >>> python_version = get_latest_python_version()
    >>> path_python_filename = get_path_python_exe_filename(version=python_version, arch=wine_arch)
    >>> path_downloaded_file = configmagick_linux.get_path_home_dir_current_user() / '.cache/wine' / path_python_filename
    >>> if path_downloaded_file.is_file():
    ...    path_downloaded_file.unlink()
    >>> download_python_exe_file(python_version=python_version, wine_prefix=wine_prefix, username=username, force_download=True)
    >>> assert path_downloaded_file.is_file()
    >>> download_python_exe_file(python_version=python_version, wine_prefix=wine_prefix, username=username, force_download=False)
    >>> assert path_downloaded_file.is_file()

    >>> wine_prefix = configmagick_linux.get_path_home_dir_current_user() / 'wine_test_64'
    >>> wine_arch = lib_wine.get_wine_arch_from_wine_prefix(wine_prefix=wine_prefix)
    >>> python_version = get_latest_python_version()
    >>> path_python_filename = get_path_python_exe_filename(version=python_version, arch=wine_arch)
    >>> path_downloaded_file = configmagick_linux.get_path_home_dir_current_user() / '.cache/wine' / path_python_filename
    >>> if path_downloaded_file.is_file():
    ...    path_downloaded_file.unlink()
    >>> download_python_exe_file(python_version=python_version, wine_prefix=wine_prefix, username=username, force_download=True)
    >>> assert path_downloaded_file.is_file()
    >>> download_python_exe_file(python_version=python_version, wine_prefix=wine_prefix, username=username, force_download=False)
    >>> assert path_downloaded_file.is_file()

    """
    wine_prefix = lib_wine.get_and_check_wine_prefix(wine_prefix, username)
    wine_arch = lib_wine.get_wine_arch_from_wine_prefix(
        wine_prefix=wine_prefix, username=username)
    python_download_link = get_python_exe_download_link(version=python_version,
                                                        arch=wine_arch)
    python_backup_download_link = get_python_exe_backup_download_link(
        version=python_version, arch=wine_arch)
    path_python_filename = get_path_python_exe_filename(version=python_version,
                                                        arch=wine_arch)

    if lib_wine.is_file_in_wine_cache(filename=path_python_filename,
                                      username=username) or force_download:
        if force_download:
            lib_wine.remove_file_from_winecache(filename=path_python_filename,
                                                username=username)
        else:
            return

    try:
        lib_wine.download_file_to_winecache(download_link=python_download_link,
                                            filename=path_python_filename,
                                            username=username)
    except subprocess.CalledProcessError:
        lib_wine.download_file_to_winecache(
            download_link=python_backup_download_link,
            filename=path_python_filename,
            username=username)