# HG changeset patch # User Sebastien Jodogne # Date 1354183180 -3600 # Node ID 4ce7fdcc8879827565eaf394a84f2a2d8f489515 # Parent f276b175dcaf91affbd902757c3fc98bec927922 access to tags, simplified-tags and file of an instance diff -r f276b175dcaf -r 4ce7fdcc8879 CMakeLists.txt --- a/CMakeLists.txt Thu Nov 29 10:13:49 2012 +0100 +++ b/CMakeLists.txt Thu Nov 29 10:59:40 2012 +0100 @@ -145,6 +145,7 @@ OrthancServer/ToDcmtkBridge.cpp OrthancServer/DatabaseWrapper.cpp OrthancServer/ServerEnumerations.cpp + OrthancServer/ServerToolbox.cpp ) # Ensure autogenerated code is built before building ServerLibrary diff -r f276b175dcaf -r 4ce7fdcc8879 OrthancServer/OrthancRestApi.cpp --- a/OrthancServer/OrthancRestApi.cpp Thu Nov 29 10:13:49 2012 +0100 +++ b/OrthancServer/OrthancRestApi.cpp Thu Nov 29 10:59:40 2012 +0100 @@ -34,6 +34,7 @@ #include "OrthancInitialization.h" #include "FromDcmtkBridge.h" +#include "ServerToolbox.h" #include "../Core/Uuid.h" #include "../Core/HttpServer/FilesystemHttpSender.h" @@ -51,71 +52,6 @@ output.AnswerBufferWithContentType(s, "application/json"); } - - static void SimplifyTagsRecursion(Json::Value& target, - const Json::Value& source) - { - assert(source.isObject()); - - target = Json::objectValue; - Json::Value::Members members = source.getMemberNames(); - - for (size_t i = 0; i < members.size(); i++) - { - const Json::Value& v = source[members[i]]; - const std::string& name = v["Name"].asString(); - const std::string& type = v["Type"].asString(); - - if (type == "String") - { - target[name] = v["Value"].asString(); - } - else if (type == "TooLong" || - type == "Null") - { - target[name] = Json::nullValue; - } - else if (type == "Sequence") - { - const Json::Value& array = v["Value"]; - assert(array.isArray()); - - Json::Value children = Json::arrayValue; - for (Json::Value::ArrayIndex i = 0; i < array.size(); i++) - { - Json::Value c; - SimplifyTagsRecursion(c, array[i]); - children.append(c); - } - - target[name] = children; - } - else - { - assert(0); - } - } - } - - - static void SimplifyTags(Json::Value& target, - const FileStorage& storage, - const std::string& fileUuid) - { - std::string s; - storage.ReadFile(s, fileUuid); - - Json::Value source; - Json::Reader reader; - if (!reader.parse(s, source)) - { - throw OrthancException("Corrupted JSON file"); - } - - SimplifyTagsRecursion(target, source); - } - - bool OrthancRestApi::Store(Json::Value& result, const std::string& postData) { @@ -437,69 +373,6 @@ } - // Information about a single object ---------------------------------------- - - else if (uri.size() == 2 && - (uri[0] == "instances" || - uri[0] == "series" || - uri[0] == "studies" || - uri[0] == "patients")) - { - if (method == "GET") - { - if (uri[0] == "patients") - { - existingResource = index_.LookupResource(result, uri[1], ResourceType_Patient); - assert(!existingResource || result["Type"] == "Patient"); - } - else if (uri[0] == "studies") - { - existingResource = index_.LookupResource(result, uri[1], ResourceType_Study); - assert(!existingResource || result["Type"] == "Study"); - } - else if (uri[0] == "series") - { - existingResource = index_.LookupResource(result, uri[1], ResourceType_Series); - assert(!existingResource || result["Type"] == "Series"); - } - else if (uri[0] == "instances") - { - existingResource = index_.LookupResource(result, uri[1], ResourceType_Instance); - assert(!existingResource || result["Type"] == "Instance"); - } - } - else if (method == "DELETE") - { - if (uri[0] == "patients") - { - existingResource = index_.DeleteResource(result, uri[1], ResourceType_Patient); - } - else if (uri[0] == "studies") - { - existingResource = index_.DeleteResource(result, uri[1], ResourceType_Study); - } - else if (uri[0] == "series") - { - existingResource = index_.DeleteResource(result, uri[1], ResourceType_Series); - } - else if (uri[0] == "instances") - { - existingResource = index_.DeleteResource(result, uri[1], ResourceType_Instance); - } - - if (existingResource) - { - result["Status"] = "Success"; - } - } - else - { - output.SendMethodNotAllowedError("GET,DELETE"); - return; - } - } - - // Get the DICOM or the JSON file of one instance --------------------------- else if (uri.size() == 3 && @@ -528,9 +401,10 @@ { if (uri[2] == "simplified-tags") { - Json::Value v; - SimplifyTags(v, storage_, fileUuid); - SendJson(output, v); + Json::Value simplified, full; + ReadJson(full, storage_, fileUuid); + SimplifyTags(simplified, full); + SendJson(output, simplified); return; } else diff -r f276b175dcaf -r 4ce7fdcc8879 OrthancServer/OrthancRestApi2.cpp --- a/OrthancServer/OrthancRestApi2.cpp Thu Nov 29 10:13:49 2012 +0100 +++ b/OrthancServer/OrthancRestApi2.cpp Thu Nov 29 10:59:40 2012 +0100 @@ -36,6 +36,7 @@ #include "FromDcmtkBridge.h" #include "../Core/Uuid.h" #include "../Core/HttpServer/FilesystemHttpSender.h" +#include "ServerToolbox.h" #include #include @@ -141,6 +142,58 @@ + // Get information about a single instance ---------------------------------- + + static void GetInstanceFile(RestApi::GetCall& call) + { + RETRIEVE_CONTEXT(call); + + CompressionType compressionType; + std::string fileUuid; + std::string publicId = call.GetUriComponent("id", ""); + + if (context.GetIndex().GetFile(fileUuid, compressionType, publicId, AttachedFileType_Dicom)) + { + assert(compressionType == CompressionType_None); + + FilesystemHttpSender sender(context.GetFileStorage(), fileUuid); + sender.SetFilename(fileUuid + ".dcm"); + sender.SetContentType("application/dicom"); + call.GetOutput().AnswerFile(sender); + } + } + + + template + static void GetInstanceTags(RestApi::GetCall& call) + { + RETRIEVE_CONTEXT(call); + + CompressionType compressionType; + std::string fileUuid; + std::string publicId = call.GetUriComponent("id", ""); + + if (context.GetIndex().GetFile(fileUuid, compressionType, publicId, AttachedFileType_Json)) + { + assert(compressionType == CompressionType_None); + + Json::Value full; + ReadJson(full, context.GetFileStorage(), fileUuid); + + if (simplify) + { + Json::Value simplified; + SimplifyTags(simplified, full); + call.GetOutput().AnswerJson(simplified); + } + else + { + call.GetOutput().AnswerJson(full); + } + } + } + + // DICOM bridge ------------------------------------------------------------- @@ -161,6 +214,9 @@ } + + // Registration of the various REST handlers -------------------------------- + OrthancRestApi2::OrthancRestApi2(ServerIndex& index, const std::string& path) : index_(index), @@ -186,5 +242,11 @@ Register("/series/{id}", GetSingleResource); Register("/studies/{id}", DeleteSingleResource); Register("/studies/{id}", GetSingleResource); + + Register("/instances/{id}/file", GetInstanceFile); + Register("/instances/{id}/tags", GetInstanceTags); + Register("/instances/{id}/simplified-tags", GetInstanceTags); + + // TODO : "content", "frames" } } diff -r f276b175dcaf -r 4ce7fdcc8879 OrthancServer/OrthancRestApi2.h --- a/OrthancServer/OrthancRestApi2.h Thu Nov 29 10:13:49 2012 +0100 +++ b/OrthancServer/OrthancRestApi2.h Thu Nov 29 10:59:40 2012 +0100 @@ -58,7 +58,7 @@ return index_; } - FileStorage& GetStorage() + FileStorage& GetFileStorage() { return storage_; } diff -r f276b175dcaf -r 4ce7fdcc8879 OrthancServer/ServerToolbox.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancServer/ServerToolbox.cpp Thu Nov 29 10:59:40 2012 +0100 @@ -0,0 +1,97 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012 Medical Physics Department, CHU of Liege, + * Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#include "ServerToolbox.h" + +#include "../Core/OrthancException.h" + +namespace Orthanc +{ + void ReadJson(Json::Value& target, + const FileStorage& storage, + const std::string& fileUuid) + { + std::string s; + storage.ReadFile(s, fileUuid); + + Json::Reader reader; + if (!reader.parse(s, target)) + { + throw OrthancException("Corrupted JSON file"); + } + } + + void SimplifyTags(Json::Value& target, + const Json::Value& source) + { + assert(source.isObject()); + + target = Json::objectValue; + Json::Value::Members members = source.getMemberNames(); + + for (size_t i = 0; i < members.size(); i++) + { + const Json::Value& v = source[members[i]]; + const std::string& name = v["Name"].asString(); + const std::string& type = v["Type"].asString(); + + if (type == "String") + { + target[name] = v["Value"].asString(); + } + else if (type == "TooLong" || + type == "Null") + { + target[name] = Json::nullValue; + } + else if (type == "Sequence") + { + const Json::Value& array = v["Value"]; + assert(array.isArray()); + + Json::Value children = Json::arrayValue; + for (Json::Value::ArrayIndex i = 0; i < array.size(); i++) + { + Json::Value c; + SimplifyTags(c, array[i]); + children.append(c); + } + + target[name] = children; + } + else + { + assert(0); + } + } + } +} diff -r f276b175dcaf -r 4ce7fdcc8879 OrthancServer/ServerToolbox.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancServer/ServerToolbox.h Thu Nov 29 10:59:40 2012 +0100 @@ -0,0 +1,47 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012 Medical Physics Department, CHU of Liege, + * Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "../Core/FileStorage.h" + +#include + +namespace Orthanc +{ + void ReadJson(Json::Value& target, + const FileStorage& storage, + const std::string& fileUuid); + + void SimplifyTags(Json::Value& target, + const Json::Value& source); +}