IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an email to s dot adaszewski at gmail dot com. User accounts are meant only to report issues and/or generate pull requests. This is a purpose-specific Git hosting for ADARED projects. Thank you for your understanding!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
2.1KB

  1. //
  2. // Copyright (C) Stanislaw Adaszewski, 2020
  3. // Contact: s.adaszewski@gmail.com
  4. // Website: https://adared.ch/wba
  5. // License: GNU Affero General Public License, Version 3
  6. //
  7. import makeArvadosRequest from 'make-arvados-request';
  8. function rdvHash(serviceId, locator) {
  9. let blockHash = /^[0-9a-f]{32}/.exec(locator);
  10. if (!blockHash)
  11. throw Error('Invalid locator');
  12. if (typeof(serviceId) !== 'string')
  13. throw Error('Invalid service ID');
  14. let res = CryptoJS.MD5(serviceId + blockHash).toString();
  15. return res;
  16. }
  17. function wbDownloadFile(arvHost, arvToken,
  18. manifestReader, path) {
  19. const file = manifestReader.getFile(path);
  20. const name = path.split('/').reverse()[0];
  21. const blockRefs = file[0];
  22. let services;
  23. let prom = makeArvadosRequest(arvHost, arvToken,
  24. '/arvados/v1/keep_services/accessible');
  25. prom = prom.then(xhr => (services = xhr.response['items']));
  26. const blocks = [];
  27. for (let i = 0; i < blockRefs.length; i++) {
  28. prom = prom.then(() => {
  29. const [ locator, position, size ] = blockRefs[i];
  30. const weights = services.map(s => rdvHash(s['uuid'], locator));
  31. const order = Object.keys(services).sort((a, b) => weights[b].localeCompare(weights[a]));
  32. const orderedServices = order.map(i => services[i]);
  33. let k = 0;
  34. const cb = () => {
  35. if (k >= orderedServices.length)
  36. throw Error('Block not found');
  37. const svc = orderedServices[k];
  38. k++;
  39. let prom_1 = makeArvadosRequest(svc.service_host +
  40. ':' + svc.service_port, arvToken,
  41. '/' + locator, { 'useSsl': svc.service_ssl_flag,
  42. 'responseType': 'arraybuffer' });
  43. //prom_1 = prom_1.then(xhr => xhr.response);
  44. prom_1 = prom_1.catch(cb);
  45. return prom_1;
  46. };
  47. return cb().then(xhr => (blocks.append(xhr.response.slice(position, size))));
  48. });
  49. }
  50. prom = prom.then(() => {
  51. const blob = new Blob(blocks);
  52. const url = window.URL.createObjectURL(blob);
  53. const a = document.createElement('a');
  54. a.href = url;
  55. a.download = name;
  56. });
  57. }
  58. export default wbDownloadFile;