changeset 402:d2c69150a979

bulk storescu
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 30 Apr 2013 11:50:51 +0200
parents 5962898fb7c8
children c3e9b74aab7a
files Core/Toolbox.cpp Core/Toolbox.h Core/Uuid.cpp Core/Uuid.h OrthancServer/OrthancRestApi.cpp UnitTests/main.cpp
diffstat 6 files changed, 125 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/Core/Toolbox.cpp	Tue Apr 30 10:57:00 2013 +0200
+++ b/Core/Toolbox.cpp	Tue Apr 30 11:50:51 2013 +0200
@@ -565,6 +565,33 @@
     }
   }
 
+  bool Toolbox::IsSHA1(const std::string& str)
+  {
+    if (str.size() != 44)
+    {
+      return false;
+    }
+
+    for (unsigned int i = 0; i < 44; i++)
+    {
+      if (i == 8 ||
+          i == 17 ||
+          i == 26 ||
+          i == 35)
+      {
+        if (str[i] != '-')
+          return false;
+      }
+      else
+      {
+        if (!isalnum(str[i]))
+          return false;
+      }
+    }
+
+    return true;
+  }
+
   std::string Toolbox::GetNowIsoString()
   {
     boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
--- a/Core/Toolbox.h	Tue Apr 30 10:57:00 2013 +0200
+++ b/Core/Toolbox.h	Tue Apr 30 11:50:51 2013 +0200
@@ -80,6 +80,8 @@
     void ComputeSHA1(std::string& result,
                      const std::string& data);
 
+    bool IsSHA1(const std::string& str);
+
     std::string DecodeBase64(const std::string& data);
 
     std::string EncodeBase64(const std::string& data);
--- a/Core/Uuid.cpp	Tue Apr 30 10:57:00 2013 +0200
+++ b/Core/Uuid.cpp	Tue Apr 30 11:50:51 2013 +0200
@@ -96,6 +96,28 @@
     }
 
 
+    bool StartsWithUuid(const std::string& str)
+    {
+      if (str.size() < 36)
+      {
+        return false;
+      }
+
+      if (str.size() == 36)
+      {
+        return IsUuid(str);
+      }
+
+      assert(str.size() > 36);
+      if (!isspace(str[36]))
+      {
+        return false;
+      }
+
+      return IsUuid(str.substr(0, 36));
+    }
+
+
     static std::string CreateTemporaryPath(const char* extension)
     {
 #if BOOST_HAS_FILESYSTEM_V3 == 1
--- a/Core/Uuid.h	Tue Apr 30 10:57:00 2013 +0200
+++ b/Core/Uuid.h	Tue Apr 30 11:50:51 2013 +0200
@@ -51,6 +51,8 @@
 
     bool IsUuid(const std::string& str);
 
+    bool StartsWithUuid(const std::string& str);
+
     class TemporaryFile
     {
     private:
--- a/OrthancServer/OrthancRestApi.cpp	Tue Apr 30 10:57:00 2013 +0200
+++ b/OrthancServer/OrthancRestApi.cpp	Tue Apr 30 11:50:51 2013 +0200
@@ -249,45 +249,67 @@
     RETRIEVE_CONTEXT(call);
 
     std::string remote = call.GetUriComponent("id", "");
+    std::string stripped = Toolbox::StripSpaces(call.GetPostBody());
+
+    Json::Value request;
+    if (Toolbox::IsSHA1(stripped))
+    {
+      // This is for compatibility with Orthanc <= 0.5.1.
+      request = stripped;
+    }
+    else if (!call.ParseJsonRequest(request))
+    {
+      // Bad JSON request
+      return;
+    }
+
+    std::list<std::string> instances;
+    if (request.isString())
+    {
+      context.GetIndex().LogExportedResource(request.asString(), remote);
+      context.GetIndex().GetChildInstances(instances, request.asString());
+    }
+    else if (request.isArray())
+    {
+      for (Json::Value::ArrayIndex i = 0; i < request.size(); i++)
+      {
+        if (!request[i].isString())
+        {
+          return;
+        }
+
+        std::string stripped = Toolbox::StripSpaces(request[i].asString());
+        if (!Toolbox::IsSHA1(stripped))
+        {
+          return;
+        }
+
+        context.GetIndex().LogExportedResource(stripped, remote);
+       
+        std::list<std::string> tmp;
+        context.GetIndex().GetChildInstances(tmp, stripped);
+        instances.merge(tmp);
+        assert(tmp.size() == 0);
+      }
+    }
+    else
+    {
+      // Neither a string, nor a list of strings. Bad request.
+      return;
+    }
+
     DicomUserConnection connection;
     ConnectToModality(connection, remote);
 
-    const std::string& resourceId = call.GetPostBody();
-
-    Json::Value found;
-    if (context.GetIndex().LookupResource(found, resourceId, ResourceType_Series))
+    for (std::list<std::string>::const_iterator 
+           it = instances.begin(); it != instances.end(); it++)
     {
-      // The UUID corresponds to a series
-      context.GetIndex().LogExportedResource(resourceId, remote);
-
-      for (Json::Value::ArrayIndex i = 0; i < found["Instances"].size(); i++)
-      {
-        std::string instanceId = found["Instances"][i].asString();
-        std::string dicom;
-        context.ReadFile(dicom, instanceId, FileContentType_Dicom);
-        connection.Store(dicom);
-      }
-
-      call.GetOutput().AnswerBuffer("{}", "application/json");
+      std::string dicom;
+      context.ReadFile(dicom, *it, FileContentType_Dicom);
+      connection.Store(dicom);
     }
-    else if (context.GetIndex().LookupResource(found, resourceId, ResourceType_Instance))
-    {
-      // The UUID corresponds to an instance
-      context.GetIndex().LogExportedResource(resourceId, remote);
 
-      std::string dicom;
-      context.ReadFile(dicom, resourceId, FileContentType_Dicom);
-      connection.Store(dicom);
-
-      call.GetOutput().AnswerBuffer("{}", "application/json");
-    }
-    else
-    {
-      // The POST body is not a known resource, assume that it
-      // contains a raw DICOM instance
-      connection.Store(resourceId);
-      call.GetOutput().AnswerBuffer("{}", "application/json");
-    }
+    call.GetOutput().AnswerBuffer("{}", "application/json");
   }
 
 
--- a/UnitTests/main.cpp	Tue Apr 30 10:57:00 2013 +0200
+++ b/UnitTests/main.cpp	Tue Apr 30 11:50:51 2013 +0200
@@ -29,6 +29,23 @@
   ASSERT_FALSE(Toolbox::IsUuid(""));
   ASSERT_FALSE(Toolbox::IsUuid("012345678901234567890123456789012345"));
   ASSERT_TRUE(Toolbox::IsUuid("550e8400-e29b-41d4-a716-446655440000"));
+  ASSERT_FALSE(Toolbox::StartsWithUuid("550e8400-e29b-41d4-a716-44665544000"));
+  ASSERT_TRUE(Toolbox::StartsWithUuid("550e8400-e29b-41d4-a716-446655440000"));
+  ASSERT_TRUE(Toolbox::StartsWithUuid("550e8400-e29b-41d4-a716-446655440000 ok"));
+  ASSERT_FALSE(Toolbox::StartsWithUuid("550e8400-e29b-41d4-a716-446655440000ok"));
+}
+
+TEST(Toolbox, IsSHA1)
+{
+  ASSERT_FALSE(Toolbox::IsSHA1(""));
+  ASSERT_FALSE(Toolbox::IsSHA1("01234567890123456789012345678901234567890123"));
+  ASSERT_FALSE(Toolbox::IsSHA1("012345678901234567890123456789012345678901234"));
+  ASSERT_TRUE(Toolbox::IsSHA1("b5ed549f-956400ce-69a8c063-bf5b78be-2732a4b9"));
+
+  std::string s;
+  Toolbox::ComputeSHA1(s, "The quick brown fox jumps over the lazy dog");
+  ASSERT_TRUE(Toolbox::IsSHA1(s));
+  ASSERT_EQ("2fd4e1c6-7a2d28fc-ed849ee1-bb76e739-1b93eb12", s);
 }
 
 TEST(Zlib, Basic)