diff Sources/StorageCommitmentScpCallback.cpp @ 119:cf6decdf9e15

wrapped new SDK callback: orthanc.RegisterStorageCommitmentScpCallback()
author Alain Mazy <am@osimis.io>
date Mon, 28 Aug 2023 18:30:42 +0200
parents
children 71d305c29cfa
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sources/StorageCommitmentScpCallback.cpp	Mon Aug 28 18:30:42 2023 +0200
@@ -0,0 +1,186 @@
+/**
+ * Python plugin for Orthanc
+ * Copyright (C) 2020-2023 Osimis S.A., Belgium
+ * Copyright (C) 2021-2023 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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
+ * Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "StorageCommitmentScpCallback.h"
+
+#include "../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h"
+#include "ICallbackRegistration.h"
+#include "PythonString.h"
+
+
+static PyObject*   storageCommitmentScpCallback_ = NULL;
+static PyObject*   storageCommitmentLookupCallback_ = NULL;
+
+
+static OrthancPluginErrorCode StorageCommitmentSCPCallback(
+  void**              handler /* out */,
+  const char*         jobId,
+  const char*         transactionUid,
+  const char* const*  sopClassUids,
+  const char* const*  sopInstanceUids,
+  uint32_t            countInstances,
+  const char*         remoteAet,
+  const char*         calledAet)
+{
+  try
+  {
+    PythonLock lock;
+
+    PythonObject args(lock, PyTuple_New(6));
+    {
+      PythonString str(lock, jobId);
+      PyTuple_SetItem(args.GetPyObject(), 0, str.Release());
+    }
+    {
+      PythonString str(lock, transactionUid);
+      PyTuple_SetItem(args.GetPyObject(), 1, str.Release());
+    }
+    {
+      PythonObject sopClassUidList(lock, PyList_New(countInstances));
+      for (uint32_t i = 0; i < countInstances; i++)
+      {
+        PythonString str(lock, sopClassUids[i]);
+        PyList_SetItem(sopClassUidList.GetPyObject(), i, str.Release());
+      }
+      PyTuple_SetItem(args.GetPyObject(), 2, sopClassUidList.Release());
+      PythonObject sopInstanceUidList(lock, PyList_New(countInstances));
+      for (uint32_t i = 0; i < countInstances; i++)
+      {
+        PythonString str(lock, sopInstanceUids[i]);
+        PyList_SetItem(sopInstanceUidList.GetPyObject(), i, str.Release());
+      }
+      PyTuple_SetItem(args.GetPyObject(), 3, sopInstanceUidList.Release());
+    }
+    {
+      PythonString str(lock, remoteAet);
+      PyTuple_SetItem(args.GetPyObject(), 4, str.Release());
+    }
+    {
+      PythonString str(lock, calledAet);
+      PyTuple_SetItem(args.GetPyObject(), 5, str.Release());
+    }
+
+    PythonObject result(lock, PyObject_CallObject(storageCommitmentScpCallback_, args.GetPyObject()));
+    *handler = result.Release();
+
+    std::string traceback;
+    if (lock.HasErrorOccurred(traceback))
+    {
+      OrthancPlugins::LogError("Error in the Python storage commitment SCP callback, "
+                               "traceback:\n" + traceback);
+      return OrthancPluginErrorCode_Plugin;
+    }
+  }
+  catch (OrthancPlugins::PluginException& e)
+  {
+    OrthancPlugins::LogError("Error in the Python storage commitment SCP callback: " +
+                             std::string(e.What(OrthancPlugins::GetGlobalContext())));
+  }
+  return OrthancPluginErrorCode_Success;
+}
+
+static OrthancPluginErrorCode StorageCommitmentLookupCallback(
+  OrthancPluginStorageCommitmentFailureReason* target /* out */,
+  void*                                        handler,
+  const char*                                  sopClassUid,
+  const char*                                  sopInstanceUid)
+{
+  try
+  {
+    PythonLock lock;
+
+    PythonObject args(lock, PyTuple_New(3));
+    {
+      PythonString str(lock, sopClassUid);
+      PyTuple_SetItem(args.GetPyObject(), 0, str.Release());
+    }
+    {
+      PythonString str(lock, sopInstanceUid);
+      PyTuple_SetItem(args.GetPyObject(), 1, str.Release());
+    }
+    {
+      PyObject* data = (PyObject*) handler;
+      Py_INCREF(data);  // Keep a reference before it was stolen by PyTuple_SetItem.
+      PyTuple_SetItem(args.GetPyObject(), 2, data);
+    }
+
+    PythonObject result(lock, PyObject_CallObject(storageCommitmentLookupCallback_, args.GetPyObject()));
+
+    if (!PyLong_Check(result.GetPyObject()))
+    {
+      OrthancPlugins::LogError("The Python storage commitment Lookup callback has not returned an int as the return value");
+      return OrthancPluginErrorCode_Plugin;
+    }
+
+    *target = static_cast<OrthancPluginStorageCommitmentFailureReason>(PyLong_AsLong(result.GetPyObject()));
+
+    std::string traceback;
+    if (lock.HasErrorOccurred(traceback))
+    {
+      OrthancPlugins::LogError("Error in the Python storage commitment Lookup callback, "
+                               "traceback:\n" + traceback);
+      return OrthancPluginErrorCode_Plugin;
+    }
+  }
+  catch (OrthancPlugins::PluginException& e)
+  {
+    OrthancPlugins::LogError("Error in the Python storage commitment Lookup callback: " +
+                             std::string(e.What(OrthancPlugins::GetGlobalContext())));
+  }
+  return OrthancPluginErrorCode_Success;
+}
+
+static void StorageCommitmentDestructor(void *handler)
+{
+  PythonLock lock;
+  Py_DECREF((PyObject*)handler);  // Release the reference
+}
+
+PyObject* RegisterStorageCommitmentScpCallback(PyObject* module, PyObject* args)
+{
+  // The GIL is locked at this point (no need to create "PythonLock")
+
+  class Registration : public ICallbackRegistration
+  {
+  public:
+    virtual void Register() ORTHANC_OVERRIDE
+    {
+      OrthancPluginRegisterStorageCommitmentScpCallback(
+        OrthancPlugins::GetGlobalContext(),
+        StorageCommitmentSCPCallback,
+        StorageCommitmentDestructor,
+        StorageCommitmentLookupCallback);
+    }
+  };
+
+  {
+    Registration registration;
+    return ICallbackRegistration::Apply2(registration, args,
+      storageCommitmentScpCallback_,
+      storageCommitmentLookupCallback_,
+      "Python storage commitment SCP & Lookup callback");
+  }
+}
+
+void FinalizeStorageCommitmentScpCallback()
+{
+  ICallbackRegistration::Unregister(storageCommitmentScpCallback_);
+  ICallbackRegistration::Unregister(storageCommitmentLookupCallback_);
+}
\ No newline at end of file