# HG changeset patch # User Sebastien Jodogne # Date 1623395023 -7200 # Node ID 091fb1903bfc2ab1ab3e7737e5dfd56b345fa8fe # Parent 32de70a1e4c77c4c4296019704ad920415291fe3 new wrapped function: orthanc.RegisterWorklistCallback() and orthanc.WorklistAnswers.WorklistAddAnswer() diff -r 32de70a1e4c7 -r 091fb1903bfc CodeAnalysis/ParseOrthancSDK.py --- a/CodeAnalysis/ParseOrthancSDK.py Thu Jun 10 18:19:27 2021 +0200 +++ b/CodeAnalysis/ParseOrthancSDK.py Fri Jun 11 09:03:43 2021 +0200 @@ -48,6 +48,8 @@ 'OrthancPluginRegisterOnStoredInstanceCallback', 'OrthancPluginRegisterRestCallback', # Implemented using OrthancPlugins::RegisterRestCallback 'OrthancPluginRegisterRestCallbackNoLock', # Implemented using OrthancPlugins::RegisterRestCallback + 'OrthancPluginRegisterWorklistCallback', + 'OrthancPluginWorklistAddAnswer', } CUSTOM_METHODS = [ @@ -63,6 +65,12 @@ 'implementation' : 'GetFindQueryTagElement', 'sdk_function' : 'OrthancPluginGetFindQueryTag', }, + { + 'class_name' : 'OrthancPluginWorklistAnswers', + 'method_name' : 'WorklistAddAnswer', + 'implementation' : 'WorklistAddAnswer', + 'sdk_function' : 'OrthancPluginWorklistAddAnswer', + }, ] diff -r 32de70a1e4c7 -r 091fb1903bfc NEWS --- a/NEWS Thu Jun 10 18:19:27 2021 +0200 +++ b/NEWS Fri Jun 11 09:03:43 2021 +0200 @@ -3,10 +3,12 @@ * New functions from the SDK wrapped in Python: - orthanc.CreateDicom() + - orthanc.FindQuery.GetFindQueryTagElement() + - orthanc.FindQuery.GetFindQueryTagGroup() - orthanc.RegisterFindCallback() - orthanc.RegisterMoveCallback() - - orthanc.FindQuery.GetFindQueryTagGroup() - - orthanc.FindQuery.GetFindQueryTagElement() + - orthanc.RegisterWorklistCallback() + - orthanc.WorklistAnswers.WorklistAddAnswer() Version 3.1 (2021-01-22) diff -r 32de70a1e4c7 -r 091fb1903bfc Sources/Autogenerated/sdk_OrthancPluginWorklistAnswers.impl.h --- a/Sources/Autogenerated/sdk_OrthancPluginWorklistAnswers.impl.h Thu Jun 10 18:19:27 2021 +0200 +++ b/Sources/Autogenerated/sdk_OrthancPluginWorklistAnswers.impl.h Fri Jun 11 09:03:43 2021 +0200 @@ -24,6 +24,8 @@ // Forward declaration of the custom methods +extern PyObject *WorklistAddAnswer( + sdk_OrthancPluginWorklistAnswers_Object* self, PyObject *args); // End of forward declarations @@ -31,6 +33,9 @@ { "WorklistMarkIncomplete", (PyCFunction) sdk_OrthancPluginWorklistAnswers_OrthancPluginWorklistMarkIncomplete, METH_VARARGS, "Generated from C function OrthancPluginWorklistMarkIncomplete()" }, + { "WorklistAddAnswer", + (PyCFunction) WorklistAddAnswer, METH_VARARGS, + "Generated from C function OrthancPluginWorklistAddAnswer()" }, { NULL } /* Sentinel */ }; diff -r 32de70a1e4c7 -r 091fb1903bfc Sources/DicomScpCallbacks.cpp --- a/Sources/DicomScpCallbacks.cpp Thu Jun 10 18:19:27 2021 +0200 +++ b/Sources/DicomScpCallbacks.cpp Fri Jun 11 09:03:43 2021 +0200 @@ -27,6 +27,7 @@ static PyObject* findScpCallback_ = NULL; static PyObject* moveScpCallback_ = NULL; +static PyObject* worklistScpCallback_ = NULL; static PyObject *GetFindQueryTag(sdk_OrthancPluginFindQuery_Object* self, @@ -70,12 +71,56 @@ return GetFindQueryTag(self, args, true); } - PyObject *GetFindQueryTagElement(sdk_OrthancPluginFindQuery_Object* self, PyObject *args) { return GetFindQueryTag(self, args, false); } +PyObject *WorklistAddAnswer(sdk_OrthancPluginWorklistAnswers_Object* self, PyObject *args) +{ + PyObject* query = NULL; + Py_buffer dicom; + + if (self->object_ == NULL) + { + PyErr_SetString(PyExc_ValueError, "Invalid object"); + return NULL; + } + else if (!PyArg_ParseTuple(args, "Os*", &query, &dicom)) + { + PyErr_SetString(PyExc_TypeError, "Please provide a orthanc.WorklistQuery object, and a DICOM buffer"); + return NULL; + } + else if (query == Py_None || + Py_TYPE(query) != GetOrthancPluginWorklistQueryType()) + { + PyErr_SetString(PyExc_TypeError, "Invalid orthanc.WorklistQuery object"); + return NULL; + } + else + { + OrthancPluginErrorCode code = OrthancPluginWorklistAddAnswer( + OrthancPlugins::GetGlobalContext(), self->object_, + reinterpret_cast(query)->object_, + dicom.buf, dicom.len); + + PyBuffer_Release(&dicom); + + if (code == OrthancPluginErrorCode_Success) + { + Py_INCREF(Py_None); + return Py_None; + } + else + { + PyErr_SetString(PyExc_ValueError, "Internal error"); + return NULL; + } + } +} +// End of "CUSTOM_METHODS" + + static OrthancPluginErrorCode FindCallback(OrthancPluginFindAnswers *answers, const OrthancPluginFindQuery *query, @@ -349,6 +394,55 @@ delete reinterpret_cast(moveDriver); } + + +OrthancPluginErrorCode WorklistCallback(OrthancPluginWorklistAnswers *answers, + const OrthancPluginWorklistQuery *query, + const char *issuerAet, + const char *calledAet) +{ + try + { + PythonLock lock; + + PyObject *pAnswers, *pQuery; + + { + PythonObject args(lock, PyTuple_New(2)); + PyTuple_SetItem(args.GetPyObject(), 0, PyLong_FromSsize_t((intptr_t) answers)); + PyTuple_SetItem(args.GetPyObject(), 1, PyBool_FromLong(true /* borrowed, don't destruct */)); + pAnswers = PyObject_CallObject((PyObject *) GetOrthancPluginWorklistAnswersType(), args.GetPyObject()); + } + + { + PythonObject args(lock, PyTuple_New(2)); + PyTuple_SetItem(args.GetPyObject(), 0, PyLong_FromSsize_t((intptr_t) query)); + PyTuple_SetItem(args.GetPyObject(), 1, PyBool_FromLong(true /* borrowed, don't destruct */)); + pQuery = PyObject_CallObject((PyObject *) GetOrthancPluginWorklistQueryType(), args.GetPyObject()); + } + + PythonString pIssuerAet(lock, issuerAet); + PythonString pCalledAet(lock, calledAet); + + { + PythonObject args(lock, PyTuple_New(4)); + PyTuple_SetItem(args.GetPyObject(), 0, pAnswers); + PyTuple_SetItem(args.GetPyObject(), 1, pQuery); + PyTuple_SetItem(args.GetPyObject(), 2, pIssuerAet.Release()); + PyTuple_SetItem(args.GetPyObject(), 3, pCalledAet.Release()); + + assert(worklistScpCallback_ != NULL); + PythonObject result(lock, PyObject_CallObject(worklistScpCallback_, args.GetPyObject())); + } + + return lock.CheckCallbackSuccess("Python C-FIND SCP for worklist callback"); + } + catch (OrthancPlugins::PluginException& e) + { + return e.GetErrorCode(); + } +} + PyObject* RegisterFindCallback(PyObject* module, PyObject* args) { @@ -389,8 +483,28 @@ } +PyObject* RegisterWorklistCallback(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 + { + OrthancPluginRegisterWorklistCallback(OrthancPlugins::GetGlobalContext(), WorklistCallback); + } + }; + + Registration registration; + return ICallbackRegistration::Apply( + registration, args, worklistScpCallback_, "Python C-FIND SCP for worklist callback"); +} + + void FinalizeDicomScpCallbacks() { ICallbackRegistration::Unregister(findScpCallback_); ICallbackRegistration::Unregister(moveScpCallback_); + ICallbackRegistration::Unregister(worklistScpCallback_); } diff -r 32de70a1e4c7 -r 091fb1903bfc Sources/DicomScpCallbacks.h --- a/Sources/DicomScpCallbacks.h Thu Jun 10 18:19:27 2021 +0200 +++ b/Sources/DicomScpCallbacks.h Fri Jun 11 09:03:43 2021 +0200 @@ -25,4 +25,6 @@ PyObject* RegisterMoveCallback(PyObject* module, PyObject* args); +PyObject* RegisterWorklistCallback(PyObject* module, PyObject* args); + void FinalizeDicomScpCallbacks(); diff -r 32de70a1e4c7 -r 091fb1903bfc Sources/Plugin.cpp --- a/Sources/Plugin.cpp Thu Jun 10 18:19:27 2021 +0200 +++ b/Sources/Plugin.cpp Fri Jun 11 09:03:43 2021 +0200 @@ -152,7 +152,7 @@ /** - * New in release 3.1 + * New in release 3.2 **/ { @@ -170,6 +170,11 @@ functions.push_back(f); } + { + PyMethodDef f = { "RegisterWorklistCallback", RegisterWorklistCallback, METH_VARARGS, "" }; + functions.push_back(f); + } + /** * Append all the global functions that were automatically generated