mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-06 21:21:24 -07:00
WINDOWS: Check for python before creating the search engine tab. Prevents the creation of python specific files in the user's PC if no python is found. Closes #1370.
This commit is contained in:
parent
5528f60a15
commit
0799dc293c
5 changed files with 105 additions and 95 deletions
|
@ -85,6 +85,9 @@ void qt_mac_set_dock_menu(QMenu *menu);
|
||||||
#include "programupdater.h"
|
#include "programupdater.h"
|
||||||
#endif
|
#endif
|
||||||
#include "powermanagement.h"
|
#include "powermanagement.h"
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#include "downloadthread.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
|
|
||||||
|
@ -98,7 +101,11 @@ using namespace libtorrent;
|
||||||
*****************************************************/
|
*****************************************************/
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
MainWindow::MainWindow(QWidget *parent, const QStringList& torrentCmdLine) : QMainWindow(parent), m_posInitialized(false), force_exit(false) {
|
MainWindow::MainWindow(QWidget *parent, const QStringList& torrentCmdLine) : QMainWindow(parent), m_posInitialized(false), force_exit(false)
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
, has_python(false)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
|
||||||
Preferences* const pref = Preferences::instance();
|
Preferences* const pref = Preferences::instance();
|
||||||
|
@ -249,9 +256,10 @@ MainWindow::MainWindow(QWidget *parent, const QStringList& torrentCmdLine) : QMa
|
||||||
actionRSS_Reader->setChecked(pref->isRSSEnabled());
|
actionRSS_Reader->setChecked(pref->isRSSEnabled());
|
||||||
actionSearch_engine->setChecked(pref->isSearchEnabled());
|
actionSearch_engine->setChecked(pref->isSearchEnabled());
|
||||||
actionExecution_Logs->setChecked(pref->isExecutionLogEnabled());
|
actionExecution_Logs->setChecked(pref->isExecutionLogEnabled());
|
||||||
displaySearchTab(actionSearch_engine->isChecked());
|
|
||||||
displayRSSTab(actionRSS_Reader->isChecked());
|
displayRSSTab(actionRSS_Reader->isChecked());
|
||||||
on_actionExecution_Logs_triggered(actionExecution_Logs->isChecked());
|
on_actionExecution_Logs_triggered(actionExecution_Logs->isChecked());
|
||||||
|
if (actionSearch_engine->isChecked())
|
||||||
|
QTimer::singleShot(0, this, SLOT(on_actionSearch_engine_triggered()));
|
||||||
|
|
||||||
// Auto shutdown actions
|
// Auto shutdown actions
|
||||||
QActionGroup * autoShutdownGroup = new QActionGroup(this);
|
QActionGroup * autoShutdownGroup = new QActionGroup(this);
|
||||||
|
@ -1317,7 +1325,27 @@ void MainWindow::on_actionRSS_Reader_triggered() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionSearch_engine_triggered() {
|
void MainWindow::on_actionSearch_engine_triggered() {
|
||||||
Preferences::instance()->setSearchEnabled(actionSearch_engine->isChecked());
|
#ifdef Q_OS_WIN
|
||||||
|
if (!has_python && actionSearch_engine->isChecked()) {
|
||||||
|
bool res = addPythonPathToEnv();
|
||||||
|
if (res)
|
||||||
|
has_python = true;
|
||||||
|
else if (QMessageBox::question(this, tr("Missing Python Interpreter"),
|
||||||
|
tr("Python 2.x 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) {
|
||||||
|
// Download and Install Python
|
||||||
|
installPython();
|
||||||
|
actionSearch_engine->setChecked(false);
|
||||||
|
Preferences::instance()->setSearchEnabled(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
actionSearch_engine->setChecked(false);
|
||||||
|
Preferences::instance()->setSearchEnabled(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
displaySearchTab(actionSearch_engine->isChecked());
|
displaySearchTab(actionSearch_engine->isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1467,3 +1495,65 @@ void MainWindow::checkProgramUpdate() {
|
||||||
updater->checkForUpdates();
|
updater->checkForUpdates();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
bool MainWindow::addPythonPathToEnv() {
|
||||||
|
if (has_python)
|
||||||
|
return true;
|
||||||
|
QString python_path = Preferences::getPythonPath();
|
||||||
|
if (!python_path.isEmpty()) {
|
||||||
|
// Add it to PATH envvar
|
||||||
|
QString path_envar = QString::fromLocal8Bit(qgetenv("PATH").constData());
|
||||||
|
if (path_envar.isNull()) {
|
||||||
|
path_envar = "";
|
||||||
|
}
|
||||||
|
path_envar = python_path+";"+path_envar;
|
||||||
|
qDebug("New PATH envvar is: %s", qPrintable(path_envar));
|
||||||
|
qputenv("PATH", fsutils::toNativePath(path_envar).toLocal8Bit());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::installPython() {
|
||||||
|
setCursor(QCursor(Qt::WaitCursor));
|
||||||
|
// Download python
|
||||||
|
DownloadThread *pydownloader = new DownloadThread(this);
|
||||||
|
connect(pydownloader, SIGNAL(downloadFinished(QString,QString)), this, SLOT(pythonDownloadSuccess(QString,QString)));
|
||||||
|
connect(pydownloader, SIGNAL(downloadFailure(QString,QString)), this, SLOT(pythonDownloadFailure(QString,QString)));
|
||||||
|
pydownloader->downloadUrl("http://python.org/ftp/python/2.7.3/python-2.7.3.msi");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::pythonDownloadSuccess(QString url, QString file_path) {
|
||||||
|
setCursor(QCursor(Qt::ArrowCursor));
|
||||||
|
Q_UNUSED(url);
|
||||||
|
QFile::rename(file_path, file_path+".msi");
|
||||||
|
QProcess installer;
|
||||||
|
qDebug("Launching Python installer in passive mode...");
|
||||||
|
|
||||||
|
installer.start("msiexec.exe /passive /i " + fsutils::toNativePath(file_path) + ".msi");
|
||||||
|
// Wait for setup to complete
|
||||||
|
installer.waitForFinished();
|
||||||
|
|
||||||
|
qDebug("Installer stdout: %s", installer.readAllStandardOutput().data());
|
||||||
|
qDebug("Installer stderr: %s", installer.readAllStandardError().data());
|
||||||
|
qDebug("Setup should be complete!");
|
||||||
|
// Delete temp file
|
||||||
|
fsutils::forceRemove(file_path);
|
||||||
|
// Reload search engine
|
||||||
|
has_python = addPythonPathToEnv();
|
||||||
|
if (has_python) {
|
||||||
|
actionSearch_engine->setChecked(true);
|
||||||
|
Preferences::instance()->setSearchEnabled(true);
|
||||||
|
displaySearchTab(true);
|
||||||
|
}
|
||||||
|
sender()->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::pythonDownloadFailure(QString url, QString error) {
|
||||||
|
Q_UNUSED(url);
|
||||||
|
setCursor(QCursor(Qt::ArrowCursor));
|
||||||
|
QMessageBox::warning(this, tr("Download error"), tr("Python setup could not be downloaded, reason: %1.\nPlease install it manually.").arg(error));
|
||||||
|
sender()->deleteLater();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -152,6 +152,12 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QIcon getSystrayIcon() const;
|
QIcon getSystrayIcon() const;
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
bool addPythonPathToEnv();
|
||||||
|
void installPython();
|
||||||
|
void pythonDownloadSuccess(QString url, QString file_path);
|
||||||
|
void pythonDownloadFailure(QString url, QString error);
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QFileSystemWatcher *executable_watcher;
|
QFileSystemWatcher *executable_watcher;
|
||||||
|
@ -200,6 +206,9 @@ private:
|
||||||
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
|
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
|
||||||
QTimer programUpdateTimer;
|
QTimer programUpdateTimer;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
bool has_python;
|
||||||
|
#endif
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_actionSearch_engine_triggered();
|
void on_actionSearch_engine_triggered();
|
||||||
|
|
|
@ -49,7 +49,6 @@
|
||||||
|
|
||||||
#include "searchengine.h"
|
#include "searchengine.h"
|
||||||
#include "qbtsession.h"
|
#include "qbtsession.h"
|
||||||
#include "downloadthread.h"
|
|
||||||
#include "fs_utils.h"
|
#include "fs_utils.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "preferences.h"
|
#include "preferences.h"
|
||||||
|
@ -79,9 +78,6 @@ SearchEngine::SearchEngine(MainWindow* parent)
|
||||||
// Boolean initialization
|
// Boolean initialization
|
||||||
search_stopped = false;
|
search_stopped = false;
|
||||||
// Creating Search Process
|
// Creating Search Process
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
has_python = addPythonPathToEnv();
|
|
||||||
#endif
|
|
||||||
searchProcess = new QProcess(this);
|
searchProcess = new QProcess(this);
|
||||||
searchProcess->setEnvironment(QProcess::systemEnvironment());
|
searchProcess->setEnvironment(QProcess::systemEnvironment());
|
||||||
connect(searchProcess, SIGNAL(started()), this, SLOT(searchStarted()));
|
connect(searchProcess, SIGNAL(started()), this, SLOT(searchStarted()));
|
||||||
|
@ -93,11 +89,7 @@ SearchEngine::SearchEngine(MainWindow* parent)
|
||||||
connect(searchTimeout, SIGNAL(timeout()), this, SLOT(on_search_button_clicked()));
|
connect(searchTimeout, SIGNAL(timeout()), this, SLOT(on_search_button_clicked()));
|
||||||
// Update nova.py search plugin if necessary
|
// Update nova.py search plugin if necessary
|
||||||
updateNova();
|
updateNova();
|
||||||
supported_engines = new SupportedEngines(
|
supported_engines = new SupportedEngines();
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
has_python
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
// Fill in category combobox
|
// Fill in category combobox
|
||||||
fillCatCombobox();
|
fillCatCombobox();
|
||||||
|
|
||||||
|
@ -114,65 +106,6 @@ void SearchEngine::fillCatCombobox() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
bool SearchEngine::addPythonPathToEnv() {
|
|
||||||
QString python_path = Preferences::getPythonPath();
|
|
||||||
if (!python_path.isEmpty()) {
|
|
||||||
// Add it to PATH envvar
|
|
||||||
QString path_envar = QString::fromLocal8Bit(qgetenv("PATH").constData());
|
|
||||||
if (path_envar.isNull()) {
|
|
||||||
path_envar = "";
|
|
||||||
}
|
|
||||||
path_envar = python_path+";"+path_envar;
|
|
||||||
qDebug("New PATH envvar is: %s", qPrintable(path_envar));
|
|
||||||
qputenv("PATH", fsutils::toNativePath(path_envar).toLocal8Bit());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SearchEngine::installPython() {
|
|
||||||
setCursor(QCursor(Qt::WaitCursor));
|
|
||||||
// Download python
|
|
||||||
DownloadThread *pydownloader = new DownloadThread(this);
|
|
||||||
connect(pydownloader, SIGNAL(downloadFinished(QString,QString)), this, SLOT(pythonDownloadSuccess(QString,QString)));
|
|
||||||
connect(pydownloader, SIGNAL(downloadFailure(QString,QString)), this, SLOT(pythonDownloadFailure(QString,QString)));
|
|
||||||
pydownloader->downloadUrl("http://python.org/ftp/python/2.7.3/python-2.7.3.msi");
|
|
||||||
}
|
|
||||||
|
|
||||||
void SearchEngine::pythonDownloadSuccess(QString url, QString file_path) {
|
|
||||||
setCursor(QCursor(Qt::ArrowCursor));
|
|
||||||
Q_UNUSED(url);
|
|
||||||
QFile::rename(file_path, file_path+".msi");
|
|
||||||
QProcess installer;
|
|
||||||
qDebug("Launching Python installer in passive mode...");
|
|
||||||
|
|
||||||
installer.start("msiexec.exe /passive /i " + fsutils::toNativePath(file_path) + ".msi");
|
|
||||||
// Wait for setup to complete
|
|
||||||
installer.waitForFinished();
|
|
||||||
|
|
||||||
qDebug("Installer stdout: %s", installer.readAllStandardOutput().data());
|
|
||||||
qDebug("Installer stderr: %s", installer.readAllStandardError().data());
|
|
||||||
qDebug("Setup should be complete!");
|
|
||||||
// Reload search engine
|
|
||||||
has_python = addPythonPathToEnv();
|
|
||||||
if (has_python) {
|
|
||||||
supported_engines->update();
|
|
||||||
// Launch the search again
|
|
||||||
on_search_button_clicked();
|
|
||||||
}
|
|
||||||
// Delete temp file
|
|
||||||
fsutils::forceRemove(file_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SearchEngine::pythonDownloadFailure(QString url, QString error) {
|
|
||||||
Q_UNUSED(url);
|
|
||||||
setCursor(QCursor(Qt::ArrowCursor));
|
|
||||||
QMessageBox::warning(this, tr("Download error"), tr("Python setup could not be downloaded, reason: %1.\nPlease install it manually.").arg(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QString SearchEngine::selectedCategory() const {
|
QString SearchEngine::selectedCategory() const {
|
||||||
return comboCategory->itemData(comboCategory->currentIndex()).toString();
|
return comboCategory->itemData(comboCategory->currentIndex()).toString();
|
||||||
}
|
}
|
||||||
|
@ -226,17 +159,6 @@ void SearchEngine::giveFocusToSearchInput() {
|
||||||
|
|
||||||
// Function called when we click on search button
|
// Function called when we click on search button
|
||||||
void SearchEngine::on_search_button_clicked() {
|
void SearchEngine::on_search_button_clicked() {
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
if (!has_python) {
|
|
||||||
if (QMessageBox::question(this, tr("Missing Python Interpreter"),
|
|
||||||
tr("Python 2.x 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) {
|
|
||||||
// Download and Install Python
|
|
||||||
installPython();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (searchProcess->state() != QProcess::NotRunning) {
|
if (searchProcess->state() != QProcess::NotRunning) {
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
searchProcess->kill();
|
searchProcess->kill();
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
#include "searchtab.h"
|
#include "searchtab.h"
|
||||||
#include "supportedengines.h"
|
#include "supportedengines.h"
|
||||||
|
|
||||||
class DownloadThread;
|
|
||||||
class SearchEngine;
|
class SearchEngine;
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
class LineEdit;
|
class LineEdit;
|
||||||
|
@ -105,12 +104,6 @@ protected slots:
|
||||||
void downloadFinished(int exitcode, QProcess::ExitStatus);
|
void downloadFinished(int exitcode, QProcess::ExitStatus);
|
||||||
void fillCatCombobox();
|
void fillCatCombobox();
|
||||||
void searchTextEdited(QString);
|
void searchTextEdited(QString);
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
bool addPythonPathToEnv();
|
|
||||||
void installPython();
|
|
||||||
void pythonDownloadSuccess(QString url, QString file_path);
|
|
||||||
void pythonDownloadFailure(QString url, QString error);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_goToDescBtn_clicked();
|
void on_goToDescBtn_clicked();
|
||||||
|
@ -130,9 +123,6 @@ private:
|
||||||
QList<QPointer<SearchTab> > all_tab; // To store all tabs
|
QList<QPointer<SearchTab> > all_tab; // To store all tabs
|
||||||
const SearchCategories full_cat_names;
|
const SearchCategories full_cat_names;
|
||||||
MainWindow *mp_mainWindow;
|
MainWindow *mp_mainWindow;
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
bool has_python;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -105,8 +105,7 @@ signals:
|
||||||
void newSupportedEngine(QString name);
|
void newSupportedEngine(QString name);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SupportedEngines(bool has_python = true) {
|
SupportedEngines() {
|
||||||
if (has_python)
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue