Skip to content

Commit

Permalink
Improve Python installation process
Browse files Browse the repository at this point in the history
Instead of waiting it to complete, now it will react on installation process finish.
Also add more logging.

PR #21863.
  • Loading branch information
Chocobo1 authored Nov 19, 2024
1 parent 6578fd0 commit 7f901a8
Showing 1 changed file with 42 additions and 22 deletions.
64 changes: 42 additions & 22 deletions src/gui/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ namespace
#define EXECUTIONLOG_SETTINGS_KEY(name) (SETTINGS_KEY(u"Log/"_s) name)

const std::chrono::seconds PREVENT_SUSPEND_INTERVAL {60};

const QString PYTHON_INSTALLER_URL = u"https://www.python.org/ftp/python/3.13.0/python-3.13.0-amd64.exe"_s;
}

MainWindow::MainWindow(IGUIApplication *app, const WindowState initialState, const QString &titleSuffix)
Expand Down Expand Up @@ -1887,50 +1889,68 @@ void MainWindow::checkProgramUpdate(const bool invokedByUser)
#ifdef Q_OS_WIN
void MainWindow::installPython()
{
setCursor(QCursor(Qt::WaitCursor));
m_ui->actionSearchWidget->setEnabled(false);
m_ui->actionSearchWidget->setToolTip(tr("Python installation in progress..."));
setCursor(Qt::WaitCursor);
// Download python
const auto installerURL = u"https://www.python.org/ftp/python/3.13.0/python-3.13.0-amd64.exe"_s;
Net::DownloadManager::instance()->download(
Net::DownloadRequest(installerURL).saveToFile(true)
Net::DownloadRequest(PYTHON_INSTALLER_URL).saveToFile(true)
, Preferences::instance()->useProxyForGeneralPurposes()
, this, &MainWindow::pythonDownloadFinished);
}

void MainWindow::pythonDownloadFinished(const Net::DownloadResult &result)
{
const auto restoreWidgetsState = [this]
{
m_ui->actionSearchWidget->setEnabled(true);
m_ui->actionSearchWidget->setToolTip({});
setCursor(Qt::ArrowCursor);
};

if (result.status != Net::DownloadStatus::Success)
{
setCursor(QCursor(Qt::ArrowCursor));
restoreWidgetsState();
QMessageBox::warning(
this, tr("Download error")
, tr("Python setup could not be downloaded, reason: %1.\nPlease install it manually.")
.arg(result.errorString));
return;
}

setCursor(QCursor(Qt::ArrowCursor));
QProcess installer;
qDebug("Launching Python installer in passive mode...");

const Path exePath = result.filePath + u".exe";
Utils::Fs::renameFile(result.filePath, exePath);
installer.start(exePath.toString(), {u"/passive"_s});

// Wait for setup to complete
installer.waitForFinished(10 * 60 * 1000);
// launch installer
auto *installer = new QProcess(this);
installer->connect(installer, &QProcess::finished, this, [this, exePath, installer, restoreWidgetsState](const int exitCode, const QProcess::ExitStatus exitStatus)
{
restoreWidgetsState();
installer->deleteLater();

qDebug("Installer stdout: %s", installer.readAllStandardOutput().data());
qDebug("Installer stderr: %s", installer.readAllStandardError().data());
qDebug("Setup should be complete!");
if ((exitStatus == QProcess::NormalExit) && (exitCode == 0))
{
LogMsg(tr("Python installation success."), Log::INFO);

// Delete temp file
Utils::Fs::removeFile(exePath);
// Delete installer
Utils::Fs::removeFile(exePath);

// Reload search engine
if (Utils::ForeignApps::pythonInfo().isSupportedVersion())
{
m_ui->actionSearchWidget->setChecked(true);
displaySearchTab(true);
}
// Reload search engine
if (Utils::ForeignApps::pythonInfo().isSupportedVersion())
{
m_ui->actionSearchWidget->setChecked(true);
displaySearchTab(true);
}
}
else
{
const QString errorInfo = (exitStatus == QProcess::NormalExit)
? tr("Exit code: %1.").arg(QString::number(exitCode))
: tr("Reason: installer crashed.");
LogMsg(u"%1 %2"_s.arg(tr("Python installation failed."), errorInfo), Log::WARNING);
}
});
LogMsg(tr("Launching Python installer. File: \"%1\".").arg(exePath.toString()), Log::INFO);
installer->start(exePath.toString(), {u"/passive"_s});
}
#endif // Q_OS_WIN

0 comments on commit 7f901a8

Please sign in to comment.