comparison OrthancServer/Sources/OrthancWebDav.cpp @ 5700:1fab9ddaf702 find-refactoring

webdav using ResourceFinder
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 12 Jul 2024 15:02:59 +0200
parents f7adfb22e20e
children 359a8adb3802
comparison
equal deleted inserted replaced
5699:e8e028aed89f 5700:1fab9ddaf702
26 #include "../../OrthancFramework/Sources/Compression/ZipReader.h" 26 #include "../../OrthancFramework/Sources/Compression/ZipReader.h"
27 #include "../../OrthancFramework/Sources/DicomFormat/DicomArray.h" 27 #include "../../OrthancFramework/Sources/DicomFormat/DicomArray.h"
28 #include "../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h" 28 #include "../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h"
29 #include "../../OrthancFramework/Sources/HttpServer/WebDavStorage.h" 29 #include "../../OrthancFramework/Sources/HttpServer/WebDavStorage.h"
30 #include "../../OrthancFramework/Sources/Logging.h" 30 #include "../../OrthancFramework/Sources/Logging.h"
31 #include "ResourceFinder.h"
31 #include "Search/DatabaseLookup.h" 32 #include "Search/DatabaseLookup.h"
32 #include "ServerContext.h" 33 #include "ServerContext.h"
33 34
34 #include <boost/regex.hpp> 35 #include <boost/regex.hpp>
35 #include <boost/algorithm/string/predicate.hpp> 36 #include <boost/algorithm/string/predicate.hpp>
48 { 49 {
49 static boost::posix_time::ptime GetNow() 50 static boost::posix_time::ptime GetNow()
50 { 51 {
51 return boost::posix_time::second_clock::universal_time(); 52 return boost::posix_time::second_clock::universal_time();
52 } 53 }
54
55
56 static void ParseTime(boost::posix_time::ptime& target,
57 const std::string& value)
58 {
59 try
60 {
61 target = boost::posix_time::from_iso_string(value);
62 }
63 catch (std::exception& e)
64 {
65 target = GetNow();
66 }
67 }
53 68
54 69
55 static void LookupTime(boost::posix_time::ptime& target, 70 static void LookupTime(boost::posix_time::ptime& target,
56 ServerContext& context, 71 ServerContext& context,
57 const std::string& publicId, 72 const std::string& publicId,
60 { 75 {
61 std::string value; 76 std::string value;
62 int64_t revision; // Ignored 77 int64_t revision; // Ignored
63 if (context.GetIndex().LookupMetadata(value, revision, publicId, level, metadata)) 78 if (context.GetIndex().LookupMetadata(value, revision, publicId, level, metadata))
64 { 79 {
65 try 80 ParseTime(target, value);
66 { 81 }
67 target = boost::posix_time::from_iso_string(value); 82 else
68 return; 83 {
69 } 84 target = GetNow();
70 catch (std::exception& e) 85 }
71 {
72 }
73 }
74
75 target = GetNow();
76 } 86 }
77 87
78 88
79 class OrthancWebDav::DicomIdentifiersVisitor : public ServerContext::ILookupVisitor 89 class OrthancWebDav::DicomIdentifiersVisitor : public ServerContext::ILookupVisitor
80 { 90 {
167 } 177 }
168 } 178 }
169 }; 179 };
170 180
171 181
182 class OrthancWebDav::DicomIdentifiersVisitorV2 : public ResourceFinder::IVisitor
183 {
184 private:
185 bool isComplete_;
186 Collection& target_;
187
188 public:
189 DicomIdentifiersVisitorV2(Collection& target) :
190 isComplete_(false),
191 target_(target)
192 {
193 }
194
195 virtual void MarkAsComplete() ORTHANC_OVERRIDE
196 {
197 isComplete_ = true; // TODO
198 }
199
200 virtual void Apply(const FindResponse::Resource& resource,
201 const DicomMap& requestedTags) ORTHANC_OVERRIDE
202 {
203 DicomMap resourceTags;
204 resource.GetMainDicomTags(resourceTags, resource.GetLevel());
205
206 std::string uid;
207 bool hasUid;
208
209 std::string time;
210 bool hasTime;
211
212 switch (resource.GetLevel())
213 {
214 case ResourceType_Study:
215 hasUid = resourceTags.LookupStringValue(uid, DICOM_TAG_STUDY_INSTANCE_UID, false);
216 hasTime = resource.LookupMetadata(time, resource.GetLevel(), MetadataType_LastUpdate);
217 break;
218
219 case ResourceType_Series:
220 hasUid = resourceTags.LookupStringValue(uid, DICOM_TAG_SERIES_INSTANCE_UID, false);
221 hasTime = resource.LookupMetadata(time, resource.GetLevel(), MetadataType_LastUpdate);
222 break;
223
224 case ResourceType_Instance:
225 hasUid = resourceTags.LookupStringValue(uid, DICOM_TAG_SOP_INSTANCE_UID, false);
226 hasTime = resource.LookupMetadata(time, resource.GetLevel(), MetadataType_Instance_ReceptionDate);
227 break;
228
229 default:
230 throw OrthancException(ErrorCode_InternalError);
231 }
232
233 if (hasUid &&
234 !uid.empty())
235 {
236 std::unique_ptr<Resource> item;
237
238 if (resource.GetLevel() == ResourceType_Instance)
239 {
240 FileInfo info;
241 if (resource.LookupAttachment(info, FileContentType_Dicom))
242 {
243 std::unique_ptr<File> f(new File(uid + ".dcm"));
244 f->SetMimeType(MimeType_Dicom);
245 f->SetContentLength(info.GetUncompressedSize());
246 item.reset(f.release());
247 }
248 }
249 else
250 {
251 item.reset(new Folder(uid));
252 }
253
254 if (item.get() != NULL)
255 {
256 if (hasTime)
257 {
258 boost::posix_time::ptime t;
259 ParseTime(t, time);
260 item->SetCreationTime(t);
261 }
262 else
263 {
264 item->SetCreationTime(GetNow());
265 }
266
267 target_.AddResource(item.release());
268 }
269 }
270 }
271 };
272
273
172 class OrthancWebDav::DicomFileVisitor : public ServerContext::ILookupVisitor 274 class OrthancWebDav::DicomFileVisitor : public ServerContext::ILookupVisitor
173 { 275 {
174 private: 276 private:
175 ServerContext& context_; 277 ServerContext& context_;
176 bool success_; 278 bool success_;
1453 else 1555 else
1454 { 1556 {
1455 return false; 1557 return false;
1456 } 1558 }
1457 1559
1458 DicomIdentifiersVisitor visitor(context_, collection, level); 1560 if (true)
1459 context_.Apply(visitor, query, level, 0 /* since */, limit); 1561 {
1460 1562 /**
1563 * EXPERIMENTAL VERSION
1564 **/
1565
1566 ResourceFinder finder(level, false /* don't expand */);
1567 finder.SetDatabaseLookup(query);
1568 finder.SetRetrieveMetadata(true);
1569
1570 switch (level)
1571 {
1572 case ResourceType_Study:
1573 finder.AddRequestedTag(DICOM_TAG_STUDY_INSTANCE_UID);
1574 break;
1575
1576 case ResourceType_Series:
1577 finder.AddRequestedTag(DICOM_TAG_SERIES_INSTANCE_UID);
1578 break;
1579
1580 case ResourceType_Instance:
1581 finder.AddRequestedTag(DICOM_TAG_SOP_INSTANCE_UID);
1582 finder.SetRetrieveAttachments(true);
1583 break;
1584
1585 default:
1586 throw OrthancException(ErrorCode_InternalError);
1587 }
1588
1589 DicomIdentifiersVisitorV2 visitor(collection);
1590 finder.Execute(visitor, context_);
1591 }
1592 else
1593 {
1594 /**
1595 * VERSION IN ORTHANC <= 1.12.4
1596 **/
1597
1598 DicomIdentifiersVisitor visitor(context_, collection, level);
1599 context_.Apply(visitor, query, level, 0 /* since */, limit);
1600 }
1601
1461 return true; 1602 return true;
1462 } 1603 }
1463 else if (path[0] == BY_PATIENTS || 1604 else if (path[0] == BY_PATIENTS ||
1464 path[0] == BY_STUDIES || 1605 path[0] == BY_STUDIES ||
1465 path[0] == BY_DATES) 1606 path[0] == BY_DATES)