Browse Source

Merge pull request #9141 from Chocobo1/delay

Omit removing python cache artifacts on qbt start
adaptive-webui-19844
Mike Tzou 6 years ago committed by GitHub
parent
commit
ca68b86550
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 165
      src/base/search/searchpluginmanager.cpp
  2. 2
      src/base/search/searchpluginmanager.h
  3. 8
      src/base/utils/foreignapps.cpp

165
src/base/search/searchpluginmanager.cpp

@ -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 (getPluginVersion(":/" + novaFolder + "/nova2dl.py") > getPluginVersion(filePath)) {
removePythonScriptIfExists(filePath);
QFile::copy(":/" + novaFolder + "/nova2dl.py", filePath);
}
filePath = searchDir.absoluteFilePath("fix_encoding.py");
QFile::copy(":/" + novaFolder + "/fix_encoding.py", filePath);
filePath = searchDir.absoluteFilePath("novaprinter.py");
if (getPluginVersion(":/" + novaFolder + "/novaprinter.py") > getPluginVersion(filePath)) {
removePythonScriptIfExists(filePath);
QFile::copy(":/" + novaFolder + "/novaprinter.py", filePath);
}
filePath = searchDir.absoluteFilePath("helpers.py"); if (compareVersion && (getPluginVersion(filePathBundled) <= getPluginVersion(filePathDisk)))
if (getPluginVersion(":/" + novaFolder + "/helpers.py") > getPluginVersion(filePath)) { return;
removePythonScriptIfExists(filePath);
QFile::copy(":/" + novaFolder + "/helpers.py", filePath);
}
filePath = searchDir.absoluteFilePath("socks.py"); Utils::Fs::forceRemove(filePathDisk);
removePythonScriptIfExists(filePath); QFile::copy(filePathBundled, filePathDisk);
QFile::copy(":/" + novaFolder + "/socks.py", filePath); };
if (novaFolder.endsWith("nova")) { updateFile("helpers.py", true);
filePath = searchDir.absoluteFilePath("fix_encoding.py"); updateFile("nova2.py", true);
removePythonScriptIfExists(filePath); updateFile("nova2dl.py", true);
QFile::copy(":/" + novaFolder + "/fix_encoding.py", filePath); updateFile("novaprinter.py", true);
} updateFile("socks.py", false);
else if (novaFolder.endsWith("nova3")) {
filePath = searchDir.absoluteFilePath("sgmllib3.py");
removePythonScriptIfExists(filePath);
QFile::copy(":/" + novaFolder + "/sgmllib3.py", filePath);
}
QDir destDir(pluginsLocation()); if (Utils::ForeignApps::pythonInfo().version.majorNumber() >= 3)
Utils::Fs::removeDirRecursive(destDir.absoluteFilePath("__pycache__")); updateFile("sgmllib3.py", false);
else
updateFile("fix_encoding.py", false);
} }
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 {};
} }

2
src/base/search/searchpluginmanager.h

@ -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();

8
src/base/utils/foreignapps.cpp

@ -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…
Cancel
Save