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
|
||||
static void setPythonPath(QString path) {
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
settings.setValue(QString::fromUtf8("Preferences/Win32/PythonPath"), path);
|
||||
}
|
||||
|
||||
static QString getPythonPath() {
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
return settings.value(QString::fromUtf8("Preferences/Win32/PythonPath"), "").toString();
|
||||
QSettings reg_python("HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore", QSettings::NativeFormat);
|
||||
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() {
|
||||
|
@ -79,11 +79,10 @@ SearchEngine::SearchEngine(GUI *parent, Bittorrent *BTSession) : QWidget(parent)
|
||||
search_stopped = false;
|
||||
// Creating Search Process
|
||||
#ifdef Q_WS_WIN
|
||||
checkForPythonExe();
|
||||
has_python = addPythonPathToEnv();
|
||||
#endif
|
||||
searchProcess = new QProcess(this);
|
||||
QStringList env = QProcess::systemEnvironment();
|
||||
searchProcess->setEnvironment(env);
|
||||
searchProcess->setEnvironment(QProcess::systemEnvironment());
|
||||
connect(searchProcess, SIGNAL(started()), this, SLOT(searchStarted()));
|
||||
connect(searchProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readSearchOutput()));
|
||||
connect(searchProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(searchFinished(int,QProcess::ExitStatus)));
|
||||
@ -111,56 +110,63 @@ void SearchEngine::fillCatCombobox() {
|
||||
}
|
||||
|
||||
#ifdef Q_WS_WIN
|
||||
void SearchEngine::checkForPythonExe() {
|
||||
QString python_path = Preferences::getPythonPath();
|
||||
if(python_path.isEmpty() || !QFile::exists(python_path+QDir::separator()+"python.exe")) {
|
||||
// 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);
|
||||
}
|
||||
bool SearchEngine::addPythonPathToEnv() {
|
||||
QString python_path = Preferences::getPythonPath();
|
||||
if(!python_path.isEmpty()) {
|
||||
// Add it to PATH envvar
|
||||
QString path_envar = QString::fromLocal8Bit(getenv("PATH"));
|
||||
if(path_envar.isNull()) {
|
||||
path_envar = "";
|
||||
path_envar = "";
|
||||
}
|
||||
path_envar = python_path+";"+path_envar;
|
||||
qDebug("New PATH envvar is: %s", qPrintable(path_envar));
|
||||
QString envar = "PATH="+path_envar;
|
||||
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
|
||||
|
||||
QString SearchEngine::selectedCategory() const {
|
||||
@ -269,6 +275,17 @@ void SearchEngine::searchTextEdited(QString) {
|
||||
|
||||
// Function called when we click on search button
|
||||
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){
|
||||
searchProcess->terminate();
|
||||
search_stopped = true;
|
||||
@ -381,6 +398,7 @@ void SearchEngine::downloadTorrent(QString engine_url, QString torrent_url) {
|
||||
parent->downloadFromURLList(urls);
|
||||
} else {
|
||||
QProcess *downloadProcess = new QProcess(this);
|
||||
downloadProcess->setEnvironment(QProcess::systemEnvironment());
|
||||
connect(downloadProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(downloadFinished(int,QProcess::ExitStatus)));
|
||||
downloaders << downloadProcess;
|
||||
QStringList params;
|
||||
|
@ -70,6 +70,9 @@ private:
|
||||
QList<QPointer<SearchTab> > all_tab; // To store all tabs
|
||||
const SearchCategories full_cat_names;
|
||||
GUI *parent;
|
||||
#ifdef Q_WS_WIN
|
||||
bool has_python;
|
||||
#endif
|
||||
|
||||
public:
|
||||
SearchEngine(GUI *parent, Bittorrent *BTSession);
|
||||
@ -127,7 +130,10 @@ protected slots:
|
||||
void fillCatCombobox();
|
||||
void searchTextEdited(QString);
|
||||
#ifdef Q_WS_WIN
|
||||
void checkForPythonExe();
|
||||
bool addPythonPathToEnv();
|
||||
void installPython();
|
||||
void pythonDownloadSuccess(QString url, QString file_path);
|
||||
void pythonDownloadFailure(QString url, QString error);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user