Mercurial > hg > orthanc
comparison Plugins/Samples/ModalityWorklists/Plugin.cpp @ 1802:138664eb59de worklists
sample worklist plugin
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 20 Nov 2015 15:54:07 +0100 |
parents | |
children | 9c2ffc4e938b |
comparison
equal
deleted
inserted
replaced
1801:2c60c357ee3e | 1802:138664eb59de |
---|---|
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 | |
64 if (OrthancPluginIsWorklistMatch(context_, query, dicom.c_str(), dicom.size())) | |
65 { | |
66 // This DICOM file matches the worklist query, add it to the answers | |
67 return OrthancPluginWorklistAddWorklistAnswer | |
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; | |
101 if (OrthancPluginGetWorklistQueryDicom(context_, &dicom, query)) | |
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; | |
172 OrthancPluginLogWarning(context_, "Storage plugin is initializing"); | |
173 | |
174 /* Check the version of the Orthanc core */ | |
175 if (OrthancPluginCheckVersion(c) == 0) | |
176 { | |
177 char info[1024]; | |
178 sprintf(info, "Your version of Orthanc (%s) must be above %d.%d.%d to run this plugin", | |
179 context_->orthancVersion, | |
180 ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER, | |
181 ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER, | |
182 ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER); | |
183 OrthancPluginLogError(context_, info); | |
184 return -1; | |
185 } | |
186 | |
187 Json::Value configuration; | |
188 if (!ConvertToJson(configuration, OrthancPluginGetConfiguration(context_))) | |
189 { | |
190 OrthancPluginLogError(context_, "Cannot access the configuration"); | |
191 return -1; | |
192 } | |
193 | |
194 if (configuration.isMember("WorklistsFolder")) | |
195 { | |
196 if (configuration["WorklistsFolder"].type() != Json::stringValue) | |
197 { | |
198 OrthancPluginLogError(context_, "The configuration option \"WorklistsFolder\" must be a string"); | |
199 return -1; | |
200 } | |
201 | |
202 folder_ = configuration["WorklistsFolder"].asString(); | |
203 } | |
204 else | |
205 { | |
206 folder_ = DEFAULT_WORKLISTS_FOLDER; | |
207 } | |
208 | |
209 std::string message = "The database of worklists will be read from folder: " + folder_; | |
210 OrthancPluginLogWarning(context_, message.c_str()); | |
211 | |
212 OrthancPluginRegisterWorklistCallback(context_, Callback); | |
213 | |
214 return 0; | |
215 } | |
216 | |
217 | |
218 ORTHANC_PLUGINS_API void OrthancPluginFinalize() | |
219 { | |
220 OrthancPluginLogWarning(context_, "Sample worklist plugin is finalizing"); | |
221 } | |
222 | |
223 | |
224 ORTHANC_PLUGINS_API const char* OrthancPluginGetName() | |
225 { | |
226 return "sample-worklists"; | |
227 } | |
228 | |
229 | |
230 ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion() | |
231 { | |
232 return SAMPLE_MODALITY_WORKLISTS_VERSION; | |
233 } | |
234 } |