Mercurial > hg > orthanc
comparison OrthancServer/Sources/OrthancWebDav.cpp @ 5809:023a99146dd0 attach-custom-data
merged find-refactoring -> attach-custom-data
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Tue, 24 Sep 2024 12:53:43 +0200 |
parents | d851a54e49b7 |
children | 593e110de3d8 |
comparison
equal
deleted
inserted
replaced
5808:63c025cf6958 | 5809:023a99146dd0 |
---|---|
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 explicit 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_; |
218 success_ = true; | 320 success_ = true; |
219 } | 321 } |
220 } | 322 } |
221 }; | 323 }; |
222 | 324 |
325 | |
326 class OrthancWebDav::DicomFileVisitorV2 : public ResourceFinder::IVisitor | |
327 { | |
328 private: | |
329 ServerContext& context_; | |
330 bool success_; | |
331 std::string& target_; | |
332 boost::posix_time::ptime& time_; | |
333 | |
334 public: | |
335 DicomFileVisitorV2(ServerContext& context, | |
336 std::string& target, | |
337 boost::posix_time::ptime& time) : | |
338 context_(context), | |
339 success_(false), | |
340 target_(target), | |
341 time_(time) | |
342 { | |
343 } | |
344 | |
345 bool IsSuccess() const | |
346 { | |
347 return success_; | |
348 } | |
349 | |
350 virtual void MarkAsComplete() ORTHANC_OVERRIDE | |
351 { | |
352 } | |
353 | |
354 virtual void Apply(const FindResponse::Resource& resource, | |
355 const DicomMap& requestedTags) ORTHANC_OVERRIDE | |
356 { | |
357 if (success_) | |
358 { | |
359 success_ = false; // Two matches => Error | |
360 } | |
361 else | |
362 { | |
363 std::string s; | |
364 if (resource.LookupMetadata(s, ResourceType_Instance, MetadataType_Instance_ReceptionDate)) | |
365 { | |
366 ParseTime(time_, s); | |
367 } | |
368 else | |
369 { | |
370 time_ = GetNow(); | |
371 } | |
372 | |
373 context_.ReadDicom(target_, resource.GetIdentifier()); | |
374 success_ = true; | |
375 } | |
376 } | |
377 }; | |
378 | |
223 | 379 |
224 class OrthancWebDav::OrthancJsonVisitor : public ServerContext::ILookupVisitor | 380 class OrthancWebDav::OrthancJsonVisitor : public ServerContext::ILookupVisitor |
225 { | 381 { |
226 private: | 382 private: |
227 ServerContext& context_; | 383 ServerContext& context_; |
953 { | 1109 { |
954 private: | 1110 private: |
955 std::string year_; | 1111 std::string year_; |
956 std::string month_; | 1112 std::string month_; |
957 | 1113 |
958 class Visitor : public ServerContext::ILookupVisitor | 1114 class Visitor : public ResourceFinder::IVisitor |
959 { | 1115 { |
960 private: | 1116 private: |
961 std::list<std::string>& resources_; | 1117 std::list<std::string>& resources_; |
962 | 1118 |
963 public: | 1119 public: |
964 explicit Visitor(std::list<std::string>& resources) : | 1120 explicit Visitor(std::list<std::string>& resources) : |
965 resources_(resources) | 1121 resources_(resources) |
966 { | 1122 { |
967 } | 1123 } |
968 | 1124 |
969 virtual bool IsDicomAsJsonNeeded() const ORTHANC_OVERRIDE | |
970 { | |
971 return false; // (*) | |
972 } | |
973 | |
974 virtual void MarkAsComplete() ORTHANC_OVERRIDE | 1125 virtual void MarkAsComplete() ORTHANC_OVERRIDE |
975 { | 1126 { |
976 } | 1127 } |
977 | 1128 |
978 virtual void Visit(const std::string& publicId, | 1129 virtual void Apply(const FindResponse::Resource& resource, |
979 const std::string& instanceId /* unused */, | 1130 const DicomMap& requestedTags) ORTHANC_OVERRIDE |
980 const DicomMap& mainDicomTags, | 1131 { |
981 const Json::Value* dicomAsJson /* unused (*) */) ORTHANC_OVERRIDE | 1132 resources_.push_back(resource.GetIdentifier()); |
982 { | |
983 resources_.push_back(publicId); | |
984 } | 1133 } |
985 }; | 1134 }; |
986 | 1135 |
987 protected: | 1136 protected: |
988 virtual void GetCurrentResources(std::list<std::string>& resources) ORTHANC_OVERRIDE | 1137 virtual void GetCurrentResources(std::list<std::string>& resources) ORTHANC_OVERRIDE |
990 DatabaseLookup query; | 1139 DatabaseLookup query; |
991 query.AddRestConstraint(DICOM_TAG_STUDY_DATE, year_ + month_ + "01-" + year_ + month_ + "31", | 1140 query.AddRestConstraint(DICOM_TAG_STUDY_DATE, year_ + month_ + "01-" + year_ + month_ + "31", |
992 true /* case sensitive */, true /* mandatory tag */); | 1141 true /* case sensitive */, true /* mandatory tag */); |
993 | 1142 |
994 Visitor visitor(resources); | 1143 Visitor visitor(resources); |
995 GetContext().Apply(visitor, query, ResourceType_Study, 0 /* since */, 0 /* no limit */); | 1144 |
1145 ResourceFinder finder(ResourceType_Study, false /* no expand */); | |
1146 finder.SetDatabaseLookup(query); | |
1147 finder.Execute(visitor, GetContext()); | |
996 } | 1148 } |
997 | 1149 |
998 virtual INode* CreateResourceNode(const std::string& resource) ORTHANC_OVERRIDE | 1150 virtual INode* CreateResourceNode(const std::string& resource) ORTHANC_OVERRIDE |
999 { | 1151 { |
1000 return new SingleDicomResource(GetContext(), ResourceType_Series, resource, GetTemplates()); | 1152 return new SingleDicomResource(GetContext(), ResourceType_Series, resource, GetTemplates()); |
1023 private: | 1175 private: |
1024 ServerContext& context_; | 1176 ServerContext& context_; |
1025 std::string year_; | 1177 std::string year_; |
1026 const Templates& templates_; | 1178 const Templates& templates_; |
1027 | 1179 |
1028 class Visitor : public ServerContext::ILookupVisitor | 1180 class Visitor : public ResourceFinder::IVisitor |
1029 { | 1181 { |
1030 private: | 1182 private: |
1031 std::set<std::string> months_; | 1183 std::set<std::string> months_; |
1032 | 1184 |
1033 public: | 1185 public: |
1034 const std::set<std::string>& GetMonths() const | 1186 const std::set<std::string>& GetMonths() const |
1035 { | 1187 { |
1036 return months_; | 1188 return months_; |
1037 } | 1189 } |
1038 | 1190 |
1039 virtual bool IsDicomAsJsonNeeded() const ORTHANC_OVERRIDE | |
1040 { | |
1041 return false; // (*) | |
1042 } | |
1043 | |
1044 virtual void MarkAsComplete() ORTHANC_OVERRIDE | 1191 virtual void MarkAsComplete() ORTHANC_OVERRIDE |
1045 { | 1192 { |
1046 } | 1193 } |
1047 | 1194 |
1048 virtual void Visit(const std::string& publicId, | 1195 virtual void Apply(const FindResponse::Resource& resource, |
1049 const std::string& instanceId /* unused */, | 1196 const DicomMap& requestedTags) ORTHANC_OVERRIDE |
1050 const DicomMap& mainDicomTags, | 1197 { |
1051 const Json::Value* dicomAsJson /* unused (*) */) ORTHANC_OVERRIDE | 1198 DicomMap mainDicomTags; |
1052 { | 1199 resource.GetMainDicomTags(mainDicomTags, ResourceType_Study); |
1200 | |
1053 std::string s; | 1201 std::string s; |
1054 if (mainDicomTags.LookupStringValue(s, DICOM_TAG_STUDY_DATE, false) && | 1202 if (mainDicomTags.LookupStringValue(s, DICOM_TAG_STUDY_DATE, false) && |
1055 s.size() == 8) | 1203 s.size() == 8) |
1056 { | 1204 { |
1057 months_.insert(s.substr(4, 2)); // Get the month from "YYYYMMDD" | 1205 months_.insert(s.substr(4, 2)); // Get the month from "YYYYMMDD" |
1069 DatabaseLookup query; | 1217 DatabaseLookup query; |
1070 query.AddRestConstraint(DICOM_TAG_STUDY_DATE, year_ + "0101-" + year_ + "1231", | 1218 query.AddRestConstraint(DICOM_TAG_STUDY_DATE, year_ + "0101-" + year_ + "1231", |
1071 true /* case sensitive */, true /* mandatory tag */); | 1219 true /* case sensitive */, true /* mandatory tag */); |
1072 | 1220 |
1073 Visitor visitor; | 1221 Visitor visitor; |
1074 context_.Apply(visitor, query, ResourceType_Study, 0 /* since */, 0 /* no limit */); | 1222 |
1223 ResourceFinder finder(ResourceType_Study, false /* no expand */); | |
1224 finder.SetDatabaseLookup(query); | |
1225 finder.Execute(visitor, context_); | |
1075 | 1226 |
1076 for (std::set<std::string>::const_iterator it = visitor.GetMonths().begin(); | 1227 for (std::set<std::string>::const_iterator it = visitor.GetMonths().begin(); |
1077 it != visitor.GetMonths().end(); ++it) | 1228 it != visitor.GetMonths().end(); ++it) |
1078 { | 1229 { |
1079 target.AddResource(new IWebDavBucket::Folder(year_ + "-" + *it)); | 1230 target.AddResource(new IWebDavBucket::Folder(year_ + "-" + *it)); |
1163 { | 1314 { |
1164 } | 1315 } |
1165 }; | 1316 }; |
1166 | 1317 |
1167 | 1318 |
1168 class OrthancWebDav::DicomDeleteVisitor : public ServerContext::ILookupVisitor | 1319 class OrthancWebDav::DicomDeleteVisitor : public ResourceFinder::IVisitor |
1169 { | 1320 { |
1170 private: | 1321 private: |
1171 ServerContext& context_; | 1322 ServerContext& context_; |
1172 ResourceType level_; | 1323 ResourceType level_; |
1173 | 1324 |
1177 context_(context), | 1328 context_(context), |
1178 level_(level) | 1329 level_(level) |
1179 { | 1330 { |
1180 } | 1331 } |
1181 | 1332 |
1182 virtual bool IsDicomAsJsonNeeded() const ORTHANC_OVERRIDE | |
1183 { | |
1184 return false; // (*) | |
1185 } | |
1186 | |
1187 virtual void MarkAsComplete() ORTHANC_OVERRIDE | 1333 virtual void MarkAsComplete() ORTHANC_OVERRIDE |
1188 { | 1334 { |
1189 } | 1335 } |
1190 | 1336 |
1191 virtual void Visit(const std::string& publicId, | 1337 virtual void Apply(const FindResponse::Resource& resource, |
1192 const std::string& instanceId /* unused */, | 1338 const DicomMap& requestedTags) ORTHANC_OVERRIDE |
1193 const DicomMap& mainDicomTags /* unused */, | |
1194 const Json::Value* dicomAsJson /* unused (*) */) ORTHANC_OVERRIDE | |
1195 { | 1339 { |
1196 Json::Value info; | 1340 Json::Value info; |
1197 context_.DeleteResource(info, publicId, level_); | 1341 context_.DeleteResource(info, resource.GetIdentifier(), level_); |
1198 } | 1342 } |
1199 }; | 1343 }; |
1200 | 1344 |
1201 | 1345 |
1202 void OrthancWebDav::AddVirtualFile(Collection& collection, | 1346 void OrthancWebDav::AddVirtualFile(Collection& collection, |
1453 else | 1597 else |
1454 { | 1598 { |
1455 return false; | 1599 return false; |
1456 } | 1600 } |
1457 | 1601 |
1458 DicomIdentifiersVisitor visitor(context_, collection, level); | 1602 if (true) |
1459 context_.Apply(visitor, query, level, 0 /* since */, limit); | 1603 { |
1460 | 1604 /** |
1605 * EXPERIMENTAL VERSION | |
1606 **/ | |
1607 | |
1608 ResourceFinder finder(level, false /* don't expand */); | |
1609 finder.SetDatabaseLookup(query); | |
1610 finder.SetRetrieveMetadata(true); | |
1611 | |
1612 switch (level) | |
1613 { | |
1614 case ResourceType_Study: | |
1615 finder.AddRequestedTag(DICOM_TAG_STUDY_INSTANCE_UID); | |
1616 break; | |
1617 | |
1618 case ResourceType_Series: | |
1619 finder.AddRequestedTag(DICOM_TAG_SERIES_INSTANCE_UID); | |
1620 break; | |
1621 | |
1622 case ResourceType_Instance: | |
1623 finder.AddRequestedTag(DICOM_TAG_SOP_INSTANCE_UID); | |
1624 finder.SetRetrieveAttachments(true); | |
1625 break; | |
1626 | |
1627 default: | |
1628 throw OrthancException(ErrorCode_InternalError); | |
1629 } | |
1630 | |
1631 DicomIdentifiersVisitorV2 visitor(collection); | |
1632 finder.Execute(visitor, context_); | |
1633 } | |
1634 else | |
1635 { | |
1636 /** | |
1637 * VERSION IN ORTHANC <= 1.12.4 | |
1638 **/ | |
1639 | |
1640 DicomIdentifiersVisitor visitor(context_, collection, level); | |
1641 context_.Apply(visitor, query, level, 0 /* since */, limit); | |
1642 } | |
1643 | |
1461 return true; | 1644 return true; |
1462 } | 1645 } |
1463 else if (path[0] == BY_PATIENTS || | 1646 else if (path[0] == BY_PATIENTS || |
1464 path[0] == BY_STUDIES || | 1647 path[0] == BY_STUDIES || |
1465 path[0] == BY_DATES) | 1648 path[0] == BY_DATES) |
1476 return false; | 1659 return false; |
1477 } | 1660 } |
1478 } | 1661 } |
1479 | 1662 |
1480 | 1663 |
1664 static bool GetOrthancJson(std::string& target, | |
1665 ServerContext& context, | |
1666 ResourceType level, | |
1667 const DatabaseLookup& query) | |
1668 { | |
1669 ResourceFinder finder(level, true /* expand */); | |
1670 finder.SetDatabaseLookup(query); | |
1671 | |
1672 Json::Value expanded; | |
1673 finder.Execute(expanded, context, DicomToJsonFormat_Human, false /* don't add "Metadata" */); | |
1674 | |
1675 if (expanded.size() != 1) | |
1676 { | |
1677 return false; | |
1678 } | |
1679 else | |
1680 { | |
1681 target = expanded[0].toStyledString(); | |
1682 | |
1683 // Replace UNIX newlines with DOS newlines | |
1684 boost::replace_all(target, "\n", "\r\n"); | |
1685 | |
1686 return true; | |
1687 } | |
1688 } | |
1689 | |
1690 | |
1481 bool OrthancWebDav::GetFileContent(MimeType& mime, | 1691 bool OrthancWebDav::GetFileContent(MimeType& mime, |
1482 std::string& content, | 1692 std::string& content, |
1483 boost::posix_time::ptime& modificationTime, | 1693 boost::posix_time::ptime& modificationTime, |
1484 const UriComponents& path) | 1694 const UriComponents& path) |
1485 { | 1695 { |
1493 path[2] == STUDY_INFO) | 1703 path[2] == STUDY_INFO) |
1494 { | 1704 { |
1495 DatabaseLookup query; | 1705 DatabaseLookup query; |
1496 query.AddRestConstraint(DICOM_TAG_STUDY_INSTANCE_UID, path[1], | 1706 query.AddRestConstraint(DICOM_TAG_STUDY_INSTANCE_UID, path[1], |
1497 true /* case sensitive */, true /* mandatory tag */); | 1707 true /* case sensitive */, true /* mandatory tag */); |
1498 | |
1499 OrthancJsonVisitor visitor(context_, content, ResourceType_Study); | |
1500 context_.Apply(visitor, query, ResourceType_Study, 0 /* since */, 0 /* no limit */); | |
1501 | 1708 |
1502 mime = MimeType_Json; | 1709 mime = MimeType_Json; |
1503 return visitor.IsSuccess(); | 1710 |
1711 if (true) | |
1712 { | |
1713 /** | |
1714 * EXPERIMENTAL VERSION | |
1715 **/ | |
1716 return GetOrthancJson(content, context_, ResourceType_Study, query); | |
1717 } | |
1718 else | |
1719 { | |
1720 /** | |
1721 * VERSION IN ORTHANC <= 1.12.4 | |
1722 **/ | |
1723 OrthancJsonVisitor visitor(context_, content, ResourceType_Study); | |
1724 context_.Apply(visitor, query, ResourceType_Study, 0 /* since */, 0 /* no limit */); | |
1725 return visitor.IsSuccess(); | |
1726 } | |
1504 } | 1727 } |
1505 else if (path.size() == 4 && | 1728 else if (path.size() == 4 && |
1506 path[3] == SERIES_INFO) | 1729 path[3] == SERIES_INFO) |
1507 { | 1730 { |
1508 DatabaseLookup query; | 1731 DatabaseLookup query; |
1509 query.AddRestConstraint(DICOM_TAG_STUDY_INSTANCE_UID, path[1], | 1732 query.AddRestConstraint(DICOM_TAG_STUDY_INSTANCE_UID, path[1], |
1510 true /* case sensitive */, true /* mandatory tag */); | 1733 true /* case sensitive */, true /* mandatory tag */); |
1511 query.AddRestConstraint(DICOM_TAG_SERIES_INSTANCE_UID, path[2], | 1734 query.AddRestConstraint(DICOM_TAG_SERIES_INSTANCE_UID, path[2], |
1512 true /* case sensitive */, true /* mandatory tag */); | 1735 true /* case sensitive */, true /* mandatory tag */); |
1513 | 1736 |
1514 OrthancJsonVisitor visitor(context_, content, ResourceType_Series); | |
1515 context_.Apply(visitor, query, ResourceType_Series, 0 /* since */, 0 /* no limit */); | |
1516 | |
1517 mime = MimeType_Json; | 1737 mime = MimeType_Json; |
1518 return visitor.IsSuccess(); | 1738 |
1739 if (true) | |
1740 { | |
1741 /** | |
1742 * EXPERIMENTAL VERSION | |
1743 **/ | |
1744 return GetOrthancJson(content, context_, ResourceType_Series, query); | |
1745 } | |
1746 else | |
1747 { | |
1748 /** | |
1749 * VERSION IN ORTHANC <= 1.12.4 | |
1750 **/ | |
1751 OrthancJsonVisitor visitor(context_, content, ResourceType_Series); | |
1752 context_.Apply(visitor, query, ResourceType_Series, 0 /* since */, 0 /* no limit */); | |
1753 return visitor.IsSuccess(); | |
1754 } | |
1519 } | 1755 } |
1520 else if (path.size() == 4 && | 1756 else if (path.size() == 4 && |
1521 boost::ends_with(path[3], ".dcm")) | 1757 boost::ends_with(path[3], ".dcm")) |
1522 { | 1758 { |
1523 const std::string sopInstanceUid = path[3].substr(0, path[3].size() - 4); | 1759 const std::string sopInstanceUid = path[3].substr(0, path[3].size() - 4); |
1528 query.AddRestConstraint(DICOM_TAG_SERIES_INSTANCE_UID, path[2], | 1764 query.AddRestConstraint(DICOM_TAG_SERIES_INSTANCE_UID, path[2], |
1529 true /* case sensitive */, true /* mandatory tag */); | 1765 true /* case sensitive */, true /* mandatory tag */); |
1530 query.AddRestConstraint(DICOM_TAG_SOP_INSTANCE_UID, sopInstanceUid, | 1766 query.AddRestConstraint(DICOM_TAG_SOP_INSTANCE_UID, sopInstanceUid, |
1531 true /* case sensitive */, true /* mandatory tag */); | 1767 true /* case sensitive */, true /* mandatory tag */); |
1532 | 1768 |
1533 DicomFileVisitor visitor(context_, content, modificationTime); | |
1534 context_.Apply(visitor, query, ResourceType_Instance, 0 /* since */, 0 /* no limit */); | |
1535 | |
1536 mime = MimeType_Dicom; | 1769 mime = MimeType_Dicom; |
1537 return visitor.IsSuccess(); | 1770 |
1771 if (true) | |
1772 { | |
1773 /** | |
1774 * EXPERIMENTAL VERSION | |
1775 **/ | |
1776 ResourceFinder finder(ResourceType_Instance, false /* no expand */); | |
1777 finder.SetDatabaseLookup(query); | |
1778 finder.SetRetrieveMetadata(true); | |
1779 finder.SetRetrieveAttachments(true); | |
1780 | |
1781 DicomFileVisitorV2 visitor(context_, content, modificationTime); | |
1782 finder.Execute(visitor, context_); | |
1783 | |
1784 return visitor.IsSuccess(); | |
1785 } | |
1786 else | |
1787 { | |
1788 /** | |
1789 * VERSION IN ORTHANC <= 1.12.4 | |
1790 **/ | |
1791 DicomFileVisitor visitor(context_, content, modificationTime); | |
1792 context_.Apply(visitor, query, ResourceType_Instance, 0 /* since */, 0 /* no limit */); | |
1793 return visitor.IsSuccess(); | |
1794 } | |
1538 } | 1795 } |
1539 else | 1796 else |
1540 { | 1797 { |
1541 return false; | 1798 return false; |
1542 } | 1799 } |
1653 return false; | 1910 return false; |
1654 } | 1911 } |
1655 } | 1912 } |
1656 | 1913 |
1657 DicomDeleteVisitor visitor(context_, level); | 1914 DicomDeleteVisitor visitor(context_, level); |
1658 context_.Apply(visitor, query, level, 0 /* since */, 0 /* no limit */); | 1915 |
1916 ResourceFinder finder(level, false /* no expand */); | |
1917 finder.SetDatabaseLookup(query); | |
1918 finder.Execute(visitor, context_); | |
1659 return true; | 1919 return true; |
1660 } | 1920 } |
1661 else | 1921 else |
1662 { | 1922 { |
1663 return false; // read-only | 1923 return false; // read-only |