comparison OrthancStone/Sources/Loaders/DicomSource.cpp @ 1512:244ad1e4e76a

reorganization of folders
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 07 Jul 2020 16:21:02 +0200
parents Framework/Loaders/DicomSource.cpp@121d01aa328e
children 4fb8fdf03314
comparison
equal deleted inserted replaced
1511:9dfeee74c1e6 1512:244ad1e4e76a
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21
22 #include "DicomSource.h"
23
24 #include "../Oracle/HttpCommand.h"
25 #include "../Oracle/OrthancRestApiCommand.h"
26
27 #include <OrthancException.h>
28
29 #include <boost/algorithm/string/predicate.hpp>
30
31 namespace OrthancStone
32 {
33 static std::string EncodeGetArguments(const std::string& uri,
34 const std::map<std::string, std::string>& arguments)
35 {
36 std::string s = uri;
37 bool first = true;
38
39 for (std::map<std::string, std::string>::const_iterator
40 it = arguments.begin(); it != arguments.end(); ++it)
41 {
42 if (first)
43 {
44 s += "?";
45 first = false;
46 }
47 else
48 {
49 s += "&";
50 }
51
52 s += it->first + "=" + it->second;
53 }
54
55 // TODO: Call Orthanc::Toolbox::UriEncode() ?
56
57 return s;
58 }
59
60
61 void DicomSource::SetOrthancSource(const Orthanc::WebServiceParameters& parameters)
62 {
63 type_ = DicomSourceType_Orthanc;
64 webService_ = parameters;
65 hasOrthancWebViewer1_ = false;
66 hasOrthancAdvancedPreview_ = false;
67 }
68
69
70 void DicomSource::SetOrthancSource()
71 {
72 Orthanc::WebServiceParameters parameters;
73 parameters.SetUrl("http://localhost:8042/");
74 SetOrthancSource(parameters);
75 }
76
77
78 const Orthanc::WebServiceParameters& DicomSource::GetOrthancParameters() const
79 {
80 if (type_ == DicomSourceType_Orthanc ||
81 type_ == DicomSourceType_DicomWebThroughOrthanc)
82 {
83 return webService_;
84 }
85 else
86 {
87 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
88 }
89 }
90
91
92 void DicomSource::SetDicomDirSource()
93 {
94 type_ = DicomSourceType_DicomDir;
95 }
96
97
98 void DicomSource::SetDicomWebSource(const std::string& baseUrl)
99 {
100 type_ = DicomSourceType_DicomWeb;
101 webService_.SetUrl(baseUrl);
102 webService_.ClearCredentials();
103 }
104
105
106 void DicomSource::SetDicomWebSource(const std::string& baseUrl,
107 const std::string& username,
108 const std::string& password)
109 {
110 type_ = DicomSourceType_DicomWeb;
111 webService_.SetUrl(baseUrl);
112 webService_.SetCredentials(username, password);
113 }
114
115
116 void DicomSource::SetDicomWebThroughOrthancSource(const Orthanc::WebServiceParameters& orthancParameters,
117 const std::string& dicomWebRoot,
118 const std::string& serverName)
119 {
120 type_ = DicomSourceType_DicomWebThroughOrthanc;
121 webService_ = orthancParameters;
122 orthancDicomWebRoot_ = dicomWebRoot;
123 serverName_ = serverName;
124 }
125
126
127 void DicomSource::SetDicomWebThroughOrthancSource(const std::string& serverName)
128 {
129 Orthanc::WebServiceParameters orthanc;
130 orthanc.SetUrl("http://localhost:8042/");
131 SetDicomWebThroughOrthancSource(orthanc, "/dicom-web/", serverName);
132 }
133
134
135 bool DicomSource::IsDicomWeb() const
136 {
137 return (type_ == DicomSourceType_DicomWeb ||
138 type_ == DicomSourceType_DicomWebThroughOrthanc);
139 }
140
141
142 IOracleCommand* DicomSource::CreateDicomWebCommand(const std::string& uri,
143 const std::map<std::string, std::string>& arguments,
144 const std::map<std::string, std::string>& headers,
145 Orthanc::IDynamicObject* payload) const
146 {
147 std::unique_ptr<Orthanc::IDynamicObject> protection(payload);
148
149 switch (type_)
150 {
151 case DicomSourceType_DicomWeb:
152 {
153 std::unique_ptr<HttpCommand> command(new HttpCommand);
154
155 command->SetMethod(Orthanc::HttpMethod_Get);
156 command->SetUrl(webService_.GetUrl() + EncodeGetArguments(uri, arguments));
157 command->SetHttpHeaders(webService_.GetHttpHeaders());
158
159 for (std::map<std::string, std::string>::const_iterator
160 it = headers.begin(); it != headers.end(); ++it)
161 {
162 command->SetHttpHeader(it->first, it->second);
163 }
164
165 if (!webService_.GetUsername().empty())
166 {
167 command->SetCredentials(webService_.GetUsername(), webService_.GetPassword());
168 }
169
170 if (protection.get())
171 {
172 command->AcquirePayload(protection.release());
173 }
174
175 return command.release();
176 }
177
178 case DicomSourceType_DicomWebThroughOrthanc:
179 {
180 Json::Value args = Json::objectValue;
181 for (std::map<std::string, std::string>::const_iterator
182 it = arguments.begin(); it != arguments.end(); ++it)
183 {
184 args[it->first] = it->second;
185 }
186
187 Json::Value h = Json::objectValue;
188 for (std::map<std::string, std::string>::const_iterator
189 it = headers.begin(); it != headers.end(); ++it)
190 {
191 h[it->first] = it->second;
192 }
193
194 Json::Value body = Json::objectValue;
195 body["Uri"] = uri;
196 body["Arguments"] = args;
197 body["HttpHeaders"] = h;
198
199 std::unique_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand);
200 command->SetMethod(Orthanc::HttpMethod_Post);
201 command->SetUri(orthancDicomWebRoot_ + "/servers/" + serverName_ + "/get");
202 command->SetBody(body);
203
204 if (protection.get())
205 {
206 command->AcquirePayload(protection.release());
207 }
208
209 return command.release();
210 }
211
212 default:
213 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
214 }
215 }
216
217
218 void DicomSource::AutodetectOrthancFeatures(const std::string& system,
219 const std::string& plugins)
220 {
221 static const char* const REST_API_VERSION = "ApiVersion";
222
223 if (IsDicomWeb())
224 {
225 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
226 }
227
228 Json::Value a, b;
229 Json::Reader reader;
230 if (reader.parse(system, a) &&
231 reader.parse(plugins, b) &&
232 a.type() == Json::objectValue &&
233 b.type() == Json::arrayValue &&
234 a.isMember(REST_API_VERSION) &&
235 a[REST_API_VERSION].type() == Json::intValue)
236 {
237 SetOrthancAdvancedPreview(a[REST_API_VERSION].asInt() >= 5);
238
239 hasOrthancWebViewer1_ = false;
240
241 for (Json::Value::ArrayIndex i = 0; i < b.size(); i++)
242 {
243 if (b[i].type() != Json::stringValue)
244 {
245 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
246 }
247
248 if (boost::iequals(b[i].asString(), "web-viewer"))
249 {
250 hasOrthancWebViewer1_ = true;
251 }
252 }
253 }
254 else
255 {
256 printf("[%s] [%s]\n", system.c_str(), plugins.c_str());
257
258 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
259 }
260 }
261
262
263 void DicomSource::SetOrthancWebViewer1(bool hasPlugin)
264 {
265 if (IsOrthanc())
266 {
267 hasOrthancWebViewer1_ = hasPlugin;
268 }
269 else
270 {
271 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
272 }
273 }
274
275 bool DicomSource::HasOrthancWebViewer1() const
276 {
277 if (IsOrthanc())
278 {
279 return hasOrthancWebViewer1_;
280 }
281 else
282 {
283 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
284 }
285 }
286
287 void DicomSource::SetOrthancAdvancedPreview(bool hasFeature)
288 {
289 if (IsOrthanc())
290 {
291 hasOrthancAdvancedPreview_ = hasFeature;
292 }
293 else
294 {
295 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
296 }
297 }
298
299 bool DicomSource::HasOrthancAdvancedPreview() const
300 {
301 if (IsOrthanc())
302 {
303 return hasOrthancAdvancedPreview_;
304 }
305 else
306 {
307 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
308 }
309 }
310
311 void DicomSource::SetDicomWebRendered(bool hasFeature)
312 {
313 if (IsDicomWeb())
314 {
315 hasDicomWebRendered_ = hasFeature;
316 }
317 else
318 {
319 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
320 }
321 }
322
323 bool DicomSource::HasDicomWebRendered() const
324 {
325 if (IsDicomWeb())
326 {
327 return hasDicomWebRendered_;
328 }
329 else
330 {
331 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
332 }
333 }
334
335
336 unsigned int DicomSource::GetQualityCount() const
337 {
338 if (IsDicomWeb())
339 {
340 return (HasDicomWebRendered() ? 2 : 1);
341 }
342 else if (IsOrthanc())
343 {
344 return (HasOrthancWebViewer1() ||
345 HasOrthancAdvancedPreview() ? 2 : 1);
346 }
347 else if (IsDicomDir())
348 {
349 return 1;
350 }
351 else
352 {
353 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
354 }
355 }
356 }