nymea/libnymea-core/integrations/python/pyapikeystorage.h

156 lines
4.7 KiB
C

#ifndef PYAPIKEYSTORAGE_H
#define PYAPIKEYSTORAGE_H
#include <Python.h>
#include "structmember.h"
#include "pyutils.h"
#include "loggingcategories.h"
#include "nymeasettings.h"
#include "typeutils.h"
#include "network/apikeys/apikeystorage.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Winvalid-offsetof"
#pragma GCC diagnostic ignored "-Wwrite-strings"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
/* Note:
* When using this, make sure to call PyApiKeyStorage_setApiKeyStorage() while holding the GIL to initialize
* stuff after constructing it.
*
* The apiKeyStorage() pointer is owned by the C++ plugin class, however, without an actual C++
* plugin it will never be accessed by anyone. So we pass it into the python context and use it in
* there.
*
*/
typedef struct {
PyObject_HEAD
ApiKey *apiKey;
} PyApiKey;
static int PyApiKey_init(PyApiKey */*self*/, PyObject */*args*/, PyObject */*kwds*/)
{
qCDebug(dcPythonIntegrations()) << "+++ PyApiKey";
return 0;
}
void PyApiKey_setApiKey(PyApiKey *self, const ApiKey &apiKey)
{
self->apiKey = new ApiKey(apiKey);
}
static void PyApiKey_dealloc(PyApiKey* self)
{
qCDebug(dcPythonIntegrations()) << "--- PyApiKey";
delete self->apiKey;
Py_TYPE(self)->tp_free(self);
}
static PyObject * PyApiKey_data(PyApiKey* self, PyObject* args) {
char *keyStr = nullptr;
if (!PyArg_ParseTuple(args, "s", &keyStr)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments in value call. Expected: requestKey(key)");
return nullptr;
}
QByteArray data = self->apiKey->data(QString(keyStr));
return QVariantToPyObject(data);
};
static PyMethodDef PyApiKey_methods[] = {
{ "data", (PyCFunction)PyApiKey_data, METH_VARARGS, "Get data from the API key." },
{nullptr, nullptr, 0, nullptr} // sentinel
};
static PyTypeObject PyApiKeyType = {
PyVarObject_HEAD_INIT(NULL, 0)
"nymea.ApiKey", /* tp_name */
sizeof(PyApiKey), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)PyApiKey_dealloc, /* tp_dealloc */
};
typedef struct {
PyObject_HEAD
ApiKeyStorage *apiKeyStorage;
} PyApiKeyStorage;
static int PyApiKeyStorage_init(PyApiKeyStorage */*self*/, PyObject */*args*/, PyObject */*kwds*/)
{
qCDebug(dcPythonIntegrations()) << "+++ PyApiKeyStorage";
return 0;
}
void PyApiKeyStorage_setApiKeyStorage(PyApiKeyStorage *self, ApiKeyStorage *apiKeyStorage)
{
self->apiKeyStorage = apiKeyStorage;
}
static void PyApiKeyStorage_dealloc(PyApiKeyStorage * self)
{
qCDebug(dcPythonIntegrations()) << "--- PyApiKeyStorage";
Py_TYPE(self)->tp_free(self);
}
static PyObject * PyApiKeyStorage_requestKey(PyApiKeyStorage* self, PyObject* args) {
char *nameStr = nullptr;
if (!PyArg_ParseTuple(args, "s", &nameStr)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments in value call. Expected: requestKey(name)");
return nullptr;
}
PyApiKey *pyApiKey = (PyApiKey*)PyObject_CallObject((PyObject*)&PyApiKeyType, args);
PyApiKey_setApiKey(pyApiKey, self->apiKeyStorage->requestKey(nameStr));
return (PyObject*)pyApiKey;
};
static PyMethodDef PyApiKeyStorage_methods[] = {
{ "requestKey", (PyCFunction)PyApiKeyStorage_requestKey, METH_VARARGS, "Get an API key from the API key storage." },
{nullptr, nullptr, 0, nullptr} // sentinel
};
static PyTypeObject PyApiKeyStorageType = {
PyVarObject_HEAD_INIT(NULL, 0)
"nymea.ApiKeyStorage", /* tp_name */
sizeof(PyApiKeyStorage), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)PyApiKeyStorage_dealloc, /* tp_dealloc */
};
static void registerApiKeyStorageType(PyObject *module)
{
PyApiKeyStorageType.tp_new = PyType_GenericNew;
PyApiKeyStorageType.tp_methods = PyApiKeyStorage_methods;
PyApiKeyStorageType.tp_init = reinterpret_cast<initproc>(PyApiKeyStorage_init);
PyApiKeyStorageType.tp_doc = "ApiKeyStorage holds API keys. API keys need to be requested in the plugin JSON file.";
PyApiKeyStorageType.tp_flags = Py_TPFLAGS_DEFAULT;
if (PyType_Ready(&PyApiKeyStorageType) < 0) {
return;
}
PyModule_AddObject(module, "ApiKeyStorage", reinterpret_cast<PyObject*>(&PyApiKeyStorageType));
PyApiKeyType.tp_new = PyType_GenericNew;
PyApiKeyType.tp_methods = PyApiKey_methods;
PyApiKeyType.tp_init = reinterpret_cast<initproc>(PyApiKey_init);
PyApiKeyType.tp_doc = "ApiKey holds an API keys data as key-value pairs.";
PyApiKeyType.tp_flags = Py_TPFLAGS_DEFAULT;
if (PyType_Ready(&PyApiKeyType) < 0) {
return;
}
PyModule_AddObject(module, "ApiKey", reinterpret_cast<PyObject*>(&PyApiKeyType));
}
#pragma GCC diagnostic pop
#endif // PYAPIKEYSTORAGE_H