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.

127 lines
3.4KB

  1. import { h, Component } from 'preact';
  2. import makeArvadosRequest from 'make-arvados-request';
  3. function contentTypeFromFilename(name) {
  4. let ext = name.split('.');
  5. ext = ext[ext.length - 1].toUpperCase();
  6. if (ext === 'TXT')
  7. return 'text/plain; charset=utf-8';
  8. if (ext === 'JPG' || ext === 'JPEG')
  9. return 'image/jpeg';
  10. if (ext === 'PNG')
  11. return 'image/png';
  12. return 'application/octet-stream; charset=utf-8';
  13. }
  14. class WBDownloadPage extends Component {
  15. componentDidMount() {
  16. const { app, blocksBlobUrl, inline } = this.props;
  17. const { arvHost, arvToken } = app.state;
  18. let prom = new Promise((accept, reject) => {
  19. const xhr = new XMLHttpRequest();
  20. xhr.open('GET', blocksBlobUrl);
  21. xhr.onreadystatechange = () => {
  22. if (xhr.readyState !== 4)
  23. return;
  24. if (xhr.status !== 200)
  25. reject(xhr);
  26. else
  27. accept(xhr);
  28. };
  29. xhr.responseType = 'blob';
  30. xhr.send();
  31. });
  32. prom = prom.then(xhr => xhr.response.text());
  33. let name, file;
  34. const { streamSaver, location } = window;
  35. streamSaver.mitm = location.protocol + '//' +
  36. location.hostname + (location.port ?
  37. ':' + location.port : '') + '/mitm.html';
  38. let fileStream;
  39. let writer;
  40. let done = false;
  41. prom = prom.then(text => {
  42. let _;
  43. [ _, _, name, file ] = JSON.parse(text);
  44. fileStream = streamSaver.createWriteStream(name, {
  45. size: file[1],
  46. inline: inline,
  47. contentType: contentTypeFromFilename(name)
  48. });
  49. writer = fileStream.getWriter();
  50. window.onunload = () => {
  51. writer.abort()
  52. };
  53. window.onbeforeunload = evt => {
  54. if (!done) {
  55. evt.returnValue = `Are you sure you want to leave?`;
  56. }
  57. };
  58. const filters = [
  59. ['service_type', '=', 'proxy']
  60. ];
  61. return makeArvadosRequest(arvHost, arvToken,
  62. '/arvados/v1/keep_services?filters=' +
  63. encodeURIComponent(JSON.stringify(filters)));
  64. });
  65. prom = prom.then(xhr => {
  66. const services = xhr.response.items;
  67. const i = Math.floor(Math.random() * services.length);
  68. const proxy = services[i];
  69. let prom_1 = new Promise(accept => accept());
  70. for (let k = 0; k < file[0].length; k++) {
  71. const loc = file[0][k];
  72. prom_1 = prom_1.then(() => makeArvadosRequest(
  73. proxy.service_host + ':' + proxy.service_port,
  74. arvToken,
  75. '/' + loc[0],
  76. { 'useSsl': proxy.service_ssl_flag,
  77. 'responseType': 'arraybuffer' }
  78. ));
  79. prom_1 = prom_1.then(xhr_1 => {
  80. const blk = xhr_1.response.slice(loc[1], loc[2]);
  81. // const r = new Response(blk);
  82. // r.body.pipeTo(fileStream);
  83. writer.write(new Uint8Array(blk));
  84. });
  85. }
  86. return prom_1;
  87. });
  88. prom = prom.then(() => {
  89. writer.close();
  90. done = true;
  91. });
  92. }
  93. render() {
  94. return (
  95. <div class="container-fluid">
  96. <div class="card my-3">
  97. <div class="card-body">
  98. Downloading, please wait...
  99. </div>
  100. </div>
  101. <div class="alert alert-danger" role="alert">
  102. Do not close this window until the download is finished.
  103. </div>
  104. </div>
  105. );
  106. }
  107. }
  108. export default WBDownloadPage;