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