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