some more hacking
This commit is contained in:
parent
d17b44c83d
commit
a21315efc5
79
libnymea-core/integrations/python/PyThingDiscoveryInfo.h
Normal file
79
libnymea-core/integrations/python/PyThingDiscoveryInfo.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#ifndef PYTHINGDISCOVERYINFO_H
|
||||||
|
#define PYTHINGDISCOVERYINFO_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Python.h>
|
||||||
|
|
||||||
|
#include "integrations/thingdiscoveryinfo.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
ThingDiscoveryInfo* ptrObj;
|
||||||
|
} PyThingDiscoveryInfo;
|
||||||
|
|
||||||
|
|
||||||
|
static int PyThingDiscoveryInfo_init(PyThingDiscoveryInfo */*self*/, PyObject */*args*/, PyObject */*kwds*/)
|
||||||
|
// initialize PyVoice Object
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void PyThingDiscoveryInfo_dealloc(PyThingDiscoveryInfo * self)
|
||||||
|
// destruct the object
|
||||||
|
{
|
||||||
|
// FIXME: Why is this not called? Seems we're leaking...
|
||||||
|
Q_ASSERT(false);
|
||||||
|
Py_TYPE(self)->tp_free(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject * PyThingDiscoveryInfo_finish(PyThingDiscoveryInfo* self, PyObject* args)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
char *message;
|
||||||
|
|
||||||
|
if (PyArg_ParseTuple(args, "is", &status, &message)) {
|
||||||
|
(self->ptrObj)->finish(static_cast<Thing::ThingError>(status), QString(message));
|
||||||
|
return Py_BuildValue("");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyArg_ParseTuple(args, "i", &status)) {
|
||||||
|
(self->ptrObj)->finish(static_cast<Thing::ThingError>(status));
|
||||||
|
return Py_BuildValue("");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Py_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef PyThingDiscoveryInfo_methods[] = {
|
||||||
|
{ "finish", (PyCFunction)PyThingDiscoveryInfo_finish, METH_VARARGS, "finish a discovery" },
|
||||||
|
{nullptr, nullptr, 0, nullptr} // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyTypeObject PyThingDiscoveryInfoType = {
|
||||||
|
PyVarObject_HEAD_INIT(NULL, 0)
|
||||||
|
"nymea.ThingDiscoveryInfo", /* tp_name */
|
||||||
|
sizeof(PyThingDiscoveryInfo), /* tp_basicsize */
|
||||||
|
0, /* tp_itemsize */
|
||||||
|
0, /* tp_dealloc */
|
||||||
|
0, /* tp_print */
|
||||||
|
0, /* tp_getattr */
|
||||||
|
0, /* tp_setattr */
|
||||||
|
0, /* tp_reserved */
|
||||||
|
0, /* tp_repr */
|
||||||
|
0, /* tp_as_number */
|
||||||
|
0, /* tp_as_sequence */
|
||||||
|
0, /* tp_as_mapping */
|
||||||
|
0, /* tp_hash */
|
||||||
|
0, /* tp_call */
|
||||||
|
0, /* tp_str */
|
||||||
|
0, /* tp_getattro */
|
||||||
|
0, /* tp_setattro */
|
||||||
|
0, /* tp_as_buffer */
|
||||||
|
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
||||||
|
"Noddy objects", /* tp_doc */
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
};
|
||||||
|
#endif // PYTHINGDISCOVERYINFO_H
|
||||||
@ -1,4 +1,5 @@
|
|||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
|
#include "python/PyThingDiscoveryInfo.h"
|
||||||
|
|
||||||
#include "pythonintegrationplugin.h"
|
#include "pythonintegrationplugin.h"
|
||||||
|
|
||||||
@ -6,7 +7,8 @@
|
|||||||
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
|
||||||
PyObject* aview_write(PyObject* /*self*/, PyObject* args)
|
// Write to stdout/stderr
|
||||||
|
PyObject* nymea_write(PyObject* /*self*/, PyObject* args)
|
||||||
{
|
{
|
||||||
const char *what;
|
const char *what;
|
||||||
if (!PyArg_ParseTuple(args, "s", &what))
|
if (!PyArg_ParseTuple(args, "s", &what))
|
||||||
@ -15,35 +17,53 @@ PyObject* aview_write(PyObject* /*self*/, PyObject* args)
|
|||||||
return Py_BuildValue("");
|
return Py_BuildValue("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flush stdout/stderr
|
||||||
PyObject* aview_flush(PyObject* /*self*/, PyObject* /*args*/)
|
PyObject* nymea_flush(PyObject* /*self*/, PyObject* /*args*/)
|
||||||
{
|
{
|
||||||
|
// Not really needed... qDebug() fluses already on its own
|
||||||
return Py_BuildValue("");
|
return Py_BuildValue("");
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef aview_methods[] =
|
static PyMethodDef nymea_methods[] =
|
||||||
{
|
{
|
||||||
{"write", aview_write, METH_VARARGS, "doc for write"},
|
{"write", nymea_write, METH_VARARGS, "write to stdout through qDebug()"},
|
||||||
{"flush", aview_flush, METH_VARARGS, "doc for flush"},
|
{"flush", nymea_flush, METH_VARARGS, "flush stdout (no-op)"},
|
||||||
{nullptr, nullptr, 0, nullptr} // sentinel
|
{nullptr, nullptr, 0, nullptr} // sentinel
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyModuleDef aview_module =
|
static PyModuleDef nymea_module =
|
||||||
{
|
{
|
||||||
PyModuleDef_HEAD_INIT, // PyModuleDef_Base m_base;
|
PyModuleDef_HEAD_INIT, // PyModuleDef_Base m_base;
|
||||||
"aview", // const char* m_name;
|
"nymea", // const char* m_name;
|
||||||
"doc for aview", // const char* m_doc;
|
"nymea module for python based integration plugins", // const char* m_doc;
|
||||||
-1, // Py_ssize_t m_size;
|
-1, // Py_ssize_t m_size;
|
||||||
aview_methods, // PyMethodDef *m_methods
|
nymea_methods, // PyMethodDef *m_methods
|
||||||
// inquiry m_reload; traverseproc m_traverse; inquiry m_clear; freefunc m_free;
|
// inquiry m_reload; traverseproc m_traverse; inquiry m_clear; freefunc m_free;
|
||||||
nullptr, nullptr, nullptr, nullptr
|
nullptr, nullptr, nullptr, nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
PyMODINIT_FUNC PyInit_aview(void)
|
PyMODINIT_FUNC PyInit_nymea(void)
|
||||||
{
|
{
|
||||||
PyObject* m = PyModule_Create(&aview_module);
|
PyObject* m = PyModule_Create(&nymea_module);
|
||||||
|
// Overrride stdout/stderr to use qDebug instead
|
||||||
PySys_SetObject("stdout", m);
|
PySys_SetObject("stdout", m);
|
||||||
PySys_SetObject("stderr", m);
|
PySys_SetObject("stderr", m);
|
||||||
|
|
||||||
|
|
||||||
|
PyThingDiscoveryInfoType.tp_new = PyType_GenericNew;
|
||||||
|
PyThingDiscoveryInfoType.tp_basicsize=sizeof(PyThingDiscoveryInfo);
|
||||||
|
PyThingDiscoveryInfoType.tp_dealloc=(destructor) PyThingDiscoveryInfo_dealloc;
|
||||||
|
PyThingDiscoveryInfoType.tp_flags=Py_TPFLAGS_DEFAULT;
|
||||||
|
PyThingDiscoveryInfoType.tp_doc="ThingDiscoveryInfo class";
|
||||||
|
PyThingDiscoveryInfoType.tp_methods=PyThingDiscoveryInfo_methods;
|
||||||
|
//~ PyVoiceType.tp_members=Noddy_members;
|
||||||
|
PyThingDiscoveryInfoType.tp_init=(initproc)PyThingDiscoveryInfo_init;
|
||||||
|
|
||||||
|
if (PyType_Ready(&PyThingDiscoveryInfoType) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
PyModule_AddObject(m, "ThingDiscoveryInfo", (PyObject *)&PyThingDiscoveryInfoType); // Add Voice object to the module
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,9 +75,9 @@ PythonIntegrationPlugin::PythonIntegrationPlugin(QObject *parent) : IntegrationP
|
|||||||
bool PythonIntegrationPlugin::loadScript(const QString &scriptFile)
|
bool PythonIntegrationPlugin::loadScript(const QString &scriptFile)
|
||||||
{
|
{
|
||||||
// TODO: Call this just once and call Py_Finalize()
|
// TODO: Call this just once and call Py_Finalize()
|
||||||
PyImport_AppendInittab("aview", PyInit_aview);
|
PyImport_AppendInittab("nymea", PyInit_nymea);
|
||||||
Py_Initialize();
|
Py_Initialize();
|
||||||
PyImport_ImportModule("aview");
|
PyImport_ImportModule("nymea");
|
||||||
|
|
||||||
QFileInfo fi(scriptFile);
|
QFileInfo fi(scriptFile);
|
||||||
qCDebug(dcThingManager()) << "Importing" << fi.absolutePath() << fi.fileName() << fi.baseName();
|
qCDebug(dcThingManager()) << "Importing" << fi.absolutePath() << fi.fileName() << fi.baseName();
|
||||||
@ -161,20 +181,36 @@ void PythonIntegrationPlugin::init()
|
|||||||
void PythonIntegrationPlugin::discoverThings(ThingDiscoveryInfo *info)
|
void PythonIntegrationPlugin::discoverThings(ThingDiscoveryInfo *info)
|
||||||
{
|
{
|
||||||
qCDebug(dcThingManager()) << "Python wrapper: discoverThings()" << info;
|
qCDebug(dcThingManager()) << "Python wrapper: discoverThings()" << info;
|
||||||
PyObject *pFunc = PyObject_GetAttrString(m_module, "init");
|
PyObject *pFunc = PyObject_GetAttrString(m_module, "discoverThings");
|
||||||
if(!pFunc || !PyCallable_Check(pFunc)) {
|
if(!pFunc || !PyCallable_Check(pFunc)) {
|
||||||
qCWarning(dcThingManager()) << "Python plugin does not implement \"discoverThings()\" method.";
|
qCWarning(dcThingManager()) << "Python plugin does not implement \"discoverThings()\" method.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// PyObject* args = Py_BuildValue("(s)", ln.c_str());
|
|
||||||
// if (!args)
|
|
||||||
// {
|
|
||||||
// PyErr_Print();
|
|
||||||
// Py_DECREF(filterFunc);
|
|
||||||
// return "Error building args tuple";
|
|
||||||
// }
|
|
||||||
|
|
||||||
// PyObject_CallObject(pFunc, nullptr);
|
PyThingDiscoveryInfo *pyInfo = (PyThingDiscoveryInfo*)_PyObject_New(&PyThingDiscoveryInfoType);
|
||||||
|
pyInfo->ptrObj = info;
|
||||||
|
|
||||||
|
connect(info, &ThingDiscoveryInfo::finished, this, [=](){
|
||||||
|
PyObject_Free(pyInfo);
|
||||||
|
});
|
||||||
|
|
||||||
|
PyObject_CallFunction(pFunc, "O", pyInfo);
|
||||||
|
|
||||||
|
if (PyErr_Occurred()) {
|
||||||
|
PyObject *ptype, *pvalue, *ptraceback;
|
||||||
|
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
|
||||||
|
if(pvalue) {
|
||||||
|
PyObject *pstr = PyObject_Str(pvalue);
|
||||||
|
if(pstr) {
|
||||||
|
const char* err_msg = PyUnicode_AsUTF8(pstr);
|
||||||
|
if(pstr) {
|
||||||
|
qWarning() << QString(err_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
PyErr_Restore(ptype, pvalue, ptraceback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@ RESOURCES += $$top_srcdir/icons.qrc \
|
|||||||
|
|
||||||
HEADERS += nymeacore.h \
|
HEADERS += nymeacore.h \
|
||||||
integrations/plugininfocache.h \
|
integrations/plugininfocache.h \
|
||||||
|
integrations/python/PyThingDiscoveryInfo.h \
|
||||||
integrations/thingmanagerimplementation.h \
|
integrations/thingmanagerimplementation.h \
|
||||||
integrations/translator.h \
|
integrations/translator.h \
|
||||||
integrations/pythonintegrationplugin.h \
|
integrations/pythonintegrationplugin.h \
|
||||||
|
|||||||
Reference in New Issue
Block a user