LT-73 Export selected studies from study list to local

- Query to get metadata of the selected studies to export
- Download and zip the queried dicom files
- Show and update the progress dialog while querying and exporting studies
This commit is contained in:
Evren Ozkan 2016-02-23 11:53:49 -05:00
parent a24387b28b
commit efa236f4cd
6 changed files with 140 additions and 1 deletions

View File

@ -51,3 +51,4 @@ check
aldeed:template-extension@4.0.0
zuuk:stale-session
gilbertwat:bootstrap3-daterangepicker
silentcicero:jszip

View File

@ -97,6 +97,7 @@ rwatts:uuid@0.0.2
service-configuration@1.0.5
session@1.1.1
sha@1.0.4
silentcicero:jszip@0.0.4
spacebars@1.0.7
spacebars-compiler@1.0.7
srp@1.0.4

View File

@ -24,7 +24,9 @@
</a>
<a class="disabled"><i class="fa fa-trash fa-lg"></i> Delete</a>
<a class="disabled"><i class="fa fa-send-o fa-lg"></i> Send</a>
<a class="disabled"><i class="fa fa-exchange fa-lg"></i> Export</a>
<a id="exportSelectedStudies" type="button"
title="Export Selected Studies">
<i class="fa fa-exchange fa-lg"></i> Export</a>
<a class="disabled"><i class="fa fa-download fa-lg"></i> Download</a>
<a class="disabled"><i class="fa fa-photo fa-lg"></i> View Series Details</a>
</li>

View File

@ -5,6 +5,7 @@ var defaultTemplate = 'studyContextMenu';
Template.lesionTrackerWorklistContextMenu.replaces(defaultTemplate);
Worklist.functions['removeTimepointAssociations'] = removeTimepointAssociations;
Worklist.functions['exportSelectedStudies'] = exportSelectedStudies;
/**
* Removes all present study / timepoint associations from the Clinical Trial
@ -72,4 +73,38 @@ function removeTimepointAssociations() {
});
}
});
}
/**
* Exports all selected studies on the worklist
*/
function exportSelectedStudies() {
var selectedStudies = WorklistSelectedStudies.find({}, {
sort: {
studyDate: 1
}
}).fetch() || [];
if (selectedStudies.length < 1) {
return;
}
var studiesToExport = [];
var numberOfStudiesToQuery = selectedStudies.length;
progressDialog.show("Querying Studies...", numberOfStudiesToQuery);
selectedStudies.forEach(function(selectedStudy) {
getStudyMetadata(selectedStudy.studyInstanceUid, function(study) {
studiesToExport.push(study);
var numberOfStudiesQueried = studiesToExport.length;
progressDialog.update(numberOfStudiesQueried);
if (numberOfStudiesQueried === numberOfStudiesToQuery) {
exportStudies(studiesToExport);
}
});
});
}

View File

@ -0,0 +1,97 @@
/**
* Exports requested studies
* @param studiesToExport Studies to export
*/
exportStudies = function(studiesToExport) {
var numberOfFilesToExport = getNumberOfFilesToExport(studiesToExport);
progressDialog.show("Exporting Studies...", numberOfFilesToExport);
try {
exportStudiesInternal(studiesToExport, numberOfFilesToExport);
} catch (err) {
progressDialog.close();
console.error("Failed to export studies: " + err.message);
}
};
function exportStudiesInternal(studiesToExport, numberOfFilesToExport) {
var zip = new JSZip();
var exportFailed = false;
var numberOfFilesExported = 0;
studiesToExport.forEach(function(study) {
sortStudy(study);
var studyFolder = zip.folder(study.studyInstanceUid);
study.seriesList.forEach(function(series) {
var seriesFolder = studyFolder.folder(series.seriesInstanceUid);
series.instances.forEach(function(instance) {
if (!instance.wadouri) {
return;
}
// If failed to download a dicom file, skip others
if (exportFailed) {
return;
}
// Download and Zip the dicom file
var xhr = new XMLHttpRequest();
xhr.open("GET", instance.wadouri, true);
xhr.responseType = "arraybuffer";
// Downloaded the dicom file completely
xhr.onload = function() {
// If failed to download a dicom file, skip others
if (exportFailed) {
return;
}
var responseArrayBuffer = xhr.response;
if (responseArrayBuffer) {
seriesFolder.file(instance.sopInstanceUid + ".dcm", responseArrayBuffer, { binary: true });
}
numberOfFilesExported++;
if (numberOfFilesExported === numberOfFilesToExport) {
var zipContent = zip.generate({ type: "blob" });
saveAs(zipContent, "studies.zip");
}
progressDialog.update(numberOfFilesExported);
};
// Failed to download the dicom file
xhr.onerror = function() {
exportFailed = true;
progressDialog.close();
console.error("Failed to export studies!");
};
xhr.send(null);
});
});
});
}
function getNumberOfFilesToExport(studiesToExport) {
var numberOFFilesToExport = 0;
studiesToExport.forEach(function(study) {
study.seriesList.forEach(function(series) {
series.instances.forEach(function(instance) {
if (instance.wadouri) {
numberOFFilesToExport++;
}
});
});
});
return numberOFFilesToExport;
}

View File

@ -169,6 +169,8 @@ Package.onUse(function(api) {
api.addFiles('lib/handleMeasurementModified.js', 'client');
api.addFiles('lib/handleMeasurementRemoved.js', 'client');
api.addFiles('lib/exportStudies.js', 'client');
// Export global functions
api.export('pixelSpacingAutorunCheck', 'client');
@ -191,6 +193,7 @@ Package.onUse(function(api) {
api.export('getTrialCriteriaConstraints', 'client');
api.export('calculateTotalLesionBurden', 'client');
api.export('convertToNonTarget', 'client');
api.export('exportStudies', 'client');
// Export global objects
api.export('TrialResponseCriteria', 'client');