Mercurial > hg > orthanc
annotate Plugins/Samples/ModalityWorklists/Plugin.cpp @ 1900:b1291df2f780
2016
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 04 Jan 2016 13:17:22 +0100 |
parents | 74dc6b764ff0 |
children | 7a05144cb919 |
rev | line source |
---|---|
1802 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
1900 | 3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics |
1802 | 4 * Department, University Hospital of Liege, Belgium |
5 * | |
6 * This program is free software: you can redistribute it and/or | |
7 * modify it under the terms of the GNU General Public License as | |
8 * published by the Free Software Foundation, either version 3 of the | |
9 * License, or (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, but | |
12 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 **/ | |
19 | |
20 | |
21 #include <orthanc/OrthancCPlugin.h> | |
22 | |
23 #include <boost/filesystem.hpp> | |
24 #include <json/value.h> | |
25 #include <json/reader.h> | |
26 #include <string.h> | |
27 #include <iostream> | |
1814 | 28 #include <algorithm> |
1802 | 29 |
30 static OrthancPluginContext* context_ = NULL; | |
31 static std::string folder_; | |
32 | |
33 | |
34 static bool ReadFile(std::string& result, | |
35 const std::string& path) | |
36 { | |
37 OrthancPluginMemoryBuffer tmp; | |
38 if (OrthancPluginReadFile(context_, &tmp, path.c_str())) | |
39 { | |
40 return false; | |
41 } | |
42 else | |
43 { | |
44 result.assign(reinterpret_cast<const char*>(tmp.data), tmp.size); | |
45 OrthancPluginFreeMemoryBuffer(context_, &tmp); | |
46 return true; | |
47 } | |
48 } | |
49 | |
50 | |
51 /** | |
52 * This is the main function for matching a DICOM worklist against a query. | |
53 **/ | |
54 static OrthancPluginErrorCode MatchWorklist(OrthancPluginWorklistAnswers* answers, | |
55 const OrthancPluginWorklistQuery* query, | |
56 const std::string& path) | |
57 { | |
58 std::string dicom; | |
59 if (!ReadFile(dicom, path)) | |
60 { | |
61 // Cannot read this file, ignore this error | |
62 return OrthancPluginErrorCode_Success; | |
63 } | |
64 | |
1810
796d0b087fb8
more consistent naming in worklist primitives
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1808
diff
changeset
|
65 if (OrthancPluginWorklistIsMatch(context_, query, dicom.c_str(), dicom.size())) |
1802 | 66 { |
67 // This DICOM file matches the worklist query, add it to the answers | |
1810
796d0b087fb8
more consistent naming in worklist primitives
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1808
diff
changeset
|
68 return OrthancPluginWorklistAddAnswer |
1802 | 69 (context_, answers, query, dicom.c_str(), dicom.size()); |
70 } | |
71 else | |
72 { | |
73 // This DICOM file does not match | |
74 return OrthancPluginErrorCode_Success; | |
75 } | |
76 } | |
77 | |
78 | |
79 | |
80 static bool ConvertToJson(Json::Value& result, | |
81 char* content) | |
82 { | |
83 if (content == NULL) | |
84 { | |
85 return false; | |
86 } | |
87 else | |
88 { | |
89 Json::Reader reader; | |
90 bool success = reader.parse(content, content + strlen(content), result); | |
91 OrthancPluginFreeString(context_, content); | |
92 return success; | |
93 } | |
94 } | |
95 | |
96 | |
97 static bool GetQueryDicom(Json::Value& value, | |
98 const OrthancPluginWorklistQuery* query) | |
99 { | |
100 OrthancPluginMemoryBuffer dicom; | |
1810
796d0b087fb8
more consistent naming in worklist primitives
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1808
diff
changeset
|
101 if (OrthancPluginWorklistGetDicomQuery(context_, &dicom, query)) |
1802 | 102 { |
103 return false; | |
104 } | |
105 | |
106 char* json = OrthancPluginDicomBufferToJson(context_, reinterpret_cast<const char*>(dicom.data), | |
107 dicom.size, | |
108 OrthancPluginDicomToJsonFormat_Short, | |
109 static_cast<OrthancPluginDicomToJsonFlags>(0), 0); | |
110 OrthancPluginFreeMemoryBuffer(context_, &dicom); | |
111 | |
112 return ConvertToJson(value, json); | |
113 } | |
114 | |
115 | |
1814 | 116 static void ToLowerCase(std::string& s) |
117 { | |
118 std::transform(s.begin(), s.end(), s.begin(), tolower); | |
119 } | |
120 | |
121 | |
1802 | 122 OrthancPluginErrorCode Callback(OrthancPluginWorklistAnswers* answers, |
123 const OrthancPluginWorklistQuery* query, | |
124 const char* remoteAet, | |
125 const char* calledAet) | |
126 { | |
127 Json::Value json; | |
128 | |
129 if (!GetQueryDicom(json, query)) | |
130 { | |
131 return OrthancPluginErrorCode_InternalError; | |
132 } | |
133 | |
1890
74dc6b764ff0
Fix modality worklists lookups if tags with UN (unknown) VR are present
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1814
diff
changeset
|
134 { |
74dc6b764ff0
Fix modality worklists lookups if tags with UN (unknown) VR are present
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1814
diff
changeset
|
135 std::string msg = ("Received worklist query from remote modality " + |
74dc6b764ff0
Fix modality worklists lookups if tags with UN (unknown) VR are present
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1814
diff
changeset
|
136 std::string(remoteAet) + ":\n" + json.toStyledString()); |
74dc6b764ff0
Fix modality worklists lookups if tags with UN (unknown) VR are present
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1814
diff
changeset
|
137 OrthancPluginLogInfo(context_, msg.c_str()); |
74dc6b764ff0
Fix modality worklists lookups if tags with UN (unknown) VR are present
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1814
diff
changeset
|
138 } |
1802 | 139 |
140 boost::filesystem::path source(folder_); | |
141 boost::filesystem::directory_iterator end; | |
142 | |
143 try | |
144 { | |
145 for (boost::filesystem::directory_iterator it(source); it != end; ++it) | |
146 { | |
147 if (is_regular_file(it->status())) | |
148 { | |
149 std::string extension = boost::filesystem::extension(it->path()); | |
1814 | 150 ToLowerCase(extension); |
151 | |
152 if (extension == ".wl") | |
1802 | 153 { |
154 OrthancPluginErrorCode error = MatchWorklist(answers, query, it->path().string()); | |
155 if (error) | |
156 { | |
157 OrthancPluginLogError(context_, "Error while adding an answer to a worklist request"); | |
158 return error; | |
159 } | |
160 } | |
161 } | |
162 } | |
163 } | |
164 catch (boost::filesystem::filesystem_error&) | |
165 { | |
166 std::string description = std::string("Inexistent folder while scanning for worklists: ") + source.string(); | |
167 OrthancPluginLogError(context_, description.c_str()); | |
168 return OrthancPluginErrorCode_DirectoryExpected; | |
169 } | |
170 | |
171 // Uncomment the following line if too many answers are to be returned | |
172 // OrthancPluginMarkWorklistAnswersIncomplete(context_, answers); | |
173 | |
174 return OrthancPluginErrorCode_Success; | |
175 } | |
176 | |
177 | |
178 extern "C" | |
179 { | |
180 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* c) | |
181 { | |
182 context_ = c; | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
183 OrthancPluginLogWarning(context_, "Sample worklist plugin is initializing"); |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
184 OrthancPluginSetDescription(context_, "Serve DICOM modality worklists from a folder with Orthanc."); |
1802 | 185 |
186 /* Check the version of the Orthanc core */ | |
187 if (OrthancPluginCheckVersion(c) == 0) | |
188 { | |
189 char info[1024]; | |
190 sprintf(info, "Your version of Orthanc (%s) must be above %d.%d.%d to run this plugin", | |
191 context_->orthancVersion, | |
192 ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER, | |
193 ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER, | |
194 ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER); | |
195 OrthancPluginLogError(context_, info); | |
196 return -1; | |
197 } | |
198 | |
199 Json::Value configuration; | |
200 if (!ConvertToJson(configuration, OrthancPluginGetConfiguration(context_))) | |
201 { | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
202 OrthancPluginLogError(context_, "Cannot access the configuration of the worklist server"); |
1802 | 203 return -1; |
204 } | |
205 | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
206 bool enabled = false; |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
207 |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
208 if (configuration.isMember("Worklists")) |
1802 | 209 { |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
210 const Json::Value& config = configuration["Worklists"]; |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
211 if (!config.isMember("Enable") || |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
212 config["Enable"].type() != Json::booleanValue) |
1802 | 213 { |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
214 OrthancPluginLogError(context_, "The configuration option \"Worklists.Enable\" must contain a Boolean"); |
1802 | 215 return -1; |
216 } | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
217 else |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
218 { |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
219 enabled = config["Enable"].asBool(); |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
220 if (enabled) |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
221 { |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
222 if (!config.isMember("Database") || |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
223 config["Database"].type() != Json::stringValue) |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
224 { |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
225 OrthancPluginLogError(context_, "The configuration option \"Worklists.Database\" must contain a path"); |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
226 return -1; |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
227 } |
1802 | 228 |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
229 folder_ = config["Database"].asString(); |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
230 } |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
231 else |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
232 { |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
233 OrthancPluginLogWarning(context_, "Worklists server is disabled by the configuration file"); |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
234 } |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
235 } |
1802 | 236 } |
237 else | |
238 { | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
239 OrthancPluginLogWarning(context_, "Worklists server is disabled, no suitable configuration section was provided"); |
1802 | 240 } |
241 | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
242 if (enabled) |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
243 { |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
244 std::string message = "The database of worklists will be read from folder: " + folder_; |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
245 OrthancPluginLogWarning(context_, message.c_str()); |
1802 | 246 |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
247 OrthancPluginRegisterWorklistCallback(context_, Callback); |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
248 } |
1802 | 249 |
250 return 0; | |
251 } | |
252 | |
253 | |
254 ORTHANC_PLUGINS_API void OrthancPluginFinalize() | |
255 { | |
256 OrthancPluginLogWarning(context_, "Sample worklist plugin is finalizing"); | |
257 } | |
258 | |
259 | |
260 ORTHANC_PLUGINS_API const char* OrthancPluginGetName() | |
261 { | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
262 return "worklists"; |
1802 | 263 } |
264 | |
265 | |
266 ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion() | |
267 { | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
268 return MODALITY_WORKLISTS_VERSION; |
1802 | 269 } |
270 } |