Skip to content

Commit

Permalink
start of logic that assembles messes of files into store definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
rbuels committed Nov 30, 2012
1 parent a5fb543 commit 06c51d5
Show file tree
Hide file tree
Showing 6 changed files with 239 additions and 15 deletions.
41 changes: 29 additions & 12 deletions src/JBrowse/View/FileDialog.js
Expand Up @@ -8,9 +8,10 @@ define( [ 'dojo/_base/declare',
'dijit/form/RadioButton',
'dojox/form/Uploader',
'dojox/form/uploader/plugins/IFrame',
'./FileDialog/SuperFileList'
'./FileDialog/SuperFileList',
'./FileDialog/TrackList'
],
function( declare, aspect, on, Dialog, TextBox, Select, Button, RadioButton, Uploader, ignore, FileList ) {
function( declare, aspect, on, Dialog, TextBox, Select, Button, RadioButton, Uploader, ignore, FileList, TrackList ) {

return declare(null,{
constructor: function( args ) {
Expand Down Expand Up @@ -47,6 +48,7 @@ return declare(null,{
}

updateInputs();
that.trackList.update();
},
onMouseOut: updateInputs
});
Expand Down Expand Up @@ -106,10 +108,9 @@ return declare(null,{
var id = 'localInput'+(inputCounter++);

var cont = dojo.create('div', {
innerHTML: '<h2>Local files</h2>'
+'<h3>'
+ (dndSupported ? 'Drag or select files to open.' : 'Select files to open.')
+ '</h3>'
innerHTML: '<h3>'
+ (dndSupported ? 'Drag or select files to open.' : 'Select files to open.')
+ '</h3>'
});

var fileBox = new dojox.form.Uploader({
Expand Down Expand Up @@ -152,34 +153,50 @@ return declare(null,{
return actionBar;
},

// files and URLS
// -> stores
// -> tracks
// -> tracks with user modifications
_makeTrackList: function( container ) {
this.trackList = new TrackList({ dialog: this });
dojo.connect( this.localFileList, 'onChange', this.trackList, 'update' );
return this.trackList.domNode;
},

show: function( args ) {
var dialog = this.dialog = new Dialog(
{ title: "Open files", className: 'fileDialog' }
);

dialog.set(
'content',
[
var content = [
dojo.create('hr'),
dojo.create('h2',{ innerHTML: 'Local files' }),
this._localControls( dialog.domNode ),
dojo.create('hr'),
dojo.create('h2',{ innerHTML: 'Remote files' }),
this._remoteControls(),
this._actionBar( args.openCallback, args.cancelCallback )
]);
];
content.unshift( this._makeTrackList() );
content.unshift( dojo.create('h2',{ innerHTML: 'Tracks' }) );


dialog.set( 'content', content );
dialog.show();

aspect.after( dialog, 'hide', function() {
dialog.destroyRecursive();
});
},

_filesToOpen: function() {
filesToOpen: function() {
if( ! this.localFileList )
return [];

return this.localFileList.getFiles();
},

_urlsToOpen: function() {
urlsToOpen: function() {
var urls = [];
for( var id in this.inputs ) {
var input = this.inputs[id];
Expand Down
20 changes: 17 additions & 3 deletions src/JBrowse/View/FileDialog/SuperFileList.js
Expand Up @@ -9,7 +9,11 @@ return declare( FileList,
{
_onUploaderChange: function(fileArray){
var seenFile = {};
this._files = array.filter( ( this._files || [] ).concat( fileArray ).reverse(), function( file ) {
var allFiles = [].concat( this._files||[] );
array.forEach( this.uploader._files, function(f) {
allFiles.unshift( f );
});
this._files = array.filter( allFiles, function( file ) {
var key = file.name;
if( seenFile[key] ) {
return false;
Expand All @@ -22,10 +26,20 @@ return declare( FileList,
array.forEach( this._files, function(f, i){
this._addRow(i+1, this.getFileType(f.name), f.name, f.size);
}, this);

this.onChange();
},

getFiles: function() {
return this._files || [];
}
return array.map( this._files || [], function(f) {
return { file: f,
type: (this.getFileType(f.name)||'').toLowerCase()
};
},this);
},

// change event stub
onChange: function() {}

});
});
47 changes: 47 additions & 0 deletions src/JBrowse/View/FileDialog/TrackList.js
@@ -0,0 +1,47 @@
define(['dojo/_base/declare',
'dojo/_base/array',
'./TrackList/BAMDriver'],
function(declare, array, BAMDriver ) {

return declare( null, {

constructor: function( args ) {
this.fileDialog = args.dialog;
this.domNode = dojo.create('div', { className: 'trackList', innerHTML: 'track list!' });
this.types = [ BAMDriver ];
},

// offer a given resource record (either a file or a URL) to the
// driver for a given store type. returns true if that driver will
// make use of that resource
_offerResource: function( resource, typeDriver ) {
return typeDriver.tryResource( this.storeConfs, resource );
},

update: function() {
// when called, rebuild the store and track configurations that we are going to add
this.storeConfs = this.storeConfs || {};

// anneal the given resources into a set of data store
// configurations by offering each file to each type driver in
// turn until no more are being accepted
var resources = this.fileDialog.filesToOpen().concat( this.fileDialog.urlsToOpen() );
var lastLength = 0;
while( resources.length && resources.length != lastLength ) {
resources = array.filter( resources, function( rec ) {
return ! array.some( this.types, function( typeDriver ) {
return this._offerResource( rec, typeDriver );
},this);
},this);

lastLength = resources.length;
}
if( resources.length )
console.warn("warning: not all resources could be used", resources );

console.log( this.storeConfs );
}

});
});

106 changes: 106 additions & 0 deletions src/JBrowse/View/FileDialog/TrackList/BAMDriver.js
@@ -0,0 +1,106 @@
define([
'JBrowse/Util',
'JBrowse/Model/FileBlob',
'JBrowse/Model/XHRBlob'
],
function( Util, FileBlob, XHRBlob ) {
var uniqCounter = 0;
return {

storeType: 'JBrowse/Store/SeqFeature/BAM',

tryResource: function( configs, resource ) {
if( resource.type == 'bam' ) {
var basename = Util.basename(
resource.file ? resource.file.name :
resource.url ? resource.url :
''
);
if( !basename )
return false;

// go through the configs and see if there is one with a BAI that seems to match
for( var n in configs ) {
var c = configs[n];
if( Util.basename( c.bai ? c.bai.blob.name : c.baiUrlTemplate, '.bai' ) == basename ) {
// it's a match, put it in
c.bam = this._makeBlob( resource );
return true;
}
}
// go through again and look for BAIs that don't have .bam on them
basename = Util.basename( basename, '.bam' );
for( var n in configs ) {
var c = configs[n];
if( Util.basename( c.bai ? c.bai.blob.name : c.baiUrlTemplate, '.bai' ) == basename ) {
// it's a match, put it in
c.bam = this._makeBlob( resource );
return true;
}
}

// otherwise make a new store config for it
var newName = 'bam_'+uniqCounter++;
configs[newName] = {
type: this.storeType,
bam: this._makeBlob( resource ),
name: newName
};
return true;
} else if( resource.type == 'bai' ) {
var basename = Util.basename(
resource.file ? resource.file.name :
resource.url ? resource.url :
''
, '.bai'
);
if( !basename )
return false;

// go through the configs and look for BAMs that match like zee.bam -> zee.bam.bai
for( var n in configs ) {
var c = configs[n];
if( Util.basename( c.bam ? c.bam.blob.name : c.urlTemplate ) == basename ) {
// it's a match, put it in
c.bai = this._makeBlob( resource );
return true;
}
}
// go through again and look for BAMs that match like zee.bam -> zee.bai
for( var n in configs ) {
var c = configs[n];
if( Util.basename( c.bam ? c.bam.blob.name : c.urlTemplate, '.bam' ) == basename ) {
// it's a match, put it in
c.bai = this._makeBlob( resource );
return true;
}
}

// otherwise make a new store
var newName = 'bam_'+uniqCounter++;
configs[newName] = {
bai: this._makeBlob( resource ),
name: newName,
type: this.storeType
};
return true;
}
else
return false;
},

_makeBlob: function( resource ) {
var r = resource.file ? new FileBlob( resource.file ) :
resource.url ? new XHRBlob( resource.url ) :
null;
if( ! r )
throw 'unknown resource type';
return r;

},

confIsValid: function( conf ) {
return (conf.bam || conf.urlTemplate) && ( conf.bai || conf.baiUrlTemplate || conf.urlTemplate );
}
};
});
1 change: 1 addition & 0 deletions tests/js_tests/index.html
Expand Up @@ -21,6 +21,7 @@
<script type="text/javascript" src="spec/BAM.spec.js"></script>
<script type="text/javascript" src="spec/RemoteBinaryFile.spec.js"></script>
<script type="text/javascript" src="spec/Util.spec.js"></script>
<script type="text/javascript" src="spec/AddFiles.spec.js"></script>

<script type="text/javascript">
(function() {
Expand Down
39 changes: 39 additions & 0 deletions tests/js_tests/spec/AddFiles.spec.js
@@ -0,0 +1,39 @@
require([
'JBrowse/View/FileDialog/TrackList/BAMDriver'
], function( BAMDriver ) {

describe( 'BAM driver', function() {
it( 'can match a simple BAM URL with its BAI URL', function( ) {
var confs = { foo: { baiUrlTemplate: 'zee.bam.bai' } };
expect( BAMDriver.tryResource( confs, { type: 'bam', url: 'zee.bam' } ) )
.toBeTruthy();
expect( confs.foo.bam.url ).toEqual( 'zee.bam' );
});

it( 'can match a simple BAM file with its BAI URL', function( ) {
var confs = { foo: { baiUrlTemplate: 'zee.bam.bai' } };
expect( BAMDriver.tryResource( confs, { type: 'bam', file: { name: 'zee.bam'} } ) )
.toBeTruthy();
expect( confs.foo.bam.blob.name ).toEqual( 'zee.bam' );
});

it( 'matches a BAI file like zee.bai -> zee.bam', function( ) {
var confs = { foo: { urlTemplate: '/zee.bam' } };
expect( BAMDriver.tryResource( confs, { type: 'bai', file: { name: 'zee.bai'} } ) )
.toBeTruthy();
expect( confs.foo.bai.blob.name ).toEqual( 'zee.bai' );
});

it( 'matches a BAM file like zee.bam -> zee.bai', function( ) {
var confs = { foo: { baiUrlTemplate: '/zee.bai' } };
expect( BAMDriver.tryResource( confs, { type: 'bam', file: { name: 'zee.bam'} } ) )
.toBeTruthy();
expect( confs.foo.bam.blob.name ).toEqual( 'zee.bam' );
});


});


});

0 comments on commit 06c51d5

Please sign in to comment.