Allow implementation of python plugin as whole module.

This commit is contained in:
Mikaël Capelle
2020-05-11 23:51:58 +02:00
parent 168b9d7b0d
commit a05006a0b3
2 changed files with 46 additions and 8 deletions
+15 -3
View File
@@ -28,7 +28,6 @@ along with python proxy plugin. If not, see <http://www.gnu.org/licenses/>.
#include <QCoreApplication>
#include "resource.h"
using namespace MOBase;
@@ -214,11 +213,24 @@ QList<PluginSetting> ProxyPython::settings() const
QStringList ProxyPython::pluginList(const QString &pluginPath) const
{
QDirIterator iter(pluginPath, QStringList("*.py"));
QDir dir(pluginPath);
dir.setFilter(dir.filter() | QDir::NoDotAndDotDot);
QDirIterator iter(dir);
// Note: We put python script (.py) and directory names, not the __init__.py
// files in those since it is easier for the runner to import them.
QStringList result;
while (iter.hasNext()) {
result.append(iter.next());
QString name = iter.next();
QFileInfo info = iter.fileInfo();
if (info.isFile() && name.endsWith(".py")) {
result.append(name);
}
else if (info.isDir() && QDir(info.absoluteFilePath()).exists("__init__.py")) {
result.append(name);
// result.append(info.baseName());
}
}
return result;
+31 -5
View File
@@ -44,6 +44,11 @@ public:
private:
void initPath();
/**
* @brief Ensure that the given folder is in sys.path.
*/
void ensureFolderInPath(QString folder);
private:
std::map<QString, boost::python::object> m_PythonObjects;
@@ -1340,6 +1345,17 @@ void PythonRunner::initPath()
Py_SetPath(paths.join(';').toStdWString().c_str());
}
void PythonRunner::ensureFolderInPath(QString folder) {
bpy::object sys = bpy::import("sys");
bpy::list sysPath = bpy::extract<bpy::list>(sys.attr("path"));
// Converting to QStringList for Qt::CaseInsensitive and because .index()
// raise an exception:
QStringList currentPath = bpy::extract<QStringList>(sysPath);
if (!currentPath.contains(folder, Qt::CaseInsensitive)) {
sysPath.insert(0, folder);
}
}
QList<QObject*> PythonRunner::instantiate(const QString &pluginName)
{
@@ -1352,12 +1368,22 @@ QList<QObject*> PythonRunner::instantiate(const QString &pluginName)
moduleNamespace["sys"] = sys;
moduleNamespace["mobase"] = bpy::import("mobase");
std::string temp = ToString(pluginName);
if (handled_exec_file(temp.c_str(), moduleNamespace)) {
reportPythonError();
return QList<QObject*>();
if (pluginName.endsWith(".py")) {
std::string temp = ToString(pluginName);
if (handled_exec_file(temp.c_str(), moduleNamespace)) {
reportPythonError();
return QList<QObject*>();
}
m_PythonObjects[pluginName] = moduleNamespace["createPlugin"]();
}
else {
// Retrieve the module name:
QStringList parts = pluginName.split("/");
std::string moduleName = ToString(parts.takeLast());
ensureFolderInPath(parts.join("/"));
bpy::object createPlugin = bpy::import(moduleName.c_str()).attr("createPlugin");
m_PythonObjects[pluginName] = createPlugin();
}
m_PythonObjects[pluginName] = moduleNamespace["createPlugin"]();
bpy::object pluginObj = m_PythonObjects[pluginName];
QList<QObject *> interfaceList;