Feat/1746 idc dev tool (#1778)

* feat: Create downloadAndUploadStudy method

* create upload handler to store instances in another server

* refactor and create reusable method to download buffers

* fix: e2e studies amount searching by Modality

* fix destructuring

* fix dataset and log info

* split instances to send multiple storeInstances calls

* minor refactor progress

* fix e2e

* replace error message for upload

Co-authored-by: James Petts <jamesapetts@gmail.com>
This commit is contained in:
Rodrigo Antinarelli 2020-06-18 05:59:07 -03:00 committed by GitHub
parent 4ede8a525a
commit b4627ecfa3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 12 deletions

View File

@ -1,17 +1,16 @@
import OHIF from '@ohif/core'; import OHIF from '@ohif/core';
import { import {
save, save,
upload,
getDicomWebClientFromContext, getDicomWebClientFromContext,
getStudyInstanceUIDFromStudies, getStudyInstanceUIDFromStudies,
getSOPInstanceReferenceFromActiveViewport, getSOPInstanceReferenceFromActiveViewport,
getSOPInstanceReferencesFromViewports, getSOPInstanceReferencesFromViewports,
} from './utils'; } from './utils';
import _downloadAndZip from './downloadAndZip'; import _downloadAndZip, { downloadInstances } from './downloadAndZip';
const { const {
utils: { utils: { Queue },
Queue,
},
} = OHIF; } = OHIF;
export function getCommands(context) { export function getCommands(context) {
@ -66,6 +65,28 @@ export function getCommands(context) {
listOfUIDs listOfUIDs
); );
}, },
downloadAndUploadStudy({ servers, studies, progress, serverConfig }) {
const dicomWebClient = getDicomWebClientFromContext(context, servers);
const listOfUIDs = getStudyInstanceUIDFromStudies(studies);
return upload(
downloadInstances(dicomWebClient, listOfUIDs, { progress }),
/**
* serverConfig is an object with the values used to create a new
* instance of DICOMwebClient.
*
* Basic Structure:
*
* const config = {
* url,
* headers,
* errorInterceptor
* }
*
* const dicomWeb = new api.DICOMwebClient(config);
*/
serverConfig
);
},
}; };
const definitions = { const definitions = {
@ -91,6 +112,11 @@ export function getCommands(context) {
storeContexts: ['servers', 'viewports'], storeContexts: ['servers', 'viewports'],
options: { progress }, options: { progress },
}, },
downloadAndUploadStudy: {
commandFn: queue.bindSafe(actions.downloadAndUploadStudy, error),
storeContexts: ['servers', 'studies'],
options: { progress },
},
}; };
return { return {

View File

@ -78,6 +78,25 @@ const {
async function downloadAndZip(dicomWebClient, listOfUIDs, options) { async function downloadAndZip(dicomWebClient, listOfUIDs, options) {
if (dicomWebClient instanceof api.DICOMwebClient) { if (dicomWebClient instanceof api.DICOMwebClient) {
const settings = buildSettings(listOfUIDs, options); const settings = buildSettings(listOfUIDs, options);
const { compression } = settings.tasks;
const buffers = await downloadBuffers(settings, dicomWebClient);
compression.deferred.resolve(zipAll(buffers, settings));
const url = await compression.deferred.promise;
return url;
}
throw new Error('A valid DICOM Web Client instance is expected');
}
async function downloadInstances(dicomWebClient, listOfUIDs, options) {
if (dicomWebClient instanceof api.DICOMwebClient) {
const settings = buildSettings(listOfUIDs, options);
const buffers = await downloadBuffers(settings, dicomWebClient);
return buffers;
}
throw new Error('A valid DICOM Web Client instance is expected');
}
async function downloadBuffers(settings, dicomWebClient) {
const { compression } = settings.tasks; const { compression } = settings.tasks;
// Register user-provided progress handler as a task list observer // Register user-provided progress handler as a task list observer
progressUtils.addObserver(settings.taskList, settings.options.progress); progressUtils.addObserver(settings.taskList, settings.options.progress);
@ -86,11 +105,7 @@ async function downloadAndZip(dicomWebClient, listOfUIDs, options) {
compression.deferred.reject(error); compression.deferred.reject(error);
throw error; throw error;
}); });
compression.deferred.resolve(zipAll(buffers, settings)); return buffers;
const url = await compression.deferred.promise;
return url;
}
throw new Error('A valid DICOM Web Client instance is expected');
} }
/** /**
@ -241,4 +256,4 @@ async function download(
* Exports * Exports
*/ */
export { downloadAndZip as default, downloadAndZip }; export { downloadAndZip as default, downloadAndZip, downloadInstances };

View File

@ -100,12 +100,55 @@ function save(promise, listOfUIDs) {
}); });
} }
function upload(promise, serverConfig) {
return Promise.resolve(promise)
.then(async instances => {
const instancesAmount = instances.length;
OHIF.log.info(`Uploading study to ${serverConfig.url}`);
OHIF.log.info(
`${instancesAmount} instances are being uploaded. Don't close your browser.`
);
try {
const dicomWeb = new api.DICOMwebClient(serverConfig);
let progress = 0;
const getProgress = () => {
return ((progress * 100) / instancesAmount).toFixed();
};
for (const instance of instances) {
const options = {
datasets: [instance],
};
await dicomWeb.storeInstances(options);
progress++;
OHIF.log.info(`Progress: ${getProgress()}%`);
}
OHIF.log.info('Successfully uploaded!');
} catch (error) {
OHIF.log.error(`Failed to upload: ${error}`);
}
return instances;
})
.catch(error => {
OHIF.log.error(`Failed to upload: ${error}`);
return null;
});
}
function getStudyInstanceUIDFromStudies(studies) { function getStudyInstanceUIDFromStudies(studies) {
return Object.keys(Object(Object(studies).studyData)).slice(0, 1); return Object.keys(Object(Object(studies).studyData)).slice(0, 1);
} }
export { export {
save, save,
upload,
validDicomUid, validDicomUid,
getDicomWebClientFromConfig, getDicomWebClientFromConfig,
getDicomWebClientFromContext, getDicomWebClientFromContext,