Mercurial > hg > orthanc
annotate Plugins/Samples/ModalityWorklists/Plugin.cpp @ 2771:87a3a8c04d8a worklists
close old branch
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 17 Jul 2018 09:45:17 +0200 |
parents | 7c5ea3e51839 |
children | 74dc6b764ff0 |
rev | line source |
---|---|
1802 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics | |
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 | |
134 std::cout << "Received worklist query from remote modality " << remoteAet | |
135 << ":" << std::endl << json.toStyledString(); | |
136 | |
137 boost::filesystem::path source(folder_); | |
138 boost::filesystem::directory_iterator end; | |
139 | |
140 try | |
141 { | |
142 for (boost::filesystem::directory_iterator it(source); it != end; ++it) | |
143 { | |
144 if (is_regular_file(it->status())) | |
145 { | |
146 std::string extension = boost::filesystem::extension(it->path()); | |
1814 | 147 ToLowerCase(extension); |
148 | |
149 if (extension == ".wl") | |
1802 | 150 { |
151 OrthancPluginErrorCode error = MatchWorklist(answers, query, it->path().string()); | |
152 if (error) | |
153 { | |
154 OrthancPluginLogError(context_, "Error while adding an answer to a worklist request"); | |
155 return error; | |
156 } | |
157 } | |
158 } | |
159 } | |
160 } | |
161 catch (boost::filesystem::filesystem_error&) | |
162 { | |
163 std::string description = std::string("Inexistent folder while scanning for worklists: ") + source.string(); | |
164 OrthancPluginLogError(context_, description.c_str()); | |
165 return OrthancPluginErrorCode_DirectoryExpected; | |
166 } | |
167 | |
168 // Uncomment the following line if too many answers are to be returned | |
169 // OrthancPluginMarkWorklistAnswersIncomplete(context_, answers); | |
170 | |
171 return OrthancPluginErrorCode_Success; | |
172 } | |
173 | |
174 | |
175 extern "C" | |
176 { | |
177 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* c) | |
178 { | |
179 context_ = c; | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
180 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
|
181 OrthancPluginSetDescription(context_, "Serve DICOM modality worklists from a folder with Orthanc."); |
1802 | 182 |
183 /* Check the version of the Orthanc core */ | |
184 if (OrthancPluginCheckVersion(c) == 0) | |
185 { | |
186 char info[1024]; | |
187 sprintf(info, "Your version of Orthanc (%s) must be above %d.%d.%d to run this plugin", | |
188 context_->orthancVersion, | |
189 ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER, | |
190 ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER, | |
191 ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER); | |
192 OrthancPluginLogError(context_, info); | |
193 return -1; | |
194 } | |
195 | |
196 Json::Value configuration; | |
197 if (!ConvertToJson(configuration, OrthancPluginGetConfiguration(context_))) | |
198 { | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
199 OrthancPluginLogError(context_, "Cannot access the configuration of the worklist server"); |
1802 | 200 return -1; |
201 } | |
202 | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
203 bool enabled = false; |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
204 |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
205 if (configuration.isMember("Worklists")) |
1802 | 206 { |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
207 const Json::Value& config = configuration["Worklists"]; |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
208 if (!config.isMember("Enable") || |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
209 config["Enable"].type() != Json::booleanValue) |
1802 | 210 { |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
211 OrthancPluginLogError(context_, "The configuration option \"Worklists.Enable\" must contain a Boolean"); |
1802 | 212 return -1; |
213 } | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
214 else |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
215 { |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
216 enabled = config["Enable"].asBool(); |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
217 if (enabled) |
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 if (!config.isMember("Database") || |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
220 config["Database"].type() != Json::stringValue) |
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 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
|
223 return -1; |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
224 } |
1802 | 225 |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
226 folder_ = config["Database"].asString(); |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
227 } |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
228 else |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
229 { |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
230 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
|
231 } |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
232 } |
1802 | 233 } |
234 else | |
235 { | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
236 OrthancPluginLogWarning(context_, "Worklists server is disabled, no suitable configuration section was provided"); |
1802 | 237 } |
238 | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
239 if (enabled) |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
240 { |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
241 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
|
242 OrthancPluginLogWarning(context_, message.c_str()); |
1802 | 243 |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
244 OrthancPluginRegisterWorklistCallback(context_, Callback); |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
245 } |
1802 | 246 |
247 return 0; | |
248 } | |
249 | |
250 | |
251 ORTHANC_PLUGINS_API void OrthancPluginFinalize() | |
252 { | |
253 OrthancPluginLogWarning(context_, "Sample worklist plugin is finalizing"); | |
254 } | |
255 | |
256 | |
257 ORTHANC_PLUGINS_API const char* OrthancPluginGetName() | |
258 { | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
259 return "worklists"; |
1802 | 260 } |
261 | |
262 | |
263 ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion() | |
264 { | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
265 return MODALITY_WORKLISTS_VERSION; |
1802 | 266 } |
267 } |