# HG changeset patch # User Sebastien Jodogne # Date 1399370951 -7200 # Node ID e7b1ca0f1e04b2d1be54d5b6dd8e453d5271961c # Parent d466b3606acadf42e796b49f4ae4eefa40bb723f creation of dicom files diff -r d466b3606aca -r e7b1ca0f1e04 NEWS --- a/NEWS Tue May 06 11:01:30 2014 +0200 +++ b/NEWS Tue May 06 12:09:11 2014 +0200 @@ -2,8 +2,9 @@ =============================== * Dynamic negotiation of SOP classes for C-Store SCU +* Creation of DICOM instances using the REST API * Reuse of the previous SCU connection to avoid unecessary handshakes -* Fix missing licensing terms about reuse of some DCMTK code +* Fix missing licensing terms about reuse of some code from DCMTK * Various code refactorings diff -r d466b3606aca -r e7b1ca0f1e04 OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp --- a/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp Tue May 06 11:01:30 2014 +0200 +++ b/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp Tue May 06 12:09:11 2014 +0200 @@ -95,8 +95,11 @@ const std::string& name = members[i]; std::string value = replacements[name].asString(); - DicomTag tag = FromDcmtkBridge::ParseTag(name); - target.Replace(tag, value); + DicomTag tag = FromDcmtkBridge::ParseTag(name); + if (tag != DICOM_TAG_PIXEL_DATA) + { + target.Replace(tag, value); + } VLOG(1) << "Replace: " << name << " " << tag << " == " << value << std::endl; } @@ -336,10 +339,25 @@ { DicomModification modification; - // TODO : modification.SetLevel(ResourceType_Series); ????? - if (ParseModifyRequest(modification, call)) { + if (modification.IsReplaced(DICOM_TAG_PATIENT_ID)) + { + modification.SetLevel(ResourceType_Patient); + } + else if (modification.IsReplaced(DICOM_TAG_STUDY_INSTANCE_UID)) + { + modification.SetLevel(ResourceType_Study); + } + else if (modification.IsReplaced(DICOM_TAG_SERIES_INSTANCE_UID)) + { + modification.SetLevel(ResourceType_Series); + } + else + { + modification.SetLevel(ResourceType_Instance); + } + AnonymizeOrModifyInstance(modification, call); } } @@ -362,26 +380,9 @@ { DicomModification modification; - switch (resourceType) - { - case ResourceType_Series: - modification.SetLevel(ResourceType_Series); - break; - - case ResourceType_Study: - modification.SetLevel(ResourceType_Study); - break; - - case ResourceType_Patient: - modification.SetLevel(ResourceType_Patient); - break; - - default: - throw OrthancException(ErrorCode_InternalError); - } - if (ParseModifyRequest(modification, call)) { + modification.SetLevel(resourceType); AnonymizeOrModifyResource(modification, MetadataType_ModifiedFrom, changeType, resourceType, call); } @@ -402,16 +403,45 @@ } + static void Create(RestApi::PostCall& call) + { + // curl http://localhost:8042/tools/create-dicom -X POST -d '{"PatientName":"Hello^World"}' + + Json::Value request; + if (call.ParseJsonRequest(request) && request.isObject()) + { + DicomModification modification; + ParseReplacements(modification, request); + + ParsedDicomFile dicom; + modification.Apply(dicom); + + std::string id; + StoreStatus status = OrthancRestApi::GetContext(call).Store(id, dicom); + + if (status == StoreStatus_Failure) + { + LOG(ERROR) << "Error while storing a manually-created instance"; + return; + } + + OrthancRestApi::GetApi(call).AnswerStoredInstance(call, id, status); + } + } + + void OrthancRestApi::RegisterAnonymizeModify() { Register("/instances/{id}/modify", ModifyInstance); Register("/series/{id}/modify", ModifyResource); Register("/studies/{id}/modify", ModifyResource); - //Register("/patients/{id}/modify", ModifyResource); + Register("/patients/{id}/modify", ModifyResource); Register("/instances/{id}/anonymize", AnonymizeInstance); Register("/series/{id}/anonymize", AnonymizeResource); Register("/studies/{id}/anonymize", AnonymizeResource); Register("/patients/{id}/anonymize", AnonymizeResource); + + Register("/tools/create-dicom", Create); } } diff -r d466b3606aca -r e7b1ca0f1e04 OrthancServer/OrthancRestApi/OrthancRestApi.cpp --- a/OrthancServer/OrthancRestApi/OrthancRestApi.cpp Tue May 06 11:01:30 2014 +0200 +++ b/OrthancServer/OrthancRestApi/OrthancRestApi.cpp Tue May 06 12:09:11 2014 +0200 @@ -32,10 +32,30 @@ #include "OrthancRestApi.h" +#include "../DicomModification.h" + #include namespace Orthanc { + void OrthancRestApi::AnswerStoredInstance(RestApi::PostCall& call, + const std::string& publicId, + StoreStatus status) + { + Json::Value result = Json::objectValue; + + if (status != StoreStatus_Failure) + { + result["ID"] = publicId; + result["Path"] = GetBasePath(ResourceType_Instance, publicId); + } + + result["Status"] = EnumerationToString(status); + call.GetOutput().AnswerJson(result); + } + + + // Upload of DICOM files through HTTP --------------------------------------- static void UploadDicomFile(RestApi::PostCall& call) @@ -52,16 +72,8 @@ std::string publicId; StoreStatus status = context.Store(publicId, postData); - Json::Value result = Json::objectValue; - if (status != StoreStatus_Failure) - { - result["ID"] = publicId; - result["Path"] = GetBasePath(ResourceType_Instance, publicId); - } - - result["Status"] = EnumerationToString(status); - call.GetOutput().AnswerJson(result); + OrthancRestApi::GetApi(call).AnswerStoredInstance(call, publicId, status); } diff -r d466b3606aca -r e7b1ca0f1e04 OrthancServer/OrthancRestApi/OrthancRestApi.h --- a/OrthancServer/OrthancRestApi/OrthancRestApi.h Tue May 06 11:01:30 2014 +0200 +++ b/OrthancServer/OrthancRestApi/OrthancRestApi.h Tue May 06 12:09:11 2014 +0200 @@ -62,15 +62,23 @@ public: OrthancRestApi(ServerContext& context); + static OrthancRestApi& GetApi(RestApi::Call& call) + { + return dynamic_cast(call.GetContext()); + } + static ServerContext& GetContext(RestApi::Call& call) { - OrthancRestApi& that = dynamic_cast(call.GetContext()); - return that.context_; + return GetApi(call).context_; } static ServerIndex& GetIndex(RestApi::Call& call) { return GetContext(call).GetIndex(); } + + void AnswerStoredInstance(RestApi::PostCall& call, + const std::string& publicId, + StoreStatus status); }; }