diff --git a/src/core/utils/misc.cpp b/src/core/utils/misc.cpp index 5e0e80806..97f5508dd 100644 --- a/src/core/utils/misc.cpp +++ b/src/core/utils/misc.cpp @@ -68,6 +68,7 @@ const int UNLEN = 256; #include "core/utils/string.h" #include "core/unicodestrings.h" +#include "core/logger.h" #include "misc.h" static struct { const char *source; const char *comment; } units[] = { @@ -241,6 +242,11 @@ int Utils::Misc::pythonVersion() python_proc.start("python3", QStringList() << "--version", QIODevice::ReadOnly); if (python_proc.waitForFinished()) { if (python_proc.exitCode() == 0) { + QByteArray output = python_proc.readAllStandardOutput(); + if (output.isEmpty()) + output = python_proc.readAllStandardError(); + const QByteArray version_str = output.split(' ').last(); + Logger::instance()->addMessage(QCoreApplication::translate("misc", "Python version: %1").arg(QString(version_str)), Log::INFO); version = 3; return 3; } @@ -248,6 +254,11 @@ int Utils::Misc::pythonVersion() python_proc.start("python2", QStringList() << "--version", QIODevice::ReadOnly); if (python_proc.waitForFinished()) { if (python_proc.exitCode() == 0) { + QByteArray output = python_proc.readAllStandardOutput(); + if (output.isEmpty()) + output = python_proc.readAllStandardError(); + const QByteArray version_str = output.split(' ').last(); + Logger::instance()->addMessage(QCoreApplication::translate("misc", "Python version: %1").arg(QString(version_str)), Log::INFO); version = 2; return 2; } @@ -260,7 +271,7 @@ int Utils::Misc::pythonVersion() if (output.isEmpty()) output = python_proc.readAllStandardError(); const QByteArray version_str = output.split(' ').last(); - qDebug() << "Python version is:" << version_str.trimmed(); + Logger::instance()->addMessage(QCoreApplication::translate("misc", "Python version: %1").arg(QString(version_str)), Log::INFO); if (version_str.startsWith("3.")) version = 3; else @@ -285,6 +296,32 @@ QString Utils::Misc::pythonExecutable() return "python"; } +/** + * Returns the complete python version + * eg 2.7.9 + * Make sure to have setup python first + */ +QString Utils::Misc::pythonVersionComplete() { + static QString version; + + if (version.isEmpty()) { + if (pythonVersion() < 0) + return QString(); + + QProcess python_proc; + python_proc.start(pythonExecutable(), QStringList() << "--version", QIODevice::ReadOnly); + if (!python_proc.waitForFinished()) return QString(); + if (python_proc.exitCode() < 0) return QString(); + QByteArray output = python_proc.readAllStandardOutput(); + if (output.isEmpty()) + output = python_proc.readAllStandardError(); + const QByteArray version_str = output.split(' ').last(); + version = version_str; + } + + return version; +} + // return best userfriendly storage unit (B, KiB, MiB, GiB, TiB) // use Binary prefix standards from IEC 60027-2 // see http://en.wikipedia.org/wiki/Kilobyte diff --git a/src/core/utils/misc.h b/src/core/utils/misc.h index dc003674f..dd390fb06 100644 --- a/src/core/utils/misc.h +++ b/src/core/utils/misc.h @@ -57,6 +57,7 @@ namespace Utils #endif int pythonVersion(); QString pythonExecutable(); + QString pythonVersionComplete(); // return best userfriendly storage unit (B, KiB, MiB, GiB, TiB) // use Binary prefix standards from IEC 60027-2 // see http://en.wikipedia.org/wiki/Kilobyte diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp index db6328e41..bf2853458 100644 --- a/src/gui/mainwindow.cpp +++ b/src/gui/mainwindow.cpp @@ -104,9 +104,7 @@ MainWindow::MainWindow(QWidget *parent) , m_posInitialized(false) , force_exit(false) , unlockDlgShowing(false) -#ifdef Q_OS_WIN , has_python(false) -#endif { setupUi(this); @@ -1366,19 +1364,73 @@ void MainWindow::on_actionRSS_Reader_triggered() void MainWindow::on_actionSearch_engine_triggered() { -#ifdef Q_OS_WIN if (!has_python && actionSearch_engine->isChecked()) { - bool res = false; + int pythonVersion = Utils::Misc::pythonVersion(); // Check if python is already in PATH - if (Utils::Misc::pythonVersion() > 0) - res = true; - else - res = addPythonPathToEnv(); + if (pythonVersion > 0) + Logger::instance()->addMessage(tr("Python found in %1").arg("PATH"), Log::INFO); // Prevent translators from messing with PATH +#ifdef Q_OS_WIN + else if (addPythonPathToEnv()) + pythonVersion = Utils::Misc::pythonVersion(); +#endif + + bool res = false; + + if (pythonVersion == 2) { + // Check if python 2.7.x or later + QString version = Utils::Misc::pythonVersionComplete().trimmed(); + QStringList splitted = version.split('.'); + if (splitted.size() > 1) { + int middleVer = splitted.at(1).toInt(); + if (middleVer < 7) { + QMessageBox::information(this, tr("Old Python Interpreter"), tr("Your Python version is %1, which is too old. You need at least version 2.7.0 for python2 or 3.3.0 for python3.").arg(version)); + actionSearch_engine->setChecked(false); + Preferences::instance()->setSearchEnabled(false); + return; + } + else { + res = true; + } + } + else { + QMessageBox::information(this, tr("Undetermined Python version"), tr("Couldn't decode your Python version: %1").arg(version)); + actionSearch_engine->setChecked(false); + Preferences::instance()->setSearchEnabled(false); + return; + } + } + else if (pythonVersion == 3) { + // Check if python 3.3.x or later + QString version = Utils::Misc::pythonVersionComplete().trimmed(); + QStringList splitted = version.split('.'); + if (splitted.size() > 1) { + int middleVer = splitted.at(1).toInt(); + if (middleVer < 3) { + QMessageBox::information(this, tr("Old Python Interpreter"), tr("Your Python version %1 is outdated. Please upgrade to latest version for search engines to work. Minimum requirement: 2.7.0/3.3.0.").arg(version)); + actionSearch_engine->setChecked(false); + Preferences::instance()->setSearchEnabled(false); + return; + } + else { + res = true; + } + } + else { + QMessageBox::information(this, tr("Undetermined Python version"), tr("Couldn't determine your Python version (%1). Search engine disabled.").arg(version)); + actionSearch_engine->setChecked(false); + Preferences::instance()->setSearchEnabled(false); + return; + } + } + else { + res = false; + } if (res) { has_python = true; } +#ifdef Q_OS_WIN else if (QMessageBox::question(this, tr("Missing Python Interpreter"), tr("Python is required to use the search engine but it does not seem to be installed.\nDo you want to install it now?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) { @@ -1388,13 +1440,16 @@ void MainWindow::on_actionSearch_engine_triggered() Preferences::instance()->setSearchEnabled(false); return; } +#endif else { +#ifndef Q_OS_WIN + QMessageBox::information(this, tr("Missing Python Interpreter"), tr("Python is required to use the search engine but it does not seem to be installed.")); +#endif actionSearch_engine->setChecked(false); Preferences::instance()->setSearchEnabled(false); return; } } -#endif displaySearchTab(actionSearch_engine->isChecked()); } @@ -1554,6 +1609,7 @@ bool MainWindow::addPythonPathToEnv() return true; QString python_path = Preferences::getPythonPath(); if (!python_path.isEmpty()) { + Logger::instance()->addMessage(tr("Python found in %1").arg(Utils::Fs::toNativePath(python_path)), Log::INFO); // Add it to PATH envvar QString path_envar = QString::fromLocal8Bit(qgetenv("PATH").constData()); if (path_envar.isNull()) @@ -1595,6 +1651,8 @@ void MainWindow::pythonDownloadSuccess(const QString &url, const QString &filePa // Reload search engine has_python = addPythonPathToEnv(); if (has_python) { + // Make it print the version to Log + Utils::Misc::pythonVersion(); actionSearch_engine->setChecked(true); displaySearchTab(true); } diff --git a/src/gui/mainwindow.h b/src/gui/mainwindow.h index cd5075923..77de76935 100644 --- a/src/gui/mainwindow.h +++ b/src/gui/mainwindow.h @@ -202,9 +202,7 @@ private: #if defined(Q_OS_WIN) || defined(Q_OS_MAC) QTimer programUpdateTimer; #endif -#ifdef Q_OS_WIN bool has_python; -#endif QMenu* toolbarMenu; private slots: