Mercurial > hg > orthanc
annotate OrthancServer/Sources/OrthancWebDav.cpp @ 4246:6c3721ff284c
simplification
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 13 Oct 2020 10:39:47 +0200 |
parents | c70df925151e |
children | f047e2734655 |
rev | line source |
---|---|
4240 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
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 General Public License as | |
9 * published by the Free Software Foundation, either version 3 of the | |
10 * License, or (at your option) any later version. | |
11 * | |
12 * In addition, as a special exception, the copyright holders of this | |
13 * program give permission to link the code of its release with the | |
14 * OpenSSL project's "OpenSSL" library (or with modified versions of it | |
15 * that use the same license as the "OpenSSL" library), and distribute | |
16 * the linked executables. You must obey the GNU General Public License | |
17 * in all respects for all of the code used other than "OpenSSL". If you | |
18 * modify file(s) with this exception, you may extend this exception to | |
19 * your version of the file(s), but you are not obligated to do so. If | |
20 * you do not wish to do so, delete this exception statement from your | |
21 * version. If you delete this exception statement from all source files | |
22 * in the program, then also delete it here. | |
23 * | |
24 * This program is distributed in the hope that it will be useful, but | |
25 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
27 * General Public License for more details. | |
28 * | |
29 * You should have received a copy of the GNU General Public License | |
30 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
31 **/ | |
32 | |
33 | |
34 #include "OrthancWebDav.h" | |
35 | |
36 #include "../../OrthancFramework/Sources/DicomFormat/DicomArray.h" | |
37 #include "../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h" | |
38 #include "../../OrthancFramework/Sources/HttpServer/WebDavStorage.h" | |
39 #include "Search/DatabaseLookup.h" | |
40 #include "ServerContext.h" | |
41 | |
42 #include <boost/regex.hpp> | |
43 #include <boost/algorithm/string/predicate.hpp> | |
44 | |
45 | |
46 static const char* const BY_PATIENTS = "by-patients"; | |
47 static const char* const BY_STUDIES = "by-studies"; | |
4241 | 48 static const char* const BY_DATES = "by-dates"; |
4240 | 49 static const char* const BY_UIDS = "by-uids"; |
50 static const char* const UPLOADS = "uploads"; | |
51 static const char* const MAIN_DICOM_TAGS = "MainDicomTags"; | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
52 static const char* const STUDY_INFO = "study.json"; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
53 static const char* const SERIES_INFO = "series.json"; |
4240 | 54 |
55 | |
56 namespace Orthanc | |
57 { | |
58 static boost::posix_time::ptime GetNow() | |
59 { | |
60 return boost::posix_time::second_clock::universal_time(); | |
61 } | |
62 | |
63 | |
64 static void LookupTime(boost::posix_time::ptime& target, | |
65 ServerContext& context, | |
66 const std::string& publicId, | |
67 MetadataType metadata) | |
68 { | |
69 std::string value; | |
70 if (context.GetIndex().LookupMetadata(value, publicId, metadata)) | |
71 { | |
72 try | |
73 { | |
74 target = boost::posix_time::from_iso_string(value); | |
75 return; | |
76 } | |
77 catch (std::exception& e) | |
78 { | |
79 } | |
80 } | |
81 | |
82 target = GetNow(); | |
83 } | |
84 | |
85 | |
86 class OrthancWebDav::DicomIdentifiersVisitor : public ServerContext::ILookupVisitor | |
87 { | |
88 private: | |
89 ServerContext& context_; | |
90 bool isComplete_; | |
91 Collection& target_; | |
92 ResourceType level_; | |
93 | |
94 public: | |
95 DicomIdentifiersVisitor(ServerContext& context, | |
96 Collection& target, | |
97 ResourceType level) : | |
98 context_(context), | |
99 isComplete_(false), | |
100 target_(target), | |
101 level_(level) | |
102 { | |
103 } | |
104 | |
105 virtual bool IsDicomAsJsonNeeded() const ORTHANC_OVERRIDE | |
106 { | |
107 return false; // (*) | |
108 } | |
109 | |
110 virtual void MarkAsComplete() ORTHANC_OVERRIDE | |
111 { | |
112 isComplete_ = true; // TODO | |
113 } | |
114 | |
115 virtual void Visit(const std::string& publicId, | |
116 const std::string& instanceId /* unused */, | |
117 const DicomMap& mainDicomTags, | |
118 const Json::Value* dicomAsJson /* unused (*) */) ORTHANC_OVERRIDE | |
119 { | |
120 DicomTag tag(0, 0); | |
121 MetadataType timeMetadata; | |
122 | |
123 switch (level_) | |
124 { | |
125 case ResourceType_Study: | |
126 tag = DICOM_TAG_STUDY_INSTANCE_UID; | |
127 timeMetadata = MetadataType_LastUpdate; | |
128 break; | |
129 | |
130 case ResourceType_Series: | |
131 tag = DICOM_TAG_SERIES_INSTANCE_UID; | |
132 timeMetadata = MetadataType_LastUpdate; | |
133 break; | |
134 | |
135 case ResourceType_Instance: | |
136 tag = DICOM_TAG_SOP_INSTANCE_UID; | |
137 timeMetadata = MetadataType_Instance_ReceptionDate; | |
138 break; | |
139 | |
140 default: | |
141 throw OrthancException(ErrorCode_InternalError); | |
142 } | |
143 | |
144 std::string s; | |
145 if (mainDicomTags.LookupStringValue(s, tag, false) && | |
146 !s.empty()) | |
147 { | |
148 std::unique_ptr<Resource> resource; | |
149 | |
150 if (level_ == ResourceType_Instance) | |
151 { | |
152 FileInfo info; | |
153 if (context_.GetIndex().LookupAttachment(info, publicId, FileContentType_Dicom)) | |
154 { | |
155 std::unique_ptr<File> f(new File(s + ".dcm")); | |
156 f->SetMimeType(MimeType_Dicom); | |
157 f->SetContentLength(info.GetUncompressedSize()); | |
158 resource.reset(f.release()); | |
159 } | |
160 } | |
161 else | |
162 { | |
163 resource.reset(new Folder(s)); | |
164 } | |
165 | |
166 if (resource.get() != NULL) | |
167 { | |
168 boost::posix_time::ptime t; | |
169 LookupTime(t, context_, publicId, timeMetadata); | |
170 resource->SetCreationTime(t); | |
171 target_.AddResource(resource.release()); | |
172 } | |
173 } | |
174 } | |
175 }; | |
176 | |
177 | |
178 class OrthancWebDav::DicomFileVisitor : public ServerContext::ILookupVisitor | |
179 { | |
180 private: | |
181 ServerContext& context_; | |
182 bool success_; | |
183 std::string& target_; | |
184 boost::posix_time::ptime& time_; | |
185 | |
186 public: | |
187 DicomFileVisitor(ServerContext& context, | |
188 std::string& target, | |
189 boost::posix_time::ptime& time) : | |
190 context_(context), | |
191 success_(false), | |
192 target_(target), | |
193 time_(time) | |
194 { | |
195 } | |
196 | |
197 bool IsSuccess() const | |
198 { | |
199 return success_; | |
200 } | |
201 | |
202 virtual bool IsDicomAsJsonNeeded() const ORTHANC_OVERRIDE | |
203 { | |
204 return false; // (*) | |
205 } | |
206 | |
207 virtual void MarkAsComplete() ORTHANC_OVERRIDE | |
208 { | |
209 } | |
210 | |
211 virtual void Visit(const std::string& publicId, | |
212 const std::string& instanceId /* unused */, | |
213 const DicomMap& mainDicomTags, | |
214 const Json::Value* dicomAsJson /* unused (*) */) ORTHANC_OVERRIDE | |
215 { | |
216 if (success_) | |
217 { | |
218 success_ = false; // Two matches => Error | |
219 } | |
220 else | |
221 { | |
222 LookupTime(time_, context_, publicId, MetadataType_Instance_ReceptionDate); | |
223 context_.ReadDicom(target_, publicId); | |
224 success_ = true; | |
225 } | |
226 } | |
227 }; | |
228 | |
229 | |
230 class OrthancWebDav::OrthancJsonVisitor : public ServerContext::ILookupVisitor | |
231 { | |
232 private: | |
233 ServerContext& context_; | |
234 bool success_; | |
235 std::string& target_; | |
236 ResourceType level_; | |
237 | |
238 public: | |
239 OrthancJsonVisitor(ServerContext& context, | |
240 std::string& target, | |
241 ResourceType level) : | |
242 context_(context), | |
243 success_(false), | |
244 target_(target), | |
245 level_(level) | |
246 { | |
247 } | |
248 | |
249 bool IsSuccess() const | |
250 { | |
251 return success_; | |
252 } | |
253 | |
254 virtual bool IsDicomAsJsonNeeded() const ORTHANC_OVERRIDE | |
255 { | |
256 return false; // (*) | |
257 } | |
258 | |
259 virtual void MarkAsComplete() ORTHANC_OVERRIDE | |
260 { | |
261 } | |
262 | |
263 virtual void Visit(const std::string& publicId, | |
264 const std::string& instanceId /* unused */, | |
265 const DicomMap& mainDicomTags, | |
266 const Json::Value* dicomAsJson /* unused (*) */) ORTHANC_OVERRIDE | |
267 { | |
268 Json::Value info; | |
269 if (context_.GetIndex().LookupResource(info, publicId, level_)) | |
270 { | |
271 if (success_) | |
272 { | |
273 success_ = false; // Two matches => Error | |
274 } | |
275 else | |
276 { | |
277 target_ = info.toStyledString(); | |
278 | |
279 // Replace UNIX newlines with DOS newlines | |
280 boost::replace_all(target_, "\n", "\r\n"); | |
281 | |
282 success_ = true; | |
283 } | |
284 } | |
285 } | |
286 }; | |
287 | |
288 | |
289 class OrthancWebDav::ResourcesIndex : public boost::noncopyable | |
290 { | |
291 public: | |
292 typedef std::map<std::string, std::string> Map; | |
293 | |
294 private: | |
295 ServerContext& context_; | |
296 ResourceType level_; | |
297 std::string template_; | |
298 Map pathToResource_; | |
299 Map resourceToPath_; | |
300 | |
301 void CheckInvariants() | |
302 { | |
303 #ifndef NDEBUG | |
304 assert(pathToResource_.size() == resourceToPath_.size()); | |
305 | |
306 for (Map::const_iterator it = pathToResource_.begin(); it != pathToResource_.end(); ++it) | |
307 { | |
308 assert(resourceToPath_[it->second] == it->first); | |
309 } | |
310 | |
311 for (Map::const_iterator it = resourceToPath_.begin(); it != resourceToPath_.end(); ++it) | |
312 { | |
313 assert(pathToResource_[it->second] == it->first); | |
314 } | |
315 #endif | |
316 } | |
317 | |
318 void AddTags(DicomMap& target, | |
319 const std::string& resourceId, | |
320 ResourceType tagsFromLevel) | |
321 { | |
322 DicomMap tags; | |
323 if (context_.GetIndex().GetMainDicomTags(tags, resourceId, level_, tagsFromLevel)) | |
324 { | |
325 target.Merge(tags); | |
326 } | |
327 } | |
328 | |
329 void Register(const std::string& resourceId) | |
330 { | |
331 // Don't register twice the same resource | |
332 if (resourceToPath_.find(resourceId) == resourceToPath_.end()) | |
333 { | |
334 std::string name = template_; | |
335 | |
336 DicomMap tags; | |
337 | |
338 AddTags(tags, resourceId, level_); | |
339 | |
340 if (level_ == ResourceType_Study) | |
341 { | |
342 AddTags(tags, resourceId, ResourceType_Patient); | |
343 } | |
344 | |
345 DicomArray arr(tags); | |
346 for (size_t i = 0; i < arr.GetSize(); i++) | |
347 { | |
348 const DicomElement& element = arr.GetElement(i); | |
349 if (!element.GetValue().IsNull() && | |
350 !element.GetValue().IsBinary()) | |
351 { | |
352 const std::string tag = FromDcmtkBridge::GetTagName(element.GetTag(), ""); | |
353 boost::replace_all(name, "{{" + tag + "}}", element.GetValue().GetContent()); | |
354 } | |
355 } | |
356 | |
357 // Blank the tags that were not matched | |
358 static const boost::regex REGEX_BLANK_TAGS("{{.*?}}"); // non-greedy match | |
359 name = boost::regex_replace(name, REGEX_BLANK_TAGS, ""); | |
360 | |
361 // UTF-8 characters cannot be used on Windows XP | |
362 name = Toolbox::ConvertToAscii(name); | |
363 boost::replace_all(name, "/", ""); | |
364 boost::replace_all(name, "\\", ""); | |
365 | |
366 // Trim sequences of spaces as one single space | |
367 static const boost::regex REGEX_TRIM_SPACES("{{.*?}}"); | |
368 name = boost::regex_replace(name, REGEX_TRIM_SPACES, " "); | |
369 name = Toolbox::StripSpaces(name); | |
370 | |
371 size_t count = 0; | |
372 for (;;) | |
373 { | |
374 std::string path = name; | |
375 if (count > 0) | |
376 { | |
377 path += " (" + boost::lexical_cast<std::string>(count) + ")"; | |
378 } | |
379 | |
380 if (pathToResource_.find(path) == pathToResource_.end()) | |
381 { | |
382 pathToResource_[path] = resourceId; | |
383 resourceToPath_[resourceId] = path; | |
384 return; | |
385 } | |
386 | |
387 count++; | |
388 } | |
389 | |
390 throw OrthancException(ErrorCode_InternalError); | |
391 } | |
392 } | |
393 | |
394 public: | |
395 ResourcesIndex(ServerContext& context, | |
396 ResourceType level, | |
397 const std::string& templateString) : | |
398 context_(context), | |
399 level_(level), | |
400 template_(templateString) | |
401 { | |
402 } | |
403 | |
404 ResourceType GetLevel() const | |
405 { | |
406 return level_; | |
407 } | |
408 | |
409 void Refresh(std::set<std::string>& removedPaths /* out */, | |
410 const std::set<std::string>& resources) | |
411 { | |
412 CheckInvariants(); | |
413 | |
414 // Detect the resources that have been removed since last refresh | |
415 removedPaths.clear(); | |
416 std::set<std::string> removedResources; | |
417 | |
418 for (Map::iterator it = resourceToPath_.begin(); it != resourceToPath_.end(); ++it) | |
419 { | |
420 if (resources.find(it->first) == resources.end()) | |
421 { | |
422 const std::string& path = it->second; | |
423 | |
424 assert(pathToResource_.find(path) != pathToResource_.end()); | |
425 pathToResource_.erase(path); | |
426 removedPaths.insert(path); | |
427 | |
428 removedResources.insert(it->first); // Delay the removal to avoid disturbing the iterator | |
429 } | |
430 } | |
431 | |
432 // Remove the missing resources | |
433 for (std::set<std::string>::const_iterator it = removedResources.begin(); it != removedResources.end(); ++it) | |
434 { | |
435 assert(resourceToPath_.find(*it) != resourceToPath_.end()); | |
436 resourceToPath_.erase(*it); | |
437 } | |
438 | |
439 CheckInvariants(); | |
440 | |
441 for (std::set<std::string>::const_iterator it = resources.begin(); it != resources.end(); ++it) | |
442 { | |
443 Register(*it); | |
444 } | |
445 | |
446 CheckInvariants(); | |
447 } | |
448 | |
449 const Map& GetPathToResource() const | |
450 { | |
451 return pathToResource_; | |
452 } | |
453 }; | |
454 | |
455 | |
456 class OrthancWebDav::InstancesOfSeries : public INode | |
457 { | |
458 private: | |
459 ServerContext& context_; | |
460 std::string parentSeries_; | |
461 | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
462 static bool LookupInstanceId(std::string& instanceId, |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
463 const UriComponents& path) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
464 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
465 if (path.size() == 1 && |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
466 boost::ends_with(path[0], ".dcm")) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
467 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
468 instanceId = path[0].substr(0, path[0].size() - 4); |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
469 return true; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
470 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
471 else |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
472 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
473 return false; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
474 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
475 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
476 |
4240 | 477 public: |
478 InstancesOfSeries(ServerContext& context, | |
479 const std::string& parentSeries) : | |
480 context_(context), | |
481 parentSeries_(parentSeries) | |
482 { | |
483 } | |
484 | |
485 virtual bool ListCollection(IWebDavBucket::Collection& target, | |
486 const UriComponents& path) ORTHANC_OVERRIDE | |
487 { | |
488 if (path.empty()) | |
489 { | |
490 std::list<std::string> resources; | |
491 try | |
492 { | |
493 context_.GetIndex().GetChildren(resources, parentSeries_); | |
494 } | |
495 catch (OrthancException&) | |
496 { | |
497 // Unknown (or deleted) parent series | |
498 return false; | |
499 } | |
500 | |
501 for (std::list<std::string>::const_iterator | |
502 it = resources.begin(); it != resources.end(); ++it) | |
503 { | |
504 boost::posix_time::ptime time; | |
505 LookupTime(time, context_, *it, MetadataType_Instance_ReceptionDate); | |
506 | |
507 FileInfo info; | |
508 if (context_.GetIndex().LookupAttachment(info, *it, FileContentType_Dicom)) | |
509 { | |
510 std::unique_ptr<File> resource(new File(*it + ".dcm")); | |
511 resource->SetMimeType(MimeType_Dicom); | |
512 resource->SetContentLength(info.GetUncompressedSize()); | |
513 resource->SetCreationTime(time); | |
514 target.AddResource(resource.release()); | |
515 } | |
516 } | |
517 | |
518 return true; | |
519 } | |
520 else | |
521 { | |
522 return false; | |
523 } | |
524 } | |
525 | |
526 virtual bool GetFileContent(MimeType& mime, | |
527 std::string& content, | |
528 boost::posix_time::ptime& time, | |
529 const UriComponents& path) ORTHANC_OVERRIDE | |
530 { | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
531 std::string instanceId; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
532 if (LookupInstanceId(instanceId, path)) |
4240 | 533 { |
534 try | |
535 { | |
536 mime = MimeType_Dicom; | |
537 context_.ReadDicom(content, instanceId); | |
538 LookupTime(time, context_, instanceId, MetadataType_Instance_ReceptionDate); | |
539 return true; | |
540 } | |
541 catch (OrthancException&) | |
542 { | |
543 // File was removed | |
544 return false; | |
545 } | |
546 } | |
547 else | |
548 { | |
549 return false; | |
550 } | |
551 } | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
552 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
553 virtual bool DeleteItem(const UriComponents& path) ORTHANC_OVERRIDE |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
554 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
555 std::string instanceId; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
556 if (LookupInstanceId(instanceId, path)) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
557 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
558 Json::Value info; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
559 return context_.DeleteResource(info, instanceId, ResourceType_Instance); |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
560 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
561 else |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
562 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
563 return false; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
564 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
565 } |
4240 | 566 }; |
567 | |
568 | |
569 | |
570 /** | |
571 * The "InternalNode" class corresponds to a non-leaf node in the | |
572 * WebDAV tree, that only contains subfolders (no file). | |
573 * | |
574 * TODO: Implement a LRU index to dynamically remove the oldest | |
575 * children on high RAM usage. | |
576 **/ | |
577 class OrthancWebDav::InternalNode : public INode | |
578 { | |
579 private: | |
580 typedef std::map<std::string, INode*> Children; | |
581 | |
582 Children children_; | |
583 | |
584 INode* GetChild(const std::string& path) // Don't delete the result pointer! | |
585 { | |
586 Children::const_iterator child = children_.find(path); | |
587 if (child == children_.end()) | |
588 { | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
589 INode* child = CreateSubfolder(path); |
4240 | 590 |
591 if (child == NULL) | |
592 { | |
593 return NULL; | |
594 } | |
595 else | |
596 { | |
597 children_[path] = child; | |
598 return child; | |
599 } | |
600 } | |
601 else | |
602 { | |
603 assert(child->second != NULL); | |
604 return child->second; | |
605 } | |
606 } | |
607 | |
608 protected: | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
609 void InvalidateSubfolder(const std::string& path) |
4240 | 610 { |
611 Children::iterator child = children_.find(path); | |
612 if (child != children_.end()) | |
613 { | |
614 assert(child->second != NULL); | |
615 delete child->second; | |
616 children_.erase(child); | |
617 } | |
618 } | |
619 | |
620 virtual void Refresh() = 0; | |
621 | |
622 virtual bool ListSubfolders(IWebDavBucket::Collection& target) = 0; | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
623 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
624 virtual INode* CreateSubfolder(const std::string& path) = 0; |
4240 | 625 |
626 public: | |
627 virtual ~InternalNode() | |
628 { | |
629 for (Children::iterator it = children_.begin(); it != children_.end(); ++it) | |
630 { | |
631 assert(it->second != NULL); | |
632 delete it->second; | |
633 } | |
634 } | |
635 | |
636 virtual bool ListCollection(IWebDavBucket::Collection& target, | |
637 const UriComponents& path) | |
638 ORTHANC_OVERRIDE ORTHANC_FINAL | |
639 { | |
640 Refresh(); | |
641 | |
642 if (path.empty()) | |
643 { | |
644 return ListSubfolders(target); | |
645 } | |
646 else | |
647 { | |
648 // Recursivity | |
649 INode* child = GetChild(path[0]); | |
650 if (child == NULL) | |
651 { | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
652 // Must be "true" to allow DELETE on folders that are |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
653 // automatically removed through recursive deletion |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
654 return true; |
4240 | 655 } |
656 else | |
657 { | |
658 UriComponents subpath(path.begin() + 1, path.end()); | |
659 return child->ListCollection(target, subpath); | |
660 } | |
661 } | |
662 } | |
663 | |
664 virtual bool GetFileContent(MimeType& mime, | |
665 std::string& content, | |
666 boost::posix_time::ptime& time, | |
667 const UriComponents& path) | |
668 ORTHANC_OVERRIDE ORTHANC_FINAL | |
669 { | |
670 if (path.empty()) | |
671 { | |
672 return false; // An internal node doesn't correspond to a file | |
673 } | |
674 else | |
675 { | |
676 // Recursivity | |
677 Refresh(); | |
678 | |
679 INode* child = GetChild(path[0]); | |
680 if (child == NULL) | |
681 { | |
682 return false; | |
683 } | |
684 else | |
685 { | |
686 UriComponents subpath(path.begin() + 1, path.end()); | |
687 return child->GetFileContent(mime, content, time, subpath); | |
688 } | |
689 } | |
690 } | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
691 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
692 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
693 virtual bool DeleteItem(const UriComponents& path) ORTHANC_OVERRIDE ORTHANC_FINAL |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
694 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
695 Refresh(); |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
696 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
697 if (path.empty()) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
698 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
699 IWebDavBucket::Collection tmp; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
700 if (ListSubfolders(tmp)) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
701 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
702 return (tmp.GetSize() == 0); |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
703 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
704 else |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
705 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
706 return false; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
707 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
708 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
709 else |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
710 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
711 INode* child = GetChild(path[0]); |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
712 if (child == NULL) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
713 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
714 return true; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
715 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
716 else |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
717 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
718 // Recursivity |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
719 UriComponents subpath(path.begin() + 1, path.end()); |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
720 return child->DeleteItem(subpath); |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
721 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
722 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
723 } |
4240 | 724 }; |
725 | |
726 | |
727 class OrthancWebDav::ListOfResources : public InternalNode | |
728 { | |
729 private: | |
730 ServerContext& context_; | |
731 const Templates& templates_; | |
732 std::unique_ptr<ResourcesIndex> index_; | |
733 MetadataType timeMetadata_; | |
734 | |
735 protected: | |
736 virtual void Refresh() ORTHANC_OVERRIDE ORTHANC_FINAL | |
737 { | |
738 std::list<std::string> resources; | |
739 GetCurrentResources(resources); | |
740 | |
741 std::set<std::string> removedPaths; | |
742 index_->Refresh(removedPaths, std::set<std::string>(resources.begin(), resources.end())); | |
743 | |
744 // Remove the children whose associated resource doesn't exist anymore | |
745 for (std::set<std::string>::const_iterator | |
746 it = removedPaths.begin(); it != removedPaths.end(); ++it) | |
747 { | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
748 InvalidateSubfolder(*it); |
4240 | 749 } |
750 } | |
751 | |
752 virtual bool ListSubfolders(IWebDavBucket::Collection& target) ORTHANC_OVERRIDE ORTHANC_FINAL | |
753 { | |
754 if (index_->GetLevel() == ResourceType_Instance) | |
755 { | |
756 // Not a collection, no subfolders | |
757 return false; | |
758 } | |
759 else | |
760 { | |
761 const ResourcesIndex::Map& paths = index_->GetPathToResource(); | |
762 | |
763 for (ResourcesIndex::Map::const_iterator it = paths.begin(); it != paths.end(); ++it) | |
764 { | |
765 boost::posix_time::ptime time; | |
766 LookupTime(time, context_, it->second, timeMetadata_); | |
767 | |
768 std::unique_ptr<IWebDavBucket::Resource> resource(new IWebDavBucket::Folder(it->first)); | |
769 resource->SetCreationTime(time); | |
770 target.AddResource(resource.release()); | |
771 } | |
772 | |
773 return true; | |
774 } | |
775 } | |
776 | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
777 virtual INode* CreateSubfolder(const std::string& path) ORTHANC_OVERRIDE ORTHANC_FINAL |
4240 | 778 { |
779 ResourcesIndex::Map::const_iterator resource = index_->GetPathToResource().find(path); | |
780 if (resource == index_->GetPathToResource().end()) | |
781 { | |
782 return NULL; | |
783 } | |
784 else | |
785 { | |
786 return CreateResourceNode(resource->second); | |
787 } | |
788 } | |
789 | |
790 ServerContext& GetContext() const | |
791 { | |
792 return context_; | |
793 } | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
794 |
4240 | 795 virtual void GetCurrentResources(std::list<std::string>& resources) = 0; |
796 | |
797 virtual INode* CreateResourceNode(const std::string& resource) = 0; | |
798 | |
799 public: | |
800 ListOfResources(ServerContext& context, | |
801 ResourceType level, | |
802 const Templates& templates) : | |
803 context_(context), | |
804 templates_(templates) | |
805 { | |
806 Templates::const_iterator t = templates.find(level); | |
807 if (t == templates.end()) | |
808 { | |
809 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
810 } | |
811 | |
812 index_.reset(new ResourcesIndex(context, level, t->second)); | |
813 | |
814 if (level == ResourceType_Instance) | |
815 { | |
816 timeMetadata_ = MetadataType_Instance_ReceptionDate; | |
817 } | |
818 else | |
819 { | |
820 timeMetadata_ = MetadataType_LastUpdate; | |
821 } | |
822 } | |
823 | |
824 ResourceType GetLevel() const | |
825 { | |
826 return index_->GetLevel(); | |
827 } | |
828 | |
829 const Templates& GetTemplates() const | |
830 { | |
831 return templates_; | |
832 } | |
833 }; | |
834 | |
835 | |
836 | |
837 class OrthancWebDav::SingleDicomResource : public ListOfResources | |
838 { | |
839 private: | |
840 std::string parentId_; | |
841 | |
842 protected: | |
843 virtual void GetCurrentResources(std::list<std::string>& resources) ORTHANC_OVERRIDE | |
844 { | |
845 try | |
846 { | |
847 GetContext().GetIndex().GetChildren(resources, parentId_); | |
848 } | |
849 catch (OrthancException&) | |
850 { | |
851 // Unknown parent resource | |
852 resources.clear(); | |
853 } | |
854 } | |
855 | |
856 virtual INode* CreateResourceNode(const std::string& resource) ORTHANC_OVERRIDE | |
857 { | |
858 if (GetLevel() == ResourceType_Instance) | |
859 { | |
860 return NULL; | |
861 } | |
862 else if (GetLevel() == ResourceType_Series) | |
863 { | |
864 return new InstancesOfSeries(GetContext(), resource); | |
865 } | |
866 else | |
867 { | |
868 ResourceType l = GetChildResourceType(GetLevel()); | |
869 return new SingleDicomResource(GetContext(), l, resource, GetTemplates()); | |
870 } | |
871 } | |
872 | |
873 public: | |
874 SingleDicomResource(ServerContext& context, | |
875 ResourceType level, | |
876 const std::string& parentId, | |
877 const Templates& templates) : | |
878 ListOfResources(context, level, templates), | |
879 parentId_(parentId) | |
880 { | |
881 } | |
882 }; | |
883 | |
884 | |
885 class OrthancWebDav::RootNode : public ListOfResources | |
886 { | |
887 protected: | |
888 virtual void GetCurrentResources(std::list<std::string>& resources) ORTHANC_OVERRIDE | |
889 { | |
890 GetContext().GetIndex().GetAllUuids(resources, GetLevel()); | |
891 } | |
892 | |
893 virtual INode* CreateResourceNode(const std::string& resource) ORTHANC_OVERRIDE | |
894 { | |
895 if (GetLevel() == ResourceType_Series) | |
896 { | |
897 return new InstancesOfSeries(GetContext(), resource); | |
898 } | |
899 else | |
900 { | |
901 ResourceType l = GetChildResourceType(GetLevel()); | |
902 return new SingleDicomResource(GetContext(), l, resource, GetTemplates()); | |
903 } | |
904 } | |
905 | |
906 public: | |
907 RootNode(ServerContext& context, | |
908 ResourceType level, | |
909 const Templates& templates) : | |
910 ListOfResources(context, level, templates) | |
911 { | |
912 } | |
913 }; | |
914 | |
915 | |
916 class OrthancWebDav::ListOfStudiesByDate : public ListOfResources | |
917 { | |
918 private: | |
919 std::string year_; | |
920 std::string month_; | |
921 | |
922 class Visitor : public ServerContext::ILookupVisitor | |
923 { | |
924 private: | |
925 std::list<std::string>& resources_; | |
926 | |
927 public: | |
928 Visitor(std::list<std::string>& resources) : | |
929 resources_(resources) | |
930 { | |
931 } | |
932 | |
933 virtual bool IsDicomAsJsonNeeded() const ORTHANC_OVERRIDE | |
934 { | |
935 return false; // (*) | |
936 } | |
937 | |
938 virtual void MarkAsComplete() ORTHANC_OVERRIDE | |
939 { | |
940 } | |
941 | |
942 virtual void Visit(const std::string& publicId, | |
943 const std::string& instanceId /* unused */, | |
944 const DicomMap& mainDicomTags, | |
945 const Json::Value* dicomAsJson /* unused (*) */) ORTHANC_OVERRIDE | |
946 { | |
947 resources_.push_back(publicId); | |
948 } | |
949 }; | |
950 | |
951 protected: | |
952 virtual void GetCurrentResources(std::list<std::string>& resources) ORTHANC_OVERRIDE | |
953 { | |
954 DatabaseLookup query; | |
955 query.AddRestConstraint(DICOM_TAG_STUDY_DATE, year_ + month_ + "01-" + year_ + month_ + "31", | |
956 true /* case sensitive */, true /* mandatory tag */); | |
957 | |
958 Visitor visitor(resources); | |
959 GetContext().Apply(visitor, query, ResourceType_Study, 0 /* since */, 0 /* no limit */); | |
960 } | |
961 | |
962 virtual INode* CreateResourceNode(const std::string& resource) ORTHANC_OVERRIDE | |
963 { | |
964 return new SingleDicomResource(GetContext(), ResourceType_Series, resource, GetTemplates()); | |
965 } | |
966 | |
967 public: | |
968 ListOfStudiesByDate(ServerContext& context, | |
969 const std::string& year, | |
970 const std::string& month, | |
971 const Templates& templates) : | |
972 ListOfResources(context, ResourceType_Study, templates), | |
973 year_(year), | |
974 month_(month) | |
975 { | |
976 if (year.size() != 4 || | |
977 month.size() != 2) | |
978 { | |
979 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
980 } | |
981 } | |
982 }; | |
983 | |
984 | |
985 class OrthancWebDav::ListOfStudiesByMonth : public InternalNode | |
986 { | |
987 private: | |
988 ServerContext& context_; | |
989 std::string year_; | |
990 const Templates& templates_; | |
991 | |
992 class Visitor : public ServerContext::ILookupVisitor | |
993 { | |
994 private: | |
995 std::set<std::string> months_; | |
996 | |
997 public: | |
998 const std::set<std::string>& GetMonths() const | |
999 { | |
1000 return months_; | |
1001 } | |
1002 | |
1003 virtual bool IsDicomAsJsonNeeded() const ORTHANC_OVERRIDE | |
1004 { | |
1005 return false; // (*) | |
1006 } | |
1007 | |
1008 virtual void MarkAsComplete() ORTHANC_OVERRIDE | |
1009 { | |
1010 } | |
1011 | |
1012 virtual void Visit(const std::string& publicId, | |
1013 const std::string& instanceId /* unused */, | |
1014 const DicomMap& mainDicomTags, | |
1015 const Json::Value* dicomAsJson /* unused (*) */) ORTHANC_OVERRIDE | |
1016 { | |
1017 std::string s; | |
1018 if (mainDicomTags.LookupStringValue(s, DICOM_TAG_STUDY_DATE, false) && | |
1019 s.size() == 8) | |
1020 { | |
1021 months_.insert(s.substr(4, 2)); // Get the month from "YYYYMMDD" | |
1022 } | |
1023 } | |
1024 }; | |
1025 | |
1026 protected: | |
1027 virtual void Refresh() ORTHANC_OVERRIDE | |
1028 { | |
1029 } | |
1030 | |
1031 virtual bool ListSubfolders(IWebDavBucket::Collection& target) ORTHANC_OVERRIDE | |
1032 { | |
1033 DatabaseLookup query; | |
1034 query.AddRestConstraint(DICOM_TAG_STUDY_DATE, year_ + "0101-" + year_ + "1231", | |
1035 true /* case sensitive */, true /* mandatory tag */); | |
1036 | |
1037 Visitor visitor; | |
1038 context_.Apply(visitor, query, ResourceType_Study, 0 /* since */, 0 /* no limit */); | |
1039 | |
1040 for (std::set<std::string>::const_iterator it = visitor.GetMonths().begin(); | |
1041 it != visitor.GetMonths().end(); ++it) | |
1042 { | |
1043 target.AddResource(new IWebDavBucket::Folder(year_ + "-" + *it)); | |
1044 } | |
1045 | |
1046 return true; | |
1047 } | |
1048 | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1049 virtual INode* CreateSubfolder(const std::string& path) ORTHANC_OVERRIDE |
4240 | 1050 { |
1051 if (path.size() != 7) // Format: "YYYY-MM" | |
1052 { | |
1053 throw OrthancException(ErrorCode_InternalError); | |
1054 } | |
1055 else | |
1056 { | |
1057 const std::string year = path.substr(0, 4); | |
1058 const std::string month = path.substr(5, 2); | |
1059 return new ListOfStudiesByDate(context_, year, month, templates_); | |
1060 } | |
1061 } | |
1062 | |
1063 public: | |
1064 ListOfStudiesByMonth(ServerContext& context, | |
1065 const std::string& year, | |
1066 const Templates& templates) : | |
1067 context_(context), | |
1068 year_(year), | |
1069 templates_(templates) | |
1070 { | |
1071 if (year_.size() != 4) | |
1072 { | |
1073 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
1074 } | |
1075 } | |
1076 }; | |
1077 | |
1078 | |
1079 class OrthancWebDav::ListOfStudiesByYear : public InternalNode | |
1080 { | |
1081 private: | |
1082 ServerContext& context_; | |
1083 const Templates& templates_; | |
1084 | |
1085 protected: | |
1086 virtual void Refresh() ORTHANC_OVERRIDE | |
1087 { | |
1088 } | |
1089 | |
1090 virtual bool ListSubfolders(IWebDavBucket::Collection& target) ORTHANC_OVERRIDE | |
1091 { | |
1092 std::list<std::string> resources; | |
1093 context_.GetIndex().GetAllUuids(resources, ResourceType_Study); | |
1094 | |
1095 std::set<std::string> years; | |
1096 | |
1097 for (std::list<std::string>::const_iterator it = resources.begin(); it != resources.end(); ++it) | |
1098 { | |
1099 DicomMap tags; | |
1100 std::string studyDate; | |
1101 if (context_.GetIndex().GetMainDicomTags(tags, *it, ResourceType_Study, ResourceType_Study) && | |
1102 tags.LookupStringValue(studyDate, DICOM_TAG_STUDY_DATE, false) && | |
1103 studyDate.size() == 8) | |
1104 { | |
1105 years.insert(studyDate.substr(0, 4)); // Get the year from "YYYYMMDD" | |
1106 } | |
1107 } | |
1108 | |
1109 for (std::set<std::string>::const_iterator it = years.begin(); it != years.end(); ++it) | |
1110 { | |
1111 target.AddResource(new IWebDavBucket::Folder(*it)); | |
1112 } | |
1113 | |
1114 return true; | |
1115 } | |
1116 | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1117 virtual INode* CreateSubfolder(const std::string& path) ORTHANC_OVERRIDE |
4240 | 1118 { |
1119 return new ListOfStudiesByMonth(context_, path, templates_); | |
1120 } | |
1121 | |
1122 public: | |
1123 ListOfStudiesByYear(ServerContext& context, | |
1124 const Templates& templates) : | |
1125 context_(context), | |
1126 templates_(templates) | |
1127 { | |
1128 } | |
1129 }; | |
1130 | |
1131 | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1132 class OrthancWebDav::DicomDeleteVisitor : public ServerContext::ILookupVisitor |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1133 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1134 private: |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1135 ServerContext& context_; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1136 ResourceType level_; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1137 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1138 public: |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1139 DicomDeleteVisitor(ServerContext& context, |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1140 ResourceType level) : |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1141 context_(context), |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1142 level_(level) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1143 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1144 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1145 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1146 virtual bool IsDicomAsJsonNeeded() const ORTHANC_OVERRIDE |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1147 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1148 return false; // (*) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1149 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1150 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1151 virtual void MarkAsComplete() ORTHANC_OVERRIDE |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1152 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1153 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1154 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1155 virtual void Visit(const std::string& publicId, |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1156 const std::string& instanceId /* unused */, |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1157 const DicomMap& mainDicomTags /* unused */, |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1158 const Json::Value* dicomAsJson /* unused (*) */) ORTHANC_OVERRIDE |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1159 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1160 Json::Value info; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1161 context_.DeleteResource(info, publicId, level_); |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1162 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1163 }; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1164 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1165 |
4240 | 1166 void OrthancWebDav::AddVirtualFile(Collection& collection, |
1167 const UriComponents& path, | |
1168 const std::string& filename) | |
1169 { | |
1170 MimeType mime; | |
1171 std::string content; | |
4246 | 1172 boost::posix_time::ptime modification; // Unused, let the date be set to "GetNow()" |
4240 | 1173 |
1174 UriComponents p = path; | |
1175 p.push_back(filename); | |
1176 | |
1177 if (GetFileContent(mime, content, modification, p)) | |
1178 { | |
1179 std::unique_ptr<File> f(new File(filename)); | |
1180 f->SetMimeType(mime); | |
1181 f->SetContentLength(content.size()); | |
1182 collection.AddResource(f.release()); | |
1183 } | |
1184 } | |
1185 | |
1186 | |
1187 void OrthancWebDav::UploadWorker(OrthancWebDav* that) | |
1188 { | |
1189 assert(that != NULL); | |
1190 | |
1191 boost::posix_time::ptime lastModification = GetNow(); | |
1192 | |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1193 while (that->uploadRunning_) |
4240 | 1194 { |
1195 std::unique_ptr<IDynamicObject> obj(that->uploadQueue_.Dequeue(100)); | |
1196 if (obj.get() != NULL) | |
1197 { | |
1198 that->Upload(reinterpret_cast<const SingleValueObject<std::string>&>(*obj).GetValue()); | |
1199 lastModification = GetNow(); | |
1200 } | |
4245
c70df925151e
RequestOrigin_WebDav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4244
diff
changeset
|
1201 else if (GetNow() - lastModification > boost::posix_time::seconds(30)) |
4240 | 1202 { |
4245
c70df925151e
RequestOrigin_WebDav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4244
diff
changeset
|
1203 /** |
c70df925151e
RequestOrigin_WebDav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4244
diff
changeset
|
1204 * After every 30 seconds of inactivity, remove the empty |
c70df925151e
RequestOrigin_WebDav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4244
diff
changeset
|
1205 * folders. This delay is needed to avoid removing |
c70df925151e
RequestOrigin_WebDav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4244
diff
changeset
|
1206 * just-created folders before the remote WebDAV has time to |
c70df925151e
RequestOrigin_WebDav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4244
diff
changeset
|
1207 * write files into it. |
c70df925151e
RequestOrigin_WebDav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4244
diff
changeset
|
1208 **/ |
4240 | 1209 LOG(INFO) << "Cleaning up the empty WebDAV upload folders"; |
1210 that->uploads_.RemoveEmptyFolders(); | |
1211 lastModification = GetNow(); | |
1212 } | |
1213 } | |
1214 } | |
1215 | |
1216 | |
1217 void OrthancWebDav::Upload(const std::string& path) | |
1218 { | |
1219 UriComponents uri; | |
1220 Toolbox::SplitUriComponents(uri, path); | |
1221 | |
1222 LOG(INFO) << "Upload from WebDAV: " << path; | |
1223 | |
1224 MimeType mime; | |
1225 std::string content; | |
1226 boost::posix_time::ptime time; | |
1227 if (uploads_.GetFileContent(mime, content, time, uri)) | |
1228 { | |
1229 DicomInstanceToStore instance; | |
4245
c70df925151e
RequestOrigin_WebDav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4244
diff
changeset
|
1230 instance.SetOrigin(DicomInstanceOrigin::FromWebDav()); |
4240 | 1231 instance.SetBuffer(content.c_str(), content.size()); |
1232 | |
4244
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1233 bool success = false; |
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1234 |
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1235 try |
4240 | 1236 { |
4244
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1237 std::string publicId; |
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1238 StoreStatus status = context_.Store(publicId, instance, StoreInstanceMode_Default); |
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1239 if (status == StoreStatus_Success || |
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1240 status == StoreStatus_AlreadyStored) |
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1241 { |
4245
c70df925151e
RequestOrigin_WebDav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4244
diff
changeset
|
1242 LOG(INFO) << "Successfully imported DICOM instance from WebDAV: " |
c70df925151e
RequestOrigin_WebDav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4244
diff
changeset
|
1243 << path << " (Orthanc ID: " << publicId << ")"; |
4244
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1244 success = true; |
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1245 } |
4240 | 1246 } |
4244
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1247 catch (OrthancException& e) |
4240 | 1248 { |
4244
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1249 } |
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1250 |
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1251 uploads_.DeleteItem(uri); |
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1252 |
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1253 if (!success) |
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1254 { |
416c35da7d25
robustness against non-dicom files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4243
diff
changeset
|
1255 LOG(WARNING) << "Cannot import DICOM instance from WebWAV (maybe not a DICOM file): " << path; |
4240 | 1256 } |
1257 } | |
1258 } | |
1259 | |
1260 | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1261 OrthancWebDav::INode& OrthancWebDav::GetRootNode(const std::string& rootPath) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1262 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1263 if (rootPath == BY_PATIENTS) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1264 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1265 return *patients_; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1266 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1267 else if (rootPath == BY_STUDIES) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1268 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1269 return *studies_; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1270 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1271 else if (rootPath == BY_DATES) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1272 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1273 return *dates_; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1274 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1275 else |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1276 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1277 throw OrthancException(ErrorCode_InternalError); |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1278 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1279 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1280 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1281 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1282 OrthancWebDav::OrthancWebDav(ServerContext& context, |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1283 bool allowDicomDelete, |
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1284 bool allowUpload) : |
4240 | 1285 context_(context), |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1286 allowDicomDelete_(allowDicomDelete), |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1287 allowUpload_(allowUpload), |
4240 | 1288 uploads_(false /* store uploads as temporary files */), |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1289 uploadRunning_(false) |
4240 | 1290 { |
1291 patientsTemplates_[ResourceType_Patient] = "{{PatientID}} - {{PatientName}}"; | |
1292 patientsTemplates_[ResourceType_Study] = "{{StudyDate}} - {{StudyDescription}}"; | |
1293 patientsTemplates_[ResourceType_Series] = "{{Modality}} - {{SeriesDescription}}"; | |
1294 | |
1295 studiesTemplates_[ResourceType_Study] = "{{PatientID}} - {{PatientName}} - {{StudyDescription}}"; | |
1296 studiesTemplates_[ResourceType_Series] = patientsTemplates_[ResourceType_Series]; | |
1297 | |
1298 patients_.reset(new RootNode(context, ResourceType_Patient, patientsTemplates_)); | |
1299 studies_.reset(new RootNode(context, ResourceType_Study, studiesTemplates_)); | |
1300 dates_.reset(new ListOfStudiesByYear(context, studiesTemplates_)); | |
1301 } | |
1302 | |
1303 | |
1304 bool OrthancWebDav::IsExistingFolder(const UriComponents& path) | |
1305 { | |
1306 if (path.empty()) | |
1307 { | |
1308 return true; | |
1309 } | |
1310 else if (path[0] == BY_UIDS) | |
1311 { | |
1312 return (path.size() <= 3 && | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1313 (path.size() != 3 || path[2] != STUDY_INFO)); |
4240 | 1314 } |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1315 else if (path[0] == BY_PATIENTS || |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1316 path[0] == BY_STUDIES || |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1317 path[0] == BY_DATES) |
4240 | 1318 { |
1319 IWebDavBucket::Collection tmp; | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1320 return GetRootNode(path[0]).ListCollection(tmp, UriComponents(path.begin() + 1, path.end())); |
4240 | 1321 } |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1322 else if (allowUpload_ && |
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1323 path[0] == UPLOADS) |
4240 | 1324 { |
1325 return uploads_.IsExistingFolder(UriComponents(path.begin() + 1, path.end())); | |
1326 } | |
1327 else | |
1328 { | |
1329 return false; | |
1330 } | |
1331 } | |
1332 | |
1333 | |
1334 bool OrthancWebDav::ListCollection(Collection& collection, | |
1335 const UriComponents& path) | |
1336 { | |
1337 if (path.empty()) | |
1338 { | |
4241 | 1339 collection.AddResource(new Folder(BY_DATES)); |
4240 | 1340 collection.AddResource(new Folder(BY_PATIENTS)); |
1341 collection.AddResource(new Folder(BY_STUDIES)); | |
1342 collection.AddResource(new Folder(BY_UIDS)); | |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1343 |
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1344 if (allowUpload_) |
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1345 { |
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1346 collection.AddResource(new Folder(UPLOADS)); |
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1347 } |
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1348 |
4240 | 1349 return true; |
1350 } | |
1351 else if (path[0] == BY_UIDS) | |
1352 { | |
1353 DatabaseLookup query; | |
1354 ResourceType level; | |
1355 size_t limit = 0; // By default, no limits | |
1356 | |
1357 if (path.size() == 1) | |
1358 { | |
1359 level = ResourceType_Study; | |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1360 limit = 0; // TODO - Should we limit here? |
4240 | 1361 } |
1362 else if (path.size() == 2) | |
1363 { | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1364 AddVirtualFile(collection, path, STUDY_INFO); |
4240 | 1365 |
1366 level = ResourceType_Series; | |
1367 query.AddRestConstraint(DICOM_TAG_STUDY_INSTANCE_UID, path[1], | |
1368 true /* case sensitive */, true /* mandatory tag */); | |
1369 } | |
1370 else if (path.size() == 3) | |
1371 { | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1372 AddVirtualFile(collection, path, SERIES_INFO); |
4240 | 1373 |
1374 level = ResourceType_Instance; | |
1375 query.AddRestConstraint(DICOM_TAG_STUDY_INSTANCE_UID, path[1], | |
1376 true /* case sensitive */, true /* mandatory tag */); | |
1377 query.AddRestConstraint(DICOM_TAG_SERIES_INSTANCE_UID, path[2], | |
1378 true /* case sensitive */, true /* mandatory tag */); | |
1379 } | |
1380 else | |
1381 { | |
1382 return false; | |
1383 } | |
1384 | |
1385 DicomIdentifiersVisitor visitor(context_, collection, level); | |
1386 context_.Apply(visitor, query, level, 0 /* since */, limit); | |
1387 | |
1388 return true; | |
1389 } | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1390 else if (path[0] == BY_PATIENTS || |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1391 path[0] == BY_STUDIES || |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1392 path[0] == BY_DATES) |
4240 | 1393 { |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1394 return GetRootNode(path[0]).ListCollection(collection, UriComponents(path.begin() + 1, path.end())); |
4240 | 1395 } |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1396 else if (allowUpload_ && |
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1397 path[0] == UPLOADS) |
4240 | 1398 { |
1399 return uploads_.ListCollection(collection, UriComponents(path.begin() + 1, path.end())); | |
1400 } | |
1401 else | |
1402 { | |
1403 return false; | |
1404 } | |
1405 } | |
1406 | |
1407 | |
1408 bool OrthancWebDav::GetFileContent(MimeType& mime, | |
1409 std::string& content, | |
1410 boost::posix_time::ptime& modificationTime, | |
1411 const UriComponents& path) | |
1412 { | |
1413 if (path.empty()) | |
1414 { | |
1415 return false; | |
1416 } | |
1417 else if (path[0] == BY_UIDS) | |
1418 { | |
1419 if (path.size() == 3 && | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1420 path[2] == STUDY_INFO) |
4240 | 1421 { |
1422 DatabaseLookup query; | |
1423 query.AddRestConstraint(DICOM_TAG_STUDY_INSTANCE_UID, path[1], | |
1424 true /* case sensitive */, true /* mandatory tag */); | |
1425 | |
1426 OrthancJsonVisitor visitor(context_, content, ResourceType_Study); | |
1427 context_.Apply(visitor, query, ResourceType_Study, 0 /* since */, 0 /* no limit */); | |
1428 | |
1429 mime = MimeType_Json; | |
1430 return visitor.IsSuccess(); | |
1431 } | |
1432 else if (path.size() == 4 && | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1433 path[3] == SERIES_INFO) |
4240 | 1434 { |
1435 DatabaseLookup query; | |
1436 query.AddRestConstraint(DICOM_TAG_STUDY_INSTANCE_UID, path[1], | |
1437 true /* case sensitive */, true /* mandatory tag */); | |
1438 query.AddRestConstraint(DICOM_TAG_SERIES_INSTANCE_UID, path[2], | |
1439 true /* case sensitive */, true /* mandatory tag */); | |
1440 | |
1441 OrthancJsonVisitor visitor(context_, content, ResourceType_Series); | |
1442 context_.Apply(visitor, query, ResourceType_Series, 0 /* since */, 0 /* no limit */); | |
1443 | |
1444 mime = MimeType_Json; | |
1445 return visitor.IsSuccess(); | |
1446 } | |
1447 else if (path.size() == 4 && | |
1448 boost::ends_with(path[3], ".dcm")) | |
1449 { | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1450 const std::string sopInstanceUid = path[3].substr(0, path[3].size() - 4); |
4240 | 1451 |
1452 DatabaseLookup query; | |
1453 query.AddRestConstraint(DICOM_TAG_STUDY_INSTANCE_UID, path[1], | |
1454 true /* case sensitive */, true /* mandatory tag */); | |
1455 query.AddRestConstraint(DICOM_TAG_SERIES_INSTANCE_UID, path[2], | |
1456 true /* case sensitive */, true /* mandatory tag */); | |
1457 query.AddRestConstraint(DICOM_TAG_SOP_INSTANCE_UID, sopInstanceUid, | |
1458 true /* case sensitive */, true /* mandatory tag */); | |
1459 | |
1460 DicomFileVisitor visitor(context_, content, modificationTime); | |
1461 context_.Apply(visitor, query, ResourceType_Instance, 0 /* since */, 0 /* no limit */); | |
1462 | |
1463 mime = MimeType_Dicom; | |
1464 return visitor.IsSuccess(); | |
1465 } | |
1466 else | |
1467 { | |
1468 return false; | |
1469 } | |
1470 } | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1471 else if (path[0] == BY_PATIENTS || |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1472 path[0] == BY_STUDIES || |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1473 path[0] == BY_DATES) |
4240 | 1474 { |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1475 return GetRootNode(path[0]).GetFileContent(mime, content, modificationTime, UriComponents(path.begin() + 1, path.end())); |
4241 | 1476 } |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1477 else if (allowUpload_ && |
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1478 path[0] == UPLOADS) |
4240 | 1479 { |
1480 return uploads_.GetFileContent(mime, content, modificationTime, UriComponents(path.begin() + 1, path.end())); | |
1481 } | |
1482 else | |
1483 { | |
1484 return false; | |
1485 } | |
1486 } | |
1487 | |
1488 | |
1489 bool OrthancWebDav::StoreFile(const std::string& content, | |
1490 const UriComponents& path) | |
1491 { | |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1492 if (allowUpload_ && |
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1493 path.size() >= 1 && |
4240 | 1494 path[0] == UPLOADS) |
1495 { | |
1496 UriComponents subpath(UriComponents(path.begin() + 1, path.end())); | |
1497 | |
1498 if (uploads_.StoreFile(content, subpath)) | |
1499 { | |
1500 if (!content.empty()) | |
1501 { | |
1502 uploadQueue_.Enqueue(new SingleValueObject<std::string>(Toolbox::FlattenUri(subpath))); | |
1503 } | |
1504 return true; | |
1505 } | |
1506 else | |
1507 { | |
1508 return false; | |
1509 } | |
1510 } | |
1511 else | |
1512 { | |
1513 return false; | |
1514 } | |
1515 } | |
1516 | |
1517 | |
1518 bool OrthancWebDav::CreateFolder(const UriComponents& path) | |
1519 { | |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1520 if (allowUpload_ && |
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1521 path.size() >= 1 && |
4240 | 1522 path[0] == UPLOADS) |
1523 { | |
1524 return uploads_.CreateFolder(UriComponents(path.begin() + 1, path.end())); | |
1525 } | |
1526 else | |
1527 { | |
1528 return false; | |
1529 } | |
1530 } | |
1531 | |
1532 | |
1533 bool OrthancWebDav::DeleteItem(const std::vector<std::string>& path) | |
1534 { | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1535 if (path.empty()) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1536 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1537 return false; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1538 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1539 else if (path[0] == BY_UIDS && |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1540 path.size() >= 2 && |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1541 path.size() <= 4) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1542 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1543 if (allowDicomDelete_) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1544 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1545 ResourceType level; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1546 DatabaseLookup query; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1547 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1548 query.AddRestConstraint(DICOM_TAG_STUDY_INSTANCE_UID, path[1], |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1549 true /* case sensitive */, true /* mandatory tag */); |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1550 level = ResourceType_Study; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1551 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1552 if (path.size() >= 3) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1553 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1554 if (path[2] == STUDY_INFO) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1555 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1556 return true; // Allow deletion of virtual files |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1557 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1558 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1559 query.AddRestConstraint(DICOM_TAG_SERIES_INSTANCE_UID, path[2], |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1560 true /* case sensitive */, true /* mandatory tag */); |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1561 level = ResourceType_Series; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1562 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1563 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1564 if (path.size() == 4) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1565 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1566 if (path[3] == SERIES_INFO) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1567 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1568 return true; // Allow deletion of virtual files |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1569 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1570 else if (boost::ends_with(path[3], ".dcm")) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1571 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1572 const std::string sopInstanceUid = path[3].substr(0, path[3].size() - 4); |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1573 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1574 query.AddRestConstraint(DICOM_TAG_SOP_INSTANCE_UID, sopInstanceUid, |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1575 true /* case sensitive */, true /* mandatory tag */); |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1576 level = ResourceType_Instance; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1577 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1578 else |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1579 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1580 return false; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1581 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1582 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1583 |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1584 DicomDeleteVisitor visitor(context_, level); |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1585 context_.Apply(visitor, query, ResourceType_Instance, 0 /* since */, 0 /* no limit */); |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1586 return true; |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1587 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1588 else |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1589 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1590 return false; // read-only |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1591 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1592 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1593 else if (path[0] == BY_PATIENTS || |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1594 path[0] == BY_STUDIES || |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1595 path[0] == BY_DATES) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1596 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1597 if (allowDicomDelete_) |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1598 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1599 return GetRootNode(path[0]).DeleteItem(UriComponents(path.begin() + 1, path.end())); |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1600 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1601 else |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1602 { |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1603 return false; // read-only |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1604 } |
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1605 } |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1606 else if (allowUpload_ && |
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1607 path[0] == UPLOADS) |
4240 | 1608 { |
1609 return uploads_.DeleteItem(UriComponents(path.begin() + 1, path.end())); | |
1610 } | |
1611 else | |
1612 { | |
4242
5cfa6ba75dfc
deleting resources from Orthanc WebDAV
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4241
diff
changeset
|
1613 return false; |
4240 | 1614 } |
1615 } | |
1616 | |
1617 | |
1618 void OrthancWebDav::Start() | |
1619 { | |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1620 if (uploadRunning_) |
4240 | 1621 { |
1622 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
1623 } | |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1624 else if (allowUpload_) |
4240 | 1625 { |
1626 LOG(INFO) << "Starting the WebDAV upload thread"; | |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1627 uploadRunning_ = true; |
4240 | 1628 uploadThread_ = boost::thread(UploadWorker, this); |
1629 } | |
1630 } | |
1631 | |
1632 | |
1633 void OrthancWebDav::Stop() | |
1634 { | |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1635 if (uploadRunning_) |
4240 | 1636 { |
1637 LOG(INFO) << "Stopping the WebDAV upload thread"; | |
4243
64f57c9d5f79
configuration options for webdav
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
4242
diff
changeset
|
1638 uploadRunning_ = false; |
4240 | 1639 if (uploadThread_.joinable()) |
1640 { | |
1641 uploadThread_.join(); | |
1642 } | |
1643 } | |
1644 } | |
1645 } |