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!
Browse Source

WBCollectionBrowse starting to work...

pull/1/head
parent
commit
a5cd564375
4 changed files with 149 additions and 57 deletions
  1. +44
    -5
      frontend/src/js/component/wb-collection-content.js
  2. +101
    -49
      frontend/src/js/misc/wb-collection-manifest.js
  3. +1
    -1
      frontend/src/js/page/wb-app.js
  4. +3
    -2
      frontend/src/js/page/wb-collection-browse.js

+ 44
- 5
frontend/src/js/component/wb-collection-content.js View File

@@ -7,11 +7,18 @@ import makeArvadosRequest from 'make-arvados-request';
class WBCollectionContent extends Component {
constructor(...args) {
super(...args);
this.state.path = '.';
this.state.rows = [];
this.state.manifestReader = null;
}
getUrl(params) {
let res = '/collection-browse/' +
(params.uuid || this.props.uuid) + '/' +
encodeURIComponent(params.collectionPath || this.props.collectionPath) + '/' +
(params.page || this.props.page);
return res;
}
componentDidMount() {
let { arvHost, arvToken } = this.props.app.state;
let { uuid } = this.props;
@@ -26,20 +33,52 @@ class WBCollectionContent extends Component {
});
}
componentWillReceiveProps(nextProps) {
this.props = nextProps;
this.prepareRows();
}
prepareRows() {
this.setState({});
let { manifestReader } = this.state;
let { collectionPath } = this.props;
//path = path.split('/');
//path = [ '.' ].concat(path);
let listing = manifestReader.listDirectory('.' + collectionPath);
this.setState({
'rows': listing.map(item => (
(item[0] === 'd') ? [
(<a href={ this.getUrl({ 'collectionPath': collectionPath + '/' + item[1] }) }>{ item[1] }/</a>),
'Directory',
null,
(<div></div>)
] : [
(<a href={ this.getUrl({ 'collectionPath': collectionPath + '/' + item[1] }) }>{ item[1] }</a>),
'File',
filesize(item[2]),
(<div></div>)
]
))
});
}
render({}, { rows }) {
render({ collectionPath }, { rows }) {
return (
<div>
<WBBreadcrumbs items={ [ 'a', 'b', 'c' ] } />
<WBBreadcrumbs items={ ('.' + collectionPath).split('/') } />
<WBTable columns={ [ 'Name', 'Size', 'Actions' ] }
<WBTable columns={ [ 'Name', 'Type', 'Size', 'Actions' ] }
rows={ rows } />
</div>
);
}
}
WBCollectionContent.defaultProps = {
'collectionPath': '',
'page': 0
};
export default WBCollectionContent;

+ 101
- 49
frontend/src/js/misc/wb-collection-manifest.js View File

@@ -1,17 +1,52 @@
class CMDirectory {
constructor() {
this.directories = {};
this.files = {};
//
// Directory: Hash[string, [Directory, File]]
// File = [blockRefs, size]
// blockRefs: Array[blockRef]
// blockRef: [locator, position, size]
// locator: String
// position: Number
// size: Number
//
class WBManifestReader {
constructor(manifest_text) {
this.rootDir = {};
if (!manifest_text)
return;
this.parse(manifest_text);
}
makeDir(parent, name) {
if (!(name in parent))
parent[name] = {};
if (parent[name] instanceof Array)
throw Error('Conflict trying to create a directory - a file with the same name already exists: ' + name);
return parent[name];
}
makePath(path) {
if (typeof(path) === 'string')
path = path.split('/');
let dir = this.rootDir;
for (let i = 1; i < path.length; i++)
dir = this.makeDir(dir, path[i]);
return dir;
}
}
class CMFile {
constructor() {
this.blockRefs = [];
this.size = 0;
appendFile(streamName, locators, position, size, fileName) {
let path = streamName + '/' + fileName;
path = path.split('/');
let dir = this.makePath(path.slice(0, path.length - 1));
if (!(fileName in dir))
dir[fileName] = [[], 0];
if (!(dir[fileName] instanceof Array))
throw Error('Conflict trying to create a file - a directory with the same name already exists: ' + fileName);
this.appendReferences(dir[fileName], locators, position, size);
}
append(locators, position, size) {
appendReferences(file, locators, position, size) {
if (size === 0)
return;
@@ -30,7 +65,7 @@ class CMFile {
let startBlock = used.indexOf(true);
let endBlock = used.lastIndexOf(true) + 1;
console.log('startBlock: ' + startBlock + ', endBlock: ' + endBlock);
// console.log('startBlock: ' + startBlock + ', endBlock: ' + endBlock);
if (startBlock === -1)
return;
@@ -47,53 +82,20 @@ class CMFile {
runSize -= blockSize;
}
this.blockRefs = this.blockRefs.concat(blockRefs);
this.size += size;
}
}
class WBManifestReader {
constructor(manifest_text) {
this.rootDir = new CMDirectory();
if (!manifest_text)
return;
this.parse(manifest_text);
}
makeDir(parent, name) {
if (!(name in parent.directories))
parent.directories[name] = new CMDirectory();
return parent.directories[name];
}
makePath(path) {
if (typeof(path) === 'string')
path = path.split('/');
let dir = this.rootDir;
for (let i = 1; i < path.length; i++)
dir = this.makeDir(dir, path[i]);
return dir;
}
appendFile(streamName, locators, position, size, fileName) {
let path = streamName + '/' + fileName;
path = path.split('/');
let dir = this.makePath(path.slice(0, path.length - 1));
if (!(fileName in dir.files))
dir.files[fileName] = new CMFile();
dir.files[fileName].append(locators, position, size);
file[0] = file[0].concat(blockRefs);
file[1] += size;
}
parse(manifest_text) {
let rx = /^[a-f0-9]{32}\+[0-9]+/;
let streams = manifest_text.split('\n');
if (!streams[streams.length - 1])
streams = streams.slice(0, streams.length - 1);
streams.map(s => {
let tokens = s.split(' ');
let streamName = tokens[0];
let streamName = this.unescapeName(tokens[0]);
let n = tokens.map(t => rx.exec(t));
n = n.indexOf(null, 1);
@@ -104,11 +106,61 @@ class WBManifestReader {
let fileTokens = tokens.slice(n);
fileTokens.map(t => {
let [ position, size, fileName ] = t.split(':');
fileName = this.unescapeName(fileName);
this.appendFile(streamName, locators,
Number(position), Number(size), fileName);
});
});
}
findDir(path) {
if (typeof(path) === 'string')
path = path.split('/');
if (path[0] !== '.')
throw Error('Path must begin with a dot component');
let dir = this.rootDir;
for (let i = 1; i < path.length; i++) {
if (!(path[i] in dir))
throw Error('Directory not found');
if (dir[path[i]] instanceof Array)
throw Error('Path is a file not directory');
dir = dir[path[i]];
}
return dir;
}
listDirectory(path) {
let dir = this.findDir(path);
let keys = Object.keys(dir);
keys.sort();
let subdirs = keys.filter(k => !(dir[k] instanceof Array));
let files = keys.filter(k => (dir[k] instanceof Array));
let res = subdirs.map(k => [ 'd', k, null ]);
res = res.concat(files.map(k => [ 'f', k, dir[k][1] ]));
return res;
}
unescapeName(name) {
return name.replace(/(\\\\|\\040)/g, (_, $1) => ($1 === '\\\\' ? '\\' : ' '));
}
escapeName(name) {
return name.replace(/ /g, '\\040');
}
/* let ids = { '\\': 1, '0': 2, '4': 3 };
let transitions = [
[ [0, 0], [1, ''], [0, 0], [0, 0] ],
[ [0, 0], [0, '\\'], [2, ''], [0, 0] ],
];
let mode = 0;
for (let i = 0; i < name.length; i++) {
let b = name[i];
let tokenId = Number(ids[b]);
[ mode, out ] = transitions[mode][tokenId];
if (out === 0)
out = b;
}
}*/
}
export { WBManifestReader };

+ 1
- 1
frontend/src/js/page/wb-app.js View File

@@ -67,7 +67,7 @@ class WBApp extends Component {
<WBCollectionView path="/collection/:uuid" app={ this } />
<WBCollectionBrowse path='/collection-browse/:uuid' app={ this } />
<WBCollectionBrowse path='/collection-browse/:uuid/:collectionPath?/:page?' app={ this } />
</Router>
);
}


+ 3
- 2
frontend/src/js/page/wb-collection-browse.js View File

@@ -4,7 +4,7 @@ import WBArvadosCrumbs from 'wb-arvados-crumbs';
import WBCollectionContent from 'wb-collection-content';
class WBCollectionBrowse extends Component {
render({ app, uuid }, {}) {
render({ app, uuid, collectionPath }, {}) {
return (
<div>
<WBNavbarCommon app={ app } />
@@ -15,7 +15,8 @@ class WBCollectionBrowse extends Component {
This is the collection browser for { uuid }
</div>
<WBCollectionContent app={ app } uuid={ uuid } />
<WBCollectionContent app={ app } uuid={ uuid }
collectionPath={ collectionPath }/>
</div>
);
}


Loading…
Cancel
Save