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!
소스 검색

Implemented file download but held back by CORS issues.

master
부모
커밋
694d8d5a52
7개의 변경된 파일110개의 추가작업 그리고 6개의 파일을 삭제
  1. +1
    -0
      frontend/package.json
  2. +2
    -0
      frontend/rollup.config.js
  3. +2
    -0
      frontend/src/html/index.html
  4. +10
    -1
      frontend/src/js/component/wb-collection-content.js
  5. +17
    -5
      frontend/src/js/misc/make-arvados-request.js
  6. +13
    -0
      frontend/src/js/misc/wb-collection-manifest.js
  7. +65
    -0
      frontend/src/js/misc/wb-download-file.js

+ 1
- 0
frontend/package.json 파일 보기

@@ -2,6 +2,7 @@
"dependencies": {
"@fortawesome/fontawesome-free": "^5.12.0",
"bootstrap": "^4.4.1",
"crypto-js": "^3.1.9-1",
"filesize": "^6.0.1",
"jquery": "^3.4.1",
"js-uuid": "0.0.6",


+ 2
- 0
frontend/rollup.config.js 파일 보기

@@ -43,6 +43,8 @@ export default {
'node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.woff2': 'dist/webfonts/fa-brands-400.woff2',
'node_modules/js-uuid/js-uuid.js': 'dist/js/js-uuid.js',
'node_modules/filesize/lib/filesize.js': 'dist/js/filesize.js',
'node_modules/crypto-js/core.js': 'dist/js/crypto-js/core.js',
'node_modules/crypto-js/md5.js': 'dist/js/crypto-js/md5.js',
verbose: true
}),
buble({jsx: 'h'}),


+ 2
- 0
frontend/src/html/index.html 파일 보기

@@ -9,6 +9,8 @@
<script language="javascript" src="/js/fontawesome.min.js"></script>
<script language="javascript" src="/js/js-uuid.js"></script>
<script language="javascript" src="/js/filesize.js"></script>
<script language="javascript" src="/js/crypto-js/core.js"></script>
<script language="javascript" src="/js/crypto-js/md5.js"></script>
</head>
<body>
<script language="javascript" src="/js/app.min.js"></script>


+ 10
- 1
frontend/src/js/component/wb-collection-content.js 파일 보기

@@ -3,6 +3,7 @@ import WBTable from 'wb-table';
import WBBreadcrumbs from 'wb-breadcrumbs';
import { WBManifestReader } from 'wb-collection-manifest';
import makeArvadosRequest from 'make-arvados-request';
import wbDownloadFile from 'wb-download-file';
class WBCollectionContent extends Component {
constructor(...args) {
@@ -41,6 +42,7 @@ class WBCollectionContent extends Component {
prepareRows() {
let { manifestReader } = this.state;
let { collectionPath } = this.props;
let { arvHost, arvToken } = this.props.app.state;
//path = path.split('/');
//path = [ '.' ].concat(path);
@@ -58,7 +60,14 @@ class WBCollectionContent extends Component {
(<a href={ this.getUrl({ 'collectionPath': collectionPath + '/' + item[1] }) }>{ item[1] }</a>),
'File',
filesize(item[2]),
(<div></div>)
(<div>
<button class="btn btn-outline-primary mx-1" title="Download"
onclick={ () => wbDownloadFile(arvHost, arvToken, manifestReader,
'.' + collectionPath + '/' + item[1]) }><i class="fas fa-download"></i></button>
<button class="btn btn-outline-primary mx-1" title="View"
onclick={ () => wbDownloadFile(arvHost, arvToken, manifestReader,
'.' + collectionPath + '/' + item[1]) }><i class="far fa-eye"></i></button>
</div>)
]
))
});


+ 17
- 5
frontend/src/js/misc/make-arvados-request.js 파일 보기

@@ -1,13 +1,25 @@
function makeArvadosRequest(arvHost, arvToken, endpoint, method='GET', data=null,
contentType='application/json;charset=utf-8', responseType='json') {
function makeArvadosRequest(arvHost, arvToken, endpoint, params={}) {
const defaultParams = {
'method': 'GET',
'data': null,
'contentType': 'application/json;charset=utf-8',
'responseType': 'json',
'useSsl': true,
'requireToken': true
};
if (!arvHost || !arvToken)
Object.keys(defaultParams).map(k => (params[k] =
(k in params ? params[k] : defaultParams[k])));
let { method, data, contentType, responseType, useSsl, requireToken } = params;
if (!(arvHost && (arvToken || !requireToken)))
return new Promise((accept, reject) => reject());
let xhr = new XMLHttpRequest();
xhr.open(method, 'https://' + arvHost + endpoint);
xhr.setRequestHeader('Authorization', 'OAuth2 ' + arvToken);
xhr.open(method, (useSsl ? 'https://' : 'http://') + arvHost + endpoint);
if (arvToken)
xhr.setRequestHeader('Authorization', 'OAuth2 ' + arvToken);
if (data !== null)
xhr.setRequestHeader('Content-Type', contentType);
xhr.responseType = responseType;


+ 13
- 0
frontend/src/js/misc/wb-collection-manifest.js 파일 보기

@@ -161,6 +161,19 @@ class WBManifestReader {
out = b;
}
}*/
getFile(path) {
if (typeof(path) === 'string')
path = path.split('/');
if (path.length < 2)
throw Error('Invalid file path');
let name = path[path.length - 1];
let dir = this.findDir(path.slice(0, path.length - 1));
if (!(name in dir))
throw Error('File not found');
if (!(dir[name] instanceof Array))
throw Error('Path points to a directory not a file');
return dir[name];
}
}
export { WBManifestReader };

+ 65
- 0
frontend/src/js/misc/wb-download-file.js 파일 보기

@@ -0,0 +1,65 @@
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;

불러오는 중...
취소
저장