cutter/src/utils/PythonAPI.cpp

204 lines
5.3 KiB
C++
Raw Normal View History

2018-03-02 13:15:53 +00:00
#ifdef CUTTER_ENABLE_JUPYTER
2018-02-11 17:59:23 +00:00
#include "PythonAPI.h"
2018-03-04 17:42:02 +00:00
#include "Cutter.h"
2018-02-22 21:08:06 +00:00
#include "JupyterConnection.h"
#include "NestedIPyKernel.h"
2018-02-11 17:59:23 +00:00
#include <QFile>
2018-02-11 17:59:23 +00:00
PyObject *api_version(PyObject *self, PyObject *null)
{
Q_UNUSED(self)
Q_UNUSED(null)
return PyUnicode_FromString("Cutter version " CUTTER_VERSION);
}
PyObject *api_cmd(PyObject *self, PyObject *args)
{
Q_UNUSED(self);
char *command;
2018-03-21 20:32:32 +00:00
char *result = (char *) "";
2018-03-03 09:53:08 +00:00
QString cmdRes;
QByteArray cmdBytes;
2018-03-21 20:32:32 +00:00
if (PyArg_ParseTuple(args, "s:command", &command)) {
2018-03-03 09:53:08 +00:00
cmdRes = Core()->cmd(command);
cmdBytes = cmdRes.toLocal8Bit();
result = cmdBytes.data();
2018-02-11 17:59:23 +00:00
}
return PyUnicode_FromString(result);
}
2018-02-28 22:00:24 +00:00
PyObject *api_cmdj(PyObject *self, PyObject *args)
{
Q_UNUSED(self);
char *command;
2018-03-21 20:32:32 +00:00
char *result = (char *) "";
2018-03-03 09:53:08 +00:00
QString cmdRes;
QByteArray cmdBytes;
2018-03-21 20:32:32 +00:00
if (PyArg_ParseTuple(args, "s:command", &command)) {
2018-03-03 09:53:08 +00:00
cmdRes = Core()->cmd(command);
cmdBytes = cmdRes.toLocal8Bit();
result = cmdBytes.data();
2018-02-28 22:00:24 +00:00
PyObject *jsonModule = PyImport_ImportModule("json");
PyObject *loadsFunc = PyObject_GetAttrString(jsonModule, "loads");
if (!PyCallable_Check(loadsFunc)) {
PyErr_SetString(PyExc_SystemError, "Could not parse JSON.");
return NULL;
}
return PyEval_CallFunction(loadsFunc, "(s)", result);
}
return Py_None;
}
2018-04-04 14:30:30 +00:00
PyObject *api_refresh(PyObject *self, PyObject *args)
{
Q_UNUSED(self);
Q_UNUSED(args);
Core()->triggerRefreshAll();
return Py_None;
}
2018-02-11 17:59:23 +00:00
PyMethodDef CutterMethods[] = {
2018-03-21 20:32:32 +00:00
{
"version", api_version, METH_NOARGS,
"Returns Cutter current version"
},
{
"cmd", api_cmd, METH_VARARGS,
"Execute a command inside Cutter"
},
{
"cmdj", api_cmdj, METH_VARARGS,
"Execute a JSON command and return the result as a dictionnary"
},
2018-04-04 14:30:30 +00:00
{
"refresh", api_refresh, METH_NOARGS,
"Refresh Cutter widgets"
},
2018-02-11 17:59:23 +00:00
{NULL, NULL, 0, NULL}
};
PyModuleDef CutterModule = {
PyModuleDef_HEAD_INIT, "cutter", NULL, -1, CutterMethods,
NULL, NULL, NULL, NULL
};
PyObject *PyInit_api()
{
return PyModule_Create(&CutterModule);
}
// -----------------------------
PyObject *api_internal_launch_ipykernel(PyObject *self, PyObject *args, PyObject *kw)
{
2018-02-22 18:51:02 +00:00
Q_UNUSED(self);
Q_UNUSED(kw);
QStringList argv;
2018-02-22 18:51:02 +00:00
PyObject *argvListObject;
2018-02-22 18:51:02 +00:00
if (!PyArg_ParseTuple(args, "O", &argvListObject)
2018-03-21 20:32:32 +00:00
|| !PyList_Check(argvListObject)) {
const char *msg = "Invalid args passed to api_internal_launch_ipykernel().";
qWarning() << msg;
PyErr_SetString(PyExc_RuntimeError, msg);
2018-02-22 18:51:02 +00:00
return nullptr;
}
2018-03-21 20:32:32 +00:00
for (int i = 0; i < PyList_Size(argvListObject); i++) {
2018-02-22 18:51:02 +00:00
PyObject *o = PyList_GetItem(argvListObject, i);
QString s = QString::fromUtf8(PyUnicode_AsUTF8(o));
argv.append(s);
}
2018-02-22 21:08:06 +00:00
long id = Jupyter()->startNestedIPyKernel(argv);
2018-02-22 21:08:06 +00:00
return PyLong_FromLong(id);
}
2018-02-23 12:04:53 +00:00
PyObject *api_internal_kernel_interface_send_signal(PyObject *, PyObject *args)
2018-02-22 21:08:06 +00:00
{
long id;
2018-02-23 12:04:53 +00:00
long signum;
2018-03-21 20:32:32 +00:00
if (!PyArg_ParseTuple(args, "ll", &id, &signum)) {
const char *msg = "Invalid args passed to api_internal_kernel_interface_send_signal().";
qWarning() << msg;
PyErr_SetString(PyExc_RuntimeError, msg);
2018-02-22 21:08:06 +00:00
return nullptr;
}
2018-02-23 12:04:53 +00:00
NestedIPyKernel *kernel = Jupyter()->getNestedIPyKernel(id);
2018-03-21 20:32:32 +00:00
if (kernel) {
2018-02-23 12:04:53 +00:00
kernel->sendSignal(signum);
}
2018-02-22 21:08:06 +00:00
Py_RETURN_NONE;
}
2018-02-23 12:04:53 +00:00
PyObject *api_internal_kernel_interface_poll(PyObject *, PyObject *args)
{
long id;
2018-03-21 20:32:32 +00:00
if (!PyArg_ParseTuple(args, "l", &id)) {
const char *msg = "Invalid args passed to api_internal_kernel_interface_poll().";
qWarning() << msg;
PyErr_SetString(PyExc_RuntimeError, msg);
2018-02-23 12:04:53 +00:00
return nullptr;
}
2018-02-23 16:42:54 +00:00
QVariant v = Jupyter()->pollNestedIPyKernel(id);
2018-02-23 12:04:53 +00:00
bool ok;
auto ret = static_cast<long>(v.toLongLong(&ok));
2018-03-21 20:32:32 +00:00
if (ok) {
2018-02-23 12:04:53 +00:00
return PyLong_FromLong(ret);
2018-03-21 20:32:32 +00:00
} else {
2018-02-23 12:04:53 +00:00
Py_RETURN_NONE;
}
}
2018-02-23 15:24:19 +00:00
PyObject *api_internal_thread_set_async_exc(PyObject *, PyObject *args)
{
long id;
PyObject *exc;
2018-03-21 20:32:32 +00:00
if (!PyArg_ParseTuple(args, "lO", &id, &exc)) {
const char *msg = "Invalid args passed to api_internal_thread_set_async_exc().";
qWarning() << msg;
PyErr_SetString(PyExc_RuntimeError, msg);
2018-02-23 15:24:19 +00:00
return nullptr;
}
int ret = PyThreadState_SetAsyncExc(id, exc);
return PyLong_FromLong(ret);
}
PyMethodDef CutterInternalMethods[] = {
2018-03-21 20:32:32 +00:00
{
2018-06-26 16:17:03 +00:00
"launch_ipykernel", reinterpret_cast<PyCFunction>((void *)api_internal_launch_ipykernel), METH_VARARGS | METH_KEYWORDS,
2018-03-21 20:32:32 +00:00
"Launch an IPython Kernel in a subinterpreter"
},
2018-02-23 12:04:53 +00:00
{"kernel_interface_send_signal", (PyCFunction)api_internal_kernel_interface_send_signal, METH_VARARGS, ""},
{"kernel_interface_poll", (PyCFunction)api_internal_kernel_interface_poll, METH_VARARGS, ""},
2018-02-23 15:24:19 +00:00
{"thread_set_async_exc", (PyCFunction)api_internal_thread_set_async_exc, METH_VARARGS, ""},
{NULL, NULL, 0, NULL}
};
PyModuleDef CutterInternalModule = {
PyModuleDef_HEAD_INIT, "cutter_internal", NULL, -1, CutterInternalMethods,
NULL, NULL, NULL, NULL
};
PyObject *PyInit_api_internal()
{
return PyModule_Create(&CutterInternalModule);
}
2018-03-02 13:15:53 +00:00
#endif