Mercurial > hg > orthanc
comparison OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp @ 4699:facea16b055b
added the "Level" argument to "/tools/bulk-content"
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 18 Jun 2021 17:58:56 +0200 |
parents | d16c3c7f11ef |
children | f0038043fb97 8ffe2fdb541f |
comparison
equal
deleted
inserted
replaced
4698:d16c3c7f11ef | 4699:facea16b055b |
---|---|
3090 | 3090 |
3091 call.GetOutput().AnswerBuffer("", MimeType_PlainText); | 3091 call.GetOutput().AnswerBuffer("", MimeType_PlainText); |
3092 } | 3092 } |
3093 | 3093 |
3094 | 3094 |
3095 static void GetBulkChildren(std::set<std::string>& target, | |
3096 ServerIndex& index, | |
3097 const std::set<std::string>& source) | |
3098 { | |
3099 target.clear(); | |
3100 | |
3101 for (std::set<std::string>::const_iterator | |
3102 it = source.begin(); it != source.end(); ++it) | |
3103 { | |
3104 std::list<std::string> children; | |
3105 index.GetChildren(children, *it); | |
3106 | |
3107 for (std::list<std::string>::const_iterator | |
3108 child = children.begin(); child != children.end(); ++child) | |
3109 { | |
3110 target.insert(*child); | |
3111 } | |
3112 } | |
3113 } | |
3114 | |
3115 | |
3095 static void BulkContent(RestApiPostCall& call) | 3116 static void BulkContent(RestApiPostCall& call) |
3096 { | 3117 { |
3097 if (call.IsDocumentation()) | 3118 if (call.IsDocumentation()) |
3098 { | 3119 { |
3099 OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Human); | 3120 OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Human); |
3100 | 3121 |
3101 call.GetDocumentation() | 3122 call.GetDocumentation() |
3102 .SetTag("System") | 3123 .SetTag("System") |
3103 .SetSummary("Describe a set of instances") | 3124 .SetSummary("Describe a set of instances") |
3104 .SetRequestField("Resources", RestApiCallDocumentation::Type_JsonListOfStrings, | 3125 .SetRequestField("Resources", RestApiCallDocumentation::Type_JsonListOfStrings, |
3105 "List of the Orthanc identifiers of the patients/studies/series/instances of interest.", false) | 3126 "List of the Orthanc identifiers of the patients/studies/series/instances of interest.", true) |
3127 .SetRequestField("Level", RestApiCallDocumentation::Type_String, | |
3128 "This optional argument specifies the level of interest (can be `Patient`, `Study`, `Series` or " | |
3129 "`Instance`). Orthanc will loop over the items inside `Resources`, and explorer upward or " | |
3130 "downward in the DICOM hierarchy in order to find the level of interest.", false) | |
3106 .SetDescription("Get the content all the DICOM patients, studies, series or instances " | 3131 .SetDescription("Get the content all the DICOM patients, studies, series or instances " |
3107 "whose identifiers are provided in the `Resources` field, in one single call."); | 3132 "whose identifiers are provided in the `Resources` field, in one single call."); |
3108 return; | 3133 return; |
3109 } | 3134 } |
3110 | 3135 |
3115 throw OrthancException(ErrorCode_BadRequest, | 3140 throw OrthancException(ErrorCode_BadRequest, |
3116 "The body must contain a JSON object"); | 3141 "The body must contain a JSON object"); |
3117 } | 3142 } |
3118 else | 3143 else |
3119 { | 3144 { |
3145 static const char* const LEVEL = "Level"; | |
3146 | |
3120 const DicomToJsonFormat format = OrthancRestApi::GetDicomFormat(request, DicomToJsonFormat_Human); | 3147 const DicomToJsonFormat format = OrthancRestApi::GetDicomFormat(request, DicomToJsonFormat_Human); |
3121 | 3148 |
3122 ServerIndex& index = OrthancRestApi::GetIndex(call); | 3149 ServerIndex& index = OrthancRestApi::GetIndex(call); |
3123 | 3150 |
3124 std::list<std::string> resources; | |
3125 SerializationToolbox::ReadListOfStrings(resources, request, "Resources"); | |
3126 | |
3127 Json::Value answer = Json::arrayValue; | 3151 Json::Value answer = Json::arrayValue; |
3128 for (std::list<std::string>::const_iterator | 3152 |
3129 it = resources.begin(); it != resources.end(); ++it) | 3153 if (request.isMember(LEVEL)) |
3130 { | 3154 { |
3131 ResourceType type; | 3155 // Complex case: Need to explore the DICOM hierarchy |
3132 Json::Value item; | 3156 ResourceType level = StringToResourceType(SerializationToolbox::ReadString(request, LEVEL).c_str()); |
3133 if (index.LookupResourceType(type, *it) && | 3157 |
3134 index.ExpandResource(item, *it, type, format)) | 3158 std::set<std::string> resources; |
3135 { | 3159 SerializationToolbox::ReadSetOfStrings(resources, request, "Resources"); |
3136 answer.append(item); | 3160 |
3137 } | 3161 std::set<std::string> interest; |
3138 else | 3162 |
3139 { | 3163 assert(ResourceType_Patient < ResourceType_Study && |
3140 CLOG(INFO, HTTP) << "Unknown resource during a bulk content retrieval: " << *it; | 3164 ResourceType_Study < ResourceType_Series && |
3165 ResourceType_Series < ResourceType_Instance); | |
3166 | |
3167 for (std::set<std::string>::const_iterator | |
3168 it = resources.begin(); it != resources.end(); ++it) | |
3169 { | |
3170 ResourceType type; | |
3171 if (index.LookupResourceType(type, *it)) | |
3172 { | |
3173 if (type == level) | |
3174 { | |
3175 // This resource is already from the level of interest | |
3176 interest.insert(*it); | |
3177 } | |
3178 else if (type < level) | |
3179 { | |
3180 // Need to explore children | |
3181 std::set<std::string> current; | |
3182 current.insert(*it); | |
3183 | |
3184 for (;;) | |
3185 { | |
3186 std::set<std::string> children; | |
3187 GetBulkChildren(children, index, current); | |
3188 | |
3189 type = GetChildResourceType(type); | |
3190 if (type == level) | |
3191 { | |
3192 for (std::set<std::string>::const_iterator | |
3193 it = children.begin(); it != children.end(); ++it) | |
3194 { | |
3195 interest.insert(*it); | |
3196 } | |
3197 | |
3198 break; // done | |
3199 } | |
3200 else | |
3201 { | |
3202 current.swap(children); | |
3203 } | |
3204 } | |
3205 } | |
3206 else | |
3207 { | |
3208 // Need to explore parents | |
3209 std::string current = *it; | |
3210 | |
3211 for (;;) | |
3212 { | |
3213 std::string parent; | |
3214 if (index.LookupParent(parent, current)) | |
3215 { | |
3216 type = GetParentResourceType(type); | |
3217 if (type == level) | |
3218 { | |
3219 interest.insert(parent); | |
3220 break; // done | |
3221 } | |
3222 else | |
3223 { | |
3224 current = parent; | |
3225 } | |
3226 } | |
3227 else | |
3228 { | |
3229 break; // The resource has been deleted during the exploration | |
3230 } | |
3231 } | |
3232 } | |
3233 } | |
3234 else | |
3235 { | |
3236 CLOG(INFO, HTTP) << "Unknown resource during a bulk content retrieval: " << *it; | |
3237 } | |
3238 } | |
3239 | |
3240 for (std::set<std::string>::const_iterator | |
3241 it = interest.begin(); it != interest.end(); ++it) | |
3242 { | |
3243 Json::Value item; | |
3244 if (index.ExpandResource(item, *it, level, format)) | |
3245 { | |
3246 answer.append(item); | |
3247 } | |
3248 } | |
3249 } | |
3250 else | |
3251 { | |
3252 // Simple case: We return the queried resources as such | |
3253 std::list<std::string> resources; | |
3254 SerializationToolbox::ReadListOfStrings(resources, request, "Resources"); | |
3255 | |
3256 for (std::list<std::string>::const_iterator | |
3257 it = resources.begin(); it != resources.end(); ++it) | |
3258 { | |
3259 ResourceType type; | |
3260 Json::Value item; | |
3261 if (index.LookupResourceType(type, *it) && | |
3262 index.ExpandResource(item, *it, type, format)) | |
3263 { | |
3264 answer.append(item); | |
3265 } | |
3266 else | |
3267 { | |
3268 CLOG(INFO, HTTP) << "Unknown resource during a bulk content retrieval: " << *it; | |
3269 } | |
3141 } | 3270 } |
3142 } | 3271 } |
3143 | 3272 |
3144 call.GetOutput().AnswerJson(answer); | 3273 call.GetOutput().AnswerJson(answer); |
3145 } | 3274 } |
3152 { | 3281 { |
3153 call.GetDocumentation() | 3282 call.GetDocumentation() |
3154 .SetTag("System") | 3283 .SetTag("System") |
3155 .SetSummary("Delete a set of instances") | 3284 .SetSummary("Delete a set of instances") |
3156 .SetRequestField("Resources", RestApiCallDocumentation::Type_JsonListOfStrings, | 3285 .SetRequestField("Resources", RestApiCallDocumentation::Type_JsonListOfStrings, |
3157 "List of the Orthanc identifiers of the patients/studies/series/instances of interest.", false) | 3286 "List of the Orthanc identifiers of the patients/studies/series/instances of interest.", true) |
3158 .SetDescription("Delete all the DICOM patients, studies, series or instances " | 3287 .SetDescription("Delete all the DICOM patients, studies, series or instances " |
3159 "whose identifiers are provided in the `Resources` field."); | 3288 "whose identifiers are provided in the `Resources` field."); |
3160 return; | 3289 return; |
3161 } | 3290 } |
3162 | 3291 |