#ifndef PYAPIKEYSTORAGE_H #define PYAPIKEYSTORAGE_H #include #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(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(&PyApiKeyStorageType)); PyApiKeyType.tp_new = PyType_GenericNew; PyApiKeyType.tp_methods = PyApiKey_methods; PyApiKeyType.tp_init = reinterpret_cast(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(&PyApiKeyType)); } #pragma GCC diagnostic pop #endif // PYAPIKEYSTORAGE_H