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:
parent
a24387b28b
commit
efa236f4cd
@ -51,3 +51,4 @@ check
|
|||||||
aldeed:template-extension@4.0.0
|
aldeed:template-extension@4.0.0
|
||||||
zuuk:stale-session
|
zuuk:stale-session
|
||||||
gilbertwat:bootstrap3-daterangepicker
|
gilbertwat:bootstrap3-daterangepicker
|
||||||
|
silentcicero:jszip
|
||||||
|
|||||||
@ -97,6 +97,7 @@ rwatts:uuid@0.0.2
|
|||||||
service-configuration@1.0.5
|
service-configuration@1.0.5
|
||||||
session@1.1.1
|
session@1.1.1
|
||||||
sha@1.0.4
|
sha@1.0.4
|
||||||
|
silentcicero:jszip@0.0.4
|
||||||
spacebars@1.0.7
|
spacebars@1.0.7
|
||||||
spacebars-compiler@1.0.7
|
spacebars-compiler@1.0.7
|
||||||
srp@1.0.4
|
srp@1.0.4
|
||||||
|
|||||||
@ -24,7 +24,9 @@
|
|||||||
</a>
|
</a>
|
||||||
<a class="disabled"><i class="fa fa-trash fa-lg"></i> Delete</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-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-download fa-lg"></i> Download</a>
|
||||||
<a class="disabled"><i class="fa fa-photo fa-lg"></i> View Series Details</a>
|
<a class="disabled"><i class="fa fa-photo fa-lg"></i> View Series Details</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@ -5,6 +5,7 @@ var defaultTemplate = 'studyContextMenu';
|
|||||||
Template.lesionTrackerWorklistContextMenu.replaces(defaultTemplate);
|
Template.lesionTrackerWorklistContextMenu.replaces(defaultTemplate);
|
||||||
|
|
||||||
Worklist.functions['removeTimepointAssociations'] = removeTimepointAssociations;
|
Worklist.functions['removeTimepointAssociations'] = removeTimepointAssociations;
|
||||||
|
Worklist.functions['exportSelectedStudies'] = exportSelectedStudies;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all present study / timepoint associations from the Clinical Trial
|
* Removes all present study / timepoint associations from the Clinical Trial
|
||||||
@ -73,3 +74,37 @@ 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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
97
Packages/lesiontracker/lib/exportStudies.js
Normal file
97
Packages/lesiontracker/lib/exportStudies.js
Normal 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;
|
||||||
|
}
|
||||||
@ -169,6 +169,8 @@ Package.onUse(function(api) {
|
|||||||
api.addFiles('lib/handleMeasurementModified.js', 'client');
|
api.addFiles('lib/handleMeasurementModified.js', 'client');
|
||||||
api.addFiles('lib/handleMeasurementRemoved.js', 'client');
|
api.addFiles('lib/handleMeasurementRemoved.js', 'client');
|
||||||
|
|
||||||
|
api.addFiles('lib/exportStudies.js', 'client');
|
||||||
|
|
||||||
|
|
||||||
// Export global functions
|
// Export global functions
|
||||||
api.export('pixelSpacingAutorunCheck', 'client');
|
api.export('pixelSpacingAutorunCheck', 'client');
|
||||||
@ -191,6 +193,7 @@ Package.onUse(function(api) {
|
|||||||
api.export('getTrialCriteriaConstraints', 'client');
|
api.export('getTrialCriteriaConstraints', 'client');
|
||||||
api.export('calculateTotalLesionBurden', 'client');
|
api.export('calculateTotalLesionBurden', 'client');
|
||||||
api.export('convertToNonTarget', 'client');
|
api.export('convertToNonTarget', 'client');
|
||||||
|
api.export('exportStudies', 'client');
|
||||||
|
|
||||||
// Export global objects
|
// Export global objects
|
||||||
api.export('TrialResponseCriteria', 'client');
|
api.export('TrialResponseCriteria', 'client');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user