From d1339c5bce73d19636849c3bb6019307cf42d7dc Mon Sep 17 00:00:00 2001 From: acpaquette <acp263@nau.edu> Date: Mon, 3 Jan 2022 10:59:40 -0700 Subject: [PATCH] Exposed the verbose and indent fields in the ale load methods --- include/ale/Load.h | 2 +- src/Load.cpp | 180 ++++++++++++++++++++++++--------------------- 2 files changed, 98 insertions(+), 84 deletions(-) diff --git a/include/ale/Load.h b/include/ale/Load.h index 56b5be1..7485740 100644 --- a/include/ale/Load.h +++ b/include/ale/Load.h @@ -26,7 +26,7 @@ namespace ale { * * @returns A string containing a JSON formatted ISD for the image. */ - std::string loads(std::string filename, std::string props="", std::string formatter="usgscsm", bool verbose=true); + std::string loads(std::string filename, std::string props="", std::string formatter="usgscsm", int indent = 2, bool verbose=true); /** * Load all of the metadata for an image into a JSON ISD. diff --git a/src/Load.cpp b/src/Load.cpp index e297593..c1dc71d 100644 --- a/src/Load.cpp +++ b/src/Load.cpp @@ -12,7 +12,7 @@ using json = nlohmann::json; using namespace std; namespace ale { - std::string getPyTraceback() { + std::string getPyTraceback() { PyObject* err = PyErr_Occurred(); if (err != NULL) { PyObject *ptype, *pvalue, *ptraceback; @@ -57,86 +57,100 @@ namespace ale { // no traceback to return return ""; - } - - std::string loads(std::string filename, std::string props, std::string formatter, bool verbose) { - static bool first_run = true; - if(first_run) { - // Initialize the Python interpreter but only once. - first_run = !first_run; - Py_Initialize(); - } - - // Import the file as a Python module. - PyObject *pModule = PyImport_Import(PyUnicode_FromString("ale")); - if(!pModule) { - throw runtime_error("Failed to import ale. Make sure the ale python library is correctly installed."); - } - // Create a dictionary for the contents of the module. - PyObject *pDict = PyModule_GetDict(pModule); - - // Get the add method from the dictionary. - PyObject *pFunc = PyDict_GetItemString(pDict, "loads"); - if(!pFunc) { - // import errors do not set a PyError flag, need to use a custom - // error message instead. - throw runtime_error("Failed to import ale.loads function from Python." - "This Usually indicates an error in the Ale Python Library." - "Check if Installed correctly and the function ale.loads exists."); - } - - - // Create a Python tuple to hold the arguments to the method. - PyObject *pArgs = PyTuple_New(3); - if(!pArgs) { - throw runtime_error(getPyTraceback()); - } - - // Set the Python int as the first and second arguments to the method. - PyObject *pStringFileName = PyUnicode_FromString(filename.c_str()); - PyTuple_SetItem(pArgs, 0, pStringFileName); - Py_INCREF(pStringFileName); // take ownership of reference - - PyObject *pStringProps = PyUnicode_FromString(props.c_str()); - PyTuple_SetItem(pArgs, 1, pStringProps); - Py_INCREF(pStringProps); // take ownership of reference - - PyObject *pStringFormatter = PyUnicode_FromString(formatter.c_str()); - PyTuple_SetItem(pArgs, 2, pStringFormatter); - Py_INCREF(pStringFormatter); // take ownership of reference - - - // Call the function with the arguments. - PyObject* pResult = PyObject_CallObject(pFunc, pArgs); - if(!pResult) { - throw invalid_argument("No Valid instrument found for label."); - } - - PyObject *pResultStr = PyObject_Str(pResult); - PyObject *temp_bytes = PyUnicode_AsUTF8String(pResultStr); // Owned reference - - if(!temp_bytes){ - throw invalid_argument(getPyTraceback()); - } - - std::string cResult; - - char *temp_str = PyBytes_AS_STRING(temp_bytes); // Borrowed pointer - cResult = temp_str; // copy into std::string - - Py_DECREF(pResultStr); - - Py_DECREF(pStringFileName); - Py_DECREF(pStringProps); - Py_DECREF(pStringFormatter); - - Py_DECREF(pArgs); - - return cResult; - } - - json load(std::string filename, std::string props, std::string formatter, bool verbose) { - std::string jsonstr = loads(filename, props, formatter, verbose); - return json::parse(jsonstr); - } + } + + std::string loads(std::string filename, std::string props, std::string formatter, int indent, bool verbose) { + static bool first_run = true; + + if(first_run) { + // Initialize the Python interpreter but only once. + first_run = !first_run; + Py_Initialize(); + } + + // Import the file as a Python module. + PyObject *pModule = PyImport_Import(PyUnicode_FromString("ale")); + if(!pModule) { + throw runtime_error("Failed to import ale. Make sure the ale python library is correctly installed."); + } + // Create a dictionary for the contents of the module. + PyObject *pDict = PyModule_GetDict(pModule); + + // Get the add method from the dictionary. + PyObject *pFunc = PyDict_GetItemString(pDict, "loads"); + if(!pFunc) { + // import errors do not set a PyError flag, need to use a custom + // error message instead. + throw runtime_error("Failed to import ale.loads function from Python." + "This Usually indicates an error in the Ale Python Library." + "Check if Installed correctly and the function ale.loads exists."); + } + + + // Create a Python tuple to hold the arguments to the method. + PyObject *pArgs = PyTuple_New(5); + if(!pArgs) { + throw runtime_error(getPyTraceback()); + } + + // Set the Python int as the first and second arguments to the method. + PyObject *pStringFileName = PyUnicode_FromString(filename.c_str()); + PyTuple_SetItem(pArgs, 0, pStringFileName); + Py_INCREF(pStringFileName); // take ownership of reference + + PyObject *pStringProps = PyUnicode_FromString(props.c_str()); + PyTuple_SetItem(pArgs, 1, pStringProps); + Py_INCREF(pStringProps); // take ownership of reference + + PyObject *pStringFormatter = PyUnicode_FromString(formatter.c_str()); + PyTuple_SetItem(pArgs, 2, pStringFormatter); + Py_INCREF(pStringFormatter); // take ownership of reference + + PyObject *pIntIndent = PyLong_FromLong((long) indent); + PyTuple_SetItem(pArgs, 3, pIntIndent); + Py_INCREF(pIntIndent); // take ownership of reference + + PyObject *pBoolVerbose = Py_False; + if (!verbose) { + pBoolVerbose = Py_True; + } + PyTuple_SetItem(pArgs, 4, pBoolVerbose); + Py_INCREF(pBoolVerbose); // take ownership of reference + + + // Call the function with the arguments. + PyObject* pResult = PyObject_CallObject(pFunc, pArgs); + if(!pResult) { + throw invalid_argument("No Valid instrument found for label."); + } + + PyObject *pResultStr = PyObject_Str(pResult); + PyObject *temp_bytes = PyUnicode_AsUTF8String(pResultStr); // Owned reference + + if(!temp_bytes){ + throw invalid_argument(getPyTraceback()); + } + + std::string cResult; + + char *temp_str = PyBytes_AS_STRING(temp_bytes); // Borrowed pointer + cResult = temp_str; // copy into std::string + + Py_DECREF(pResultStr); + + Py_DECREF(pStringFileName); + Py_DECREF(pStringProps); + Py_DECREF(pStringFormatter); + Py_DECREF(pIntIndent); + Py_DECREF(pBoolVerbose); + + Py_DECREF(pArgs); + + return cResult; + } + + json load(std::string filename, std::string props, std::string formatter, bool verbose) { + std::string jsonstr = loads(filename, props, formatter, verbose); + return json::parse(jsonstr); + } } -- GitLab