changeset 5447:dacdce5e5c22

now accepting GET requests on the /tools/create-archive route and siblings
author Alain Mazy <am@osimis.io>
date Fri, 24 Nov 2023 18:14:52 +0100
parents 912565317b9a
children 2d23c92c359a
files NEWS OrthancServer/Sources/OrthancRestApi/OrthancRestArchive.cpp
diffstat 2 files changed, 80 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Fri Nov 24 12:12:03 2023 +0100
+++ b/NEWS	Fri Nov 24 18:14:52 2023 +0100
@@ -42,6 +42,10 @@
 * Added a route to delete completed jobs from history: DELETE /jobs/{id}
 * added a "transcode" option to the /file route:
   e.g: /instances/../file?transcode=1.2.840.10008.1.2.4.80
+* now accepting GET requests on these 3 routes to create archive/media:
+  /tools/create-archive?resources=..,..2&transcode=1.2.840.10008.1.2.4.80
+  /tools/create-media?resources=..,..2&transcode=1.2.840.10008.1.2.4.80
+  /tools/create-media-extended?resources=..,..2&transcode=1.2.840.10008.1.2.4.80
 * All 'expand' GET arguments now accepts expand=true and expand=false values.
   The /studies/../instances and sibling routes are the only whose expand is true if not specified.
   These routes now accepts expand=false to simply list the child resources ids.
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestArchive.cpp	Fri Nov 24 12:12:03 2023 +0100
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestArchive.cpp	Fri Nov 24 18:14:52 2023 +0100
@@ -28,6 +28,7 @@
 #include "../../../OrthancFramework/Sources/Logging.h"
 #include "../../../OrthancFramework/Sources/OrthancException.h"
 #include "../../../OrthancFramework/Sources/SerializationToolbox.h"
+#include "../../../OrthancFramework/Sources/Toolbox.h"
 #include "../OrthancConfiguration.h"
 #include "../ServerContext.h"
 #include "../ServerJobs/ArchiveJob.h"
@@ -43,6 +44,19 @@
 
   static const char* const CONFIG_LOADER_THREADS = "ZipLoaderThreads";
 
+
+  static void AddResourcesOfInterestFromString(ArchiveJob& job,
+                                              const std::string& resourcesList)
+  {
+    std::set<std::string> resources;
+    Toolbox::SplitString(resources, resourcesList, ',');
+
+    for (std::set<std::string>::const_iterator it = resources.begin(); it != resources.end(); ++it)
+    {
+      job.AddResource(*it, false, ResourceType_Patient /* dummy value */);
+    }
+  }
+
   static void AddResourcesOfInterestFromArray(ArchiveJob& job,
                                               const Json::Value& resources)
   {
@@ -513,7 +527,7 @@
   
   template <bool IS_MEDIA,
             bool DEFAULT_IS_EXTENDED  /* only makes sense for media (i.e. not ZIP archives) */ >
-  static void CreateBatch(RestApiPostCall& call)
+  static void CreateBatchPost(RestApiPostCall& call)
   {
     if (call.IsDocumentation())
     {
@@ -561,6 +575,56 @@
   }
   
 
+  template <bool IS_MEDIA,
+            bool DEFAULT_IS_EXTENDED  /* only makes sense for media (i.e. not ZIP archives) */ >
+  static void CreateBatchGet(RestApiGetCall& call)
+  {
+    static const char* const TRANSCODE = "transcode";
+    static const char* const RESOURCES = "resources";
+
+    if (call.IsDocumentation())
+    {
+      std::string m = (IS_MEDIA ? "DICOMDIR media" : "ZIP archive");
+      call.GetDocumentation()
+        .SetTag("System")
+        .SetSummary("Create " + m)
+        .SetDescription("Create a " + m + " containing the DICOM resources (patients, studies, series, or instances) "
+                        "whose Orthanc identifiers are provided in the 'resources' argument")
+        .SetHttpGetArgument(TRANSCODE, RestApiCallDocumentation::Type_String,
+                            "If present, the DICOM files will be transcoded to the provided "
+                            "transfer syntax: https://orthanc.uclouvain.be/book/faq/transcoding.html", false)
+        .SetHttpGetArgument(RESOURCES, RestApiCallDocumentation::Type_String,
+                            "A comma separated list of Orthanc resource identifiers to include in the " + m + ".", true);
+      return;
+    }
+
+    ServerContext& context = OrthancRestApi::GetContext(call);
+    bool transcode = false;
+    DicomTransferSyntax transferSyntax;
+
+    if (call.HasArgument(TRANSCODE))
+    {
+      transcode = true;
+      transferSyntax = GetTransferSyntax(call.GetArgument(TRANSCODE, ""));
+    }
+    
+    if (!call.HasArgument(RESOURCES))
+    {
+      throw OrthancException(Orthanc::ErrorCode_BadRequest, std::string("Missing ") + RESOURCES + " argument");
+    }
+
+    std::unique_ptr<ArchiveJob> job(new ArchiveJob(context, IS_MEDIA, DEFAULT_IS_EXTENDED, ResourceType_Patient));
+    AddResourcesOfInterestFromString(*job, call.GetArgument(RESOURCES, ""));
+
+    if (transcode)
+    {
+      job->SetTranscode(transferSyntax);
+    }
+
+    SubmitJob(call.GetOutput(), context, job, 0, true, "Archive.zip");
+  }
+
+
   template <ResourceType LEVEL,
             bool IS_MEDIA>
   static void CreateSingleGet(RestApiGetCall& call)
@@ -699,10 +763,18 @@
     Register("/studies/{id}/media",    CreateSinglePost<ResourceType_Study, true /* media */>);
 
     Register("/tools/create-archive",
-             CreateBatch<false /* ZIP */,  false /* extended makes no sense in ZIP */>);
+             CreateBatchPost<false /* ZIP */,  false /* extended makes no sense in ZIP */>);
     Register("/tools/create-media",
-             CreateBatch<true /* media */, false /* not extended by default */>);
+             CreateBatchPost<true /* media */, false /* not extended by default */>);
     Register("/tools/create-media-extended",
-             CreateBatch<true /* media */, true /* extended by default */>);
+             CreateBatchPost<true /* media */, true /* extended by default */>);
+
+    Register("/tools/create-archive",
+             CreateBatchGet<false /* ZIP */,  false /* extended makes no sense in ZIP */>);
+    Register("/tools/create-media",
+             CreateBatchGet<true /* media */, false /* not extended by default */>);
+    Register("/tools/create-media-extended",
+             CreateBatchGet<true /* media */, true /* extended by default */>);
+
   }
 }