mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-09 14:27:56 +00:00
Improved Python detection (Win32)
Propose to download and install python if missing (Win32)
This commit is contained in:
parent
83a2ae7ad3
commit
a3041b7f9f
@ -990,14 +990,30 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_WS_WIN
|
#ifdef Q_WS_WIN
|
||||||
static void setPythonPath(QString path) {
|
|
||||||
QSettings settings("qBittorrent", "qBittorrent");
|
|
||||||
settings.setValue(QString::fromUtf8("Preferences/Win32/PythonPath"), path);
|
|
||||||
}
|
|
||||||
|
|
||||||
static QString getPythonPath() {
|
static QString getPythonPath() {
|
||||||
QSettings settings("qBittorrent", "qBittorrent");
|
QSettings reg_python("HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore", QSettings::NativeFormat);
|
||||||
return settings.value(QString::fromUtf8("Preferences/Win32/PythonPath"), "").toString();
|
QStringList versions = reg_python.childGroups();
|
||||||
|
qDebug("Python versions nb: %d", versions.size());
|
||||||
|
versions = versions.filter(QRegExp("2\\..*"));
|
||||||
|
versions.sort();
|
||||||
|
while(!versions.empty()) {
|
||||||
|
const QString version = versions.takeLast();
|
||||||
|
qDebug("Detected possible Python v%s location", qPrintable(version));
|
||||||
|
QString path = reg_python.value(version+"/InstallPath/Default", "").toString().replace("/", "\\");
|
||||||
|
if(!path.isEmpty() && QDir(path).exists("python.exe")) {
|
||||||
|
qDebug("Found python.exe at %s", qPrintable(path));
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(QFile::exists("C:/Python26/python.exe")) {
|
||||||
|
reg_python.setValue("2.6/InstallPath/Default", "C:\\Python26");
|
||||||
|
return "C:\\Python26";
|
||||||
|
}
|
||||||
|
if(QFile::exists("C:/Python25/python.exe")) {
|
||||||
|
reg_python.setValue("2.5/InstallPath/Default", "C:\\Python26");
|
||||||
|
return "C:\\Python25";
|
||||||
|
}
|
||||||
|
return QString::null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool neverCheckFileAssoc() {
|
static bool neverCheckFileAssoc() {
|
||||||
|
@ -79,11 +79,10 @@ SearchEngine::SearchEngine(GUI *parent, Bittorrent *BTSession) : QWidget(parent)
|
|||||||
search_stopped = false;
|
search_stopped = false;
|
||||||
// Creating Search Process
|
// Creating Search Process
|
||||||
#ifdef Q_WS_WIN
|
#ifdef Q_WS_WIN
|
||||||
checkForPythonExe();
|
has_python = addPythonPathToEnv();
|
||||||
#endif
|
#endif
|
||||||
searchProcess = new QProcess(this);
|
searchProcess = new QProcess(this);
|
||||||
QStringList env = QProcess::systemEnvironment();
|
searchProcess->setEnvironment(QProcess::systemEnvironment());
|
||||||
searchProcess->setEnvironment(env);
|
|
||||||
connect(searchProcess, SIGNAL(started()), this, SLOT(searchStarted()));
|
connect(searchProcess, SIGNAL(started()), this, SLOT(searchStarted()));
|
||||||
connect(searchProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readSearchOutput()));
|
connect(searchProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readSearchOutput()));
|
||||||
connect(searchProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(searchFinished(int,QProcess::ExitStatus)));
|
connect(searchProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(searchFinished(int,QProcess::ExitStatus)));
|
||||||
@ -111,56 +110,63 @@ void SearchEngine::fillCatCombobox() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_WS_WIN
|
#ifdef Q_WS_WIN
|
||||||
void SearchEngine::checkForPythonExe() {
|
bool SearchEngine::addPythonPathToEnv() {
|
||||||
QString python_path = Preferences::getPythonPath();
|
QString python_path = Preferences::getPythonPath();
|
||||||
if(python_path.isEmpty() || !QFile::exists(python_path+QDir::separator()+"python.exe")) {
|
if(!python_path.isEmpty()) {
|
||||||
// Attempt to detect python in standard location
|
|
||||||
QStringList filters;
|
|
||||||
filters << "Python25" << "Python26";
|
|
||||||
QStringList python_folders = QDir::root().entryList(filters, QDir::Dirs, QDir::Name);
|
|
||||||
if(!python_folders.isEmpty()) {
|
|
||||||
python_path = QDir::root().absoluteFilePath(python_folders.last());
|
|
||||||
qDebug("Detected python folder at %s", qPrintable(python_path));
|
|
||||||
} else {
|
|
||||||
filters.clear();
|
|
||||||
filters << "Python*";
|
|
||||||
python_folders = QDir::root().entryList(filters, QDir::Dirs, QDir::Name);
|
|
||||||
if(!python_folders.isEmpty()) {
|
|
||||||
python_path = QDir::root().absoluteFilePath(python_folders.last());
|
|
||||||
qDebug("Detected python folder at %s", qPrintable(python_path));
|
|
||||||
} else {
|
|
||||||
qDebug("Failed to detect Python folder");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(python_path.isEmpty() || !QFile::exists(python_path+QDir::separator()+"python.exe")) {
|
|
||||||
QMessageBox::warning(0, tr("Failed to locate the Python interpreter"), tr("The Python interpreter was not found.\nqBittorrent will now ask you to point to its correct location."));
|
|
||||||
QString python_exe_path = QFileDialog::getOpenFileName(0, tr("Please point to its location on your hard disk."),
|
|
||||||
QDir::root().absolutePath(), tr("Python executable (python.exe)"));
|
|
||||||
if(python_exe_path.isEmpty() || !QFile::exists(python_exe_path)) {
|
|
||||||
QMessageBox::warning(0, tr("No Python interpreter"), tr("The Python interpreter is missing. qBittorrent search engine will not work."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
qDebug("Python exe path is: %s", qPrintable(python_exe_path));
|
|
||||||
QStringList tmp_list = python_exe_path.split(QDir::separator());
|
|
||||||
if(tmp_list.size() == 1)
|
|
||||||
tmp_list = tmp_list.first().split("/");
|
|
||||||
tmp_list.removeLast();
|
|
||||||
python_path = tmp_list.join(QDir::separator());
|
|
||||||
qDebug("New Python path is: %s", qPrintable(python_path));
|
|
||||||
// Save python path
|
|
||||||
Preferences::setPythonPath(python_path);
|
|
||||||
}
|
|
||||||
// Add it to PATH envvar
|
// Add it to PATH envvar
|
||||||
QString path_envar = QString::fromLocal8Bit(getenv("PATH"));
|
QString path_envar = QString::fromLocal8Bit(getenv("PATH"));
|
||||||
if(path_envar.isNull()) {
|
if(path_envar.isNull()) {
|
||||||
path_envar = "";
|
path_envar = "";
|
||||||
}
|
}
|
||||||
path_envar = python_path+";"+path_envar;
|
path_envar = python_path+";"+path_envar;
|
||||||
qDebug("New PATH envvar is: %s", qPrintable(path_envar));
|
qDebug("New PATH envvar is: %s", qPrintable(path_envar));
|
||||||
QString envar = "PATH="+path_envar;
|
QString envar = "PATH="+path_envar;
|
||||||
putenv(envar.toLocal8Bit().data());
|
putenv(envar.toLocal8Bit().data());
|
||||||
|
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.6.5/python-2.6.5.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 "+file_path.replace("/", "\\")+".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
|
||||||
|
QFile::remove(file_path+".msi");
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
#endif
|
||||||
|
|
||||||
QString SearchEngine::selectedCategory() const {
|
QString SearchEngine::selectedCategory() const {
|
||||||
@ -269,6 +275,17 @@ void SearchEngine::searchTextEdited(QString) {
|
|||||||
|
|
||||||
// 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_WS_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){
|
||||||
searchProcess->terminate();
|
searchProcess->terminate();
|
||||||
search_stopped = true;
|
search_stopped = true;
|
||||||
@ -381,6 +398,7 @@ void SearchEngine::downloadTorrent(QString engine_url, QString torrent_url) {
|
|||||||
parent->downloadFromURLList(urls);
|
parent->downloadFromURLList(urls);
|
||||||
} else {
|
} else {
|
||||||
QProcess *downloadProcess = new QProcess(this);
|
QProcess *downloadProcess = new QProcess(this);
|
||||||
|
downloadProcess->setEnvironment(QProcess::systemEnvironment());
|
||||||
connect(downloadProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(downloadFinished(int,QProcess::ExitStatus)));
|
connect(downloadProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(downloadFinished(int,QProcess::ExitStatus)));
|
||||||
downloaders << downloadProcess;
|
downloaders << downloadProcess;
|
||||||
QStringList params;
|
QStringList params;
|
||||||
|
@ -70,6 +70,9 @@ 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;
|
||||||
GUI *parent;
|
GUI *parent;
|
||||||
|
#ifdef Q_WS_WIN
|
||||||
|
bool has_python;
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SearchEngine(GUI *parent, Bittorrent *BTSession);
|
SearchEngine(GUI *parent, Bittorrent *BTSession);
|
||||||
@ -127,7 +130,10 @@ protected slots:
|
|||||||
void fillCatCombobox();
|
void fillCatCombobox();
|
||||||
void searchTextEdited(QString);
|
void searchTextEdited(QString);
|
||||||
#ifdef Q_WS_WIN
|
#ifdef Q_WS_WIN
|
||||||
void checkForPythonExe();
|
bool addPythonPathToEnv();
|
||||||
|
void installPython();
|
||||||
|
void pythonDownloadSuccess(QString url, QString file_path);
|
||||||
|
void pythonDownloadFailure(QString url, QString error);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user