From d5e00817d730be4d21634f693f2f0d9ded0ca9c9 Mon Sep 17 00:00:00 2001 From: Zaid Safadi Date: Mon, 21 Nov 2022 21:40:52 +0000 Subject: [PATCH] fix: update DicomJSONDataSource to support directURL method (#3018) --- .../default/src/DicomJSONDataSource/index.js | 21 ++++- .../default/src/DicomWebDataSource/index.js | 65 +------------- extensions/default/src/utils/getDirectURL.js | 85 +++++++++++++++++++ 3 files changed, 108 insertions(+), 63 deletions(-) create mode 100644 extensions/default/src/utils/getDirectURL.js diff --git a/extensions/default/src/DicomJSONDataSource/index.js b/extensions/default/src/DicomJSONDataSource/index.js index ee5eba5d4..faf120985 100644 --- a/extensions/default/src/DicomJSONDataSource/index.js +++ b/extensions/default/src/DicomJSONDataSource/index.js @@ -2,6 +2,7 @@ import { DicomMetadataStore, IWebApiDataSource } from '@ohif/core'; import OHIF from '@ohif/core'; import getImageId from '../DicomWebDataSource/utils/getImageId'; +import getDirectURL from '../utils/getDirectURL'; const metadataProvider = OHIF.classes.MetadataProvider; @@ -40,7 +41,7 @@ const findStudies = (key, value) => { }; function createDicomJSONApi(dicomJsonConfig) { - const { name } = dicomJsonConfig; + const { name, wadoRoot } = dicomJsonConfig; const implementation = { initialize: async ({ params, query, url }) => { @@ -93,7 +94,7 @@ function createDicomJSONApi(dicomJsonConfig) { }, query: { studies: { - mapParams: () => {}, + mapParams: () => { }, search: async param => { const [key, value] = Object.entries(param)[0]; const mappedParam = mappings[key]; @@ -133,6 +134,22 @@ function createDicomJSONApi(dicomJsonConfig) { }, }, retrieve: { + /** + * Generates a URL that can be used for direct retrieve of the bulkdata + * + * @param {object} params + * @param {string} params.tag is the tag name of the URL to retrieve + * @param {string} params.defaultPath path for the pixel data url + * @param {object} params.instance is the instance object that the tag is in + * @param {string} params.defaultType is the mime type of the response + * @param {string} params.singlepart is the type of the part to retrieve + * @param {string} params.fetchPart unknown? + * @returns an absolute URL to the resource, if the absolute URL can be retrieved as singlepart, + * or is already retrieved, or a promise to a URL for such use if a BulkDataURI + */ + directURL: params => { + return getDirectURL(wadoRoot, params); + }, series: { metadata: ({ StudyInstanceUID, diff --git a/extensions/default/src/DicomWebDataSource/index.js b/extensions/default/src/DicomWebDataSource/index.js index 36c6cc1da..e51c7fd01 100644 --- a/extensions/default/src/DicomWebDataSource/index.js +++ b/extensions/default/src/DicomWebDataSource/index.js @@ -23,6 +23,7 @@ import { deleteStudyMetadataPromise, } from './retrieveStudyMetadata.js'; import StaticWadoClient from './utils/StaticWadoClient.js'; +import getDirectURL from '../utils/getDirectURL.js'; const { DicomMetaDictionary, DicomDict } = dcmjs.data; @@ -103,7 +104,7 @@ function createDicomWebApi(dicomWebConfig, UserAuthenticationService) { query: { studies: { mapParams: mapParams.bind(), - search: async function(origParams) { + search: async function (origParams) { const headers = UserAuthenticationService.getAuthorizationHeader(); if (headers) { qidoDicomWebClient.headers = headers; @@ -128,7 +129,7 @@ function createDicomWebApi(dicomWebConfig, UserAuthenticationService) { }, series: { // mapParams: mapParams.bind(), - search: async function(studyInstanceUid) { + search: async function (studyInstanceUid) { const headers = UserAuthenticationService.getAuthorizationHeader(); if (headers) { qidoDicomWebClient.headers = headers; @@ -173,65 +174,7 @@ function createDicomWebApi(dicomWebConfig, UserAuthenticationService) { * or is already retrieved, or a promise to a URL for such use if a BulkDataURI */ directURL: params => { - const { - instance, - tag = 'PixelData', - defaultPath = '/pixeldata', - defaultType = 'video/mp4', - singlepart: fetchPart = 'video', - } = params; - const value = instance[tag]; - if (!value) return undefined; - - if (value.DirectRetrieveURL) return value.DirectRetrieveURL; - if (value.InlineBinary) { - const blob = utils.b64toBlob(value.InlineBinary, defaultType); - value.DirectRetrieveURL = URL.createObjectURL(blob); - return value.DirectRetrieveURL; - } - if ( - !singlepart || - (singlepart !== true && singlepart.indexOf(fetchPart) === -1) - ) { - if (value.retrieveBulkData) { - return value.retrieveBulkData().then(arr => { - value.DirectRetrieveURL = URL.createObjectURL( - new Blob([arr], { type: defaultType }) - ); - return value.DirectRetrieveURL; - }); - } - console.warn('Unable to retrieve', tag, 'from', instance); - return undefined; - } - - const { - StudyInstanceUID, - SeriesInstanceUID, - SOPInstanceUID, - } = instance; - const BulkDataURI = - (value && value.BulkDataURI) || - `series/${SeriesInstanceUID}/instances/${SOPInstanceUID}${defaultPath}`; - const hasQuery = BulkDataURI.indexOf('?') != -1; - const hasAccept = BulkDataURI.indexOf('accept=') != -1; - const acceptUri = - BulkDataURI + - (hasAccept ? '' : (hasQuery ? '&' : '?') + `accept=${defaultType}`); - if (BulkDataURI.indexOf('http') === 0) return acceptUri; - if (BulkDataURI.indexOf('/') === 0) { - return wadoRoot + acceptUri; - } - if (BulkDataURI.indexOf('series/') == 0) { - return `${wadoRoot}/studies/${StudyInstanceUID}/${acceptUri}`; - } - if (BulkDataURI.indexOf('instances/') === 0) { - return `${wadoRoot}/studies/${StudyInstanceUID}/series/${SeriesInstanceUID}/${acceptUri}`; - } - if (BulkDataURI.indexOf('bulkdata/') === 0) { - return `${wadoRoot}/studies/${StudyInstanceUID}/${acceptUri}`; - } - throw new Error('BulkDataURI in unknown format:' + BulkDataURI); + return getDirectURL(wadoRoot, params); }, series: { metadata: async ({ diff --git a/extensions/default/src/utils/getDirectURL.js b/extensions/default/src/utils/getDirectURL.js new file mode 100644 index 000000000..e90ff17af --- /dev/null +++ b/extensions/default/src/utils/getDirectURL.js @@ -0,0 +1,85 @@ +import { + DicomMetadataStore, + IWebApiDataSource, + utils, + errorHandler, + classes, +} from '@ohif/core'; + +/** + * Generates a URL that can be used for direct retrieve of the bulkdata + * + * @param {object} params + * @param {string} params.tag is the tag name of the URL to retrieve + * @param {string} params.defaultPath path for the pixel data url + * @param {object} params.instance is the instance object that the tag is in + * @param {string} params.defaultType is the mime type of the response + * @param {string} params.singlepart is the type of the part to retrieve + * @param {string} params.fetchPart unknown? + * @returns an absolute URL to the resource, if the absolute URL can be retrieved as singlepart, + * or is already retrieved, or a promise to a URL for such use if a BulkDataURI + */ +const getDirectURL = (wadoRoot, params) => { + const { + instance, + tag = 'PixelData', + defaultPath = '/pixeldata', + defaultType = 'video/mp4', + singlepart = null, + singlepart: fetchPart = 'video', + } = params; + const value = instance[tag]; + if (!value) return undefined; + + if (value.DirectRetrieveURL) return value.DirectRetrieveURL; + if (value.InlineBinary) { + const blob = utils.b64toBlob(value.InlineBinary, defaultType); + value.DirectRetrieveURL = URL.createObjectURL(blob); + return value.DirectRetrieveURL; + } + if ( + !singlepart || + (singlepart !== true && singlepart.indexOf(fetchPart) === -1) + ) { + if (value.retrieveBulkData) { + return value.retrieveBulkData().then(arr => { + value.DirectRetrieveURL = URL.createObjectURL( + new Blob([arr], { type: defaultType }) + ); + return value.DirectRetrieveURL; + }); + } + console.warn('Unable to retrieve', tag, 'from', instance); + return undefined; + } + + const { + StudyInstanceUID, + SeriesInstanceUID, + SOPInstanceUID, + } = instance; + const BulkDataURI = + (value && value.BulkDataURI) || + `series/${SeriesInstanceUID}/instances/${SOPInstanceUID}${defaultPath}`; + const hasQuery = BulkDataURI.indexOf('?') != -1; + const hasAccept = BulkDataURI.indexOf('accept=') != -1; + const acceptUri = + BulkDataURI + + (hasAccept ? '' : (hasQuery ? '&' : '?') + `accept=${defaultType}`); + if (BulkDataURI.indexOf('http') === 0) return acceptUri; + if (BulkDataURI.indexOf('/') === 0) { + return wadoRoot + acceptUri; + } + if (BulkDataURI.indexOf('series/') == 0) { + return `${wadoRoot}/studies/${StudyInstanceUID}/${acceptUri}`; + } + if (BulkDataURI.indexOf('instances/') === 0) { + return `${wadoRoot}/studies/${StudyInstanceUID}/series/${SeriesInstanceUID}/${acceptUri}`; + } + if (BulkDataURI.indexOf('bulkdata/') === 0) { + return `${wadoRoot}/studies/${StudyInstanceUID}/${acceptUri}`; + } + throw new Error('BulkDataURI in unknown format:' + BulkDataURI); +}; + +export default getDirectURL;