Mercurial > hg > orthanc
comparison OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp @ 4935:acd3f72e2a21 more-tags
split ExpandResource in 2: read from DB and serialize to json. This will allow us to merge requested tags from both the DB and the file system
author | Alain Mazy <am@osimis.io> |
---|---|
date | Thu, 10 Mar 2022 19:00:43 +0100 |
parents | df86d2505df8 |
children | 8422e4f99a18 |
comparison
equal
deleted
inserted
replaced
4934:94a7b681b340 | 4935:acd3f72e2a21 |
---|---|
124 | 124 |
125 | 125 |
126 // List all the patients, studies, series or instances ---------------------- | 126 // List all the patients, studies, series or instances ---------------------- |
127 | 127 |
128 static void AnswerListOfResources(RestApiOutput& output, | 128 static void AnswerListOfResources(RestApiOutput& output, |
129 ServerIndex& index, | 129 ServerContext& context, |
130 const std::list<std::string>& resources, | 130 const std::list<std::string>& resources, |
131 ResourceType level, | 131 ResourceType level, |
132 bool expand, | 132 bool expand, |
133 DicomToJsonFormat format) | 133 DicomToJsonFormat format) |
134 { | 134 { |
138 resource = resources.begin(); resource != resources.end(); ++resource) | 138 resource = resources.begin(); resource != resources.end(); ++resource) |
139 { | 139 { |
140 if (expand) | 140 if (expand) |
141 { | 141 { |
142 Json::Value expanded; | 142 Json::Value expanded; |
143 if (index.ExpandResource(expanded, *resource, level, format)) | 143 if (context.ExpandResource(expanded, *resource, level, format)) |
144 { | 144 { |
145 answer.append(expanded); | 145 answer.append(expanded); |
146 } | 146 } |
147 } | 147 } |
148 else | 148 else |
176 .SetHttpGetSample("https://demo.orthanc-server.com/" + resources + "?since=0&limit=2", true); | 176 .SetHttpGetSample("https://demo.orthanc-server.com/" + resources + "?since=0&limit=2", true); |
177 return; | 177 return; |
178 } | 178 } |
179 | 179 |
180 ServerIndex& index = OrthancRestApi::GetIndex(call); | 180 ServerIndex& index = OrthancRestApi::GetIndex(call); |
181 ServerContext& context = OrthancRestApi::GetContext(call); | |
181 | 182 |
182 std::list<std::string> result; | 183 std::list<std::string> result; |
183 | 184 |
184 if (call.HasArgument("limit") || | 185 if (call.HasArgument("limit") || |
185 call.HasArgument("since")) | 186 call.HasArgument("since")) |
205 else | 206 else |
206 { | 207 { |
207 index.GetAllUuids(result, resourceType); | 208 index.GetAllUuids(result, resourceType); |
208 } | 209 } |
209 | 210 |
210 AnswerListOfResources(call.GetOutput(), index, result, resourceType, call.HasArgument("expand"), | 211 AnswerListOfResources(call.GetOutput(), context, result, resourceType, call.HasArgument("expand"), |
211 OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human)); | 212 OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human)); |
212 } | 213 } |
213 | 214 |
214 | 215 |
215 | 216 |
224 call.GetDocumentation() | 225 call.GetDocumentation() |
225 .SetTag(GetResourceTypeText(resourceType, true /* plural */, true /* upper case */)) | 226 .SetTag(GetResourceTypeText(resourceType, true /* plural */, true /* upper case */)) |
226 .SetSummary("Get information about some " + resource) | 227 .SetSummary("Get information about some " + resource) |
227 .SetDescription("Get detailed information about the DICOM " + resource + " whose Orthanc identifier is provided in the URL") | 228 .SetDescription("Get detailed information about the DICOM " + resource + " whose Orthanc identifier is provided in the URL") |
228 .SetUriArgument("id", "Orthanc identifier of the " + resource + " of interest") | 229 .SetUriArgument("id", "Orthanc identifier of the " + resource + " of interest") |
230 .SetHttpGetArgument("requestedTags", RestApiCallDocumentation::Type_String, | |
231 "If present, list the DICOM Tags you want to list in the response. This argument is a semi-column separated list " | |
232 "of DICOM Tags identifiers; e.g: 'requestedTags=0010,0010;PatientBirthDate'. " | |
233 "The tags requested tags are returned in the 'RequestedTags' field in the response. " | |
234 "Note that, if you are requesting tags that are not listed in the Main Dicom Tags stored in DB, building the response " | |
235 "might be slow since Orthanc will need to access the DICOM files. If not specified, Orthanc will return ", false) | |
229 .AddAnswerType(MimeType_Json, "Information about the DICOM " + resource) | 236 .AddAnswerType(MimeType_Json, "Information about the DICOM " + resource) |
230 .SetHttpGetSample(GetDocumentationSampleResource(resourceType), true); | 237 .SetHttpGetSample(GetDocumentationSampleResource(resourceType), true); |
231 return; | 238 return; |
232 } | 239 } |
233 | 240 |
234 const DicomToJsonFormat format = OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human); | 241 const DicomToJsonFormat format = OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human); |
235 | 242 |
243 std::set<DicomTag> responseTags; | |
244 if (call.HasArgument("requestedTags")) | |
245 { | |
246 try | |
247 { | |
248 FromDcmtkBridge::ParseListOfTags(responseTags, call.GetArgument("requestedTags", "")); | |
249 } | |
250 catch (OrthancException& ex) | |
251 { | |
252 throw OrthancException(ErrorCode_BadRequest, std::string("Invalid requestedTags argument: ") + ex.What() + " " + ex.GetDetails()); | |
253 } | |
254 } | |
255 | |
236 Json::Value json; | 256 Json::Value json; |
237 if (OrthancRestApi::GetIndex(call).ExpandResource( | 257 if (OrthancRestApi::GetContext(call).ExpandResource( |
238 json, call.GetUriComponent("id", ""), resourceType, format)) | 258 json, call.GetUriComponent("id", ""), resourceType, format)) // TODO, requestedTags)) |
239 { | 259 { |
240 call.GetOutput().AnswerJson(json); | 260 call.GetOutput().AnswerJson(json); |
241 } | 261 } |
242 } | 262 } |
243 | 263 |
2843 { | 2863 { |
2844 resources_.push_back(publicId); | 2864 resources_.push_back(publicId); |
2845 } | 2865 } |
2846 | 2866 |
2847 void Answer(RestApiOutput& output, | 2867 void Answer(RestApiOutput& output, |
2848 ServerIndex& index, | 2868 ServerContext& context, |
2849 ResourceType level, | 2869 ResourceType level, |
2850 bool expand) const | 2870 bool expand) const |
2851 { | 2871 { |
2852 AnswerListOfResources(output, index, resources_, level, expand, format_); | 2872 AnswerListOfResources(output, context, resources_, level, expand, format_); |
2853 } | 2873 } |
2854 }; | 2874 }; |
2855 } | 2875 } |
2856 | 2876 |
2857 | 2877 |
2860 static const char* const KEY_CASE_SENSITIVE = "CaseSensitive"; | 2880 static const char* const KEY_CASE_SENSITIVE = "CaseSensitive"; |
2861 static const char* const KEY_EXPAND = "Expand"; | 2881 static const char* const KEY_EXPAND = "Expand"; |
2862 static const char* const KEY_LEVEL = "Level"; | 2882 static const char* const KEY_LEVEL = "Level"; |
2863 static const char* const KEY_LIMIT = "Limit"; | 2883 static const char* const KEY_LIMIT = "Limit"; |
2864 static const char* const KEY_QUERY = "Query"; | 2884 static const char* const KEY_QUERY = "Query"; |
2885 static const char* const KEY_REQUESTED_TAGS = "RequestedTags"; | |
2865 static const char* const KEY_SINCE = "Since"; | 2886 static const char* const KEY_SINCE = "Since"; |
2866 | 2887 |
2867 if (call.IsDocumentation()) | 2888 if (call.IsDocumentation()) |
2868 { | 2889 { |
2869 OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Human); | 2890 OrthancRestApi::DocumentDicomFormat(call, DicomToJsonFormat_Human); |
2882 "Level of the query (`Patient`, `Study`, `Series` or `Instance`)", true) | 2903 "Level of the query (`Patient`, `Study`, `Series` or `Instance`)", true) |
2883 .SetRequestField(KEY_LIMIT, RestApiCallDocumentation::Type_Number, | 2904 .SetRequestField(KEY_LIMIT, RestApiCallDocumentation::Type_Number, |
2884 "Limit the number of reported resources", false) | 2905 "Limit the number of reported resources", false) |
2885 .SetRequestField(KEY_SINCE, RestApiCallDocumentation::Type_Number, | 2906 .SetRequestField(KEY_SINCE, RestApiCallDocumentation::Type_Number, |
2886 "Show only the resources since the provided index (in conjunction with `Limit`)", false) | 2907 "Show only the resources since the provided index (in conjunction with `Limit`)", false) |
2908 .SetRequestField(KEY_REQUESTED_TAGS, RestApiCallDocumentation::Type_JsonListOfStrings, | |
2909 "A list of DICOM tags to include in the response (applicable only if \"Expand\" is set to true). " | |
2910 "The tags requested tags are returned in the 'RequestedTags' field in the response. " | |
2911 "Note that, if you are requesting tags that are not listed in the Main Dicom Tags stored in DB, building the response " | |
2912 "might be slow since Orthanc will need to access the DICOM files. If not specified, Orthanc will return " | |
2913 "all Main Dicom Tags to keep backward compatibility with Orthanc prior to 1.11.0.", false) | |
2914 | |
2887 .SetRequestField(KEY_QUERY, RestApiCallDocumentation::Type_JsonObject, | 2915 .SetRequestField(KEY_QUERY, RestApiCallDocumentation::Type_JsonObject, |
2888 "Associative array containing the filter on the values of the DICOM tags", true) | 2916 "Associative array containing the filter on the values of the DICOM tags", true) |
2889 .AddAnswerType(MimeType_Json, "JSON array containing either the Orthanc identifiers, or detailed information " | 2917 .AddAnswerType(MimeType_Json, "JSON array containing either the Orthanc identifiers, or detailed information " |
2890 "about the reported resources (if `Expand` argument is `true`)"); | 2918 "about the reported resources (if `Expand` argument is `true`)"); |
2891 return; | 2919 return; |
2892 } | 2920 } |
2893 | 2921 |
2894 ServerContext& context = OrthancRestApi::GetContext(call); | 2922 ServerContext& context = OrthancRestApi::GetContext(call); |
2923 | |
2924 // MORE_TAGS: TODO: handle RequestedTags | |
2895 | 2925 |
2896 Json::Value request; | 2926 Json::Value request; |
2897 if (!call.ParseJsonRequest(request) || | 2927 if (!call.ParseJsonRequest(request) || |
2898 request.type() != Json::objectValue) | 2928 request.type() != Json::objectValue) |
2899 { | 2929 { |
2995 } | 3025 } |
2996 } | 3026 } |
2997 | 3027 |
2998 FindVisitor visitor(OrthancRestApi::GetDicomFormat(request, DicomToJsonFormat_Human)); | 3028 FindVisitor visitor(OrthancRestApi::GetDicomFormat(request, DicomToJsonFormat_Human)); |
2999 context.Apply(visitor, query, level, since, limit); | 3029 context.Apply(visitor, query, level, since, limit); |
3000 visitor.Answer(call.GetOutput(), context.GetIndex(), level, expand); | 3030 visitor.Answer(call.GetOutput(), context, level, expand); |
3001 } | 3031 } |
3002 } | 3032 } |
3003 | 3033 |
3004 | 3034 |
3005 template <enum ResourceType start, | 3035 template <enum ResourceType start, |
3052 | 3082 |
3053 for (std::list<std::string>::const_iterator | 3083 for (std::list<std::string>::const_iterator |
3054 it = a.begin(); it != a.end(); ++it) | 3084 it = a.begin(); it != a.end(); ++it) |
3055 { | 3085 { |
3056 Json::Value resource; | 3086 Json::Value resource; |
3057 if (OrthancRestApi::GetIndex(call).ExpandResource(resource, *it, end, format)) | 3087 if (OrthancRestApi::GetContext(call).ExpandResource(resource, *it, end, format)) |
3058 { | 3088 { |
3059 result.append(resource); | 3089 result.append(resource); |
3060 } | 3090 } |
3061 } | 3091 } |
3062 | 3092 |
3167 assert(currentType == end); | 3197 assert(currentType == end); |
3168 | 3198 |
3169 const DicomToJsonFormat format = OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human); | 3199 const DicomToJsonFormat format = OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human); |
3170 | 3200 |
3171 Json::Value resource; | 3201 Json::Value resource; |
3172 if (OrthancRestApi::GetIndex(call).ExpandResource(resource, current, end, format)) | 3202 if (OrthancRestApi::GetContext(call).ExpandResource(resource, current, end, format)) |
3173 { | 3203 { |
3174 call.GetOutput().AnswerJson(resource); | 3204 call.GetOutput().AnswerJson(resource); |
3175 } | 3205 } |
3176 } | 3206 } |
3177 | 3207 |
3539 | 3569 |
3540 for (std::set<std::string>::const_iterator | 3570 for (std::set<std::string>::const_iterator |
3541 it = interest.begin(); it != interest.end(); ++it) | 3571 it = interest.begin(); it != interest.end(); ++it) |
3542 { | 3572 { |
3543 Json::Value item; | 3573 Json::Value item; |
3544 if (index.ExpandResource(item, *it, level, format)) | 3574 if (OrthancRestApi::GetContext(call).ExpandResource(item, *it, level, format)) |
3545 { | 3575 { |
3546 if (metadata) | 3576 if (metadata) |
3547 { | 3577 { |
3548 AddMetadata(item[METADATA], index, *it, level); | 3578 AddMetadata(item[METADATA], index, *it, level); |
3549 } | 3579 } |
3562 it = resources.begin(); it != resources.end(); ++it) | 3592 it = resources.begin(); it != resources.end(); ++it) |
3563 { | 3593 { |
3564 ResourceType level; | 3594 ResourceType level; |
3565 Json::Value item; | 3595 Json::Value item; |
3566 if (index.LookupResourceType(level, *it) && | 3596 if (index.LookupResourceType(level, *it) && |
3567 index.ExpandResource(item, *it, level, format)) | 3597 OrthancRestApi::GetContext(call).ExpandResource(item, *it, level, format)) |
3568 { | 3598 { |
3569 if (metadata) | 3599 if (metadata) |
3570 { | 3600 { |
3571 AddMetadata(item[METADATA], index, *it, level); | 3601 AddMetadata(item[METADATA], index, *it, level); |
3572 } | 3602 } |