# HG changeset patch # User Sebastien Jodogne # Date 1720789379 -7200 # Node ID 1fab9ddaf702745f910eb4d858e18a49ffb773b9 # Parent e8e028aed89f00948766e0a8d13fa809a71ca242 webdav using ResourceFinder diff -r e8e028aed89f -r 1fab9ddaf702 OrthancServer/Sources/OrthancFindRequestHandler.cpp --- a/OrthancServer/Sources/OrthancFindRequestHandler.cpp Fri Jul 12 14:08:31 2024 +0200 +++ b/OrthancServer/Sources/OrthancFindRequestHandler.cpp Fri Jul 12 15:02:59 2024 +0200 @@ -336,32 +336,21 @@ { private: DicomFindAnswers& answers_; - ServerContext& context_; - ResourceType level_; - const DicomMap& query_; DicomArray queryAsArray_; const std::list& sequencesToReturn_; std::string defaultPrivateCreator_; // the private creator to use if the group is not defined in the query itself const std::map& privateCreators_; // the private creators defined in the query itself std::string retrieveAet_; - FindStorageAccessMode findStorageAccessMode_; public: - LookupVisitorV2(DicomFindAnswers& answers, - ServerContext& context, - ResourceType level, + LookupVisitorV2(DicomFindAnswers& answers, const DicomMap& query, const std::list& sequencesToReturn, - const std::map& privateCreators, - FindStorageAccessMode findStorageAccessMode) : + const std::map& privateCreators) : answers_(answers), - context_(context), - level_(level), - query_(query), queryAsArray_(query), sequencesToReturn_(sequencesToReturn), - privateCreators_(privateCreators), - findStorageAccessMode_(findStorageAccessMode) + privateCreators_(privateCreators) { answers_.SetComplete(false); @@ -647,7 +636,7 @@ finder.SetDatabaseLookup(lookup); finder.AddRequestedTags(requestedTags); - LookupVisitorV2 visitor(answers, context_, level, *filteredInput, sequencesToReturn, privateCreators, context_.GetFindStorageAccessMode()); + LookupVisitorV2 visitor(answers, *filteredInput, sequencesToReturn, privateCreators); finder.Execute(visitor, context_); } else diff -r e8e028aed89f -r 1fab9ddaf702 OrthancServer/Sources/OrthancWebDav.cpp --- a/OrthancServer/Sources/OrthancWebDav.cpp Fri Jul 12 14:08:31 2024 +0200 +++ b/OrthancServer/Sources/OrthancWebDav.cpp Fri Jul 12 15:02:59 2024 +0200 @@ -28,6 +28,7 @@ #include "../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h" #include "../../OrthancFramework/Sources/HttpServer/WebDavStorage.h" #include "../../OrthancFramework/Sources/Logging.h" +#include "ResourceFinder.h" #include "Search/DatabaseLookup.h" #include "ServerContext.h" @@ -50,6 +51,20 @@ { return boost::posix_time::second_clock::universal_time(); } + + + static void ParseTime(boost::posix_time::ptime& target, + const std::string& value) + { + try + { + target = boost::posix_time::from_iso_string(value); + } + catch (std::exception& e) + { + target = GetNow(); + } + } static void LookupTime(boost::posix_time::ptime& target, @@ -62,17 +77,12 @@ int64_t revision; // Ignored if (context.GetIndex().LookupMetadata(value, revision, publicId, level, metadata)) { - try - { - target = boost::posix_time::from_iso_string(value); - return; - } - catch (std::exception& e) - { - } + ParseTime(target, value); } - - target = GetNow(); + else + { + target = GetNow(); + } } @@ -169,6 +179,98 @@ }; + class OrthancWebDav::DicomIdentifiersVisitorV2 : public ResourceFinder::IVisitor + { + private: + bool isComplete_; + Collection& target_; + + public: + DicomIdentifiersVisitorV2(Collection& target) : + isComplete_(false), + target_(target) + { + } + + virtual void MarkAsComplete() ORTHANC_OVERRIDE + { + isComplete_ = true; // TODO + } + + virtual void Apply(const FindResponse::Resource& resource, + const DicomMap& requestedTags) ORTHANC_OVERRIDE + { + DicomMap resourceTags; + resource.GetMainDicomTags(resourceTags, resource.GetLevel()); + + std::string uid; + bool hasUid; + + std::string time; + bool hasTime; + + switch (resource.GetLevel()) + { + case ResourceType_Study: + hasUid = resourceTags.LookupStringValue(uid, DICOM_TAG_STUDY_INSTANCE_UID, false); + hasTime = resource.LookupMetadata(time, resource.GetLevel(), MetadataType_LastUpdate); + break; + + case ResourceType_Series: + hasUid = resourceTags.LookupStringValue(uid, DICOM_TAG_SERIES_INSTANCE_UID, false); + hasTime = resource.LookupMetadata(time, resource.GetLevel(), MetadataType_LastUpdate); + break; + + case ResourceType_Instance: + hasUid = resourceTags.LookupStringValue(uid, DICOM_TAG_SOP_INSTANCE_UID, false); + hasTime = resource.LookupMetadata(time, resource.GetLevel(), MetadataType_Instance_ReceptionDate); + break; + + default: + throw OrthancException(ErrorCode_InternalError); + } + + if (hasUid && + !uid.empty()) + { + std::unique_ptr item; + + if (resource.GetLevel() == ResourceType_Instance) + { + FileInfo info; + if (resource.LookupAttachment(info, FileContentType_Dicom)) + { + std::unique_ptr f(new File(uid + ".dcm")); + f->SetMimeType(MimeType_Dicom); + f->SetContentLength(info.GetUncompressedSize()); + item.reset(f.release()); + } + } + else + { + item.reset(new Folder(uid)); + } + + if (item.get() != NULL) + { + if (hasTime) + { + boost::posix_time::ptime t; + ParseTime(t, time); + item->SetCreationTime(t); + } + else + { + item->SetCreationTime(GetNow()); + } + + target_.AddResource(item.release()); + } + } + } + }; + + class OrthancWebDav::DicomFileVisitor : public ServerContext::ILookupVisitor { private: @@ -1455,9 +1557,48 @@ return false; } - DicomIdentifiersVisitor visitor(context_, collection, level); - context_.Apply(visitor, query, level, 0 /* since */, limit); - + if (true) + { + /** + * EXPERIMENTAL VERSION + **/ + + ResourceFinder finder(level, false /* don't expand */); + finder.SetDatabaseLookup(query); + finder.SetRetrieveMetadata(true); + + switch (level) + { + case ResourceType_Study: + finder.AddRequestedTag(DICOM_TAG_STUDY_INSTANCE_UID); + break; + + case ResourceType_Series: + finder.AddRequestedTag(DICOM_TAG_SERIES_INSTANCE_UID); + break; + + case ResourceType_Instance: + finder.AddRequestedTag(DICOM_TAG_SOP_INSTANCE_UID); + finder.SetRetrieveAttachments(true); + break; + + default: + throw OrthancException(ErrorCode_InternalError); + } + + DicomIdentifiersVisitorV2 visitor(collection); + finder.Execute(visitor, context_); + } + else + { + /** + * VERSION IN ORTHANC <= 1.12.4 + **/ + + DicomIdentifiersVisitor visitor(context_, collection, level); + context_.Apply(visitor, query, level, 0 /* since */, limit); + } + return true; } else if (path[0] == BY_PATIENTS || diff -r e8e028aed89f -r 1fab9ddaf702 OrthancServer/Sources/OrthancWebDav.h --- a/OrthancServer/Sources/OrthancWebDav.h Fri Jul 12 14:08:31 2024 +0200 +++ b/OrthancServer/Sources/OrthancWebDav.h Fri Jul 12 15:02:59 2024 +0200 @@ -40,6 +40,7 @@ class DicomDeleteVisitor; class DicomFileVisitor; class DicomIdentifiersVisitor; + class DicomIdentifiersVisitorV2; class InstancesOfSeries; class InternalNode; class ListOfResources; diff -r e8e028aed89f -r 1fab9ddaf702 OrthancServer/Sources/ResourceFinder.h --- a/OrthancServer/Sources/ResourceFinder.h Fri Jul 12 14:08:31 2024 +0200 +++ b/OrthancServer/Sources/ResourceFinder.h Fri Jul 12 15:02:59 2024 +0200 @@ -165,6 +165,16 @@ request_.SetRetrieveOneInstanceIdentifier(retrieve); } + void SetRetrieveMetadata(bool retrieve) + { + request_.SetRetrieveMetadata(retrieve); + } + + void SetRetrieveAttachments(bool retrieve) + { + request_.SetRetrieveAttachments(retrieve); + } + void Execute(FindResponse& target, ServerIndex& index) const;