mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-02-02 18:04:32 +00:00
Merge pull request #9141 from Chocobo1/delay
Omit removing python cache artifacts on qbt start
This commit is contained in:
commit
ca68b86550
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QDirIterator>
|
||||||
#include <QDomDocument>
|
#include <QDomDocument>
|
||||||
#include <QDomElement>
|
#include <QDomElement>
|
||||||
#include <QDomNode>
|
#include <QDomNode>
|
||||||
@ -54,10 +55,29 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
inline void removePythonScriptIfExists(const QString &scriptPath)
|
void clearPythonCache(const QString &path)
|
||||||
{
|
{
|
||||||
Utils::Fs::forceRemove(scriptPath);
|
// remove python cache artifacts in `path` and subdirs
|
||||||
Utils::Fs::forceRemove(scriptPath + "c");
|
|
||||||
|
QStringList dirs = {path};
|
||||||
|
QDirIterator iter {path, (QDir::AllDirs | QDir::NoDotAndDotDot), QDirIterator::Subdirectories};
|
||||||
|
while (iter.hasNext())
|
||||||
|
dirs += iter.next();
|
||||||
|
|
||||||
|
for (const QString &dir : qAsConst(dirs)) {
|
||||||
|
// python 3: remove "__pycache__" folders
|
||||||
|
if (dir.endsWith("/__pycache__")) {
|
||||||
|
Utils::Fs::removeDirRecursive(dir);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// python 2: remove "*.pyc" files
|
||||||
|
const QStringList files = QDir(dir).entryList(QDir::Files);
|
||||||
|
for (const QString file : files) {
|
||||||
|
if (file.endsWith(".pyc"))
|
||||||
|
Utils::Fs::forceRemove(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +189,8 @@ void SearchPluginManager::installPlugin(const QString &source)
|
|||||||
{
|
{
|
||||||
qDebug("Asked to install plugin at %s", qUtf8Printable(source));
|
qDebug("Asked to install plugin at %s", qUtf8Printable(source));
|
||||||
|
|
||||||
|
clearPythonCache(engineLocation());
|
||||||
|
|
||||||
if (Utils::Misc::isUrl(source)) {
|
if (Utils::Misc::isUrl(source)) {
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
DownloadHandler *handler = DownloadManager::instance()->download(DownloadRequest(source).saveToFile(true));
|
DownloadHandler *handler = DownloadManager::instance()->download(DownloadRequest(source).saveToFile(true));
|
||||||
@ -210,7 +232,6 @@ void SearchPluginManager::installPlugin_impl(const QString &name, const QString
|
|||||||
// Backup in case install fails
|
// Backup in case install fails
|
||||||
QFile::copy(destPath, destPath + ".bak");
|
QFile::copy(destPath, destPath + ".bak");
|
||||||
Utils::Fs::forceRemove(destPath);
|
Utils::Fs::forceRemove(destPath);
|
||||||
Utils::Fs::forceRemove(destPath + "c");
|
|
||||||
updated = true;
|
updated = true;
|
||||||
}
|
}
|
||||||
// Copy the plugin
|
// Copy the plugin
|
||||||
@ -242,6 +263,8 @@ void SearchPluginManager::installPlugin_impl(const QString &name, const QString
|
|||||||
|
|
||||||
bool SearchPluginManager::uninstallPlugin(const QString &name)
|
bool SearchPluginManager::uninstallPlugin(const QString &name)
|
||||||
{
|
{
|
||||||
|
clearPythonCache(engineLocation());
|
||||||
|
|
||||||
// remove it from hard drive
|
// remove it from hard drive
|
||||||
QDir pluginsFolder(pluginsLocation());
|
QDir pluginsFolder(pluginsLocation());
|
||||||
QStringList filters;
|
QStringList filters;
|
||||||
@ -322,13 +345,16 @@ QString SearchPluginManager::pluginsLocation()
|
|||||||
|
|
||||||
QString SearchPluginManager::engineLocation()
|
QString SearchPluginManager::engineLocation()
|
||||||
{
|
{
|
||||||
QString folder = "nova";
|
static QString location;
|
||||||
if (Utils::ForeignApps::pythonInfo().version.majorNumber() >= 3)
|
if (location.isEmpty()) {
|
||||||
folder = "nova3";
|
const QString folder = (Utils::ForeignApps::pythonInfo().version.majorNumber() >= 3)
|
||||||
const QString location = Utils::Fs::expandPathAbs(specialFolderLocation(SpecialFolder::Data) + folder);
|
? "nova3" : "nova";
|
||||||
QDir locationDir(location);
|
location = Utils::Fs::expandPathAbs(specialFolderLocation(SpecialFolder::Data) + folder);
|
||||||
if (!locationDir.exists())
|
|
||||||
|
const QDir locationDir(location);
|
||||||
locationDir.mkpath(locationDir.absolutePath());
|
locationDir.mkpath(locationDir.absolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,81 +393,56 @@ void SearchPluginManager::pluginDownloadFailed(const QString &url, const QString
|
|||||||
// Update nova.py search plugin if necessary
|
// Update nova.py search plugin if necessary
|
||||||
void SearchPluginManager::updateNova()
|
void SearchPluginManager::updateNova()
|
||||||
{
|
{
|
||||||
qDebug("Updating nova");
|
|
||||||
|
|
||||||
// create nova directory if necessary
|
// create nova directory if necessary
|
||||||
QDir searchDir(engineLocation());
|
const QDir searchDir(engineLocation());
|
||||||
QString novaFolder = Utils::ForeignApps::pythonInfo().version.majorNumber() >= 3 ? "searchengine/nova3" : "searchengine/nova";
|
const QString novaFolder = Utils::ForeignApps::pythonInfo().version.majorNumber() >= 3
|
||||||
|
? "searchengine/nova3" : "searchengine/nova";
|
||||||
|
|
||||||
QFile packageFile(searchDir.absoluteFilePath("__init__.py"));
|
QFile packageFile(searchDir.absoluteFilePath("__init__.py"));
|
||||||
packageFile.open(QIODevice::WriteOnly | QIODevice::Text);
|
packageFile.open(QIODevice::WriteOnly);
|
||||||
packageFile.close();
|
packageFile.close();
|
||||||
if (!searchDir.exists("engines"))
|
|
||||||
searchDir.mkdir("engines");
|
searchDir.mkdir("engines");
|
||||||
Utils::Fs::removeDirRecursive(searchDir.absoluteFilePath("__pycache__"));
|
|
||||||
|
|
||||||
QFile packageFile2(searchDir.absolutePath() + "/engines/__init__.py");
|
QFile packageFile2(searchDir.absolutePath() + "/engines/__init__.py");
|
||||||
packageFile2.open(QIODevice::WriteOnly | QIODevice::Text);
|
packageFile2.open(QIODevice::WriteOnly);
|
||||||
packageFile2.close();
|
packageFile2.close();
|
||||||
|
|
||||||
// Copy search plugin files (if necessary)
|
// Copy search plugin files (if necessary)
|
||||||
QString filePath = searchDir.absoluteFilePath("nova2.py");
|
const auto updateFile = [&novaFolder](const QString &filename, const bool compareVersion)
|
||||||
if (getPluginVersion(":/" + novaFolder + "/nova2.py") > getPluginVersion(filePath)) {
|
{
|
||||||
removePythonScriptIfExists(filePath);
|
const QString filePathBundled = ":/" + novaFolder + '/' + filename;
|
||||||
QFile::copy(":/" + novaFolder + "/nova2.py", filePath);
|
const QString filePathDisk = QDir(engineLocation()).absoluteFilePath(filename);
|
||||||
}
|
|
||||||
|
|
||||||
filePath = searchDir.absoluteFilePath("nova2dl.py");
|
if (compareVersion && (getPluginVersion(filePathBundled) <= getPluginVersion(filePathDisk)))
|
||||||
if (getPluginVersion(":/" + novaFolder + "/nova2dl.py") > getPluginVersion(filePath)) {
|
return;
|
||||||
removePythonScriptIfExists(filePath);
|
|
||||||
QFile::copy(":/" + novaFolder + "/nova2dl.py", filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
filePath = searchDir.absoluteFilePath("fix_encoding.py");
|
Utils::Fs::forceRemove(filePathDisk);
|
||||||
QFile::copy(":/" + novaFolder + "/fix_encoding.py", filePath);
|
QFile::copy(filePathBundled, filePathDisk);
|
||||||
|
};
|
||||||
|
|
||||||
filePath = searchDir.absoluteFilePath("novaprinter.py");
|
updateFile("helpers.py", true);
|
||||||
if (getPluginVersion(":/" + novaFolder + "/novaprinter.py") > getPluginVersion(filePath)) {
|
updateFile("nova2.py", true);
|
||||||
removePythonScriptIfExists(filePath);
|
updateFile("nova2dl.py", true);
|
||||||
QFile::copy(":/" + novaFolder + "/novaprinter.py", filePath);
|
updateFile("novaprinter.py", true);
|
||||||
}
|
updateFile("socks.py", false);
|
||||||
|
|
||||||
filePath = searchDir.absoluteFilePath("helpers.py");
|
if (Utils::ForeignApps::pythonInfo().version.majorNumber() >= 3)
|
||||||
if (getPluginVersion(":/" + novaFolder + "/helpers.py") > getPluginVersion(filePath)) {
|
updateFile("sgmllib3.py", false);
|
||||||
removePythonScriptIfExists(filePath);
|
else
|
||||||
QFile::copy(":/" + novaFolder + "/helpers.py", filePath);
|
updateFile("fix_encoding.py", false);
|
||||||
}
|
|
||||||
|
|
||||||
filePath = searchDir.absoluteFilePath("socks.py");
|
|
||||||
removePythonScriptIfExists(filePath);
|
|
||||||
QFile::copy(":/" + novaFolder + "/socks.py", filePath);
|
|
||||||
|
|
||||||
if (novaFolder.endsWith("nova")) {
|
|
||||||
filePath = searchDir.absoluteFilePath("fix_encoding.py");
|
|
||||||
removePythonScriptIfExists(filePath);
|
|
||||||
QFile::copy(":/" + novaFolder + "/fix_encoding.py", filePath);
|
|
||||||
}
|
|
||||||
else if (novaFolder.endsWith("nova3")) {
|
|
||||||
filePath = searchDir.absoluteFilePath("sgmllib3.py");
|
|
||||||
removePythonScriptIfExists(filePath);
|
|
||||||
QFile::copy(":/" + novaFolder + "/sgmllib3.py", filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
QDir destDir(pluginsLocation());
|
|
||||||
Utils::Fs::removeDirRecursive(destDir.absoluteFilePath("__pycache__"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchPluginManager::update()
|
void SearchPluginManager::update()
|
||||||
{
|
{
|
||||||
QProcess nova;
|
QProcess nova;
|
||||||
nova.setEnvironment(QProcess::systemEnvironment());
|
nova.setProcessEnvironment(QProcessEnvironment::systemEnvironment());
|
||||||
QStringList params;
|
|
||||||
params << Utils::Fs::toNativePath(engineLocation() + "/nova2.py");
|
const QStringList params {Utils::Fs::toNativePath(engineLocation() + "/nova2.py"), "--capabilities"};
|
||||||
params << "--capabilities";
|
|
||||||
nova.start(Utils::ForeignApps::pythonInfo().executableName, params, QIODevice::ReadOnly);
|
nova.start(Utils::ForeignApps::pythonInfo().executableName, params, QIODevice::ReadOnly);
|
||||||
nova.waitForStarted();
|
|
||||||
nova.waitForFinished();
|
nova.waitForFinished();
|
||||||
|
|
||||||
QString capabilities = QString(nova.readAll());
|
QString capabilities = nova.readAll();
|
||||||
QDomDocument xmlDoc;
|
QDomDocument xmlDoc;
|
||||||
if (!xmlDoc.setContent(capabilities)) {
|
if (!xmlDoc.setContent(capabilities)) {
|
||||||
qWarning() << "Could not parse Nova search engine capabilities, msg: " << capabilities.toLocal8Bit().data();
|
qWarning() << "Could not parse Nova search engine capabilities, msg: " << capabilities.toLocal8Bit().data();
|
||||||
@ -466,7 +467,8 @@ void SearchPluginManager::update()
|
|||||||
plugin->fullName = engineElem.elementsByTagName("name").at(0).toElement().text();
|
plugin->fullName = engineElem.elementsByTagName("name").at(0).toElement().text();
|
||||||
plugin->url = engineElem.elementsByTagName("url").at(0).toElement().text();
|
plugin->url = engineElem.elementsByTagName("url").at(0).toElement().text();
|
||||||
|
|
||||||
foreach (QString cat, engineElem.elementsByTagName("categories").at(0).toElement().text().split(" ")) {
|
const auto categories = engineElem.elementsByTagName("categories").at(0).toElement().text().split(' ');
|
||||||
|
for (QString cat : categories) {
|
||||||
cat = cat.trimmed();
|
cat = cat.trimmed();
|
||||||
if (!cat.isEmpty())
|
if (!cat.isEmpty())
|
||||||
plugin->supportedCategories << cat;
|
plugin->supportedCategories << cat;
|
||||||
@ -540,32 +542,25 @@ QString SearchPluginManager::pluginPath(const QString &name)
|
|||||||
return QString("%1/%2.py").arg(pluginsLocation(), name);
|
return QString("%1/%2.py").arg(pluginsLocation(), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginVersion SearchPluginManager::getPluginVersion(QString filePath)
|
PluginVersion SearchPluginManager::getPluginVersion(const QString &filePath)
|
||||||
{
|
{
|
||||||
QFile plugin(filePath);
|
QFile pluginFile(filePath);
|
||||||
if (!plugin.exists()) {
|
if (!pluginFile.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||||
qDebug("%s plugin does not exist, returning 0.0", qUtf8Printable(filePath));
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!plugin.open(QIODevice::ReadOnly | QIODevice::Text))
|
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
const PluginVersion invalidVersion;
|
while (!pluginFile.atEnd()) {
|
||||||
|
const QString line = QString(pluginFile.readLine()).remove(' ');
|
||||||
PluginVersion version;
|
|
||||||
while (!plugin.atEnd()) {
|
|
||||||
const QString line = QString(plugin.readLine()).remove(' ');
|
|
||||||
if (!line.startsWith("#VERSION:", Qt::CaseInsensitive)) continue;
|
if (!line.startsWith("#VERSION:", Qt::CaseInsensitive)) continue;
|
||||||
|
|
||||||
const QString versionStr = line.mid(9);
|
const QString versionStr = line.mid(9);
|
||||||
version = PluginVersion::tryParse(versionStr, invalidVersion);
|
const PluginVersion version = PluginVersion::tryParse(versionStr, {});
|
||||||
if (version == invalidVersion) {
|
if (version.isValid())
|
||||||
LogMsg(tr("Search plugin '%1' contains invalid version string ('%2')")
|
return version;
|
||||||
.arg(Utils::Fs::fileName(filePath), line), Log::MsgType::WARNING);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
LogMsg(tr("Search plugin '%1' contains invalid version string ('%2')")
|
||||||
|
.arg(Utils::Fs::fileName(filePath), versionStr), Log::MsgType::WARNING);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return version;
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ public:
|
|||||||
SearchHandler *startSearch(const QString &pattern, const QString &category, const QStringList &usedPlugins);
|
SearchHandler *startSearch(const QString &pattern, const QString &category, const QStringList &usedPlugins);
|
||||||
SearchDownloadHandler *downloadTorrent(const QString &siteUrl, const QString &url);
|
SearchDownloadHandler *downloadTorrent(const QString &siteUrl, const QString &url);
|
||||||
|
|
||||||
static PluginVersion getPluginVersion(QString filePath);
|
static PluginVersion getPluginVersion(const QString &filePath);
|
||||||
static QString categoryFullName(const QString &categoryName);
|
static QString categoryFullName(const QString &categoryName);
|
||||||
QString pluginFullName(const QString &pluginName);
|
QString pluginFullName(const QString &pluginName);
|
||||||
static QString pluginsLocation();
|
static QString pluginsLocation();
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
#include <QRegularExpression>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
#include "base/logger.h"
|
#include "base/logger.h"
|
||||||
@ -56,8 +57,13 @@ namespace
|
|||||||
if (outputSplit.size() <= 1)
|
if (outputSplit.size() <= 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// User reports: `python --version` -> "Python 3.6.6+"
|
||||||
|
// So trim off unrelated characters
|
||||||
|
const QString versionStr = outputSplit[1];
|
||||||
|
const int idx = versionStr.indexOf(QRegularExpression("[^\\.\\d]"));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
info = {exeName, outputSplit[1]};
|
info = {exeName, versionStr.left(idx)};
|
||||||
}
|
}
|
||||||
catch (const std::runtime_error &err) {
|
catch (const std::runtime_error &err) {
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user