Skip to content

Commit

Permalink
Merge branch 'dev' into data_column_1
Browse files Browse the repository at this point in the history
  • Loading branch information
qiagu committed Jun 22, 2018
2 parents 6815ad6 + d64bae6 commit 8d3f1b7
Show file tree
Hide file tree
Showing 16 changed files with 416 additions and 68 deletions.
133 changes: 133 additions & 0 deletions client/galaxy/scripts/components/DataDialog.vue
@@ -0,0 +1,133 @@
<template>
<b-modal class="data-dialog-modal" v-model="modalShow" :ok-only="true" ok-title="Close">
<template slot="modal-header">
<h5 class="modal-title">{{modalTitle}}</h5>
<b-input-group v-if="optionsShow">
<b-input v-model="filter" placeholder="Type to Search"/>
<b-input-group-append>
<b-btn :disabled="!filter" @click="filter = ''">Clear</b-btn>
</b-input-group-append>
</b-input-group>
</template>
<b-alert v-if="errorMessage" variant="danger" :show="errorShow">
{{ errorMessage }}
</b-alert>
<div v-else>
<div v-if="optionsShow">
<b-table small hover
:items="items"
:fields="fields"
:filter="filter"
@row-clicked="clicked"
@filtered="filtered">
<template slot="name" slot-scope="data">
<i v-if="data.item.history_content_type == 'dataset'" class="fa fa-file-o"/>
<i v-else class="fa fa-copy"/>
{{ data.item.hid }}: {{ data.value }}
</template>
<template slot="extension" slot-scope="data">
{{ data.value ? data.value : "-" }}
</template>
<template slot="update_time" slot-scope="data">
{{ data.value ? data.value.substring(0, 16).replace("T", " ") : "-" }}
</template>
</b-table>
<div v-if="nItems == 0">
No search results found for: {{ this.filter }}.
</div>
</div>
<div v-else>
<span class="fa fa-spinner fa-spin"/>
<span>Please wait...</span>
</div>
</div>
</b-modal>
</template>

<script>
import axios from "axios";
import Vue from "vue";
import BootstrapVue from "bootstrap-vue";
Vue.use(BootstrapVue);
export default {
props: {
callback: {
type: Function,
required: true
}
},
computed: {
modalTitle() {
if (this.errorMessage) {
return "Failed to load datasets";
} else if (!this.optionsShow) {
return "Loading datasets";
}
}
},
data() {
return {
fields: {
name: {
sortable: true
},
extension: {
sortable: true
},
update_time: {
sortable: true
}
},
filter: null,
nItems: 0,
currentPage: 0,
perPage: 10,
items: [],
errorMessage: null,
errorShow: true,
historyId: null,
modalShow: true,
optionsShow: false
};
},
created: function() {this.load()},
methods: {
filtered: function(items) {
this.nItems = items.length;
},
clicked: function(record) {
let host = `${window.location.protocol}//${window.location.hostname}:${window.location.port}`;
this.callback(`${host}/${record.url}/display`);
this.modalShow = false;
},
load: function() {
this.historyId = Galaxy.currHistoryPanel && Galaxy.currHistoryPanel.model.id;
if (this.historyId) {
axios
.get(`${Galaxy.root}api/histories/${this.historyId}/contents`)
.then(response => {
this.items = response.data;
this.optionsShow = true;
})
.catch(e => {
if (e.response) {
this.errorMessage = e.response.data.err_msg || `${e.response.statusText} (${e.response.status})`;
} else {
this.errorMessage = "Server unavailable.";
}
});
} else {
this.errorMessage = "History not accessible.";
}
}
}
};
</script>
<style>
.data-dialog-modal .modal-body {
max-height: 50vh;
overflow-y: auto;
}
</style>
19 changes: 19 additions & 0 deletions client/galaxy/scripts/layout/data.js
@@ -0,0 +1,19 @@
import DataDialog from "components/DataDialog.vue";
import Vue from "vue";

export default class Data {
/**
* Opens a modal dialog for data selection
* @param {function} callback - Result function called with selection
*/
dialog(callback) {
var instance = Vue.extend(DataDialog);
var vm = document.createElement("div");
$('body').append(vm);
new instance(({
propsData: {
callback: callback
}
})).$mount(vm);
}
}
33 changes: 12 additions & 21 deletions client/galaxy/scripts/layout/modal.js
Expand Up @@ -68,28 +68,19 @@ $.extend(Modal.prototype, {
this.$body.html(body);
},
show: function(options, callback) {
if (!this.$dialog.is(":visible")) {
if (options.backdrop) {
this.$backdrop.addClass("in");
} else {
this.$backdrop.removeClass("in");
}
this.$overlay.show();
this.$dialog.show();
this.$overlay.addClass("in");
// Fix min-width so that modal cannot shrink considerably if new content is loaded.
this.$body.css("min-width", this.$body.width());
// Set max-height so that modal does not exceed window size and is in middle of page.
// TODO: this could perhaps be handled better using CSS.
this.$body.css(
"max-height",
$(window).height() -
this.$footer.outerHeight() -
this.$header.outerHeight() -
parseInt(this.$dialog.css("padding-top"), 10) -
parseInt(this.$dialog.css("padding-bottom"), 10)
);
if (options.backdrop) {
this.$backdrop.addClass("in");
} else {
this.$backdrop.removeClass("in");
}
this.$overlay.show();
this.$dialog.show();
this.$overlay.addClass("in");
// Fix min-width so that modal cannot shrink considerably if new content is loaded.
this.$body.css("min-width", this.$body.width());
// Set max-height so that modal does not exceed window size and is in middle of page.
// TODO: this could perhaps be handled better using CSS.
this.$body.css("max-height", $(window).height() / 1.5);
// Callback on init
if (callback) {
callback();
Expand Down
2 changes: 2 additions & 0 deletions client/galaxy/scripts/layout/page.js
@@ -1,3 +1,4 @@
import Data from "layout/data";
import Masthead from "layout/masthead";
import Panel from "layout/panel";
import Modal from "mvc/ui/ui-modal";
Expand All @@ -23,6 +24,7 @@ var View = Backbone.View.extend({
// attach global objects, build mastheads
Galaxy.modal = this.modal = new Modal.View();
Galaxy.router = this.router = options.Router && new options.Router(self, options);
Galaxy.data = this.data = new Data(this);
this.masthead = new Masthead.View(this.config);
this.center = new Panel.CenterPanel();

Expand Down
4 changes: 4 additions & 0 deletions config/datatypes_conf.xml.sample
Expand Up @@ -288,6 +288,8 @@
<datatype extension="twobit" type="galaxy.datatypes.binary:TwoBit" mimetype="application/octet-stream" display_in_upload="true"/>
<datatype extension="sqlite" type="galaxy.datatypes.binary:SQlite" mimetype="application/octet-stream" display_in_upload="true"/>
<datatype extension="gemini.sqlite" type="galaxy.datatypes.binary:GeminiSQLite" mimetype="application/octet-stream" display_in_upload="true"/>
<datatype extension="cuffdiff.sqlite" type="galaxy.datatypes.binary:CuffDiffSQlite" display_in_upload="true"/>
<datatype extension="gafa.sqlite" type="galaxy.datatypes.binary:GAFASQLite" mimetype="application/octet-stream" display_in_upload="true"/>
<datatype extension="txt" type="galaxy.datatypes.data:Text" display_in_upload="true" description="Any text file." description_url="https://wiki.galaxyproject.org/Learn/Datatypes#Plain_text"/>
<datatype extension="linecount" type="galaxy.datatypes.data:LineCount" display_in_upload="false"/>
<datatype extension="memepsp" type="galaxy.datatypes.sequence:MemePsp" display_in_upload="true" description="The MEME Position Specific Priors (PSP) format includes the name of the sequence for which a prior distribution corresponds." description_url="http://meme-suite.org/doc/psp-format.html"/>
Expand Down Expand Up @@ -696,6 +698,8 @@
<sniffer type="galaxy.datatypes.binary:MzSQlite"/>
<sniffer type="galaxy.datatypes.binary:IdpDB"/>
<sniffer type="galaxy.datatypes.binary:BlibSQlite"/>
<sniffer type="galaxy.datatypes.binary:CuffDiffSQlite"/>
<sniffer type="galaxy.datatypes.binary:GAFASQLite"/>
<sniffer type="galaxy.datatypes.binary:SQlite"/>
<sniffer type="galaxy.datatypes.binary:Cool"/>
<sniffer type="galaxy.datatypes.binary:Biom2"/>
Expand Down
4 changes: 3 additions & 1 deletion config/plugins/visualizations/msa/config/msa.xml
Expand Up @@ -6,6 +6,8 @@
<data_source>
<model_class>HistoryDatasetAssociation</model_class>
<test test_attr="ext" result_type="datatype">txt</test>
<test test_attr="ext" result_type="datatype">fasta</test>
<test test_attr="ext" result_type="datatype">phylip</test>
<to_param param_attr="id">dataset_id</to_param>
</data_source>
</data_sources>
Expand Down Expand Up @@ -36,4 +38,4 @@
<value>true</value>
</input>
</settings>
</visualization>
</visualization>
108 changes: 108 additions & 0 deletions lib/galaxy/datatypes/binary.py
Expand Up @@ -1157,6 +1157,81 @@ def display_peek(self, dataset):
return "Gemini SQLite Database, version %s" % (dataset.metadata.gemini_version or 'unknown')


class CuffDiffSQlite(SQlite):
"""Class describing a CuffDiff SQLite database """
MetadataElement(name="cuffdiff_version", default='2.2.1', param=MetadataParameter, desc="CuffDiff Version",
readonly=True, visible=True, no_value='2.2.1')
MetadataElement(name="genes", default=[], param=MetadataParameter, desc="Genes",
readonly=True, visible=True, no_value=[])
MetadataElement(name="samples", default=[], param=MetadataParameter, desc="Samples",
readonly=True, visible=True, no_value=[])
file_ext = "cuffdiff.sqlite"
# TODO: Update this when/if there is a specific EDAM format for CuffDiff SQLite data.
edam_format = "format_3621"

def set_meta(self, dataset, overwrite=True, **kwd):
super(CuffDiffSQlite, self).set_meta(dataset, overwrite=overwrite, **kwd)
try:
genes = []
samples = []
conn = sqlite.connect(dataset.file_name)
c = conn.cursor()
tables_query = "SELECT value FROM runInfo where param = 'version'"
result = c.execute(tables_query).fetchall()
for version, in result:
dataset.metadata.cuffdiff_version = version
genes_query = 'SELECT gene_id, gene_short_name FROM genes ORDER BY gene_short_name'
result = c.execute(genes_query).fetchall()
for gene_id, gene_name in result:
if gene_name is None:
continue
gene = '%s: %s' % (gene_id, gene_name)
if gene not in genes:
genes.append(gene)
samples_query = 'SELECT DISTINCT(sample_name) as sample_name FROM samples ORDER BY sample_name'
result = c.execute(samples_query).fetchall()
for sample_name, in result:
if sample_name not in samples:
samples.append(sample_name)
dataset.metadata.genes = genes
dataset.metadata.samples = samples
except Exception as e:
log.warning('%s, set_meta Exception: %s', self, e)

def sniff(self, filename):
if super(CuffDiffSQlite, self).sniff(filename):
# These tables should be in any CuffDiff SQLite output.
cuffdiff_table_names = ['CDS', 'genes', 'isoforms', 'replicates',
'runInfo', 'samples', 'TSS']
try:
conn = sqlite.connect(filename)
c = conn.cursor()
tables_query = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"
result = c.execute(tables_query).fetchall()
result = [_[0] for _ in result]
for table_name in cuffdiff_table_names:
if table_name not in result:
return False
return True
except Exception as e:
log.warning('%s, sniff Exception: %s', self, e)
return False

def set_peek(self, dataset, is_multi_byte=False):
if not dataset.dataset.purged:
dataset.peek = "CuffDiff SQLite Database, version %s" % (dataset.metadata.cuffdiff_version or 'unknown')
dataset.blurb = nice_size(dataset.get_size())
else:
dataset.peek = 'file does not exist'
dataset.blurb = 'file purged from disk'

def display_peek(self, dataset):
try:
return dataset.peek
except Exception:
return "CuffDiff SQLite Database, version %s" % (dataset.metadata.gemini_version or 'unknown')


class MzSQlite(SQlite):
"""Class describing a Proteomics Sqlite database """
file_ext = "mz.sqlite"
Expand Down Expand Up @@ -1266,6 +1341,39 @@ def display_peek(self, dataset):
return "IDPickerDB SQLite file (%s)" % (nice_size(dataset.get_size()))


class GAFASQLite(SQlite):
"""Class describing a GAFA SQLite database"""
MetadataElement(name='gafa_schema_version', default='0.1.0', param=MetadataParameter, desc='GAFA schema version',
readonly=True, visible=True, no_value='0.1.0')
file_ext = 'gafa.sqlite'

def set_meta(self, dataset, overwrite=True, **kwd):
super(GAFASQLite, self).set_meta(dataset, overwrite=overwrite, **kwd)
try:
conn = sqlite.connect(dataset.file_name)
c = conn.cursor()
version_query = 'SELECT version FROM meta'
results = c.execute(version_query).fetchall()
if len(results) == 0:
raise Exception('version not found in meta table')
elif len(results) > 1:
raise Exception('Multiple versions found in meta table')
dataset.metadata.gafa_schema_version = results[0][0]
except Exception as e:
log.warn("%s, set_meta Exception: %s", self, e)

def sniff(self, filename):
if super(GAFASQLite, self).sniff(filename):
gafa_table_names = frozenset(['gene', 'gene_family', 'gene_family_member', 'meta', 'transcript'])
conn = sqlite.connect(filename)
c = conn.cursor()
tables_query = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"
results = c.execute(tables_query).fetchall()
found_table_names = frozenset(_[0] for _ in results)
return gafa_table_names <= found_table_names
return False


class Xlsx(Binary):
"""Class for Excel 2007 (xlsx) files"""
file_ext = "xlsx"
Expand Down

0 comments on commit 8d3f1b7

Please sign in to comment.