Mercurial > hg > orthanc-python
annotate Sources/Plugin.cpp @ 63:32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 10 Jun 2021 18:19:27 +0200 |
parents | 23f3099bed47 |
children | 091fb1903bfc |
rev | line source |
---|---|
0 | 1 /** |
2 * Python plugin for Orthanc | |
56
23f3099bed47
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
3 * Copyright (C) 2020-2021 Osimis S.A., Belgium |
0 | 4 * |
5 * This program is free software: you can redistribute it and/or | |
6 * modify it under the terms of the GNU Affero General Public License | |
7 * as published by the Free Software Foundation, either version 3 of | |
8 * the License, or (at your option) any later version. | |
9 * | |
10 * This program is distributed in the hope that it will be useful, but | |
11 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Affero General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Affero General Public License | |
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
17 **/ | |
18 | |
19 | |
20 // http://edcjones.tripod.com/refcount.html | |
21 // https://docs.python.org/3/extending/extending.html | |
22 | |
23 // https://www.codevate.com/blog/7-concurrency-with-embedded-python-in-a-multi-threaded-c-application | |
24 // https://fr.slideshare.net/YiLungTsai/embed-python | |
25 | |
26 | |
63
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
27 #include "DicomScpCallbacks.h" |
50
70abe3ebbbfc
New Python function: "orthanc.RegisterIncomingHttpRequestFilter()"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
47
diff
changeset
|
28 #include "IncomingHttpRequestFilter.h" |
70abe3ebbbfc
New Python function: "orthanc.RegisterIncomingHttpRequestFilter()"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
47
diff
changeset
|
29 #include "OnChangeCallback.h" |
0 | 30 #include "OnStoredInstanceCallback.h" |
50
70abe3ebbbfc
New Python function: "orthanc.RegisterIncomingHttpRequestFilter()"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
47
diff
changeset
|
31 |
0 | 32 #include "RestCallbacks.h" |
33 #include "PythonModule.h" | |
34 | |
35 #include "Autogenerated/sdk.h" | |
36 | |
36
fd58eb5749ed
CMake simplification using DownloadOrthancFramework.cmake
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
11
diff
changeset
|
37 #include "../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h" |
0 | 38 |
39 #include <boost/algorithm/string/predicate.hpp> | |
40 #include <boost/filesystem.hpp> | |
41 | |
47
42de8b600c0c
Support of Apple OS X
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
36
diff
changeset
|
42 |
42de8b600c0c
Support of Apple OS X
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
36
diff
changeset
|
43 // The "dl_iterate_phdr()" function (to walk through shared libraries) |
42de8b600c0c
Support of Apple OS X
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
36
diff
changeset
|
44 // is not available on Microsoft Windows and Apple OS X |
42de8b600c0c
Support of Apple OS X
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
36
diff
changeset
|
45 #if defined(_WIN32) |
42de8b600c0c
Support of Apple OS X
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
36
diff
changeset
|
46 # define HAS_DL_ITERATE 0 |
42de8b600c0c
Support of Apple OS X
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
36
diff
changeset
|
47 #elif defined(__APPLE__) && defined(__MACH__) |
42de8b600c0c
Support of Apple OS X
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
36
diff
changeset
|
48 # define HAS_DL_ITERATE 0 |
42de8b600c0c
Support of Apple OS X
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
36
diff
changeset
|
49 #else |
42de8b600c0c
Support of Apple OS X
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
36
diff
changeset
|
50 # define HAS_DL_ITERATE 1 |
0 | 51 #endif |
52 | |
53 | |
54 | |
63
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
55 PyObject* CreateDicom(PyObject* module, PyObject* args) |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
56 { |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
57 // The GIL is locked at this point (no need to create "PythonLock") |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
58 const char* json = NULL; |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
59 PyObject* pixelData = NULL; |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
60 long int flags = 0; |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
61 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
62 if (!PyArg_ParseTuple(args, "sOl", &json, &pixelData, &flags)) |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
63 { |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
64 PyErr_SetString(PyExc_TypeError, "Please provide a JSON string, an orthanc.Image object, and a set of orthanc.CreateDicomFlags"); |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
65 return NULL; |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
66 } |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
67 else |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
68 { |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
69 OrthancPluginImage* image = NULL; |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
70 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
71 if (pixelData == Py_None) |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
72 { |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
73 // No pixel data |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
74 } |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
75 else if (Py_TYPE(pixelData) == GetOrthancPluginImageType()) |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
76 { |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
77 image = reinterpret_cast<sdk_OrthancPluginImage_Object*>(pixelData)->object_; |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
78 } |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
79 else |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
80 { |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
81 PyErr_SetString(PyExc_TypeError, "Second parameter is not a valid orthanc.Image"); |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
82 return NULL; |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
83 } |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
84 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
85 OrthancPlugins::MemoryBuffer buffer; |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
86 OrthancPluginErrorCode code = OrthancPluginCreateDicom(OrthancPlugins::GetGlobalContext(), *buffer, json, image, |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
87 static_cast<OrthancPluginCreateDicomFlags>(flags)); |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
88 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
89 if (code == OrthancPluginErrorCode_Success) |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
90 { |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
91 return PyBytes_FromStringAndSize(buffer.GetData(), buffer.GetSize()); |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
92 } |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
93 else |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
94 { |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
95 PyErr_SetString(PyExc_ValueError, "Cannot create the DICOM instance"); |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
96 return NULL; |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
97 } |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
98 } |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
99 } |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
100 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
101 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
102 |
0 | 103 static bool pythonEnabled_ = false; |
104 static std::string userScriptName_; | |
105 static std::vector<PyMethodDef> globalFunctions_; | |
106 | |
107 | |
108 static void InstallClasses(PyObject* module) | |
109 { | |
110 RegisterOrthancSdk(module); | |
111 } | |
112 | |
113 | |
114 static void SetupGlobalFunctions() | |
115 { | |
116 if (!globalFunctions_.empty()) | |
117 { | |
118 ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls); | |
119 } | |
120 | |
121 /** | |
122 * Add all the manual global functions | |
123 **/ | |
124 | |
125 std::list<PyMethodDef> functions; | |
126 | |
127 { | |
128 PyMethodDef f = { "RegisterRestCallback", RegisterRestCallback, METH_VARARGS, "" }; | |
129 functions.push_back(f); | |
130 } | |
131 | |
132 { | |
133 PyMethodDef f = { "RegisterOnChangeCallback", RegisterOnChangeCallback, METH_VARARGS, "" }; | |
134 functions.push_back(f); | |
135 } | |
136 | |
137 { | |
138 PyMethodDef f = { "RegisterOnStoredInstanceCallback", RegisterOnStoredInstanceCallback, | |
139 METH_VARARGS, "" }; | |
140 functions.push_back(f); | |
141 } | |
50
70abe3ebbbfc
New Python function: "orthanc.RegisterIncomingHttpRequestFilter()"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
47
diff
changeset
|
142 |
63
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
143 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
144 /** |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
145 * New in release 3.0 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
146 **/ |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
147 |
50
70abe3ebbbfc
New Python function: "orthanc.RegisterIncomingHttpRequestFilter()"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
47
diff
changeset
|
148 { |
70abe3ebbbfc
New Python function: "orthanc.RegisterIncomingHttpRequestFilter()"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
47
diff
changeset
|
149 PyMethodDef f = { "RegisterIncomingHttpRequestFilter", RegisterIncomingHttpRequestFilter, METH_VARARGS, "" }; |
70abe3ebbbfc
New Python function: "orthanc.RegisterIncomingHttpRequestFilter()"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
47
diff
changeset
|
150 functions.push_back(f); |
70abe3ebbbfc
New Python function: "orthanc.RegisterIncomingHttpRequestFilter()"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
47
diff
changeset
|
151 } |
63
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
152 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
153 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
154 /** |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
155 * New in release 3.1 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
156 **/ |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
157 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
158 { |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
159 PyMethodDef f = { "CreateDicom", CreateDicom, METH_VARARGS, "" }; |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
160 functions.push_back(f); |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
161 } |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
162 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
163 { |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
164 PyMethodDef f = { "RegisterFindCallback", RegisterFindCallback, METH_VARARGS, "" }; |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
165 functions.push_back(f); |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
166 } |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
167 |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
168 { |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
169 PyMethodDef f = { "RegisterMoveCallback", RegisterMoveCallback, METH_VARARGS, "" }; |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
170 functions.push_back(f); |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
171 } |
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
172 |
0 | 173 |
174 /** | |
175 * Append all the global functions that were automatically generated | |
176 **/ | |
177 | |
178 const PyMethodDef* sdk = GetOrthancSdkFunctions(); | |
179 | |
180 for (size_t i = 0; sdk[i].ml_name != NULL; i++) | |
181 { | |
182 functions.push_back(sdk[i]); | |
183 } | |
184 | |
185 /** | |
186 * Flatten the list of functions into the vector | |
187 **/ | |
188 | |
189 globalFunctions_.resize(functions.size()); | |
190 std::copy(functions.begin(), functions.end(), globalFunctions_.begin()); | |
191 | |
192 PyMethodDef sentinel = { NULL }; | |
193 globalFunctions_.push_back(sentinel); | |
194 } | |
195 | |
196 | |
197 static PyMethodDef* GetGlobalFunctions() | |
198 { | |
199 if (globalFunctions_.empty()) | |
200 { | |
201 // "SetupGlobalFunctions()" should have been called | |
202 ORTHANC_PLUGINS_THROW_EXCEPTION(BadSequenceOfCalls); | |
203 } | |
204 else | |
205 { | |
206 return &globalFunctions_[0]; | |
207 } | |
208 } | |
209 | |
210 | |
211 | |
47
42de8b600c0c
Support of Apple OS X
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
36
diff
changeset
|
212 #if HAS_DL_ITERATE == 1 |
0 | 213 |
47
42de8b600c0c
Support of Apple OS X
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
36
diff
changeset
|
214 #include <dlfcn.h> |
0 | 215 #include <link.h> // For dl_phdr_info |
216 | |
217 static int ForceImportCallback(struct dl_phdr_info *info, size_t size, void *data) | |
218 { | |
219 /** | |
220 * The following line solves the error: "ImportError: | |
221 * /usr/lib/python2.7/dist-packages/PIL/_imaging.x86_64-linux-gnu.so: | |
222 * undefined symbol: PyExc_SystemError" | |
223 * https://stackoverflow.com/a/48517485/881731 | |
224 * | |
225 * dlopen("/usr/lib/x86_64-linux-gnu/libpython2.7.so", RTLD_NOW | RTLD_LAZY | RTLD_GLOBAL); | |
226 * | |
227 * Another fix consists in using LD_PRELOAD as follows: | |
228 * LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libpython2.7.so ~/Subversion/orthanc/i/Orthanc tutu.json | |
229 **/ | |
230 | |
231 std::string module(info->dlpi_name); | |
232 | |
233 if (module.find("python") != std::string::npos) | |
234 { | |
235 OrthancPlugins::LogWarning("Force global loading of Python shared library: " + module); | |
236 dlopen(module.c_str(), RTLD_NOW | RTLD_LAZY | RTLD_GLOBAL); | |
237 } | |
238 | |
239 return 0; | |
240 } | |
241 | |
242 #endif | |
243 | |
244 | |
245 extern "C" | |
246 { | |
247 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* c) | |
248 { | |
249 OrthancPlugins::SetGlobalContext(c); | |
250 OrthancPlugins::LogWarning("Python plugin is initializing"); | |
251 | |
252 | |
253 /* Check the version of the Orthanc core */ | |
254 if (OrthancPluginCheckVersion(c) == 0) | |
255 { | |
256 char info[1024]; | |
257 sprintf(info, "Your version of Orthanc (%s) must be above %d.%d.%d to run this plugin", | |
258 c->orthancVersion, | |
259 ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER, | |
260 ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER, | |
261 ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER); | |
262 OrthancPluginLogError(c, info); | |
263 return -1; | |
264 } | |
11 | 265 |
266 OrthancPluginSetDescription(c, "Run Python scripts as Orthanc plugins"); | |
267 | |
0 | 268 try |
269 { | |
270 /** | |
271 * Detection of the user script | |
272 **/ | |
273 | |
274 OrthancPlugins::OrthancConfiguration config; | |
275 | |
276 static const char* const OPTION = "PythonScript"; | |
277 | |
278 std::string script; | |
279 if (!config.LookupStringValue(script, OPTION)) | |
280 { | |
281 pythonEnabled_ = false; | |
282 | |
283 OrthancPlugins::LogWarning("The option \"" + std::string(OPTION) + "\" is not provided: " + | |
284 "Python scripting is disabled"); | |
285 } | |
286 else | |
287 { | |
288 pythonEnabled_ = true; | |
289 | |
290 /** | |
291 * Installation of the user script | |
292 **/ | |
293 | |
294 const boost::filesystem::path path(script); | |
295 if (!boost::iequals(path.extension().string(), ".py")) | |
296 { | |
297 OrthancPlugins::LogError("Python script must have the \".py\" file extension: " + | |
298 path.string()); | |
299 return -1; | |
300 } | |
301 | |
302 if (!boost::filesystem::is_regular_file(path)) | |
303 { | |
304 OrthancPlugins::LogError("Inexistent directory for the Python script: " + | |
305 path.string()); | |
306 return -1; | |
307 } | |
308 | |
309 boost::filesystem::path userScriptDirectory = boost::filesystem::absolute(path).parent_path(); | |
310 | |
311 { | |
312 boost::filesystem::path module = path.filename().replace_extension(""); | |
313 userScriptName_ = module.string(); | |
314 } | |
315 | |
316 OrthancPlugins::LogWarning("Using Python script \"" + userScriptName_ + | |
317 ".py\" from directory: " + userScriptDirectory.string()); | |
318 | |
319 | |
320 /** | |
321 * Initialization of Python | |
322 **/ | |
323 | |
47
42de8b600c0c
Support of Apple OS X
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
36
diff
changeset
|
324 #if HAS_DL_ITERATE == 1 |
0 | 325 dl_iterate_phdr(ForceImportCallback, NULL); |
326 #endif | |
327 | |
328 SetupGlobalFunctions(); | |
329 PythonLock::GlobalInitialize("orthanc", "Exception", | |
330 GetGlobalFunctions, InstallClasses, | |
331 config.GetBooleanValue("PythonVerbose", false)); | |
332 PythonLock::AddSysPath(userScriptDirectory.string()); | |
333 | |
334 | |
335 /** | |
336 * Force loading the declarations in the user script | |
337 **/ | |
338 | |
339 PythonLock lock; | |
340 | |
341 { | |
342 PythonModule module(lock, userScriptName_); | |
343 } | |
344 | |
345 std::string traceback; | |
346 if (lock.HasErrorOccurred(traceback)) | |
347 { | |
348 OrthancPlugins::LogError("Error during the installation of the Python script, " | |
349 "traceback:\n" + traceback); | |
350 return -1; | |
351 } | |
352 } | |
353 } | |
354 catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e) | |
355 { | |
356 OrthancPlugins::LogError("Exception while starting the Python plugin: " + | |
357 std::string(e.What(c))); | |
358 return -1; | |
359 } | |
360 | |
361 return 0; | |
362 } | |
363 | |
364 | |
365 ORTHANC_PLUGINS_API void OrthancPluginFinalize() | |
366 { | |
367 OrthancPlugins::LogWarning("Python plugin is finalizing"); | |
368 | |
369 if (pythonEnabled_) | |
370 { | |
371 FinalizeOnChangeCallback(); | |
372 FinalizeRestCallbacks(); | |
373 FinalizeOnStoredInstanceCallback(); | |
50
70abe3ebbbfc
New Python function: "orthanc.RegisterIncomingHttpRequestFilter()"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
47
diff
changeset
|
374 FinalizeIncomingHttpRequestFilter(); |
63
32de70a1e4c7
New functions from the SDK wrapped in Python: CreateDicom, RegisterFindCallback, RegisterMoveCallback
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
56
diff
changeset
|
375 FinalizeDicomScpCallbacks(); |
0 | 376 |
377 PythonLock::GlobalFinalize(); | |
378 } | |
379 } | |
380 | |
381 | |
382 ORTHANC_PLUGINS_API const char* OrthancPluginGetName() | |
383 { | |
384 return "python"; | |
385 } | |
386 | |
387 | |
388 ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion() | |
389 { | |
390 return PLUGIN_VERSION; | |
391 } | |
392 } |