Mercurial > hg > orthanc
annotate OrthancServer/OrthancRestApi.cpp @ 187:8e673a65564d
refactoring of storing new instances
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 12 Nov 2012 17:29:11 +0100 |
parents | 93e1b0e3b83a |
children | b6cef9d45cc3 |
rev | line source |
---|---|
0 | 1 /** |
62 | 2 * Orthanc - A Lightweight, RESTful DICOM Store |
0 | 3 * Copyright (C) 2012 Medical Physics Department, CHU of Liege, |
4 * 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. | |
136 | 10 * |
11 * In addition, as a special exception, the copyright holders of this | |
12 * program give permission to link the code of its release with the | |
13 * OpenSSL project's "OpenSSL" library (or with modified versions of it | |
14 * that use the same license as the "OpenSSL" library), and distribute | |
15 * the linked executables. You must obey the GNU General Public License | |
16 * in all respects for all of the code used other than "OpenSSL". If you | |
17 * modify file(s) with this exception, you may extend this exception to | |
18 * your version of the file(s), but you are not obligated to do so. If | |
19 * you do not wish to do so, delete this exception statement from your | |
20 * version. If you delete this exception statement from all source files | |
21 * in the program, then also delete it here. | |
0 | 22 * |
23 * This program is distributed in the hope that it will be useful, but | |
24 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
26 * General Public License for more details. | |
27 * | |
28 * You should have received a copy of the GNU General Public License | |
29 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
30 **/ | |
31 | |
32 | |
62 | 33 #include "OrthancRestApi.h" |
0 | 34 |
62 | 35 #include "OrthancInitialization.h" |
0 | 36 #include "FromDcmtkBridge.h" |
37 #include "../Core/Uuid.h" | |
38 | |
39 #include <dcmtk/dcmdata/dcistrmb.h> | |
40 #include <dcmtk/dcmdata/dcfilefo.h> | |
41 #include <boost/lexical_cast.hpp> | |
42 | |
62 | 43 namespace Orthanc |
0 | 44 { |
45 static void SendJson(HttpOutput& output, | |
46 const Json::Value& value) | |
47 { | |
48 Json::StyledWriter writer; | |
49 std::string s = writer.write(value); | |
50 output.AnswerBufferWithContentType(s, "application/json"); | |
51 } | |
52 | |
35
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
53 |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
54 static void SimplifyTagsRecursion(Json::Value& target, |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
55 const Json::Value& source) |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
56 { |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
57 assert(source.isObject()); |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
58 |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
59 target = Json::objectValue; |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
60 Json::Value::Members members = source.getMemberNames(); |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
61 |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
62 for (size_t i = 0; i < members.size(); i++) |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
63 { |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
64 const Json::Value& v = source[members[i]]; |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
65 const std::string& name = v["Name"].asString(); |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
66 const std::string& type = v["Type"].asString(); |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
67 |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
68 if (type == "String") |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
69 { |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
70 target[name] = v["Value"].asString(); |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
71 } |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
72 else if (type == "TooLong" || |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
73 type == "Null") |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
74 { |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
75 target[name] = Json::nullValue; |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
76 } |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
77 else if (type == "Sequence") |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
78 { |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
79 const Json::Value& array = v["Value"]; |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
80 assert(array.isArray()); |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
81 |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
82 Json::Value children = Json::arrayValue; |
126 | 83 for (Json::Value::ArrayIndex i = 0; i < array.size(); i++) |
35
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
84 { |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
85 Json::Value c; |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
86 SimplifyTagsRecursion(c, array[i]); |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
87 children.append(c); |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
88 } |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
89 |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
90 target[name] = children; |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
91 } |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
92 else |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
93 { |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
94 assert(0); |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
95 } |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
96 } |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
97 } |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
98 |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
99 |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
100 static void SimplifyTags(Json::Value& target, |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
101 const FileStorage& storage, |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
102 const std::string& fileUuid) |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
103 { |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
104 std::string s; |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
105 storage.ReadFile(s, fileUuid); |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
106 |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
107 Json::Value source; |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
108 Json::Reader reader; |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
109 if (!reader.parse(s, source)) |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
110 { |
62 | 111 throw OrthancException("Corrupted JSON file"); |
35
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
112 } |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
113 |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
114 SimplifyTagsRecursion(target, source); |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
115 } |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
116 |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
117 |
62 | 118 bool OrthancRestApi::Store(Json::Value& result, |
50 | 119 const std::string& postData) |
0 | 120 { |
121 // Prepare an input stream for the memory buffer | |
122 DcmInputBufferStream is; | |
123 if (postData.size() > 0) | |
124 { | |
125 is.setBuffer(&postData[0], postData.size()); | |
126 } | |
127 is.setEos(); | |
128 | |
34
96e57b863dd9
option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
8
diff
changeset
|
129 //printf("[%d]\n", postData.size()); |
0 | 130 |
131 DcmFileFormat dicomFile; | |
132 if (dicomFile.read(is).good()) | |
133 { | |
134 DicomMap dicomSummary; | |
135 FromDcmtkBridge::Convert(dicomSummary, *dicomFile.getDataset()); | |
187
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
136 |
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
137 DicomInstanceHasher hasher(dicomSummary); |
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
138 |
0 | 139 Json::Value dicomJson; |
140 FromDcmtkBridge::ToJson(dicomJson, *dicomFile.getDataset()); | |
141 | |
142 StoreStatus status = StoreStatus_Failure; | |
143 if (postData.size() > 0) | |
144 { | |
145 status = index_.Store | |
187
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
146 (storage_, reinterpret_cast<const char*>(&postData[0]), |
0 | 147 postData.size(), dicomSummary, dicomJson, ""); |
148 } | |
149 | |
187
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
150 result["ID"] = hasher.HashInstance(); |
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
151 result["Path"] = "/instances/" + hasher.HashInstance(); |
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
152 |
0 | 153 switch (status) |
154 { | |
155 case StoreStatus_Success: | |
156 result["Status"] = "Success"; | |
157 return true; | |
158 | |
159 case StoreStatus_AlreadyStored: | |
160 result["Status"] = "AlreadyStored"; | |
161 return true; | |
162 | |
163 default: | |
164 return false; | |
165 } | |
166 } | |
167 | |
168 return false; | |
169 } | |
170 | |
62 | 171 void OrthancRestApi::ConnectToModality(DicomUserConnection& c, |
50 | 172 const std::string& name) |
0 | 173 { |
174 std::string aet, address; | |
175 int port; | |
176 GetDicomModality(name, aet, address, port); | |
62 | 177 c.SetLocalApplicationEntityTitle(GetGlobalStringParameter("DicomAet", "ORTHANC")); |
0 | 178 c.SetDistantApplicationEntityTitle(aet); |
179 c.SetDistantHost(address); | |
180 c.SetDistantPort(port); | |
181 c.Open(); | |
182 } | |
183 | |
62 | 184 bool OrthancRestApi::MergeQueryAndTemplate(DicomMap& result, |
50 | 185 const std::string& postData) |
0 | 186 { |
187 Json::Value query; | |
188 Json::Reader reader; | |
189 | |
190 if (!reader.parse(postData, query) || | |
8 | 191 query.type() != Json::objectValue) |
0 | 192 { |
193 return false; | |
194 } | |
195 | |
196 Json::Value::Members members = query.getMemberNames(); | |
197 for (size_t i = 0; i < members.size(); i++) | |
198 { | |
199 DicomTag t = FromDcmtkBridge::FindTag(members[i]); | |
200 result.SetValue(t, query[members[i]].asString()); | |
201 } | |
202 | |
203 return true; | |
204 } | |
205 | |
62 | 206 bool OrthancRestApi::DicomFindPatient(Json::Value& result, |
50 | 207 DicomUserConnection& c, |
208 const std::string& postData) | |
0 | 209 { |
210 DicomMap m; | |
211 DicomMap::SetupFindPatientTemplate(m); | |
212 if (!MergeQueryAndTemplate(m, postData)) | |
213 { | |
214 return false; | |
215 } | |
216 | |
217 DicomFindAnswers answers; | |
218 c.FindPatient(answers, m); | |
219 answers.ToJson(result); | |
220 return true; | |
221 } | |
222 | |
62 | 223 bool OrthancRestApi::DicomFindStudy(Json::Value& result, |
50 | 224 DicomUserConnection& c, |
225 const std::string& postData) | |
0 | 226 { |
227 DicomMap m; | |
228 DicomMap::SetupFindStudyTemplate(m); | |
229 if (!MergeQueryAndTemplate(m, postData)) | |
230 { | |
231 return false; | |
232 } | |
233 | |
80 | 234 if (m.GetValue(DICOM_TAG_ACCESSION_NUMBER).AsString().size() <= 2 && |
235 m.GetValue(DICOM_TAG_PATIENT_ID).AsString().size() <= 2) | |
0 | 236 { |
237 return false; | |
238 } | |
239 | |
240 DicomFindAnswers answers; | |
241 c.FindStudy(answers, m); | |
242 answers.ToJson(result); | |
243 return true; | |
244 } | |
245 | |
62 | 246 bool OrthancRestApi::DicomFindSeries(Json::Value& result, |
50 | 247 DicomUserConnection& c, |
248 const std::string& postData) | |
0 | 249 { |
250 DicomMap m; | |
251 DicomMap::SetupFindSeriesTemplate(m); | |
252 if (!MergeQueryAndTemplate(m, postData)) | |
253 { | |
254 return false; | |
255 } | |
256 | |
80 | 257 if ((m.GetValue(DICOM_TAG_ACCESSION_NUMBER).AsString().size() <= 2 && |
258 m.GetValue(DICOM_TAG_PATIENT_ID).AsString().size() <= 2) || | |
259 m.GetValue(DICOM_TAG_STUDY_INSTANCE_UID).AsString().size() <= 2) | |
0 | 260 { |
261 return false; | |
262 } | |
263 | |
264 DicomFindAnswers answers; | |
265 c.FindSeries(answers, m); | |
266 answers.ToJson(result); | |
267 return true; | |
268 } | |
269 | |
62 | 270 bool OrthancRestApi::DicomFind(Json::Value& result, |
50 | 271 DicomUserConnection& c, |
272 const std::string& postData) | |
0 | 273 { |
274 DicomMap m; | |
275 DicomMap::SetupFindPatientTemplate(m); | |
276 if (!MergeQueryAndTemplate(m, postData)) | |
277 { | |
278 return false; | |
279 } | |
280 | |
281 DicomFindAnswers patients; | |
282 c.FindPatient(patients, m); | |
283 | |
284 // Loop over the found patients | |
285 result = Json::arrayValue; | |
286 for (size_t i = 0; i < patients.GetSize(); i++) | |
287 { | |
288 Json::Value patient(Json::objectValue); | |
289 FromDcmtkBridge::ToJson(patient, patients.GetAnswer(i)); | |
290 | |
291 DicomMap::SetupFindStudyTemplate(m); | |
292 if (!MergeQueryAndTemplate(m, postData)) | |
293 { | |
294 return false; | |
295 } | |
80 | 296 m.CopyTagIfExists(patients.GetAnswer(i), DICOM_TAG_PATIENT_ID); |
0 | 297 |
298 DicomFindAnswers studies; | |
299 c.FindStudy(studies, m); | |
300 | |
301 patient["Studies"] = Json::arrayValue; | |
302 | |
303 // Loop over the found studies | |
304 for (size_t j = 0; j < studies.GetSize(); j++) | |
305 { | |
306 Json::Value study(Json::objectValue); | |
307 FromDcmtkBridge::ToJson(study, studies.GetAnswer(j)); | |
308 | |
309 DicomMap::SetupFindSeriesTemplate(m); | |
310 if (!MergeQueryAndTemplate(m, postData)) | |
311 { | |
312 return false; | |
313 } | |
80 | 314 m.CopyTagIfExists(studies.GetAnswer(j), DICOM_TAG_PATIENT_ID); |
315 m.CopyTagIfExists(studies.GetAnswer(j), DICOM_TAG_STUDY_INSTANCE_UID); | |
0 | 316 |
317 DicomFindAnswers series; | |
318 c.FindSeries(series, m); | |
319 | |
320 // Loop over the found series | |
321 study["Series"] = Json::arrayValue; | |
322 for (size_t k = 0; k < series.GetSize(); k++) | |
323 { | |
324 Json::Value series2(Json::objectValue); | |
325 FromDcmtkBridge::ToJson(series2, series.GetAnswer(k)); | |
326 study["Series"].append(series2); | |
327 } | |
328 | |
329 patient["Studies"].append(study); | |
330 } | |
331 | |
332 result.append(patient); | |
333 } | |
334 | |
335 return true; | |
336 } | |
337 | |
338 | |
339 | |
62 | 340 bool OrthancRestApi::DicomStore(Json::Value& result, |
50 | 341 DicomUserConnection& c, |
342 const std::string& postData) | |
0 | 343 { |
344 Json::Value found(Json::objectValue); | |
345 | |
346 if (!Toolbox::IsUuid(postData)) | |
347 { | |
348 // This is not a UUID, assume this is a DICOM instance | |
349 c.Store(postData); | |
350 } | |
351 else if (index_.GetSeries(found, postData)) | |
352 { | |
353 // The UUID corresponds to a series | |
126 | 354 for (Json::Value::ArrayIndex i = 0; i < found["Instances"].size(); i++) |
0 | 355 { |
356 std::string uuid = found["Instances"][i].asString(); | |
357 Json::Value instance(Json::objectValue); | |
358 if (index_.GetInstance(instance, uuid)) | |
359 { | |
360 std::string content; | |
361 storage_.ReadFile(content, instance["FileUuid"].asString()); | |
362 c.Store(content); | |
363 } | |
364 else | |
365 { | |
366 return false; | |
367 } | |
368 } | |
369 } | |
370 else if (index_.GetInstance(found, postData)) | |
371 { | |
372 // The UUID corresponds to an instance | |
373 std::string content; | |
374 storage_.ReadFile(content, found["FileUuid"].asString()); | |
375 c.Store(content); | |
376 } | |
377 else | |
378 { | |
379 return false; | |
380 } | |
381 | |
382 return true; | |
383 } | |
384 | |
385 | |
62 | 386 OrthancRestApi::OrthancRestApi(ServerIndex& index, |
50 | 387 const std::string& path) : |
0 | 388 index_(index), |
389 storage_(path) | |
390 { | |
391 GetListOfDicomModalities(modalities_); | |
392 } | |
393 | |
394 | |
62 | 395 void OrthancRestApi::Handle( |
0 | 396 HttpOutput& output, |
397 const std::string& method, | |
398 const UriComponents& uri, | |
399 const Arguments& headers, | |
400 const Arguments& arguments, | |
401 const std::string& postData) | |
402 { | |
403 if (uri.size() == 0) | |
404 { | |
405 if (method == "GET") | |
406 { | |
85
ebce15865cce
relative redirection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
80
diff
changeset
|
407 output.Redirect("app/explorer.html"); |
0 | 408 } |
409 else | |
410 { | |
411 output.SendMethodNotAllowedError("GET"); | |
412 } | |
413 | |
414 return; | |
415 } | |
416 | |
417 bool existingResource = false; | |
418 Json::Value result(Json::objectValue); | |
419 | |
420 | |
151 | 421 // Version information ------------------------------------------------------ |
422 | |
423 if (uri.size() == 1 && uri[0] == "system") | |
424 { | |
425 if (method == "GET") | |
426 { | |
427 result = Json::Value(Json::objectValue); | |
428 result["Version"] = ORTHANC_VERSION; | |
429 result["Name"] = GetGlobalStringParameter("Name", ""); | |
187
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
430 result["TotalCompressedSize"] = boost::lexical_cast<std::string>(index_.GetTotalCompressedSize()); |
8e673a65564d
refactoring of storing new instances
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
431 result["TotalUncompressedSize"] = boost::lexical_cast<std::string>(index_.GetTotalUncompressedSize()); |
151 | 432 existingResource = true; |
433 } | |
434 else | |
435 { | |
436 output.SendMethodNotAllowedError("GET,POST"); | |
437 return; | |
438 } | |
439 } | |
440 | |
441 | |
0 | 442 // List all the instances --------------------------------------------------- |
443 | |
444 if (uri.size() == 1 && uri[0] == "instances") | |
445 { | |
446 if (method == "GET") | |
447 { | |
448 result = Json::Value(Json::arrayValue); | |
449 index_.GetAllUuids(result, "Instances"); | |
450 existingResource = true; | |
451 } | |
452 else if (method == "POST") | |
453 { | |
454 // Add a new instance to the storage | |
455 if (Store(result, postData)) | |
456 { | |
457 SendJson(output, result); | |
458 return; | |
459 } | |
460 else | |
461 { | |
62 | 462 output.SendHeader(Orthanc_HttpStatus_415_UnsupportedMediaType); |
0 | 463 return; |
464 } | |
465 } | |
466 else | |
467 { | |
468 output.SendMethodNotAllowedError("GET,POST"); | |
469 return; | |
470 } | |
471 } | |
472 | |
473 | |
474 // List all the patients, studies or series --------------------------------- | |
475 | |
476 if (uri.size() == 1 && | |
477 (uri[0] == "series" || | |
478 uri[0] == "studies" || | |
479 uri[0] == "patients")) | |
480 { | |
481 if (method == "GET") | |
482 { | |
483 result = Json::Value(Json::arrayValue); | |
484 | |
485 if (uri[0] == "instances") | |
486 index_.GetAllUuids(result, "Instances"); | |
487 else if (uri[0] == "series") | |
488 index_.GetAllUuids(result, "Series"); | |
489 else if (uri[0] == "studies") | |
490 index_.GetAllUuids(result, "Studies"); | |
491 else if (uri[0] == "patients") | |
492 index_.GetAllUuids(result, "Patients"); | |
493 | |
494 existingResource = true; | |
495 } | |
496 else | |
497 { | |
498 output.SendMethodNotAllowedError("GET"); | |
499 return; | |
500 } | |
501 } | |
502 | |
503 | |
504 // Information about a single object ---------------------------------------- | |
505 | |
506 else if (uri.size() == 2 && | |
507 (uri[0] == "instances" || | |
508 uri[0] == "series" || | |
509 uri[0] == "studies" || | |
510 uri[0] == "patients")) | |
511 { | |
512 if (method == "GET") | |
513 { | |
514 if (uri[0] == "patients") | |
515 { | |
516 existingResource = index_.GetPatient(result, uri[1]); | |
517 } | |
518 else if (uri[0] == "studies") | |
519 { | |
520 existingResource = index_.GetStudy(result, uri[1]); | |
521 } | |
522 else if (uri[0] == "series") | |
523 { | |
524 existingResource = index_.GetSeries(result, uri[1]); | |
525 } | |
526 else if (uri[0] == "instances") | |
527 { | |
528 existingResource = index_.GetInstance(result, uri[1]); | |
529 } | |
530 } | |
531 else if (method == "DELETE") | |
532 { | |
533 if (uri[0] == "patients") | |
534 { | |
535 existingResource = index_.DeletePatient(result, uri[1]); | |
536 } | |
537 else if (uri[0] == "studies") | |
538 { | |
539 existingResource = index_.DeleteStudy(result, uri[1]); | |
540 } | |
541 else if (uri[0] == "series") | |
542 { | |
543 existingResource = index_.DeleteSeries(result, uri[1]); | |
544 } | |
545 else if (uri[0] == "instances") | |
546 { | |
547 existingResource = index_.DeleteInstance(result, uri[1]); | |
548 } | |
549 | |
550 if (existingResource) | |
551 { | |
552 result["Status"] = "Success"; | |
553 } | |
554 } | |
555 else | |
556 { | |
557 output.SendMethodNotAllowedError("GET,DELETE"); | |
558 return; | |
559 } | |
560 } | |
561 | |
562 | |
563 // Get the DICOM or the JSON file of one instance --------------------------- | |
564 | |
565 else if (uri.size() == 3 && | |
566 uri[0] == "instances" && | |
567 (uri[2] == "file" || | |
34
96e57b863dd9
option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
8
diff
changeset
|
568 uri[2] == "tags" || |
35
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
569 uri[2] == "simplified-tags")) |
0 | 570 { |
155
93e1b0e3b83a
filenames when downloading json/dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
151
diff
changeset
|
571 std::string fileUuid, contentType, filename; |
0 | 572 if (uri[2] == "file") |
573 { | |
574 existingResource = index_.GetDicomFile(fileUuid, uri[1]); | |
575 contentType = "application/dicom"; | |
155
93e1b0e3b83a
filenames when downloading json/dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
151
diff
changeset
|
576 filename = fileUuid + ".dcm"; |
0 | 577 } |
34
96e57b863dd9
option to disallow remote access
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
8
diff
changeset
|
578 else if (uri[2] == "tags" || |
35
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
579 uri[2] == "simplified-tags") |
0 | 580 { |
581 existingResource = index_.GetJsonFile(fileUuid, uri[1]); | |
582 contentType = "application/json"; | |
155
93e1b0e3b83a
filenames when downloading json/dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
151
diff
changeset
|
583 filename = fileUuid + ".json"; |
0 | 584 } |
585 | |
586 if (existingResource) | |
587 { | |
35
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
588 if (uri[2] == "simplified-tags") |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
589 { |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
590 Json::Value v; |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
591 SimplifyTags(v, storage_, fileUuid); |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
592 SendJson(output, v); |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
593 return; |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
594 } |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
595 else |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
596 { |
155
93e1b0e3b83a
filenames when downloading json/dicom
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
151
diff
changeset
|
597 output.AnswerFile(storage_, fileUuid, contentType, filename.c_str()); |
35
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
598 return; |
f6d12037f886
full json vs. simplified json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
34
diff
changeset
|
599 } |
0 | 600 } |
601 } | |
602 | |
603 | |
604 else if (uri.size() == 3 && | |
605 uri[0] == "instances" && | |
53
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
606 uri[2] == "frames") |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
607 { |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
608 Json::Value instance(Json::objectValue); |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
609 existingResource = index_.GetInstance(instance, uri[1]); |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
610 |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
611 if (existingResource) |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
612 { |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
613 result = Json::arrayValue; |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
614 |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
615 unsigned int numberOfFrames = 1; |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
616 try |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
617 { |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
618 Json::Value tmp = instance["MainDicomTags"]["NumberOfFrames"]; |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
619 numberOfFrames = boost::lexical_cast<unsigned int>(tmp.asString()); |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
620 } |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
621 catch (boost::bad_lexical_cast) |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
622 { |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
623 } |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
624 |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
625 for (unsigned int i = 0; i < numberOfFrames; i++) |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
626 { |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
627 result.append(i); |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
628 } |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
629 } |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
630 } |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
631 |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
632 |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
633 else if (uri[0] == "instances" && |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
634 ((uri.size() == 3 && |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
635 (uri[2] == "preview" || |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
636 uri[2] == "image-uint8" || |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
637 uri[2] == "image-uint16")) || |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
638 (uri.size() == 5 && |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
639 uri[2] == "frames" && |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
640 (uri[4] == "preview" || |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
641 uri[4] == "image-uint8" || |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
642 uri[4] == "image-uint16")))) |
0 | 643 { |
644 std::string uuid; | |
645 existingResource = index_.GetDicomFile(uuid, uri[1]); | |
646 | |
53
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
647 std::string action = uri[2]; |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
648 |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
649 unsigned int frame = 0; |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
650 if (existingResource && |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
651 uri.size() == 5) |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
652 { |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
653 // Access to multi-frame image |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
654 action = uri[4]; |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
655 try |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
656 { |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
657 frame = boost::lexical_cast<unsigned int>(uri[3]); |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
658 } |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
659 catch (boost::bad_lexical_cast) |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
660 { |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
661 existingResource = false; |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
662 } |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
663 } |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
664 |
0 | 665 if (existingResource) |
666 { | |
667 std::string dicomContent, png; | |
668 storage_.ReadFile(dicomContent, uuid); | |
669 try | |
670 { | |
53
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
671 if (action == "preview") |
42
ea48f38afe5f
access to raw images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
41
diff
changeset
|
672 { |
53
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
673 FromDcmtkBridge::ExtractPngImage(png, dicomContent, frame, ImageExtractionMode_Preview); |
42
ea48f38afe5f
access to raw images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
41
diff
changeset
|
674 } |
53
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
675 else if (action == "image-uint8") |
42
ea48f38afe5f
access to raw images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
41
diff
changeset
|
676 { |
53
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
677 FromDcmtkBridge::ExtractPngImage(png, dicomContent, frame, ImageExtractionMode_UInt8); |
42
ea48f38afe5f
access to raw images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
41
diff
changeset
|
678 } |
53
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
679 else if (action == "image-uint16") |
42
ea48f38afe5f
access to raw images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
41
diff
changeset
|
680 { |
53
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
681 FromDcmtkBridge::ExtractPngImage(png, dicomContent, frame, ImageExtractionMode_UInt16); |
42
ea48f38afe5f
access to raw images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
41
diff
changeset
|
682 } |
ea48f38afe5f
access to raw images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
41
diff
changeset
|
683 else |
ea48f38afe5f
access to raw images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
41
diff
changeset
|
684 { |
62 | 685 throw OrthancException(ErrorCode_InternalError); |
42
ea48f38afe5f
access to raw images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
41
diff
changeset
|
686 } |
ea48f38afe5f
access to raw images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
41
diff
changeset
|
687 |
0 | 688 output.AnswerBufferWithContentType(png, "image/png"); |
689 return; | |
690 } | |
62 | 691 catch (OrthancException&) |
0 | 692 { |
85
ebce15865cce
relative redirection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
80
diff
changeset
|
693 std::string root = ""; |
ebce15865cce
relative redirection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
80
diff
changeset
|
694 for (size_t i = 1; i < uri.size(); i++) |
ebce15865cce
relative redirection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
80
diff
changeset
|
695 { |
ebce15865cce
relative redirection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
80
diff
changeset
|
696 root += "../"; |
ebce15865cce
relative redirection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
80
diff
changeset
|
697 } |
ebce15865cce
relative redirection
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
80
diff
changeset
|
698 |
129 | 699 output.Redirect(root + "app/images/unsupported.png"); |
0 | 700 return; |
701 } | |
702 } | |
703 } | |
704 | |
705 | |
706 | |
707 // Changes API -------------------------------------------------------------- | |
708 | |
709 if (uri.size() == 1 && uri[0] == "changes") | |
710 { | |
711 if (method == "GET") | |
712 { | |
713 const static unsigned int MAX_RESULTS = 100; | |
714 | |
715 std::string filter = GetArgument(arguments, "filter", ""); | |
716 int64_t since; | |
717 unsigned int limit; | |
718 try | |
719 { | |
720 since = boost::lexical_cast<int64_t>(GetArgument(arguments, "since", "0")); | |
721 limit = boost::lexical_cast<unsigned int>(GetArgument(arguments, "limit", "0")); | |
722 } | |
723 catch (boost::bad_lexical_cast) | |
724 { | |
62 | 725 output.SendHeader(Orthanc_HttpStatus_400_BadRequest); |
0 | 726 return; |
727 } | |
728 | |
729 if (limit == 0 || limit > MAX_RESULTS) | |
730 { | |
731 limit = MAX_RESULTS; | |
732 } | |
733 | |
734 if (!index_.GetChanges(result, since, filter, limit)) | |
735 { | |
62 | 736 output.SendHeader(Orthanc_HttpStatus_400_BadRequest); |
0 | 737 return; |
738 } | |
739 | |
740 existingResource = true; | |
741 } | |
742 else | |
743 { | |
744 output.SendMethodNotAllowedError("GET"); | |
745 return; | |
746 } | |
747 } | |
748 | |
749 | |
750 // DICOM bridge ------------------------------------------------------------- | |
751 | |
752 if (uri.size() == 1 && | |
753 uri[0] == "modalities") | |
754 { | |
755 if (method == "GET") | |
756 { | |
757 result = Json::Value(Json::arrayValue); | |
758 existingResource = true; | |
759 | |
760 for (Modalities::const_iterator it = modalities_.begin(); | |
761 it != modalities_.end(); it++) | |
762 { | |
763 result.append(*it); | |
764 } | |
765 } | |
766 else | |
767 { | |
768 output.SendMethodNotAllowedError("GET"); | |
769 return; | |
770 } | |
771 } | |
772 | |
773 if ((uri.size() == 2 || | |
774 uri.size() == 3) && | |
775 uri[0] == "modalities") | |
776 { | |
777 if (modalities_.find(uri[1]) == modalities_.end()) | |
778 { | |
779 // Unknown modality | |
780 } | |
781 else if (uri.size() == 2) | |
782 { | |
783 if (method != "GET") | |
784 { | |
785 output.SendMethodNotAllowedError("POST"); | |
786 return; | |
787 } | |
788 else | |
789 { | |
790 existingResource = true; | |
791 result = Json::arrayValue; | |
792 result.append("find-patient"); | |
793 result.append("find-study"); | |
794 result.append("find-series"); | |
795 result.append("find"); | |
796 result.append("store"); | |
797 } | |
798 } | |
799 else if (uri.size() == 3) | |
800 { | |
801 if (uri[2] != "find-patient" && | |
802 uri[2] != "find-study" && | |
803 uri[2] != "find-series" && | |
804 uri[2] != "find" && | |
805 uri[2] != "store") | |
806 { | |
807 // Unknown request | |
808 } | |
809 else if (method != "POST") | |
810 { | |
811 output.SendMethodNotAllowedError("POST"); | |
812 return; | |
813 } | |
814 else | |
815 { | |
816 DicomUserConnection connection; | |
817 ConnectToModality(connection, uri[1]); | |
818 existingResource = true; | |
819 | |
820 if ((uri[2] == "find-patient" && !DicomFindPatient(result, connection, postData)) || | |
821 (uri[2] == "find-study" && !DicomFindStudy(result, connection, postData)) || | |
822 (uri[2] == "find-series" && !DicomFindSeries(result, connection, postData)) || | |
823 (uri[2] == "find" && !DicomFind(result, connection, postData)) || | |
824 (uri[2] == "store" && !DicomStore(result, connection, postData))) | |
825 { | |
62 | 826 output.SendHeader(Orthanc_HttpStatus_400_BadRequest); |
0 | 827 return; |
828 } | |
829 } | |
830 } | |
831 } | |
832 | |
833 | |
834 if (existingResource) | |
835 { | |
836 SendJson(output, result); | |
837 } | |
838 else | |
839 { | |
62 | 840 output.SendHeader(Orthanc_HttpStatus_404_NotFound); |
0 | 841 } |
842 } | |
843 } |