Mercurial > hg > orthanc
annotate Plugins/Samples/ModalityWorklists/Plugin.cpp @ 1810:796d0b087fb8 worklists
more consistent naming in worklist primitives
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 23 Nov 2015 17:09:27 +0100 |
parents | 9c2ffc4e938b |
children | 5fc11b79b406 |
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> | |
28 | |
29 static OrthancPluginContext* context_ = NULL; | |
30 static std::string folder_; | |
31 | |
32 | |
33 static bool ReadFile(std::string& result, | |
34 const std::string& path) | |
35 { | |
36 OrthancPluginMemoryBuffer tmp; | |
37 if (OrthancPluginReadFile(context_, &tmp, path.c_str())) | |
38 { | |
39 return false; | |
40 } | |
41 else | |
42 { | |
43 result.assign(reinterpret_cast<const char*>(tmp.data), tmp.size); | |
44 OrthancPluginFreeMemoryBuffer(context_, &tmp); | |
45 return true; | |
46 } | |
47 } | |
48 | |
49 | |
50 /** | |
51 * This is the main function for matching a DICOM worklist against a query. | |
52 **/ | |
53 static OrthancPluginErrorCode MatchWorklist(OrthancPluginWorklistAnswers* answers, | |
54 const OrthancPluginWorklistQuery* query, | |
55 const std::string& path) | |
56 { | |
57 std::string dicom; | |
58 if (!ReadFile(dicom, path)) | |
59 { | |
60 // Cannot read this file, ignore this error | |
61 return OrthancPluginErrorCode_Success; | |
62 } | |
63 | |
1810
796d0b087fb8
more consistent naming in worklist primitives
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1808
diff
changeset
|
64 if (OrthancPluginWorklistIsMatch(context_, query, dicom.c_str(), dicom.size())) |
1802 | 65 { |
66 // 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
|
67 return OrthancPluginWorklistAddAnswer |
1802 | 68 (context_, answers, query, dicom.c_str(), dicom.size()); |
69 } | |
70 else | |
71 { | |
72 // This DICOM file does not match | |
73 return OrthancPluginErrorCode_Success; | |
74 } | |
75 } | |
76 | |
77 | |
78 | |
79 static bool ConvertToJson(Json::Value& result, | |
80 char* content) | |
81 { | |
82 if (content == NULL) | |
83 { | |
84 return false; | |
85 } | |
86 else | |
87 { | |
88 Json::Reader reader; | |
89 bool success = reader.parse(content, content + strlen(content), result); | |
90 OrthancPluginFreeString(context_, content); | |
91 return success; | |
92 } | |
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 | |
116 OrthancPluginErrorCode Callback(OrthancPluginWorklistAnswers* answers, | |
117 const OrthancPluginWorklistQuery* query, | |
118 const char* remoteAet, | |
119 const char* calledAet) | |
120 { | |
121 Json::Value json; | |
122 | |
123 if (!GetQueryDicom(json, query)) | |
124 { | |
125 return OrthancPluginErrorCode_InternalError; | |
126 } | |
127 | |
128 std::cout << "Received worklist query from remote modality " << remoteAet | |
129 << ":" << std::endl << json.toStyledString(); | |
130 | |
131 boost::filesystem::path source(folder_); | |
132 boost::filesystem::directory_iterator end; | |
133 | |
134 try | |
135 { | |
136 for (boost::filesystem::directory_iterator it(source); it != end; ++it) | |
137 { | |
138 if (is_regular_file(it->status())) | |
139 { | |
140 std::string extension = boost::filesystem::extension(it->path()); | |
141 if (!strcasecmp(".wl", extension.c_str())) | |
142 { | |
143 OrthancPluginErrorCode error = MatchWorklist(answers, query, it->path().string()); | |
144 if (error) | |
145 { | |
146 OrthancPluginLogError(context_, "Error while adding an answer to a worklist request"); | |
147 return error; | |
148 } | |
149 } | |
150 } | |
151 } | |
152 } | |
153 catch (boost::filesystem::filesystem_error&) | |
154 { | |
155 std::string description = std::string("Inexistent folder while scanning for worklists: ") + source.string(); | |
156 OrthancPluginLogError(context_, description.c_str()); | |
157 return OrthancPluginErrorCode_DirectoryExpected; | |
158 } | |
159 | |
160 // Uncomment the following line if too many answers are to be returned | |
161 // OrthancPluginMarkWorklistAnswersIncomplete(context_, answers); | |
162 | |
163 return OrthancPluginErrorCode_Success; | |
164 } | |
165 | |
166 | |
167 extern "C" | |
168 { | |
169 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* c) | |
170 { | |
171 context_ = c; | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
172 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
|
173 OrthancPluginSetDescription(context_, "Serve DICOM modality worklists from a folder with Orthanc."); |
1802 | 174 |
175 /* Check the version of the Orthanc core */ | |
176 if (OrthancPluginCheckVersion(c) == 0) | |
177 { | |
178 char info[1024]; | |
179 sprintf(info, "Your version of Orthanc (%s) must be above %d.%d.%d to run this plugin", | |
180 context_->orthancVersion, | |
181 ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER, | |
182 ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER, | |
183 ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER); | |
184 OrthancPluginLogError(context_, info); | |
185 return -1; | |
186 } | |
187 | |
188 Json::Value configuration; | |
189 if (!ConvertToJson(configuration, OrthancPluginGetConfiguration(context_))) | |
190 { | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
191 OrthancPluginLogError(context_, "Cannot access the configuration of the worklist server"); |
1802 | 192 return -1; |
193 } | |
194 | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
195 bool enabled = false; |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
196 |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
197 if (configuration.isMember("Worklists")) |
1802 | 198 { |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
199 const Json::Value& config = configuration["Worklists"]; |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
200 if (!config.isMember("Enable") || |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
201 config["Enable"].type() != Json::booleanValue) |
1802 | 202 { |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
203 OrthancPluginLogError(context_, "The configuration option \"Worklists.Enable\" must contain a Boolean"); |
1802 | 204 return -1; |
205 } | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
206 else |
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 enabled = config["Enable"].asBool(); |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
209 if (enabled) |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
210 { |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
211 if (!config.isMember("Database") || |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
212 config["Database"].type() != Json::stringValue) |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
213 { |
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.Database\" must contain a path"); |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
215 return -1; |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
216 } |
1802 | 217 |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
218 folder_ = config["Database"].asString(); |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
219 } |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
220 else |
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 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
|
223 } |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
224 } |
1802 | 225 } |
226 else | |
227 { | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
228 OrthancPluginLogWarning(context_, "Worklists server is disabled, no suitable configuration section was provided"); |
1802 | 229 } |
230 | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
231 if (enabled) |
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 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
|
234 OrthancPluginLogWarning(context_, message.c_str()); |
1802 | 235 |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
236 OrthancPluginRegisterWorklistCallback(context_, Callback); |
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
237 } |
1802 | 238 |
239 return 0; | |
240 } | |
241 | |
242 | |
243 ORTHANC_PLUGINS_API void OrthancPluginFinalize() | |
244 { | |
245 OrthancPluginLogWarning(context_, "Sample worklist plugin is finalizing"); | |
246 } | |
247 | |
248 | |
249 ORTHANC_PLUGINS_API const char* OrthancPluginGetName() | |
250 { | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
251 return "worklists"; |
1802 | 252 } |
253 | |
254 | |
255 ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion() | |
256 { | |
1808
9c2ffc4e938b
configuration of the sample modality worklists plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1802
diff
changeset
|
257 return MODALITY_WORKLISTS_VERSION; |
1802 | 258 } |
259 } |