diff options
Diffstat (limited to 'python')
-rw-r--r-- | python/astra/plugin_c.pyx | 2 | ||||
-rw-r--r-- | python/astra/src/PythonPluginAlgorithm.cpp | 168 | ||||
-rw-r--r-- | python/astra/src/PythonPluginAlgorithm.h | 24 | ||||
-rw-r--r-- | python/astra/src/PythonPluginAlgorithmFactory.cpp | 211 | ||||
-rw-r--r-- | python/astra/src/PythonPluginAlgorithmFactory.h | 70 | ||||
-rw-r--r-- | python/builder.py | 3 |
6 files changed, 287 insertions, 191 deletions
diff --git a/python/astra/plugin_c.pyx b/python/astra/plugin_c.pyx index 2f473c1..2fd9a8f 100644 --- a/python/astra/plugin_c.pyx +++ b/python/astra/plugin_c.pyx @@ -45,7 +45,7 @@ cdef extern from "src/PythonPluginAlgorithm.h" namespace "astra": object getRegistered() string getHelp(string &name) -cdef extern from "src/PythonPluginAlgorithm.h" namespace "astra::CPythonPluginAlgorithmFactory": +cdef extern from "src/PythonPluginAlgorithmFactory.h" namespace "astra::CPythonPluginAlgorithmFactory": cdef CPythonPluginAlgorithmFactory* getSingletonPtr() cdef extern from "astra/PluginAlgorithmFactory.h" namespace "astra::CPluginAlgorithmFactory": diff --git a/python/astra/src/PythonPluginAlgorithm.cpp b/python/astra/src/PythonPluginAlgorithm.cpp index 3c892ff..b7ecdb5 100644 --- a/python/astra/src/PythonPluginAlgorithm.cpp +++ b/python/astra/src/PythonPluginAlgorithm.cpp @@ -130,172 +130,6 @@ PyObject *CPluginAlgorithm::getInstance() const { return instance; } - - -CPythonPluginAlgorithmFactory::CPythonPluginAlgorithmFactory(){ - if(!Py_IsInitialized()){ - Py_Initialize(); - PyEval_InitThreads(); - } - pluginDict = PyDict_New(); - inspect = PyImport_ImportModule("inspect"); - six = PyImport_ImportModule("six"); -} - -CPythonPluginAlgorithmFactory::~CPythonPluginAlgorithmFactory(){ - if(pluginDict!=NULL){ - Py_DECREF(pluginDict); - } - if(inspect!=NULL) Py_DECREF(inspect); - if(six!=NULL) Py_DECREF(six); -} - -PyObject * getClassFromString(std::string str){ - std::vector<std::string> items; - StringUtil::splitString(items, str, "."); - PyObject *pyclass = PyImport_ImportModule(items[0].c_str()); - if(pyclass==NULL){ - logPythonError(); - return NULL; - } - PyObject *submod = pyclass; - for(unsigned int i=1;i<items.size();i++){ - submod = PyObject_GetAttrString(submod,items[i].c_str()); - Py_DECREF(pyclass); - pyclass = submod; - if(pyclass==NULL){ - logPythonError(); - return NULL; - } - } - return pyclass; -} - -bool CPythonPluginAlgorithmFactory::registerPlugin(std::string name, std::string className){ - PyObject *str = PyBytes_FromString(className.c_str()); - PyDict_SetItemString(pluginDict, name.c_str(), str); - Py_DECREF(str); - return true; -} - -bool CPythonPluginAlgorithmFactory::registerPlugin(std::string className){ - PyObject *pyclass = getClassFromString(className); - if(pyclass==NULL) return false; - bool ret = registerPluginClass(pyclass); - Py_DECREF(pyclass); - return ret; -} - -bool CPythonPluginAlgorithmFactory::registerPluginClass(std::string name, PyObject * className){ - PyDict_SetItemString(pluginDict, name.c_str(), className); - return true; -} - -bool CPythonPluginAlgorithmFactory::registerPluginClass(PyObject * className){ - PyObject *astra_name = PyObject_GetAttrString(className,"astra_name"); - if(astra_name==NULL){ - logPythonError(); - return false; - } - PyObject *retb = PyObject_CallMethod(six,"b","O",astra_name); - if(retb!=NULL){ - PyDict_SetItemString(pluginDict,PyBytes_AsString(retb),className); - Py_DECREF(retb); - }else{ - logPythonError(); - } - Py_DECREF(astra_name); - return true; -} - -CAlgorithm * CPythonPluginAlgorithmFactory::getPlugin(const std::string &name){ - PyObject *className = PyDict_GetItemString(pluginDict, name.c_str()); - if(className==NULL) return NULL; - CPluginAlgorithm *alg = NULL; - if(PyBytes_Check(className)){ - std::string str = std::string(PyBytes_AsString(className)); - PyObject *pyclass = getClassFromString(str); - if(pyclass!=NULL){ - alg = new CPluginAlgorithm(pyclass); - Py_DECREF(pyclass); - } - }else{ - alg = new CPluginAlgorithm(className); - } - return alg; -} - -PyObject * CPythonPluginAlgorithmFactory::getRegistered(){ - Py_INCREF(pluginDict); - return pluginDict; -} - -std::map<std::string, std::string> CPythonPluginAlgorithmFactory::getRegisteredMap(){ - std::map<std::string, std::string> ret; - PyObject *key, *value; - Py_ssize_t pos = 0; - while (PyDict_Next(pluginDict, &pos, &key, &value)) { - PyObject *keystr = PyObject_Str(key); - if(keystr!=NULL){ - PyObject *valstr = PyObject_Str(value); - if(valstr!=NULL){ - PyObject * keyb = PyObject_CallMethod(six,"b","O",keystr); - if(keyb!=NULL){ - PyObject * valb = PyObject_CallMethod(six,"b","O",valstr); - if(valb!=NULL){ - ret[PyBytes_AsString(keyb)] = PyBytes_AsString(valb); - Py_DECREF(valb); - } - Py_DECREF(keyb); - } - Py_DECREF(valstr); - } - Py_DECREF(keystr); - } - logPythonError(); - } - return ret; -} - -std::string CPythonPluginAlgorithmFactory::getHelp(const std::string &name){ - PyObject *className = PyDict_GetItemString(pluginDict, name.c_str()); - if(className==NULL){ - ASTRA_ERROR("Plugin %s not found!",name.c_str()); - PyErr_Clear(); - return ""; - } - std::string ret = ""; - PyObject *pyclass; - if(PyBytes_Check(className)){ - std::string str = std::string(PyBytes_AsString(className)); - pyclass = getClassFromString(str); - }else{ - pyclass = className; - } - if(pyclass==NULL) return ""; - if(inspect!=NULL && six!=NULL){ - PyObject *retVal = PyObject_CallMethod(inspect,"getdoc","O",pyclass); - if(retVal!=NULL){ - if(retVal!=Py_None){ - PyObject *retb = PyObject_CallMethod(six,"b","O",retVal); - if(retb!=NULL){ - ret = std::string(PyBytes_AsString(retb)); - Py_DECREF(retb); - } - } - Py_DECREF(retVal); - }else{ - logPythonError(); - } - } - if(PyBytes_Check(className)){ - Py_DECREF(pyclass); - } - return ret; -} - -DEFINE_SINGLETON(CPythonPluginAlgorithmFactory); - #if PY_MAJOR_VERSION >= 3 PyObject * pyStringFromString(std::string str){ return PyUnicode_FromString(str.c_str()); @@ -374,5 +208,7 @@ PyObject* XMLNode2dict(XMLNode node){ return dct; } + } + #endif diff --git a/python/astra/src/PythonPluginAlgorithm.h b/python/astra/src/PythonPluginAlgorithm.h index f2fd76d..791e9ba 100644 --- a/python/astra/src/PythonPluginAlgorithm.h +++ b/python/astra/src/PythonPluginAlgorithm.h @@ -57,30 +57,6 @@ private: }; -class CPythonPluginAlgorithmFactory : public CPluginAlgorithmFactory, public Singleton<CPythonPluginAlgorithmFactory> { - -public: - - CPythonPluginAlgorithmFactory(); - virtual ~CPythonPluginAlgorithmFactory(); - - virtual CAlgorithm * getPlugin(const std::string &name); - - virtual bool registerPlugin(std::string name, std::string className); - virtual bool registerPlugin(std::string className); - bool registerPluginClass(std::string name, PyObject * className); - bool registerPluginClass(PyObject * className); - - PyObject * getRegistered(); - virtual std::map<std::string, std::string> getRegisteredMap(); - - virtual std::string getHelp(const std::string &name); - -private: - PyObject * pluginDict; - PyObject *inspect, *six; -}; - PyObject* XMLNode2dict(XMLNode node); } diff --git a/python/astra/src/PythonPluginAlgorithmFactory.cpp b/python/astra/src/PythonPluginAlgorithmFactory.cpp new file mode 100644 index 0000000..8fee6fb --- /dev/null +++ b/python/astra/src/PythonPluginAlgorithmFactory.cpp @@ -0,0 +1,211 @@ +/* +----------------------------------------------------------------------- +Copyright: 2010-2016, imec Vision Lab, University of Antwerp + 2014-2018, CWI, Amsterdam + +Contact: astra@astra-toolbox.com +Website: http://www.astra-toolbox.com/ + +This file is part of the ASTRA Toolbox. + + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. + +----------------------------------------------------------------------- +*/ + +#ifdef ASTRA_PYTHON + +#include "PythonPluginAlgorithmFactory.h" +#include "PythonPluginAlgorithm.h" + +#include "astra/Logging.h" +#include "astra/Utilities.h" +#include <iostream> +#include <fstream> +#include <string> + +#include <Python.h> +#include "bytesobject.h" + +namespace astra { + +void logPythonError(); + +CPythonPluginAlgorithmFactory::CPythonPluginAlgorithmFactory(){ + if(!Py_IsInitialized()){ + Py_Initialize(); + PyEval_InitThreads(); + } + pluginDict = PyDict_New(); + inspect = PyImport_ImportModule("inspect"); + six = PyImport_ImportModule("six"); +} + +CPythonPluginAlgorithmFactory::~CPythonPluginAlgorithmFactory(){ + if(pluginDict!=NULL){ + Py_DECREF(pluginDict); + } + if(inspect!=NULL) Py_DECREF(inspect); + if(six!=NULL) Py_DECREF(six); +} + +PyObject * getClassFromString(std::string str){ + std::vector<std::string> items; + StringUtil::splitString(items, str, "."); + PyObject *pyclass = PyImport_ImportModule(items[0].c_str()); + if(pyclass==NULL){ + logPythonError(); + return NULL; + } + PyObject *submod = pyclass; + for(unsigned int i=1;i<items.size();i++){ + submod = PyObject_GetAttrString(submod,items[i].c_str()); + Py_DECREF(pyclass); + pyclass = submod; + if(pyclass==NULL){ + logPythonError(); + return NULL; + } + } + return pyclass; +} + +bool CPythonPluginAlgorithmFactory::registerPlugin(std::string name, std::string className){ + PyObject *str = PyBytes_FromString(className.c_str()); + PyDict_SetItemString(pluginDict, name.c_str(), str); + Py_DECREF(str); + return true; +} + +bool CPythonPluginAlgorithmFactory::registerPlugin(std::string className){ + PyObject *pyclass = getClassFromString(className); + if(pyclass==NULL) return false; + bool ret = registerPluginClass(pyclass); + Py_DECREF(pyclass); + return ret; +} + +bool CPythonPluginAlgorithmFactory::registerPluginClass(std::string name, PyObject * className){ + PyDict_SetItemString(pluginDict, name.c_str(), className); + return true; +} + +bool CPythonPluginAlgorithmFactory::registerPluginClass(PyObject * className){ + PyObject *astra_name = PyObject_GetAttrString(className,"astra_name"); + if(astra_name==NULL){ + logPythonError(); + return false; + } + PyObject *retb = PyObject_CallMethod(six,"b","O",astra_name); + if(retb!=NULL){ + PyDict_SetItemString(pluginDict,PyBytes_AsString(retb),className); + Py_DECREF(retb); + }else{ + logPythonError(); + } + Py_DECREF(astra_name); + return true; +} + +CAlgorithm * CPythonPluginAlgorithmFactory::getPlugin(const std::string &name){ + PyObject *className = PyDict_GetItemString(pluginDict, name.c_str()); + if(className==NULL) return NULL; + CPluginAlgorithm *alg = NULL; + if(PyBytes_Check(className)){ + std::string str = std::string(PyBytes_AsString(className)); + PyObject *pyclass = getClassFromString(str); + if(pyclass!=NULL){ + alg = new CPluginAlgorithm(pyclass); + Py_DECREF(pyclass); + } + }else{ + alg = new CPluginAlgorithm(className); + } + return alg; +} + +PyObject * CPythonPluginAlgorithmFactory::getRegistered(){ + Py_INCREF(pluginDict); + return pluginDict; +} + +std::map<std::string, std::string> CPythonPluginAlgorithmFactory::getRegisteredMap(){ + std::map<std::string, std::string> ret; + PyObject *key, *value; + Py_ssize_t pos = 0; + while (PyDict_Next(pluginDict, &pos, &key, &value)) { + PyObject *keystr = PyObject_Str(key); + if(keystr!=NULL){ + PyObject *valstr = PyObject_Str(value); + if(valstr!=NULL){ + PyObject * keyb = PyObject_CallMethod(six,"b","O",keystr); + if(keyb!=NULL){ + PyObject * valb = PyObject_CallMethod(six,"b","O",valstr); + if(valb!=NULL){ + ret[PyBytes_AsString(keyb)] = PyBytes_AsString(valb); + Py_DECREF(valb); + } + Py_DECREF(keyb); + } + Py_DECREF(valstr); + } + Py_DECREF(keystr); + } + logPythonError(); + } + return ret; +} + +std::string CPythonPluginAlgorithmFactory::getHelp(const std::string &name){ + PyObject *className = PyDict_GetItemString(pluginDict, name.c_str()); + if(className==NULL){ + ASTRA_ERROR("Plugin %s not found!",name.c_str()); + PyErr_Clear(); + return ""; + } + std::string ret = ""; + PyObject *pyclass; + if(PyBytes_Check(className)){ + std::string str = std::string(PyBytes_AsString(className)); + pyclass = getClassFromString(str); + }else{ + pyclass = className; + } + if(pyclass==NULL) return ""; + if(inspect!=NULL && six!=NULL){ + PyObject *retVal = PyObject_CallMethod(inspect,"getdoc","O",pyclass); + if(retVal!=NULL){ + if(retVal!=Py_None){ + PyObject *retb = PyObject_CallMethod(six,"b","O",retVal); + if(retb!=NULL){ + ret = std::string(PyBytes_AsString(retb)); + Py_DECREF(retb); + } + } + Py_DECREF(retVal); + }else{ + logPythonError(); + } + } + if(PyBytes_Check(className)){ + Py_DECREF(pyclass); + } + return ret; +} + +DEFINE_SINGLETON(CPythonPluginAlgorithmFactory); + +} +#endif diff --git a/python/astra/src/PythonPluginAlgorithmFactory.h b/python/astra/src/PythonPluginAlgorithmFactory.h new file mode 100644 index 0000000..9cb567e --- /dev/null +++ b/python/astra/src/PythonPluginAlgorithmFactory.h @@ -0,0 +1,70 @@ +/* +----------------------------------------------------------------------- +Copyright: 2010-2018, imec Vision Lab, University of Antwerp + 2014-2018, CWI, Amsterdam + +Contact: astra@astra-toolbox.com +Website: http://www.astra-toolbox.com/ + +This file is part of the ASTRA Toolbox. + + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. + +----------------------------------------------------------------------- +*/ + +#ifndef _INC_PYTHONPLUGINALGORITHMFACTORY +#define _INC_PYTHONPLUGINALGORITHMFACTORY + +#ifdef ASTRA_PYTHON + +#include "astra/Singleton.h" +#include "astra/Algorithm.h" +#include "astra/PluginAlgorithmFactory.h" + +#include <Python.h> + +namespace astra { + +class CPythonPluginAlgorithmFactory : public CPluginAlgorithmFactory, public Singleton<CPythonPluginAlgorithmFactory> { + +public: + + CPythonPluginAlgorithmFactory(); + virtual ~CPythonPluginAlgorithmFactory(); + + virtual CAlgorithm * getPlugin(const std::string &name); + + virtual bool registerPlugin(std::string name, std::string className); + virtual bool registerPlugin(std::string className); + bool registerPluginClass(std::string name, PyObject * className); + bool registerPluginClass(PyObject * className); + + PyObject * getRegistered(); + virtual std::map<std::string, std::string> getRegisteredMap(); + + virtual std::string getHelp(const std::string &name); + +private: + PyObject * pluginDict; + PyObject *inspect, *six; +}; + +} + + +#endif + +#endif diff --git a/python/builder.py b/python/builder.py index b373366..81636a1 100644 --- a/python/builder.py +++ b/python/builder.py @@ -69,6 +69,9 @@ for m in ext_modules: if m.name in ('astra.plugin_c', 'astra.algorithm_c'): m.sources.append(os.path.join(self_path, 'astra', 'src', 'PythonPluginAlgorithm.cpp')) + if m.name in ('astra.plugin_c'): + m.sources.append(os.path.join(self_path, 'astra', 'src', + 'PythonPluginAlgorithmFactory.cpp')) setup(name='astra-toolbox', version='1.9.0dev', |