// // Copyright (C) Stanislaw Adaszewski, 2020 // Contact: s.adaszewski@gmail.com // Website: https://adared.ch/wba // License: GNU Affero General Public License, Version 3 // import makeArvadosRequest from 'make-arvados-request'; function rdvHash(serviceId, locator) { let blockHash = /^[0-9a-f]{32}/.exec(locator); if (!blockHash) throw Error('Invalid locator'); if (typeof(serviceId) !== 'string') throw Error('Invalid service ID'); let res = CryptoJS.MD5(serviceId + blockHash).toString(); return res; } function wbDownloadFile(arvHost, arvToken, manifestReader, path) { const file = manifestReader.getFile(path); const name = path.split('/').reverse()[0]; const blockRefs = file[0]; let services; let prom = makeArvadosRequest(arvHost, arvToken, '/arvados/v1/keep_services/accessible'); prom = prom.then(xhr => (services = xhr.response['items'])); const blocks = []; for (let i = 0; i < blockRefs.length; i++) { prom = prom.then(() => { const [ locator, position, size ] = blockRefs[i]; const weights = services.map(s => rdvHash(s['uuid'], locator)); const order = Object.keys(services).sort((a, b) => weights[b].localeCompare(weights[a])); const orderedServices = order.map(i => services[i]); let k = 0; const cb = () => { if (k >= orderedServices.length) throw Error('Block not found'); const svc = orderedServices[k]; k++; let prom_1 = makeArvadosRequest(svc.service_host + ':' + svc.service_port, arvToken, '/' + locator, { 'useSsl': svc.service_ssl_flag, 'responseType': 'arraybuffer' }); //prom_1 = prom_1.then(xhr => xhr.response); prom_1 = prom_1.catch(cb); return prom_1; }; return cb().then(xhr => (blocks.append(xhr.response.slice(position, size)))); }); } prom = prom.then(() => { const blob = new Blob(blocks); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = name; }); } export default wbDownloadFile;