Mercurial > hg > orthanc
comparison OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp @ 4697:569d9ef165b1
Added "short", "simplify" and/or "full" options to control the format of DICOM tags wherever possible
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 18 Jun 2021 16:08:35 +0200 |
parents | da1edb7d6332 |
children | d16c3c7f11ef |
comparison
equal
deleted
inserted
replaced
4696:dd6274412ff4 | 4697:569d9ef165b1 |
---|---|
110 call.GetOutput().AnswerJson(dicom); | 110 call.GetOutput().AnswerJson(dicom); |
111 } | 111 } |
112 } | 112 } |
113 | 113 |
114 | 114 |
115 static DicomToJsonFormat GetDicomFormat(const RestApiGetCall& call) | |
116 { | |
117 if (call.HasArgument("simplify")) | |
118 { | |
119 return DicomToJsonFormat_Human; | |
120 } | |
121 else if (call.HasArgument("short")) | |
122 { | |
123 return DicomToJsonFormat_Short; | |
124 } | |
125 else | |
126 { | |
127 return DicomToJsonFormat_Full; | |
128 } | |
129 } | |
130 | |
131 | |
132 static void AnswerDicomAsJson(RestApiGetCall& call, | |
133 const Json::Value& dicom) | |
134 { | |
135 AnswerDicomAsJson(call, dicom, GetDicomFormat(call)); | |
136 } | |
137 | |
138 | |
139 static void ParseSetOfTags(std::set<DicomTag>& target, | 115 static void ParseSetOfTags(std::set<DicomTag>& target, |
140 const RestApiGetCall& call, | 116 const RestApiGetCall& call, |
141 const std::string& argument) | 117 const std::string& argument) |
142 { | 118 { |
143 target.clear(); | 119 target.clear(); |
159 | 135 |
160 static void AnswerListOfResources(RestApiOutput& output, | 136 static void AnswerListOfResources(RestApiOutput& output, |
161 ServerIndex& index, | 137 ServerIndex& index, |
162 const std::list<std::string>& resources, | 138 const std::list<std::string>& resources, |
163 ResourceType level, | 139 ResourceType level, |
164 bool expand) | 140 bool expand, |
141 DicomToJsonFormat format) | |
165 { | 142 { |
166 Json::Value answer = Json::arrayValue; | 143 Json::Value answer = Json::arrayValue; |
167 | 144 |
168 for (std::list<std::string>::const_iterator | 145 for (std::list<std::string>::const_iterator |
169 resource = resources.begin(); resource != resources.end(); ++resource) | 146 resource = resources.begin(); resource != resources.end(); ++resource) |
170 { | 147 { |
171 if (expand) | 148 if (expand) |
172 { | 149 { |
173 Json::Value expanded; | 150 Json::Value expanded; |
174 if (index.ExpandResource(expanded, *resource, level)) | 151 if (index.ExpandResource(expanded, *resource, level, format)) |
175 { | 152 { |
176 answer.append(expanded); | 153 answer.append(expanded); |
177 } | 154 } |
178 } | 155 } |
179 else | 156 else |
189 template <enum ResourceType resourceType> | 166 template <enum ResourceType resourceType> |
190 static void ListResources(RestApiGetCall& call) | 167 static void ListResources(RestApiGetCall& call) |
191 { | 168 { |
192 if (call.IsDocumentation()) | 169 if (call.IsDocumentation()) |
193 { | 170 { |
171 OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Human); | |
172 | |
194 const std::string resources = GetResourceTypeText(resourceType, true /* plural */, false /* lower case */); | 173 const std::string resources = GetResourceTypeText(resourceType, true /* plural */, false /* lower case */); |
195 call.GetDocumentation() | 174 call.GetDocumentation() |
196 .SetTag(GetResourceTypeText(resourceType, true /* plural */, true /* upper case */)) | 175 .SetTag(GetResourceTypeText(resourceType, true /* plural */, true /* upper case */)) |
197 .SetSummary("List the available " + resources) | 176 .SetSummary("List the available " + resources) |
198 .SetDescription("List the Orthanc identifiers of all the available DICOM " + resources) | 177 .SetDescription("List the Orthanc identifiers of all the available DICOM " + resources) |
234 else | 213 else |
235 { | 214 { |
236 index.GetAllUuids(result, resourceType); | 215 index.GetAllUuids(result, resourceType); |
237 } | 216 } |
238 | 217 |
239 | 218 AnswerListOfResources(call.GetOutput(), index, result, resourceType, call.HasArgument("expand"), |
240 AnswerListOfResources(call.GetOutput(), index, result, resourceType, call.HasArgument("expand")); | 219 OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human)); |
241 } | 220 } |
242 | 221 |
243 | 222 |
244 | 223 |
245 template <enum ResourceType resourceType> | 224 template <enum ResourceType resourceType> |
246 static void GetSingleResource(RestApiGetCall& call) | 225 static void GetSingleResource(RestApiGetCall& call) |
247 { | 226 { |
248 if (call.IsDocumentation()) | 227 if (call.IsDocumentation()) |
249 { | 228 { |
229 OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Human); | |
230 | |
250 const std::string resource = GetResourceTypeText(resourceType, false /* plural */, false /* lower case */); | 231 const std::string resource = GetResourceTypeText(resourceType, false /* plural */, false /* lower case */); |
251 call.GetDocumentation() | 232 call.GetDocumentation() |
252 .SetTag(GetResourceTypeText(resourceType, true /* plural */, true /* upper case */)) | 233 .SetTag(GetResourceTypeText(resourceType, true /* plural */, true /* upper case */)) |
253 .SetSummary("Get information about some " + resource) | 234 .SetSummary("Get information about some " + resource) |
254 .SetDescription("Get detailed information about the DICOM " + resource + " whose Orthanc identifier is provided in the URL") | 235 .SetDescription("Get detailed information about the DICOM " + resource + " whose Orthanc identifier is provided in the URL") |
256 .AddAnswerType(MimeType_Json, "Information about the DICOM " + resource) | 237 .AddAnswerType(MimeType_Json, "Information about the DICOM " + resource) |
257 .SetHttpGetSample(GetDocumentationSampleResource(resourceType), true); | 238 .SetHttpGetSample(GetDocumentationSampleResource(resourceType), true); |
258 return; | 239 return; |
259 } | 240 } |
260 | 241 |
242 const DicomToJsonFormat format = OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human); | |
243 | |
261 Json::Value json; | 244 Json::Value json; |
262 if (OrthancRestApi::GetIndex(call).ExpandResource(json, call.GetUriComponent("id", ""), resourceType)) | 245 if (OrthancRestApi::GetIndex(call).ExpandResource( |
246 json, call.GetUriComponent("id", ""), resourceType, format)) | |
263 { | 247 { |
264 call.GetOutput().AnswerJson(json); | 248 call.GetOutput().AnswerJson(json); |
265 } | 249 } |
266 } | 250 } |
267 | 251 |
419 call.GetOutput().AnswerBuffer("{}", MimeType_Json); | 403 call.GetOutput().AnswerBuffer("{}", MimeType_Json); |
420 } | 404 } |
421 | 405 |
422 | 406 |
423 template <DicomToJsonFormat format> | 407 template <DicomToJsonFormat format> |
424 static void GetInstanceTags(RestApiGetCall& call) | 408 static void GetInstanceTagsInternal(RestApiGetCall& call) |
425 { | 409 { |
426 if (call.IsDocumentation()) | |
427 { | |
428 if (format == DicomToJsonFormat_Human) | |
429 { | |
430 call.GetDocumentation() | |
431 .SetTag("Instances") | |
432 .SetSummary("Get human-readable tags") | |
433 .SetDescription("Get the DICOM tags in human-readable format") | |
434 .SetUriArgument("id", "Orthanc identifier of the DICOM instance of interest") | |
435 .SetHttpGetArgument("ignore-length", RestApiCallDocumentation::Type_JsonListOfStrings, | |
436 "Also include the DICOM tags that are provided in this list, even if their associated value is long", false) | |
437 .AddAnswerType(MimeType_Json, "JSON object containing the DICOM tags and their associated value") | |
438 .SetTruncatedJsonHttpGetSample("https://demo.orthanc-server.com/instances/7c92ce8e-bbf67ed2-ffa3b8c1-a3b35d94-7ff3ae26/simplified-tags", 10); | |
439 return; | |
440 } | |
441 else | |
442 { | |
443 throw OrthancException(ErrorCode_NotImplemented); | |
444 } | |
445 } | |
446 | |
447 ServerContext& context = OrthancRestApi::GetContext(call); | 410 ServerContext& context = OrthancRestApi::GetContext(call); |
448 | 411 |
449 std::string publicId = call.GetUriComponent("id", ""); | 412 std::string publicId = call.GetUriComponent("id", ""); |
450 | 413 |
451 std::set<DicomTag> ignoreTagLength; | 414 std::set<DicomTag> ignoreTagLength; |
468 call.GetOutput().AnswerJson(full); | 431 call.GetOutput().AnswerJson(full); |
469 } | 432 } |
470 } | 433 } |
471 | 434 |
472 | 435 |
473 static void GetInstanceTagsBis(RestApiGetCall& call) | 436 static void GetInstanceTags(RestApiGetCall& call) |
474 { | 437 { |
475 if (call.IsDocumentation()) | 438 if (call.IsDocumentation()) |
476 { | 439 { |
440 OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Full); | |
477 call.GetDocumentation() | 441 call.GetDocumentation() |
478 .SetTag("Instances") | 442 .SetTag("Instances") |
479 .SetSummary("Get DICOM tags") | 443 .SetSummary("Get DICOM tags") |
480 .SetDescription("Get the DICOM tags in the specified format. By default, the `full` format is used, which " | 444 .SetDescription("Get the DICOM tags in the specified format. By default, the `full` format is used, which " |
481 "combines hexadecimal tags with human-readable description.") | 445 "combines hexadecimal tags with human-readable description.") |
482 .SetUriArgument("id", "Orthanc identifier of the DICOM instance of interest") | 446 .SetUriArgument("id", "Orthanc identifier of the DICOM instance of interest") |
483 .SetHttpGetArgument("simplify", RestApiCallDocumentation::Type_String, | |
484 "If present, report the DICOM tags in human-readable format " | |
485 "(same as the `/instances/{id}/simplified-tags` route)", false) | |
486 .SetHttpGetArgument("short", RestApiCallDocumentation::Type_String, | |
487 "If present, report the DICOM tags indexed in hexadecimal format", false) | |
488 .AddAnswerType(MimeType_Json, "JSON object containing the DICOM tags and their associated value") | 447 .AddAnswerType(MimeType_Json, "JSON object containing the DICOM tags and their associated value") |
489 .SetTruncatedJsonHttpGetSample("https://demo.orthanc-server.com/instances/7c92ce8e-bbf67ed2-ffa3b8c1-a3b35d94-7ff3ae26/tags", 10); | 448 .SetTruncatedJsonHttpGetSample("https://demo.orthanc-server.com/instances/7c92ce8e-bbf67ed2-ffa3b8c1-a3b35d94-7ff3ae26/tags", 10); |
490 return; | 449 return; |
491 } | 450 } |
492 | 451 |
493 switch (GetDicomFormat(call)) | 452 switch (OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Full)) |
494 { | 453 { |
495 case DicomToJsonFormat_Human: | 454 case DicomToJsonFormat_Human: |
496 GetInstanceTags<DicomToJsonFormat_Human>(call); | 455 GetInstanceTagsInternal<DicomToJsonFormat_Human>(call); |
497 break; | 456 break; |
498 | 457 |
499 case DicomToJsonFormat_Short: | 458 case DicomToJsonFormat_Short: |
500 GetInstanceTags<DicomToJsonFormat_Short>(call); | 459 GetInstanceTagsInternal<DicomToJsonFormat_Short>(call); |
501 break; | 460 break; |
502 | 461 |
503 case DicomToJsonFormat_Full: | 462 case DicomToJsonFormat_Full: |
504 GetInstanceTags<DicomToJsonFormat_Full>(call); | 463 GetInstanceTagsInternal<DicomToJsonFormat_Full>(call); |
505 break; | 464 break; |
506 | 465 |
507 default: | 466 default: |
508 throw OrthancException(ErrorCode_InternalError); | 467 throw OrthancException(ErrorCode_InternalError); |
509 } | 468 } |
510 } | 469 } |
511 | 470 |
512 | 471 |
472 static void GetInstanceSimplifiedTags(RestApiGetCall& call) | |
473 { | |
474 if (call.IsDocumentation()) | |
475 { | |
476 call.GetDocumentation() | |
477 .SetTag("Instances") | |
478 .SetSummary("Get human-readable tags") | |
479 .SetDescription("Get the DICOM tags in human-readable format (same as the `/instances/{id}/tags?simplify` route)") | |
480 .SetUriArgument("id", "Orthanc identifier of the DICOM instance of interest") | |
481 .SetHttpGetArgument("ignore-length", RestApiCallDocumentation::Type_JsonListOfStrings, | |
482 "Also include the DICOM tags that are provided in this list, even if their associated value is long", false) | |
483 .AddAnswerType(MimeType_Json, "JSON object containing the DICOM tags and their associated value") | |
484 .SetTruncatedJsonHttpGetSample("https://demo.orthanc-server.com/instances/7c92ce8e-bbf67ed2-ffa3b8c1-a3b35d94-7ff3ae26/simplified-tags", 10); | |
485 return; | |
486 } | |
487 else | |
488 { | |
489 GetInstanceTagsInternal<DicomToJsonFormat_Human>(call); | |
490 } | |
491 } | |
492 | |
493 | |
513 static void ListFrames(RestApiGetCall& call) | 494 static void ListFrames(RestApiGetCall& call) |
514 { | 495 { |
515 if (call.IsDocumentation()) | 496 if (call.IsDocumentation()) |
516 { | 497 { |
517 call.GetDocumentation() | 498 call.GetDocumentation() |
2365 | 2346 |
2366 static void GetSharedTags(RestApiGetCall& call) | 2347 static void GetSharedTags(RestApiGetCall& call) |
2367 { | 2348 { |
2368 if (call.IsDocumentation()) | 2349 if (call.IsDocumentation()) |
2369 { | 2350 { |
2351 OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Full); | |
2352 | |
2370 ResourceType t = StringToResourceType(call.GetFullUri()[0].c_str()); | 2353 ResourceType t = StringToResourceType(call.GetFullUri()[0].c_str()); |
2371 std::string r = GetResourceTypeText(t, false /* plural */, false /* upper case */); | 2354 std::string r = GetResourceTypeText(t, false /* plural */, false /* upper case */); |
2372 call.GetDocumentation() | 2355 call.GetDocumentation() |
2373 .SetTag(GetResourceTypeText(t, true /* plural */, true /* upper case */)) | 2356 .SetTag(GetResourceTypeText(t, true /* plural */, true /* upper case */)) |
2374 .SetSummary("Get shared tags") | 2357 .SetSummary("Get shared tags") |
2385 | 2368 |
2386 Json::Value sharedTags; | 2369 Json::Value sharedTags; |
2387 if (ExtractSharedTags(sharedTags, context, publicId)) | 2370 if (ExtractSharedTags(sharedTags, context, publicId)) |
2388 { | 2371 { |
2389 // Success: Send the value of the shared tags | 2372 // Success: Send the value of the shared tags |
2390 AnswerDicomAsJson(call, sharedTags); | 2373 AnswerDicomAsJson(call, sharedTags, OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Full)); |
2391 } | 2374 } |
2392 } | 2375 } |
2393 | |
2394 | |
2395 static void GetModuleInternal(RestApiGetCall& call, | |
2396 ResourceType resourceType, | |
2397 DicomModule module) | |
2398 { | |
2399 if (!((resourceType == ResourceType_Patient && module == DicomModule_Patient) || | |
2400 (resourceType == ResourceType_Study && module == DicomModule_Patient) || | |
2401 (resourceType == ResourceType_Study && module == DicomModule_Study) || | |
2402 (resourceType == ResourceType_Series && module == DicomModule_Series) || | |
2403 (resourceType == ResourceType_Instance && module == DicomModule_Instance) || | |
2404 (resourceType == ResourceType_Instance && module == DicomModule_Image))) | |
2405 { | |
2406 throw OrthancException(ErrorCode_NotImplemented); | |
2407 } | |
2408 | |
2409 ServerContext& context = OrthancRestApi::GetContext(call); | |
2410 std::string publicId = call.GetUriComponent("id", ""); | |
2411 | |
2412 std::set<DicomTag> ignoreTagLength; | |
2413 ParseSetOfTags(ignoreTagLength, call, "ignore-length"); | |
2414 | |
2415 typedef std::set<DicomTag> ModuleTags; | |
2416 ModuleTags moduleTags; | |
2417 DicomTag::AddTagsForModule(moduleTags, module); | |
2418 | |
2419 Json::Value tags; | |
2420 | |
2421 if (resourceType != ResourceType_Instance) | |
2422 { | |
2423 // Retrieve all the instances of this patient/study/series | |
2424 typedef std::list<std::string> Instances; | |
2425 Instances instances; | |
2426 context.GetIndex().GetChildInstances(instances, publicId); | |
2427 | |
2428 if (instances.empty()) | |
2429 { | |
2430 return; // Error: No instance (should never happen) | |
2431 } | |
2432 | |
2433 // Select one child instance | |
2434 publicId = instances.front(); | |
2435 } | |
2436 | |
2437 context.ReadDicomAsJson(tags, publicId, ignoreTagLength); | |
2438 | |
2439 // Filter the tags of the instance according to the module | |
2440 Json::Value result = Json::objectValue; | |
2441 for (ModuleTags::const_iterator tag = moduleTags.begin(); tag != moduleTags.end(); ++tag) | |
2442 { | |
2443 std::string s = tag->Format(); | |
2444 if (tags.isMember(s)) | |
2445 { | |
2446 result[s] = tags[s]; | |
2447 } | |
2448 } | |
2449 | |
2450 AnswerDicomAsJson(call, result); | |
2451 } | |
2452 | |
2453 | 2376 |
2454 | 2377 |
2455 template <enum ResourceType resourceType, | 2378 template <enum ResourceType resourceType, |
2456 enum DicomModule module> | 2379 enum DicomModule module> |
2457 static void GetModule(RestApiGetCall& call) | 2380 static void GetModule(RestApiGetCall& call) |
2475 m = "instance"; | 2398 m = "instance"; |
2476 break; | 2399 break; |
2477 default: | 2400 default: |
2478 throw OrthancException(ErrorCode_ParameterOutOfRange); | 2401 throw OrthancException(ErrorCode_ParameterOutOfRange); |
2479 } | 2402 } |
2403 | |
2404 OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Full); | |
2405 | |
2480 call.GetDocumentation() | 2406 call.GetDocumentation() |
2481 .SetTag(GetResourceTypeText(resourceType, true /* plural */, true /* upper case */)) | 2407 .SetTag(GetResourceTypeText(resourceType, true /* plural */, true /* upper case */)) |
2482 .SetSummary("Get " + m + " module" + std::string(resource == m ? "" : " of " + resource)) | 2408 .SetSummary("Get " + m + " module" + std::string(resource == m ? "" : " of " + resource)) |
2483 .SetDescription("Get the " + m + " module of the DICOM " + resource + " whose Orthanc identifier is provided in the URL") | 2409 .SetDescription("Get the " + m + " module of the DICOM " + resource + " whose Orthanc identifier is provided in the URL") |
2484 .SetUriArgument("id", "Orthanc identifier of the " + resource + " of interest") | 2410 .SetUriArgument("id", "Orthanc identifier of the " + resource + " of interest") |
2487 .AddAnswerType(MimeType_Json, "Information about the DICOM " + resource) | 2413 .AddAnswerType(MimeType_Json, "Information about the DICOM " + resource) |
2488 .SetHttpGetSample(GetDocumentationSampleResource(resourceType) + "/" + (*call.GetFullUri().rbegin()), true); | 2414 .SetHttpGetSample(GetDocumentationSampleResource(resourceType) + "/" + (*call.GetFullUri().rbegin()), true); |
2489 return; | 2415 return; |
2490 } | 2416 } |
2491 | 2417 |
2492 GetModuleInternal(call, resourceType, module); | 2418 if (!((resourceType == ResourceType_Patient && module == DicomModule_Patient) || |
2419 (resourceType == ResourceType_Study && module == DicomModule_Patient) || | |
2420 (resourceType == ResourceType_Study && module == DicomModule_Study) || | |
2421 (resourceType == ResourceType_Series && module == DicomModule_Series) || | |
2422 (resourceType == ResourceType_Instance && module == DicomModule_Instance) || | |
2423 (resourceType == ResourceType_Instance && module == DicomModule_Image))) | |
2424 { | |
2425 throw OrthancException(ErrorCode_NotImplemented); | |
2426 } | |
2427 | |
2428 ServerContext& context = OrthancRestApi::GetContext(call); | |
2429 std::string publicId = call.GetUriComponent("id", ""); | |
2430 | |
2431 std::set<DicomTag> ignoreTagLength; | |
2432 ParseSetOfTags(ignoreTagLength, call, "ignore-length"); | |
2433 | |
2434 typedef std::set<DicomTag> ModuleTags; | |
2435 ModuleTags moduleTags; | |
2436 DicomTag::AddTagsForModule(moduleTags, module); | |
2437 | |
2438 Json::Value tags; | |
2439 | |
2440 if (resourceType != ResourceType_Instance) | |
2441 { | |
2442 // Retrieve all the instances of this patient/study/series | |
2443 typedef std::list<std::string> Instances; | |
2444 Instances instances; | |
2445 context.GetIndex().GetChildInstances(instances, publicId); | |
2446 | |
2447 if (instances.empty()) | |
2448 { | |
2449 return; // Error: No instance (should never happen) | |
2450 } | |
2451 | |
2452 // Select one child instance | |
2453 publicId = instances.front(); | |
2454 } | |
2455 | |
2456 context.ReadDicomAsJson(tags, publicId, ignoreTagLength); | |
2457 | |
2458 // Filter the tags of the instance according to the module | |
2459 Json::Value result = Json::objectValue; | |
2460 for (ModuleTags::const_iterator tag = moduleTags.begin(); tag != moduleTags.end(); ++tag) | |
2461 { | |
2462 std::string s = tag->Format(); | |
2463 if (tags.isMember(s)) | |
2464 { | |
2465 result[s] = tags[s]; | |
2466 } | |
2467 } | |
2468 | |
2469 AnswerDicomAsJson(call, result, OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Full)); | |
2493 } | 2470 } |
2494 | 2471 |
2495 | 2472 |
2496 namespace | 2473 namespace |
2497 { | 2474 { |
2565 class FindVisitor : public ServerContext::ILookupVisitor | 2542 class FindVisitor : public ServerContext::ILookupVisitor |
2566 { | 2543 { |
2567 private: | 2544 private: |
2568 bool isComplete_; | 2545 bool isComplete_; |
2569 std::list<std::string> resources_; | 2546 std::list<std::string> resources_; |
2547 DicomToJsonFormat format_; | |
2570 | 2548 |
2571 public: | 2549 public: |
2572 FindVisitor() : | 2550 FindVisitor(DicomToJsonFormat format) : |
2573 isComplete_(false) | 2551 isComplete_(false), |
2552 format_(format) | |
2574 { | 2553 { |
2575 } | 2554 } |
2576 | 2555 |
2577 virtual bool IsDicomAsJsonNeeded() const ORTHANC_OVERRIDE | 2556 virtual bool IsDicomAsJsonNeeded() const ORTHANC_OVERRIDE |
2578 { | 2557 { |
2595 void Answer(RestApiOutput& output, | 2574 void Answer(RestApiOutput& output, |
2596 ServerIndex& index, | 2575 ServerIndex& index, |
2597 ResourceType level, | 2576 ResourceType level, |
2598 bool expand) const | 2577 bool expand) const |
2599 { | 2578 { |
2600 AnswerListOfResources(output, index, resources_, level, expand); | 2579 AnswerListOfResources(output, index, resources_, level, expand, format_); |
2601 } | 2580 } |
2602 }; | 2581 }; |
2603 } | 2582 } |
2604 | 2583 |
2605 | 2584 |
2612 static const char* const KEY_QUERY = "Query"; | 2591 static const char* const KEY_QUERY = "Query"; |
2613 static const char* const KEY_SINCE = "Since"; | 2592 static const char* const KEY_SINCE = "Since"; |
2614 | 2593 |
2615 if (call.IsDocumentation()) | 2594 if (call.IsDocumentation()) |
2616 { | 2595 { |
2596 OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Human); | |
2597 | |
2617 call.GetDocumentation() | 2598 call.GetDocumentation() |
2618 .SetTag("System") | 2599 .SetTag("System") |
2619 .SetSummary("Look for local resources") | 2600 .SetSummary("Look for local resources") |
2620 .SetDescription("This URI can be used to perform a search on the content of the local Orthanc server, " | 2601 .SetDescription("This URI can be used to perform a search on the content of the local Orthanc server, " |
2621 "in a way that is similar to querying remote DICOM modalities using C-FIND SCU: " | 2602 "in a way that is similar to querying remote DICOM modalities using C-FIND SCU: " |
2739 query.AddRestConstraint(FromDcmtkBridge::ParseTag(members[i]), | 2720 query.AddRestConstraint(FromDcmtkBridge::ParseTag(members[i]), |
2740 value, caseSensitive, true); | 2721 value, caseSensitive, true); |
2741 } | 2722 } |
2742 } | 2723 } |
2743 | 2724 |
2744 FindVisitor visitor; | 2725 FindVisitor visitor(OrthancRestApi::GetDicomFormat(request, DicomToJsonFormat_Human)); |
2745 context.Apply(visitor, query, level, since, limit); | 2726 context.Apply(visitor, query, level, since, limit); |
2746 visitor.Answer(call.GetOutput(), context.GetIndex(), level, expand); | 2727 visitor.Answer(call.GetOutput(), context.GetIndex(), level, expand); |
2747 } | 2728 } |
2748 } | 2729 } |
2749 | 2730 |
2752 enum ResourceType end> | 2733 enum ResourceType end> |
2753 static void GetChildResources(RestApiGetCall& call) | 2734 static void GetChildResources(RestApiGetCall& call) |
2754 { | 2735 { |
2755 if (call.IsDocumentation()) | 2736 if (call.IsDocumentation()) |
2756 { | 2737 { |
2738 OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Human); | |
2739 | |
2757 const std::string children = GetResourceTypeText(end, true /* plural */, false /* lower case */); | 2740 const std::string children = GetResourceTypeText(end, true /* plural */, false /* lower case */); |
2758 const std::string resource = GetResourceTypeText(start, false /* plural */, false /* lower case */); | 2741 const std::string resource = GetResourceTypeText(start, false /* plural */, false /* lower case */); |
2759 call.GetDocumentation() | 2742 call.GetDocumentation() |
2760 .SetTag(GetResourceTypeText(start, true /* plural */, true /* upper case */)) | 2743 .SetTag(GetResourceTypeText(start, true /* plural */, true /* upper case */)) |
2761 .SetSummary("Get child " + children) | 2744 .SetSummary("Get child " + children) |
2790 a.splice(a.begin(), b); | 2773 a.splice(a.begin(), b); |
2791 } | 2774 } |
2792 | 2775 |
2793 Json::Value result = Json::arrayValue; | 2776 Json::Value result = Json::arrayValue; |
2794 | 2777 |
2778 const DicomToJsonFormat format = OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human); | |
2779 | |
2795 for (std::list<std::string>::const_iterator | 2780 for (std::list<std::string>::const_iterator |
2796 it = a.begin(); it != a.end(); ++it) | 2781 it = a.begin(); it != a.end(); ++it) |
2797 { | 2782 { |
2798 Json::Value resource; | 2783 Json::Value resource; |
2799 if (OrthancRestApi::GetIndex(call).ExpandResource(resource, *it, end)) | 2784 if (OrthancRestApi::GetIndex(call).ExpandResource(resource, *it, end, format)) |
2800 { | 2785 { |
2801 result.append(resource); | 2786 result.append(resource); |
2802 } | 2787 } |
2803 } | 2788 } |
2804 | 2789 |
2808 | 2793 |
2809 static void GetChildInstancesTags(RestApiGetCall& call) | 2794 static void GetChildInstancesTags(RestApiGetCall& call) |
2810 { | 2795 { |
2811 if (call.IsDocumentation()) | 2796 if (call.IsDocumentation()) |
2812 { | 2797 { |
2798 OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Full); | |
2799 | |
2813 ResourceType t = StringToResourceType(call.GetFullUri()[0].c_str()); | 2800 ResourceType t = StringToResourceType(call.GetFullUri()[0].c_str()); |
2814 std::string r = GetResourceTypeText(t, false /* plural */, false /* upper case */); | 2801 std::string r = GetResourceTypeText(t, false /* plural */, false /* upper case */); |
2815 call.GetDocumentation() | 2802 call.GetDocumentation() |
2816 .SetTag(GetResourceTypeText(t, true /* plural */, true /* upper case */)) | 2803 .SetTag(GetResourceTypeText(t, true /* plural */, true /* upper case */)) |
2817 .SetSummary("Get tags of instances") | 2804 .SetSummary("Get tags of instances") |
2825 return; | 2812 return; |
2826 } | 2813 } |
2827 | 2814 |
2828 ServerContext& context = OrthancRestApi::GetContext(call); | 2815 ServerContext& context = OrthancRestApi::GetContext(call); |
2829 std::string publicId = call.GetUriComponent("id", ""); | 2816 std::string publicId = call.GetUriComponent("id", ""); |
2830 DicomToJsonFormat format = GetDicomFormat(call); | 2817 DicomToJsonFormat format = OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Full); |
2831 | 2818 |
2832 std::set<DicomTag> ignoreTagLength; | 2819 std::set<DicomTag> ignoreTagLength; |
2833 ParseSetOfTags(ignoreTagLength, call, "ignore-length"); | 2820 ParseSetOfTags(ignoreTagLength, call, "ignore-length"); |
2834 | 2821 |
2835 // Retrieve all the instances of this patient/study/series | 2822 // Retrieve all the instances of this patient/study/series |
2869 { | 2856 { |
2870 assert(start > end); | 2857 assert(start > end); |
2871 | 2858 |
2872 if (call.IsDocumentation()) | 2859 if (call.IsDocumentation()) |
2873 { | 2860 { |
2861 OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Human); | |
2862 | |
2874 const std::string parent = GetResourceTypeText(end, false /* plural */, false /* lower case */); | 2863 const std::string parent = GetResourceTypeText(end, false /* plural */, false /* lower case */); |
2875 const std::string resource = GetResourceTypeText(start, false /* plural */, false /* lower case */); | 2864 const std::string resource = GetResourceTypeText(start, false /* plural */, false /* lower case */); |
2876 call.GetDocumentation() | 2865 call.GetDocumentation() |
2877 .SetTag(GetResourceTypeText(start, true /* plural */, true /* upper case */)) | 2866 .SetTag(GetResourceTypeText(start, true /* plural */, true /* upper case */)) |
2878 .SetSummary("Get parent " + parent) | 2867 .SetSummary("Get parent " + parent) |
2902 currentType = GetParentResourceType(currentType); | 2891 currentType = GetParentResourceType(currentType); |
2903 } | 2892 } |
2904 | 2893 |
2905 assert(currentType == end); | 2894 assert(currentType == end); |
2906 | 2895 |
2896 const DicomToJsonFormat format = OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human); | |
2897 | |
2907 Json::Value resource; | 2898 Json::Value resource; |
2908 if (OrthancRestApi::GetIndex(call).ExpandResource(resource, current, end)) | 2899 if (OrthancRestApi::GetIndex(call).ExpandResource(resource, current, end, format)) |
2909 { | 2900 { |
2910 call.GetOutput().AnswerJson(resource); | 2901 call.GetOutput().AnswerJson(resource); |
2911 } | 2902 } |
2912 } | 2903 } |
2913 | 2904 |
2976 | 2967 |
2977 static void GetInstanceHeader(RestApiGetCall& call) | 2968 static void GetInstanceHeader(RestApiGetCall& call) |
2978 { | 2969 { |
2979 if (call.IsDocumentation()) | 2970 if (call.IsDocumentation()) |
2980 { | 2971 { |
2972 OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Full); | |
2981 call.GetDocumentation() | 2973 call.GetDocumentation() |
2982 .SetTag("Instances") | 2974 .SetTag("Instances") |
2983 .SetSummary("Get DICOM meta-header") | 2975 .SetSummary("Get DICOM meta-header") |
2984 .SetDescription("Get the DICOM tags in the meta-header of the DICOM instance. By default, the `full` format is used, which " | 2976 .SetDescription("Get the DICOM tags in the meta-header of the DICOM instance. By default, the `full` format is used, which " |
2985 "combines hexadecimal tags with human-readable description.") | 2977 "combines hexadecimal tags with human-readable description.") |
2986 .SetUriArgument("id", "Orthanc identifier of the DICOM instance of interest") | 2978 .SetUriArgument("id", "Orthanc identifier of the DICOM instance of interest") |
2987 .SetHttpGetArgument("simplify", RestApiCallDocumentation::Type_String, | |
2988 "If present, report the DICOM tags in human-readable format", false) | |
2989 .SetHttpGetArgument("short", RestApiCallDocumentation::Type_String, | |
2990 "If present, report the DICOM tags indexed in hexadecimal format", false) | |
2991 .AddAnswerType(MimeType_Json, "JSON object containing the DICOM tags and their associated value") | 2979 .AddAnswerType(MimeType_Json, "JSON object containing the DICOM tags and their associated value") |
2992 .SetHttpGetSample("https://demo.orthanc-server.com/instances/7c92ce8e-bbf67ed2-ffa3b8c1-a3b35d94-7ff3ae26/header", true); | 2980 .SetHttpGetSample("https://demo.orthanc-server.com/instances/7c92ce8e-bbf67ed2-ffa3b8c1-a3b35d94-7ff3ae26/header", true); |
2993 return; | 2981 return; |
2994 } | 2982 } |
2995 | 2983 |
3006 ParsedDicomFile dicom(dicomContent); | 2994 ParsedDicomFile dicom(dicomContent); |
3007 | 2995 |
3008 Json::Value header; | 2996 Json::Value header; |
3009 OrthancConfiguration::DefaultDicomHeaderToJson(header, dicom); | 2997 OrthancConfiguration::DefaultDicomHeaderToJson(header, dicom); |
3010 | 2998 |
3011 AnswerDicomAsJson(call, header); | 2999 AnswerDicomAsJson(call, header, OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Full)); |
3012 } | 3000 } |
3013 | 3001 |
3014 | 3002 |
3015 static void InvalidateTags(RestApiPostCall& call) | 3003 static void InvalidateTags(RestApiPostCall& call) |
3016 { | 3004 { |
3181 Register("/studies/{id}/module", GetModule<ResourceType_Study, DicomModule_Study>); | 3169 Register("/studies/{id}/module", GetModule<ResourceType_Study, DicomModule_Study>); |
3182 Register("/studies/{id}/module-patient", GetModule<ResourceType_Study, DicomModule_Patient>); | 3170 Register("/studies/{id}/module-patient", GetModule<ResourceType_Study, DicomModule_Patient>); |
3183 | 3171 |
3184 Register("/instances/{id}/file", GetInstanceFile); | 3172 Register("/instances/{id}/file", GetInstanceFile); |
3185 Register("/instances/{id}/export", ExportInstanceFile); | 3173 Register("/instances/{id}/export", ExportInstanceFile); |
3186 Register("/instances/{id}/tags", GetInstanceTagsBis); | 3174 Register("/instances/{id}/tags", GetInstanceTags); |
3187 Register("/instances/{id}/simplified-tags", GetInstanceTags<DicomToJsonFormat_Human>); | 3175 Register("/instances/{id}/simplified-tags", GetInstanceSimplifiedTags); |
3188 Register("/instances/{id}/frames", ListFrames); | 3176 Register("/instances/{id}/frames", ListFrames); |
3189 | 3177 |
3190 Register("/instances/{id}/frames/{frame}", RestApi::AutoListChildren); | 3178 Register("/instances/{id}/frames/{frame}", RestApi::AutoListChildren); |
3191 Register("/instances/{id}/frames/{frame}/preview", GetImage<ImageExtractionMode_Preview>); | 3179 Register("/instances/{id}/frames/{frame}/preview", GetImage<ImageExtractionMode_Preview>); |
3192 Register("/instances/{id}/frames/{frame}/rendered", GetRenderedFrame); | 3180 Register("/instances/{id}/frames/{frame}/rendered", GetRenderedFrame); |