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