Move everything Jupyter related out of PythonManager

Fix importing cutter in Python
This commit is contained in:
Florian Märkl 2019-02-03 12:31:59 +01:00
parent b9c859bc0c
commit 74a201ecba
5 changed files with 71 additions and 49 deletions

View File

@ -5,6 +5,7 @@
#include "JupyterConnection.h"
#include "NestedIPyKernel.h"
#include "PythonManager.h"
#include "QtResImporter.h"
#include <QVariant>
#include <QDebug>
@ -18,6 +19,7 @@ JupyterConnection *JupyterConnection::getInstance()
JupyterConnection::JupyterConnection(QObject *parent) : QObject(parent)
{
connect(Python(), &PythonManager::willShutDown, this, &JupyterConnection::stop);
}
JupyterConnection::~JupyterConnection()
@ -31,18 +33,29 @@ void JupyterConnection::start()
return;
}
notebookInstanceExists = Python()->startJupyterNotebook();
notebookInstanceExists = startJupyterNotebook();
emit urlReceived(getUrl());
}
void JupyterConnection::stop()
{
if (cutterNotebookAppInstance) {
Python()->restoreThread();
auto stopFunc = PyObject_GetAttrString(cutterNotebookAppInstance, "stop");
PyObject_CallObject(stopFunc, nullptr);
Py_DECREF(cutterNotebookAppInstance);
Python()->saveThread();
}
}
QString JupyterConnection::getUrl()
{
if (!notebookInstanceExists) {
return nullptr;
}
QString url = Python()->getJupyterUrl();
QString url = getJupyterUrl();
return url;
}
@ -94,4 +107,39 @@ QVariant JupyterConnection::pollNestedIPyKernel(long id)
return v;
}
bool JupyterConnection::startJupyterNotebook()
{
Python()->restoreThread();
if (!cutterJupyterModule) {
cutterJupyterModule = QtResImport("cutter_jupyter");
}
PyObject* startFunc = PyObject_GetAttrString(cutterJupyterModule, "start_jupyter");
if (!startFunc) {
qWarning() << "Couldn't get attribute start_jupyter.";
return false;
}
cutterNotebookAppInstance = PyObject_CallObject(startFunc, nullptr);
Python()->saveThread();
return cutterNotebookAppInstance != nullptr;
}
QString JupyterConnection::getJupyterUrl()
{
Python()->restoreThread();
auto urlWithToken = PyObject_GetAttrString(cutterNotebookAppInstance, "url_with_token");
auto asciiBytes = PyUnicode_AsASCIIString(urlWithToken);
auto urlWithTokenString = QString::fromUtf8(PyBytes_AsString(asciiBytes));
Py_DECREF(asciiBytes);
Py_DECREF(urlWithToken);
Python()->saveThread();
return urlWithTokenString;
}
#endif

View File

@ -7,6 +7,7 @@
#include <QMap>
class NestedIPyKernel;
typedef struct _object PyObject;
class JupyterConnection : public QObject
{
@ -25,6 +26,9 @@ public:
NestedIPyKernel *getNestedIPyKernel(long id);
QVariant pollNestedIPyKernel(long id);
public slots:
void stop();
signals:
void urlReceived(const QString &url);
void creationFailed();
@ -34,6 +38,12 @@ private:
long nextKernelId = 1;
bool notebookInstanceExists = false;
PyObject *cutterJupyterModule = nullptr;
PyObject *cutterNotebookAppInstance = nullptr;
bool startJupyterNotebook();
QString getJupyterUrl();
};

View File

@ -66,7 +66,7 @@ PyMethodDef CutterMethods[] = {
"Refresh Cutter widgets"
},
{
"message", (PyCFunction) api_message, METH_VARARGS | METH_KEYWORDS,
"message", (PyCFunction)(void *)/* don't remove this double cast! */api_message, METH_VARARGS | METH_KEYWORDS,
"Print message"
},
{NULL, NULL, 0, NULL}

View File

@ -32,11 +32,7 @@ PythonManager::~PythonManager()
restoreThread();
if (cutterNotebookAppInstance) {
auto stopFunc = PyObject_GetAttrString(cutterNotebookAppInstance, "stop");
PyObject_CallObject(stopFunc, nullptr);
Py_DECREF(cutterNotebookAppInstance);
}
emit willShutDown();
Py_Finalize();
@ -81,8 +77,9 @@ void PythonManager::initialize()
Py_Initialize();
PyEval_InitThreads();
RegQtResImporter();
// Import other modules
cutterJupyterModule = QtResImport("cutter_jupyter");
cutterPluginModule = QtResImport("cutter_plugin");
saveThread();
@ -108,36 +105,6 @@ void PythonManager::addPythonPath(char *path) {
saveThread();
}
bool PythonManager::startJupyterNotebook()
{
restoreThread();
PyObject* startFunc = PyObject_GetAttrString(cutterJupyterModule, "start_jupyter");
if (!startFunc) {
qWarning() << "Couldn't get attribute start_jupyter.";
return false;
}
cutterNotebookAppInstance = PyObject_CallObject(startFunc, nullptr);
saveThread();
return cutterNotebookAppInstance != nullptr;
}
QString PythonManager::getJupyterUrl()
{
restoreThread();
auto urlWithToken = PyObject_GetAttrString(cutterNotebookAppInstance, "url_with_token");
auto asciiBytes = PyUnicode_AsASCIIString(urlWithToken);
auto urlWithTokenString = QString::fromUtf8(PyBytes_AsString(asciiBytes));
Py_DECREF(asciiBytes);
Py_DECREF(urlWithToken);
saveThread();
return urlWithTokenString;
}
CutterPythonPlugin* PythonManager::loadPlugin(const char *pluginName) {
CutterPythonPlugin *plugin = nullptr;

View File

@ -7,40 +7,37 @@ class CutterPythonPlugin;
typedef struct _ts PyThreadState;
typedef struct _object PyObject;
class PythonManager
class PythonManager: public QObject
{
Q_OBJECT
public:
static PythonManager *getInstance();
PythonManager();
~PythonManager();
void setPythonHome(const QString pythonHome)
{
customPythonHome = pythonHome;
}
void setPythonHome(const QString &pythonHome) { customPythonHome = pythonHome; }
void initPythonHome();
void initialize();
void addPythonPath(char *path);
bool startJupyterNotebook();
QString getJupyterUrl();
PyObject *createModule(QString module);
CutterPythonPlugin *loadPlugin(const char *pluginName);
void restoreThread();
void saveThread();
signals:
void willShutDown();
private:
QString customPythonHome;
wchar_t *pythonHome = nullptr;
PyThreadState *pyThreadState = nullptr;
PyObject *cutterJupyterModule;
PyObject *cutterPluginModule;
PyObject *cutterNotebookAppInstance = nullptr;
};
#define Python() (PythonManager::getInstance())