aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2018-09-21 13:15:47 +0200
committerEike Ziller <eike.ziller@qt.io>2018-09-21 11:54:38 +0000
commit9ebe20ca27fbce2ca2934e40dfd1a7a21aaa6658 (patch)
tree03effab1e69b9213210ee63c7ad32c37418b42ab
parent4d6487e753b8838f460769ff9758ac6c82a88a35 (diff)
Avoid scanning extension directory over and over again
And get rid of separate management of a list of loaded extensions. Instead save the name and state of an extension in a separate class. It will probably get more information about the extension, like its location. The extension manager UI now can also iterate over that list once. Change-Id: I4872e55d621837a7d476e69b919f06aeb491ff03 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
-rw-r--r--docs/extensions.md5
-rw-r--r--plugins/pythonextensions/bindingheaders/pythonextensions_extension.h0
-rw-r--r--plugins/pythonextensions/pythonextensions.pro1
-rw-r--r--plugins/pythonextensions/pythonextensionsplugin.cpp76
-rw-r--r--plugins/pythonextensions/pythonextensionsplugin.h13
-rw-r--r--plugins/pythonextensions/pyutil.h2
-rw-r--r--plugins/pythonextensions/typesystem_qtcreator.xml1
-rw-r--r--python/extensionmanager/actions.py4
-rw-r--r--python/extensionmanager/list.py6
9 files changed, 69 insertions, 39 deletions
diff --git a/docs/extensions.md b/docs/extensions.md
index ae5cb5c..709acff 100644
--- a/docs/extensions.md
+++ b/docs/extensions.md
@@ -21,9 +21,8 @@ from PythonExtension import PluginInstance as inst
inst.extensionDir()
# Returns a list with the names of all Python extensions
-# If loaded only is supplied as True, only extensions that
-# where loaded successfully are returned
-inst.extensionList(loadedOnly = False)
+# Each extension has properties 'name' and 'loaded'
+inst.extensionList()
# Returns the path of the custom location to
# where missing dependencies should be pip installed
diff --git a/plugins/pythonextensions/bindingheaders/pythonextensions_extension.h b/plugins/pythonextensions/bindingheaders/pythonextensions_extension.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/pythonextensions/bindingheaders/pythonextensions_extension.h
diff --git a/plugins/pythonextensions/pythonextensions.pro b/plugins/pythonextensions/pythonextensions.pro
index c8fe73d..e28b860 100644
--- a/plugins/pythonextensions/pythonextensions.pro
+++ b/plugins/pythonextensions/pythonextensions.pro
@@ -36,6 +36,7 @@ WRAPPED_CLASSES = \
bindingheaders/pythonextensions.h \
bindingheaders/pythonextensions_internal.h \
bindingheaders/pythonextensions_internal_pythonextensionsplugin.h \
+ bindingheaders/pythonextensions_extension.h \
bindingheaders/core.h \
bindingheaders/core_actioncontainer.h \
bindingheaders/core_actionmanager.h \
diff --git a/plugins/pythonextensions/pythonextensionsplugin.cpp b/plugins/pythonextensions/pythonextensionsplugin.cpp
index 3136bbc..b3730b4 100644
--- a/plugins/pythonextensions/pythonextensionsplugin.cpp
+++ b/plugins/pythonextensions/pythonextensionsplugin.cpp
@@ -39,6 +39,8 @@
#include <extensionsystem/pluginmanager.h>
#include <extensionsystem/pluginspec.h>
+#include <utils/algorithm.h>
+
#include <QDir>
#include <QIODevice>
#include <QFile>
@@ -131,19 +133,32 @@ QDir PythonExtensionsPlugin::extensionDir()
return extension_dir;
}
-QStringList PythonExtensionsPlugin::extensionList(const bool loadedOnly)
+static QVector<Extension> getExtensionList(const QDir &directory)
{
- if (loadedOnly)
- return m_loadedExtensions;
+ if (!directory.exists())
+ return {};
+
+ QStringList entries = directory.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
+ entries.removeAll("site-packages");
+ entries.removeAll("__pycache__");
+ return Utils::transform<QVector>(entries, [](const QString &entry) {
+ return Extension({entry, false});
+ });
+}
- QDir extension_dir = extensionDir();
- if (!extension_dir.exists())
- return QStringList();
+QVector<Extension> PythonExtensionsPlugin::extensionList()
+{
+ return extensionListRef();
+}
- QStringList extension_list = extension_dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
- extension_list.removeAll("site-packages");
- extension_list.removeAll("__pycache__");
- return extension_list;
+QVector<Extension> &PythonExtensionsPlugin::extensionListRef()
+{
+ static bool initialized = false;
+ if (!initialized) {
+ m_extensions = getExtensionList(extensionDir());
+ initialized = true;
+ }
+ return m_extensions;
}
QString PythonExtensionsPlugin::pythonPackagePath()
@@ -207,16 +222,18 @@ void PythonExtensionsPlugin::installRequirements()
if (!extension_dir.exists())
return;
- QStringList extension_list = extensionList();
- for (const QString &extension : extension_list) {
- QString extension_requirements(extension_dir.absolutePath() + "/" + extension + "/requirements.txt");
- if (QFileInfo::exists(extension_requirements) && !QFileInfo::exists(extension_requirements + ".installed")) {
- if (!PyUtil::pipInstallRequirements(
- extension_requirements.toStdString(),
- pythonPackagePath().toStdString()
- )) {
- qWarning() << "Failed to install requirements for extension" << extension;
- Core::MessageManager::write(Constants::MESSAGE_MANAGER_PREFIX + tr("Failed to install requirements for extension ") + extension);
+ QVector<Extension> extension_list = extensionListRef();
+ for (const Extension &extension : extension_list) {
+ QString extension_requirements(extension_dir.absolutePath() + "/" + extension.name
+ + "/requirements.txt");
+ if (QFileInfo::exists(extension_requirements)
+ && !QFileInfo::exists(extension_requirements + ".installed")) {
+ if (!PyUtil::pipInstallRequirements(extension_requirements.toStdString(),
+ pythonPackagePath().toStdString())) {
+ qWarning() << "Failed to install requirements for extension" << extension.name;
+ Core::MessageManager::write(Constants::MESSAGE_MANAGER_PREFIX
+ + tr("Failed to install requirements for extension ")
+ + extension.name);
}
}
}
@@ -234,22 +251,25 @@ void PythonExtensionsPlugin::initializePythonExtensions()
qDebug() << "Found Python extension directory at location" << extension_dir.absolutePath();
- QStringList extension_list = extensionList();
+ QVector<Extension> &extension_list = extensionListRef();
qDebug() << "Number of Python extensions found:" << extension_list.size();
+ int loadedCount = 0;
// Run the extension initialization code
- for (const QString &extension : extension_list) {
- qDebug() << "Trying to initialize extension" << extension;
- if (!PyUtil::runScript("import " + extension.toStdString())) {
- qWarning() << "Failed to initialize extension" << extension;
- Core::MessageManager::write(Constants::MESSAGE_MANAGER_PREFIX + tr("Failed to initialize extension ") + extension);
+ for (Extension &extension : extension_list) {
+ qDebug() << "Trying to initialize extension" << extension.name;
+ if (PyUtil::runScript("import " + extension.name.toStdString())) {
+ extension.loaded = true;
+ ++loadedCount;
} else {
- m_loadedExtensions << extension;
+ qWarning() << "Failed to initialize extension" << extension.name;
+ Core::MessageManager::write(Constants::MESSAGE_MANAGER_PREFIX
+ + tr("Failed to initialize extension ") + extension.name);
}
}
- qDebug() << "Number of Python extensions loaded:" << m_loadedExtensions.size();
+ qDebug() << "Number of Python extensions loaded:" << loadedCount;
}
} // namespace Internal
diff --git a/plugins/pythonextensions/pythonextensionsplugin.h b/plugins/pythonextensions/pythonextensionsplugin.h
index 106ee63..1a4bce3 100644
--- a/plugins/pythonextensions/pythonextensionsplugin.h
+++ b/plugins/pythonextensions/pythonextensionsplugin.h
@@ -33,6 +33,13 @@
#include <QStringList>
namespace PythonExtensions {
+
+class Extension {
+public:
+ QString name;
+ bool loaded;
+};
+
namespace Internal {
class PythonExtensionsPlugin : public ExtensionSystem::IPlugin
@@ -50,14 +57,16 @@ public:
ShutdownFlag aboutToShutdown() final;
QDir extensionDir();
- QStringList extensionList(const bool loadedOnly = false);
+ QVector<Extension> extensionList();
QString pythonPackagePath();
+
private:
- QStringList m_loadedExtensions;
void initializePythonBindings();
void initializeOptionalBindings();
void installRequirements();
void initializePythonExtensions();
+ QVector<Extension> &extensionListRef();
+ QVector<Extension> m_extensions;
};
// Util functions
diff --git a/plugins/pythonextensions/pyutil.h b/plugins/pythonextensions/pyutil.h
index 62a1622..23fdb37 100644
--- a/plugins/pythonextensions/pyutil.h
+++ b/plugins/pythonextensions/pyutil.h
@@ -37,7 +37,7 @@ namespace PyUtil {
// Note: If modifying the bindings, check these types still align
enum QtCreatorTypes
{
- PythonExtensionsPluginType = 33, // SBK_PYTHONEXTENSIONS_INTERNAL_PYTHONEXTENSIONSPLUGIN_IDX
+ PythonExtensionsPluginType = 34, // SBK_PYTHONEXTENSIONS_INTERNAL_PYTHONEXTENSIONSPLUGIN_IDX
};
enum State
diff --git a/plugins/pythonextensions/typesystem_qtcreator.xml b/plugins/pythonextensions/typesystem_qtcreator.xml
index 736fe44..49dd794 100644
--- a/plugins/pythonextensions/typesystem_qtcreator.xml
+++ b/plugins/pythonextensions/typesystem_qtcreator.xml
@@ -47,6 +47,7 @@
<load-typesystem name="typesystem_widgets.xml" generate="no"/>
<namespace-type name="PythonExtensions">
+ <value-type name="Extension"/>
<namespace-type name="Internal">
<object-type name="PythonExtensionsPlugin"/>
</namespace-type>
diff --git a/python/extensionmanager/actions.py b/python/extensionmanager/actions.py
index 29d64cc..7f05e77 100644
--- a/python/extensionmanager/actions.py
+++ b/python/extensionmanager/actions.py
@@ -60,8 +60,8 @@ def install(path):
# Make sure the extension manager does not overwrite
# extensions that are already installed
for ext in instance.extensionList():
- if extName == ext:
- return "The extension \"{}\" is already installed. Uninstall it before trying again.".format(ext)
+ if extName == ext.name:
+ return "The extension \"{}\" is already installed. Uninstall it before trying again.".format(extName)
extZip.extractall(instance.extensionDir().absolutePath())
extZip.close()
except Exception as e:
diff --git a/python/extensionmanager/list.py b/python/extensionmanager/list.py
index d213c35..32002b1 100644
--- a/python/extensionmanager/list.py
+++ b/python/extensionmanager/list.py
@@ -58,11 +58,11 @@ class ExtensionList(QtWidgets.QListWidget):
i = 0
for ext in instance.extensionList():
item = QtWidgets.QListWidgetItem(self)
- if not ext in instance.extensionList(True):
- item.setText(ext + " [did not load]")
+ if not ext.loaded:
+ item.setText(ext.name + " [did not load]")
item.setIcon(QtGui.QIcon.fromTheme("dialog-error"))
else:
- item.setText(ext)
+ item.setText(ext.name)
item.setIcon(QtGui.QIcon.fromTheme("applications-development"))
if i % 2 == 1:
item.setBackground(QtGui.QBrush(QtGui.QColor.fromRgb(240, 240, 240)))