/*
-----------------------------------------------------------------------
Copyright: 2010-2016, imec Vision Lab, University of Antwerp
2014-2021, 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 .
-----------------------------------------------------------------------
*/
#ifdef ASTRA_PYTHON
#include "PythonPluginAlgorithmFactory.h"
#include "PythonPluginAlgorithm.h"
#include "astra/Logging.h"
#include "astra/Utilities.h"
#include
#include
#include
#include
#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 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 CPythonPluginAlgorithmFactory::getRegisteredMap(){
std::map 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