galaxy-commits
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
October 2012
- 1 participants
- 194 discussions
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/1dc4dd32eaf8/
changeset: 1dc4dd32eaf8
user: jgoecks
date: 2012-10-22 16:47:46
summary: Code cleanup in vis framework.
affected #: 2 files
diff -r 5fc775a03f0bcb083b375629518924138aed1a88 -r 1dc4dd32eaf8b38da3e66bdc2de287f907b3605e static/scripts/viz/trackster/tracks.js
--- a/static/scripts/viz/trackster/tracks.js
+++ b/static/scripts/viz/trackster/tracks.js
@@ -148,9 +148,6 @@
});
};
-// TODO: do we need to export?
-exports.moveable = moveable;
-
/**
* Init constants & functions used throughout trackster.
*/
diff -r 5fc775a03f0bcb083b375629518924138aed1a88 -r 1dc4dd32eaf8b38da3e66bdc2de287f907b3605e static/scripts/viz/visualization.js
--- a/static/scripts/viz/visualization.js
+++ b/static/scripts/viz/visualization.js
@@ -594,14 +594,7 @@
defaults: {
chrom: null,
start: 0,
- end: 0,
- DIF_CHROMS: 1000,
- BEFORE: 1001,
- CONTAINS: 1002,
- OVERLAP_START: 1003,
- OVERLAP_END: 1004,
- CONTAINED_BY: 1005,
- AFTER: 1006
+ end: 0
},
/**
@@ -657,30 +650,30 @@
// Look at chroms.
if (first_chrom && second_chrom && first_chrom !== second_chrom) {
- return this.get('DIF_CHROMS');
+ return GenomeRegion.overlap_results.DIF_CHROMS;
}
// Look at regions.
if (first_start < second_start) {
if (first_end < second_start) {
- overlap = this.get('BEFORE');
+ overlap = GenomeRegion.overlap_results.BEFORE;
}
else if (first_end <= second_end) {
- overlap = this.get('OVERLAP_START');
+ overlap = GenomeRegion.overlap_results.OVERLAP_START;
}
else { // first_end > second_end
- overlap = this.get('CONTAINS');
+ overlap = GenomeRegion.overlap_results.CONTAINS;
}
}
else { // first_start >= second_start
if (first_start > second_end) {
- overlap = this.get('AFTER');
+ overlap = GenomeRegion.overlap_results.AFTER;
}
else if (first_end <= second_end) {
- overlap = this.get('CONTAINED_BY');
+ overlap = GenomeRegion.overlap_results.CONTAINED_BY;
}
else {
- overlap = this.get('OVERLAP_END');
+ overlap = GenomeRegion.overlap_results.OVERLAP_END;
}
}
@@ -691,7 +684,7 @@
* Returns true if this region contains a given region.
*/
contains: function(a_region) {
- return this.compute_overlap(a_region) === this.get('CONTAINS');
+ return this.compute_overlap(a_region) === GenomeRegion.overlap_results.CONTAINS;
},
/**
@@ -699,7 +692,18 @@
*/
overlaps: function(a_region) {
return _.intersection( [this.compute_overlap(a_region)],
- [this.get('DIF_CHROMS'), this.get('BEFORE'), this.get('AFTER')] ).length === 0;
+ [GenomeRegion.overlap_results.DIF_CHROMS, GenomeRegion.overlap_results.BEFORE, GenomeRegion.overlap_results.AFTER] ).length === 0;
+ }
+},
+{
+ overlap_results: {
+ DIF_CHROMS: 1000,
+ BEFORE: 1001,
+ CONTAINS: 1002,
+ OVERLAP_START: 1003,
+ OVERLAP_END: 1004,
+ CONTAINED_BY: 1005,
+ AFTER: 1006
}
});
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
22 Oct '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/5fc775a03f0b/
changeset: 5fc775a03f0b
user: greg
date: 2012-10-22 16:43:59
summary: Apply patches from John Chilton to resolve the issues where (1) Galaxy doesn't load tool sections from multiple files in a consistent manner, and (2) John's standing request in the now-defunct Galaxy bitbucket bug tracker to allow directories to appear in the tool_config_file option.
affected #: 2 files
diff -r d2c998e06f0ef7b117bf2e05150bbed877d5dcb3 -r 5fc775a03f0bcb083b375629518924138aed1a88 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -313,7 +313,7 @@
if self.migrated_tools_config not in tool_configs:
tool_configs.append( self.migrated_tools_config )
for path in tool_configs:
- if not os.path.isfile( path ):
+ if not os.path.exists( path ):
raise ConfigurationError("File not found: %s" % path )
if not os.path.isfile( self.datatypes_config ):
raise ConfigurationError("File not found: %s" % self.datatypes_config )
diff -r d2c998e06f0ef7b117bf2e05150bbed877d5dcb3 -r 5fc775a03f0bcb083b375629518924138aed1a88 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -73,6 +73,7 @@
self.workflows_by_id = {}
# In-memory dictionary that defines the layout of the tool panel.
self.tool_panel = odict()
+ self.index = 0
# File that contains the XML section and tool tags from all tool panel config files integrated into a
# single file that defines the tool panel layout. This file can be changed by the Galaxy administrator
# (in a way similar to the single tool_conf.xml file in the past) to alter the layout of the tool panel.
@@ -87,7 +88,14 @@
self.tool_root_dir = tool_root_dir
self.app = app
self.init_dependency_manager()
- for config_filename in listify( config_filenames ):
+ config_filenames = listify( config_filenames )
+ for config_filename in config_filenames:
+ if os.path.isdir( config_filename ):
+ directory_contents = sorted( os.listdir( config_filename ) )
+ directory_config_files = [ config_file for config_file in directory_contents if config_file.endswith( ".xml" ) ]
+ config_filenames.remove( config_filename )
+ config_filenames.extend( directory_config_files )
+ for config_filename in config_filenames:
try:
self.init_tools( config_filename )
except:
@@ -134,7 +142,9 @@
tool_path = self.tool_root_dir
# Only load the panel_dict under certain conditions.
load_panel_dict = not self.integrated_tool_panel_config_has_contents
- for index, elem in enumerate( root ):
+ for _, elem in enumerate( root ):
+ index = self.index
+ self.index += 1
if parsing_shed_tool_conf:
config_elems.append( elem )
if elem.tag == 'tool':
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
4 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/6ee0412ee742/
changeset: 6ee0412ee742
user: jgoecks
date: 2012-10-20 22:12:00
summary: Circster: transition paths when loading more detailed data.
affected #: 1 file
diff -r afc8e93452687063301398854dbcf0d450c8558c -r 6ee0412ee7424227548e5568765e4f99ad4a2a29 static/scripts/viz/circster.js
--- a/static/scripts/viz/circster.js
+++ b/static/scripts/viz/circster.js
@@ -286,32 +286,7 @@
this.options.parent_elt.selectAll('g>path.chrom-background').transition().duration(1000).attr('d', new_d);
- // -- Update chrom data. --
- var track = this.options.track,
- chrom_arcs = this.options.chroms_layout,
- chrom_data_paths = this.options.parent_elt.selectAll('g>path.chrom-data'),
- num_paths = chrom_data_paths[0].length;
-
- if (num_paths > 0) {
- var self = this;
- $.when(track.get('data_manager').get_genome_wide_data(this.options.genome)).then(function(genome_wide_data) {
- // Map chrom data to path data, filtering out null values.
- var path_data = _.reject( _.map(genome_wide_data, function(chrom_data, i) {
- var rval = null,
- path_fn = self._compute_path_data(chrom_arcs[i], chrom_data);
- if (path_fn) {
- rval = path_fn(chrom_data.data);
- }
- return rval;
- }), function(p_data) { return p_data === null; } );
-
- // Transition each path.
- chrom_data_paths.each(function(path, index) {
- d3.select(this).transition().duration(1000).attr('d', path_data[index]);
- });
-
- });
- }
+ this._transition_chrom_data();
},
/**
@@ -370,12 +345,47 @@
/* ----------------------- Internal Methods ------------------------- */
/**
+ * Transitions chrom data to new values (e.g new radius or data bounds).
+ */
+ _transition_chrom_data: function() {
+ var track = this.options.track,
+ chrom_arcs = this.options.chroms_layout,
+ chrom_data_paths = this.options.parent_elt.selectAll('g>path.chrom-data'),
+ num_paths = chrom_data_paths[0].length;
+
+ if (num_paths > 0) {
+ var self = this;
+ $.when(track.get('data_manager').get_genome_wide_data(this.options.genome)).then(function(genome_wide_data) {
+ // Map chrom data to path data, filtering out null values.
+ var path_data = _.reject( _.map(genome_wide_data, function(chrom_data, i) {
+ var rval = null,
+ path_fn = self._get_path_function(chrom_arcs[i], chrom_data);
+ if (path_fn) {
+ rval = path_fn(chrom_data.data);
+ }
+ return rval;
+ }), function(p_data) { return p_data === null; } );
+
+ // Transition each path.
+ chrom_data_paths.each(function(path, index) {
+ d3.select(this).transition().duration(1000).attr('d', path_data[index]);
+ });
+
+ });
+ }
+ },
+
+ /**
* Update data bounds.
*/
_update_data_bounds: function() {
- //this.options.data_bounds = this.get_data_bounds(this.options.track.get_genome_wide_data(this.options.genome));
+ var old_bounds = this.options.data_bounds;
+ this.options.data_bounds = this.get_data_bounds(this.options.track.get('data_manager').get_genome_wide_data(this.options.genome));
- // TODO: transition all paths to use the new data bounds.
+ // If bounds have changed, transition all paths to use the new data bounds.
+ if (this.options.data_bounds[0] < old_bounds[0] || this.options.data_bounds[1] > old_bounds[1]) {
+ this._transition_chrom_data();
+ }
},
/**
@@ -422,7 +432,7 @@
/**
* Returns data for creating a path for the given data using chrom_arc and data bounds.
*/
- _compute_path_data: function(chrom_arc, chrom_data) {},
+ _get_path_function: function(chrom_arc, chrom_data) {},
/**
* Returns arc layouts for genome's chromosomes/contigs. Arcs are arranged in a circle
@@ -490,7 +500,7 @@
* chromosome. Attachs a dict with track and chrom name information to DOM element.
*/
_render_chrom_data: function(svg, chrom_arc, chrom_data) {
- var path_data = this._compute_path_data(chrom_arc, chrom_data);
+ var path_data = this._get_path_function(chrom_arc, chrom_data);
if (!path_data) { return null; }
@@ -505,9 +515,9 @@
},
/**
- * Returns data for creating a path for the given data using chrom_arc, radius bounds, and data bounds.
+ * Returns function for creating a path across the chrom arc.
*/
- _compute_path_data: function(chrom_arc, chrom_data) {
+ _get_path_function: function(chrom_arc, chrom_data) {
// If no chrom data, return null.
if (typeof chrom_data === "string" || !chrom_data.data || chrom_data.data.length === 0) {
return null;
https://bitbucket.org/galaxy/galaxy-central/changeset/96e230aed769/
changeset: 96e230aed769
user: jgoecks
date: 2012-10-20 22:25:28
summary: Circster: code cleanup to remove use of options dictionary.
affected #: 1 file
diff -r 6ee0412ee7424227548e5568765e4f99ad4a2a29 -r 96e230aed76971953f62728c28b28730608ee2c9 static/scripts/viz/circster.js
--- a/static/scripts/viz/circster.js
+++ b/static/scripts/viz/circster.js
@@ -214,16 +214,19 @@
/* ----------------------- Public Methods ------------------------- */
initialize: function(options) {
- this.options = options;
- this.options.bg_stroke = 'ccc';
+ this.bg_stroke = 'ccc';
// Fill color when loading data.
- this.options.loading_bg_fill = '000';
+ this.loading_bg_fill = '000';
// Fill color when data has been loaded.
- this.options.bg_fill = 'ccc';
- this.options.chroms_layout = this._chroms_layout();
- this.options.data_bounds = [];
- this.options.scale = 1;
- this.options.parent_elt = d3.select(this.$el[0]);
+ this.bg_fill = 'ccc';
+ this.total_gap = options.total_gap;
+ this.track = options.track;
+ this.radius_bounds = options.radius_bounds;
+ this.genome = options.genome;
+ this.chroms_layout = this._chroms_layout();
+ this.data_bounds = [];
+ this.scale = 1;
+ this.parent_elt = d3.select(this.$el[0]);
},
/**
@@ -231,17 +234,17 @@
*/
render: function() {
// -- Create track group element. --
- var track_parent_elt = this.options.parent_elt;
+ var track_parent_elt = this.parent_elt;
if (!track_parent_elt) {
console.log('no parent elt');
}
// -- Render background arcs. --
- var genome_arcs = this.options.chroms_layout,
+ var genome_arcs = this.chroms_layout,
arc_gen = d3.svg.arc()
- .innerRadius(this.options.radius_bounds[0])
- .outerRadius(this.options.radius_bounds[1]),
+ .innerRadius(this.radius_bounds[0])
+ .outerRadius(this.radius_bounds[1]),
// Attach data to group element.
chroms_elts = track_parent_elt.selectAll('g')
@@ -251,8 +254,8 @@
chroms_paths = chroms_elts.append('path')
.attr("d", arc_gen)
.attr('class', 'chrom-background')
- .style("stroke", this.options.bg_stroke)
- .style("fill", this.options.loading_bg_fill);
+ .style("stroke", this.bg_stroke)
+ .style("fill", this.loading_bg_fill);
// Append titles to paths.
chroms_paths.append("title").text(function(d) { return d.data.chrom; });
@@ -260,14 +263,14 @@
// -- Render track data and, when track data is rendered, apply preferences and update chrom_elts fill. --
var self = this,
- data_manager = self.options.track.get('data_manager'),
+ data_manager = self.track.get('data_manager'),
// If track has a data manager, get deferred that resolves when data is ready.
data_ready_deferred = (data_manager ? data_manager.data_is_ready() : true );
// When data is ready, render track.
$.when(data_ready_deferred).then(function() {
$.when(self._render_data(track_parent_elt)).then(function() {
- chroms_paths.style("fill", self.options.bg_fill);
+ chroms_paths.style("fill", self.bg_fill);
});
});
},
@@ -277,14 +280,14 @@
*/
update_radius_bounds: function(radius_bounds) {
// Update bounds.
- this.options.radius_bounds = radius_bounds;
+ this.radius_bounds = radius_bounds;
// -- Update background arcs. --
var new_d = d3.svg.arc()
- .innerRadius(this.options.radius_bounds[0])
- .outerRadius(this.options.radius_bounds[1]);
+ .innerRadius(this.radius_bounds[0])
+ .outerRadius(this.radius_bounds[1]);
- this.options.parent_elt.selectAll('g>path.chrom-background').transition().duration(1000).attr('d', new_d);
+ this.parent_elt.selectAll('g>path.chrom-background').transition().duration(1000).attr('d', new_d);
this._transition_chrom_data();
},
@@ -295,8 +298,8 @@
update_scale: function(new_scale) {
// -- Update scale and return if new scale is less than old scale. --
- var old_scale = this.options.scale;
- this.options.scale = new_scale;
+ var old_scale = this.scale;
+ this.scale = new_scale;
if (new_scale <= old_scale) {
return;
}
@@ -307,16 +310,16 @@
utils = new SVGUtils();
// Select all chrom data and filter to operate on those that are visible.
- this.options.parent_elt.selectAll('path.chrom-data').filter(function(d, i) {
+ this.parent_elt.selectAll('path.chrom-data').filter(function(d, i) {
return utils.is_visible(this);
}).each(function(d, i) {
// Now operating on a single path element representing chromosome data.
var path_elt = d3.select(this),
chrom = path_elt.attr('chrom'),
- chrom_region = self.options.genome.get_chrom_region(chrom),
+ chrom_region = self.genome.get_chrom_region(chrom),
// Get more detailde data for chrom.
- data_deferred = self.options.track.get('data_manager').get_more_detailed_data(chrom_region, 'Coverage', 0, new_scale);
+ data_deferred = self.track.get('data_manager').get_more_detailed_data(chrom_region, 'Coverage', 0, new_scale);
// When more data is available, use new data to redraw path.
$.when(data_deferred).then(function(data) {
@@ -327,15 +330,15 @@
self._update_data_bounds();
// Find chromosome arc to draw data on.
- var chrom_arc = _.find(self.options.chroms_layout, function(layout) {
+ var chrom_arc = _.find(self.chroms_layout, function(layout) {
return layout.data.chrom === chrom;
});
// Add new data path and apply preferences.
- var prefs = self.options.track.get('prefs'),
+ var prefs = self.track.get('prefs'),
block_color = prefs.block_color;
if (!block_color) { block_color = prefs.color; }
- self._render_chrom_data(self.options.parent_elt, chrom_arc, data).style('stroke', block_color).style('fill', block_color);
+ self._render_chrom_data(self.parent_elt, chrom_arc, data).style('stroke', block_color).style('fill', block_color);
});
});
@@ -348,14 +351,14 @@
* Transitions chrom data to new values (e.g new radius or data bounds).
*/
_transition_chrom_data: function() {
- var track = this.options.track,
- chrom_arcs = this.options.chroms_layout,
- chrom_data_paths = this.options.parent_elt.selectAll('g>path.chrom-data'),
+ var track = this.track,
+ chrom_arcs = this.chroms_layout,
+ chrom_data_paths = this.parent_elt.selectAll('g>path.chrom-data'),
num_paths = chrom_data_paths[0].length;
if (num_paths > 0) {
var self = this;
- $.when(track.get('data_manager').get_genome_wide_data(this.options.genome)).then(function(genome_wide_data) {
+ $.when(track.get('data_manager').get_genome_wide_data(this.genome)).then(function(genome_wide_data) {
// Map chrom data to path data, filtering out null values.
var path_data = _.reject( _.map(genome_wide_data, function(chrom_data, i) {
var rval = null,
@@ -379,11 +382,11 @@
* Update data bounds.
*/
_update_data_bounds: function() {
- var old_bounds = this.options.data_bounds;
- this.options.data_bounds = this.get_data_bounds(this.options.track.get('data_manager').get_genome_wide_data(this.options.genome));
+ var old_bounds = this.data_bounds;
+ this.data_bounds = this.get_data_bounds(this.track.get('data_manager').get_genome_wide_data(this.genome));
// If bounds have changed, transition all paths to use the new data bounds.
- if (this.options.data_bounds[0] < old_bounds[0] || this.options.data_bounds[1] > old_bounds[1]) {
+ if (this.data_bounds[0] < old_bounds[0] || this.data_bounds[1] > old_bounds[1]) {
this._transition_chrom_data();
}
},
@@ -393,14 +396,14 @@
*/
_render_data: function(svg) {
var self = this,
- chrom_arcs = this.options.chroms_layout,
- track = this.options.track,
+ chrom_arcs = this.chroms_layout,
+ track = this.track,
rendered_deferred = $.Deferred();
// When genome-wide data is available, render data.
- $.when(track.get('data_manager').get_genome_wide_data(this.options.genome)).then(function(genome_wide_data) {
+ $.when(track.get('data_manager').get_genome_wide_data(this.genome)).then(function(genome_wide_data) {
// Set bounds.
- self.options.data_bounds = self.get_data_bounds(genome_wide_data);
+ self.data_bounds = self.get_data_bounds(genome_wide_data);
// Merge chroms layout with data.
layout_and_data = _.zip(chrom_arcs, genome_wide_data),
@@ -416,7 +419,7 @@
var config = track.get('config'),
block_color = config.get_value('block_color');;
if (!block_color) { block_color = config.get_value('color'); }
- self.options.parent_elt.selectAll('path.chrom-data').style('stroke', block_color).style('fill', block_color);
+ self.parent_elt.selectAll('path.chrom-data').style('stroke', block_color).style('fill', block_color);
rendered_deferred.resolve(svg);
});
@@ -440,10 +443,10 @@
*/
_chroms_layout: function() {
// Setup chroms layout using pie.
- var chroms_info = this.options.genome.get_chroms_info(),
+ var chroms_info = this.genome.get_chroms_info(),
pie_layout = d3.layout.pie().value(function(d) { return d.len; }).sort(null),
init_arcs = pie_layout(chroms_info),
- gap_per_chrom = this.options.total_gap / chroms_info.length,
+ gap_per_chrom = this.total_gap / chroms_info.length,
chrom_arcs = _.map(init_arcs, function(arc, index) {
// For short chroms, endAngle === startAngle.
var new_endAngle = arc.endAngle - gap_per_chrom;
@@ -461,8 +464,8 @@
initialize: function(options) {
CircsterTrackView.prototype.initialize.call(this, options);
- this.options.bg_stroke = 'fff';
- this.options.bg_fill = 'fff';
+ this.bg_stroke = 'fff';
+ this.bg_fill = 'fff';
},
/**
@@ -525,8 +528,8 @@
// Radius scaler.
var radius = d3.scale.linear()
- .domain(this.options.data_bounds)
- .range(this.options.radius_bounds);
+ .domain(this.data_bounds)
+ .range(this.radius_bounds);
// Scaler for placing data points across arc.
var angle = d3.scale.linear()
https://bitbucket.org/galaxy/galaxy-central/changeset/043012c62cfc/
changeset: 043012c62cfc
user: jgoecks
date: 2012-10-20 22:39:39
summary: Circster, cleanup for fetching more data: do not fetch more data for summary tree and use linear function for fetching more bigwig data.
affected #: 2 files
diff -r 96e230aed76971953f62728c28b28730608ee2c9 -r 043012c62cfca6a30694445d47790726736c7032 static/scripts/viz/circster.js
--- a/static/scripts/viz/circster.js
+++ b/static/scripts/viz/circster.js
@@ -167,7 +167,7 @@
});
// Render new track.
- var track_index = this.track_views.length
+ var track_index = this.track_views.length,
track_view_class = (new_track.get('track_type') === 'LineTrack' ?
CircsterBigWigTrackView :
CircsterSummaryTreeTrackView ),
@@ -313,13 +313,21 @@
this.parent_elt.selectAll('path.chrom-data').filter(function(d, i) {
return utils.is_visible(this);
}).each(function(d, i) {
- // Now operating on a single path element representing chromosome data.
+ // -- Now operating on a single path element representing chromosome data. --
+
var path_elt = d3.select(this),
chrom = path_elt.attr('chrom'),
chrom_region = self.genome.get_chrom_region(chrom),
+ data_manager = self.track.get('data_manager'),
+ data_deferred;
- // Get more detailde data for chrom.
- data_deferred = self.track.get('data_manager').get_more_detailed_data(chrom_region, 'Coverage', 0, new_scale);
+ // If can't get more detailed data, return.
+ if (!data_manager.can_get_more_detailed_data(chrom_region)) {
+ return;
+ }
+
+ // -- Get more detailed data. --
+ data_deferred = self.track.get('data_manager').get_more_detailed_data(chrom_region, 'Coverage', 0, new_scale);
// When more data is available, use new data to redraw path.
$.when(data_deferred).then(function(data) {
@@ -417,7 +425,7 @@
// Apply prefs to all track data.
var config = track.get('config'),
- block_color = config.get_value('block_color');;
+ block_color = config.get_value('block_color');
if (!block_color) { block_color = config.get_value('color'); }
self.parent_elt.selectAll('path.chrom-data').style('stroke', block_color).style('fill', block_color);
diff -r 96e230aed76971953f62728c28b28730608ee2c9 -r 043012c62cfca6a30694445d47790726736c7032 static/scripts/viz/visualization.js
--- a/static/scripts/viz/visualization.js
+++ b/static/scripts/viz/visualization.js
@@ -429,6 +429,17 @@
},
/**
+ * Returns true if more detailed data can be obtained for entry.
+ */
+ can_get_more_detailed_data: function(region) {
+ var cur_data = this.get_elt(region);
+
+ // Can only get more detailed data for bigwig data that has less than 8000 data points.
+ // Summary tree returns *way* too much data, and 8000 data points ~ 500KB.
+ return (cur_data.dataset_type === 'bigwig' && cur_data.data.length < 8000);
+ },
+
+ /**
* Returns more detailed data for an entry.
*/
get_more_detailed_data: function(region, mode, resolution, detail_multiplier, extra_params) {
@@ -443,7 +454,8 @@
// Use additional parameters to get more detailed data.
if (cur_data.dataset_type === 'bigwig') {
- extra_params.num_samples = cur_data.data.length * detail_multiplier;
+ // FIXME: constant should go somewhere.
+ extra_params.num_samples = 1000 * detail_multiplier;
}
else if (cur_data.dataset_type === 'summary_tree') {
extra_params.level = Math.min(cur_data.level - 1, 2);
https://bitbucket.org/galaxy/galaxy-central/changeset/d2c998e06f0e/
changeset: d2c998e06f0e
user: jgoecks
date: 2012-10-20 22:40:38
summary: Pack scripts.
affected #: 4 files
diff -r 043012c62cfca6a30694445d47790726736c7032 -r d2c998e06f0ef7b117bf2e05150bbed877d5dcb3 static/scripts/packed/utils/config.js
--- a/static/scripts/packed/utils/config.js
+++ b/static/scripts/packed/utils/config.js
@@ -1,1 +1,1 @@
-define(["libs/underscore","viz/trackster/util"],function(b,e){var c=Backbone.Model.extend({defaults:{key:null,value:null,type:"text",label:null,options:null,hidden:false},initialize:function(f){var g=this.get("key");this.set("id",g);var h=b.find(c.known_settings,function(i){return i.key===g});if(h){this.set(b.extend({},h,f))}if(this.get("type")==="color"){this.set("value",e.get_random_color())}this.on("change:value",this.cast_value,this)},cast_value:function(){var f=this.get("type"),g=this.get("value");if(f==="float"){g=parseFloat(g)}else{if(f==="int"){g=parseInt(g,10)}}this.set("value")}},{known_settings:[{key:"name",label:"Name",type:"text",default_value:""},{key:"color",label:"Color",type:"color",default_value:undefined},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:32,hidden:true},{key:"pos_color",label:"Positive Color",type:"color",default_value:"4169E1"},{key:"negative_color",label:"Negative Color",type:"color",default_value:"FF8C00"},{key:"block_color",label:"Block color",type:"color",default_value:undefined},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:undefined},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"histogram_max",label:"Histogram maximum",type:"float",default_value:null,help:"Clear value to set automatically"},{key:"mode",type:"string",default_value:this.mode,hidden:true}]});var d=Backbone.Collection.extend({model:c,to_key_value_dict:function(){var f={};this.each(function(g){f[g.get("key")]=g.get("value")});return f},restore_values:function(g){var f=this;b.keys(g,function(h){var i=f.find(function(j){return j.get("key")===h});if(i){i.set("value",g.key)}})},get_value:function(f){return this.get(f).get("value")}},{from_config_dict:function(g){var f=b.map(b.keys(g),function(h){return{key:h,value:g[h]}});return new d(f)}});var a=Backbone.View.extend({className:"config-settings-view",render:function(){var i=this.model;var f=this.$el;var h;function g(n,j){for(var r=0;r<n.length;r++){h=n[r];if(h.hidden){continue}var l="param_"+r;var v=i.values[h.key];var x=$("<div class='form-row' />").appendTo(j);x.append($("<label />").attr("for",l).text(h.label+":"));if(type==="bool"){x.append($('<input type="checkbox" />').attr("id",l).attr("name",l).attr("checked",v))}else{if(type==="text"){x.append($('<input type="text"/>').attr("id",l).val(v).click(function(){$(this).select()}))}else{if(type==="select"){var t=$("<select />").attr("id",l);for(var p=0;p<h.options.length;p++){$("<option/>").text(h.options[p].label).attr("value",h.options[p].value).appendTo(t)}t.val(v);x.append(t)}else{if(type==="color"){var w=$("<div/>").appendTo(x),s=$("<input />").attr("id",l).attr("name",l).val(v).css("float","left").appendTo(w).click(function(z){$(".bs-tooltip").removeClass("in");var y=$(this).siblings(".bs-tooltip").addClass("in");y.css({left:$(this).position().left+$(this).width()+5,top:$(this).position().top-($(y).height()/2)+($(this).height()/2)}).show();y.click(function(A){A.stopPropagation()});$(document).bind("click.color-picker",function(){y.hide();$(document).unbind("click.color-picker")});z.stopPropagation()}),q=$("<a href='javascript:void(0)'/>").addClass("icon-button arrow-circle").appendTo(w).attr("title","Set new random color").tooltip(),u=$("<div class='bs-tooltip right' style='position: absolute;' />").appendTo(w).hide(),m=$("<div class='tooltip-inner' style='text-align: inherit'></div>").appendTo(u),k=$("<div class='tooltip-arrow'></div>").appendTo(u),o=$.farbtastic(m,{width:100,height:100,callback:s,color:v});w.append($("<div/>").css("clear","both"));(function(y){q.click(function(){y.setColor(e.get_random_color())})})(o)}else{x.append($("<input />").attr("id",l).attr("name",l).val(v))}}}}if(h.help){x.append($("<div class='help'/>").text(h.help))}}}g(this.params,f);return this},render_in_modal:function(){var h=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},f=function(){this.update_from_form();hide_modal();$(window).unbind("keypress.check_enter_esc")},g=function(i){if((i.keyCode||i.which)===27){h()}else{if((i.keyCode||i.which)===13){f()}}};$(window).bind("keypress.check_enter_esc",g);if(this.$el.children().length===0){this.render()}show_modal("Configure",drawable.config.build_form(),{Cancel:h,OK:f})},update_from_form:function(){var f=this;this.collection.each(function(h,g){if(!h.get("hidden")){var j="param_"+g;var i=f.$el.find("#"+j).val();if(type==="bool"){i=container.find("#"+j).is(":checked")}h.set("value",i)}})}});return{ConfigSettingCollection:d,ConfigSettingCollectionView:a}});
\ No newline at end of file
+define(["libs/underscore","viz/trackster/util"],function(b,e){var c=Backbone.Model.extend({initialize:function(f){var g=this.get("key");this.set("id",g);var h=b.find(c.known_settings_defaults,function(i){return i.key===g});if(h){this.set(b.extend({},h,f))}if(this.get("type")==="color"&&!this.get("value")){this.set("value",e.get_random_color())}this.on("change:value",this.cast_value,this)},cast_value:function(){var f=this.get("type"),g=this.get("value");if(f==="float"){g=parseFloat(g)}else{if(f==="int"){g=parseInt(g,10)}}this.set("value")}},{known_settings_defaults:[{key:"name",label:"Name",type:"text",default_value:""},{key:"color",label:"Color",type:"color",default_value:null},{key:"min_value",label:"Min Value",type:"float",default_value:null},{key:"max_value",label:"Max Value",type:"float",default_value:null},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:32,hidden:true},{key:"pos_color",label:"Positive Color",type:"color",default_value:"4169E1"},{key:"negative_color",label:"Negative Color",type:"color",default_value:"FF8C00"},{key:"block_color",label:"Block color",type:"color",default_value:null},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:null},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"histogram_max",label:"Histogram maximum",type:"float",default_value:null,help:"Clear value to set automatically"},{key:"mode",type:"string",default_value:this.mode,hidden:true}]});var d=Backbone.Collection.extend({model:c,to_key_value_dict:function(){var f={};this.each(function(g){f[g.get("key")]=g.get("value")});return f},get_value:function(f){var g=this.get(f);if(g){return g.get("value")}return undefined}},{from_config_dict:function(g){var f=b.map(b.keys(g),function(h){return{key:h,value:g[h]}});return new d(f)}});var a=Backbone.View.extend({className:"config-settings-view",render:function(){var i=this.model;var f=this.$el;var h;function g(n,j){for(var r=0;r<n.length;r++){h=n[r];if(h.hidden){continue}var l="param_"+r;var v=i.values[h.key];var x=$("<div class='form-row' />").appendTo(j);x.append($("<label />").attr("for",l).text(h.label+":"));if(type==="bool"){x.append($('<input type="checkbox" />').attr("id",l).attr("name",l).attr("checked",v))}else{if(type==="text"){x.append($('<input type="text"/>').attr("id",l).val(v).click(function(){$(this).select()}))}else{if(type==="select"){var t=$("<select />").attr("id",l);for(var p=0;p<h.options.length;p++){$("<option/>").text(h.options[p].label).attr("value",h.options[p].value).appendTo(t)}t.val(v);x.append(t)}else{if(type==="color"){var w=$("<div/>").appendTo(x),s=$("<input />").attr("id",l).attr("name",l).val(v).css("float","left").appendTo(w).click(function(z){$(".bs-tooltip").removeClass("in");var y=$(this).siblings(".bs-tooltip").addClass("in");y.css({left:$(this).position().left+$(this).width()+5,top:$(this).position().top-($(y).height()/2)+($(this).height()/2)}).show();y.click(function(A){A.stopPropagation()});$(document).bind("click.color-picker",function(){y.hide();$(document).unbind("click.color-picker")});z.stopPropagation()}),q=$("<a href='javascript:void(0)'/>").addClass("icon-button arrow-circle").appendTo(w).attr("title","Set new random color").tooltip(),u=$("<div class='bs-tooltip right' style='position: absolute;' />").appendTo(w).hide(),m=$("<div class='tooltip-inner' style='text-align: inherit'></div>").appendTo(u),k=$("<div class='tooltip-arrow'></div>").appendTo(u),o=$.farbtastic(m,{width:100,height:100,callback:s,color:v});w.append($("<div/>").css("clear","both"));(function(y){q.click(function(){y.setColor(e.get_random_color())})})(o)}else{x.append($("<input />").attr("id",l).attr("name",l).val(v))}}}}if(h.help){x.append($("<div class='help'/>").text(h.help))}}}g(this.params,f);return this},render_in_modal:function(){var h=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},f=function(){this.update_from_form();hide_modal();$(window).unbind("keypress.check_enter_esc")},g=function(i){if((i.keyCode||i.which)===27){h()}else{if((i.keyCode||i.which)===13){f()}}};$(window).bind("keypress.check_enter_esc",g);if(this.$el.children().length===0){this.render()}show_modal("Configure",drawable.config.build_form(),{Cancel:h,OK:f})},update_from_form:function(){var f=this;this.collection.each(function(h,g){if(!h.get("hidden")){var j="param_"+g;var i=f.$el.find("#"+j).val();if(type==="bool"){i=container.find("#"+j).is(":checked")}h.set("value",i)}})}});return{ConfigSettingCollection:d,ConfigSettingCollectionView:a}});
\ No newline at end of file
diff -r 043012c62cfca6a30694445d47790726736c7032 -r d2c998e06f0ef7b117bf2e05150bbed877d5dcb3 static/scripts/packed/viz/circster.js
--- a/static/scripts/packed/viz/circster.js
+++ b/static/scripts/packed/viz/circster.js
@@ -1,1 +1,1 @@
-define(["libs/underscore","libs/d3","viz/visualization"],function(g,j,h){var k=Backbone.Model.extend({is_visible:function(o,l){var m=o.getBoundingClientRect(),n=$("svg")[0].getBoundingClientRect();if(m.right<0||m.left>n.right||m.bottom<0||m.top>n.bottom){return false}return true}});var c=Backbone.Model.extend({defaults:{prefs:{color:"#ccc"}}});var a=Backbone.View.extend({className:"circster",initialize:function(l){this.total_gap=l.total_gap;this.genome=l.genome;this.dataset_arc_height=l.dataset_arc_height;this.track_gap=5;this.label_arc_height=20;this.scale=1;this.track_views=null;this.model.get("tracks").on("add",this.add_track,this)},get_tracks_bounds:function(){var n=this.dataset_arc_height,l=Math.min(this.$el.width(),this.$el.height()),p=l/2-this.model.get("tracks").length*(this.dataset_arc_height+this.track_gap)-(this.label_arc_height+this.track_gap),o=j.range(p,l/2,this.dataset_arc_height+this.track_gap);var m=this;return g.map(o,function(q){return[q,q+m.dataset_arc_height]})},render:function(){var o=this,q=this.dataset_arc_height,r=o.$el.width(),l=o.$el.height(),p=this.model.get("tracks"),s=this.get_tracks_bounds(),n=j.select(o.$el[0]).append("svg").attr("width",r).attr("height",l).attr("pointer-events","all").append("svg:g").call(j.behavior.zoom().on("zoom",function(){var t=j.event.scale;n.attr("transform","translate("+j.event.translate+") scale("+t+")");if(o.scale!==t){if(o.zoom_drag_timeout){clearTimeout(o.zoom_drag_timeout)}o.zoom_drag_timeout=setTimeout(function(){g.each(o.track_views,function(u){u.update_scale(t)})},400)}})).attr("transform","translate("+r/2+","+l/2+")").append("svg:g").attr("class","tracks");this.track_views=p.map(function(t,u){track_view_class=(t.get("track_type")==="LineTrack"?d:e);return new track_view_class({el:n.append("g")[0],track:t,radius_bounds:s[u],genome:o.genome,total_gap:o.total_gap})});g.each(this.track_views,function(t){t.render()});var m=s[p.length];m[1]=m[0];this.label_track_view=new b({el:n.append("g")[0],track:new c(),radius_bounds:m,genome:o.genome,total_gap:o.total_gap});this.label_track_view.render()},add_track:function(o){var n=this.get_tracks_bounds();g.each(this.track_views,function(p,q){p.update_radius_bounds(n[q])});var m=this.track_views.length;track_view_class=(o.get("track_type")==="LineTrack"?d:e),track_view=new track_view_class({el:j.select("g.tracks").append("g")[0],track:o,radius_bounds:n[m],genome:this.genome,total_gap:this.total_gap});track_view.render();this.track_views.push(track_view);var l=n[n.length-1];l[1]=l[0];this.label_track_view.update_radius_bounds(l)}});var i=Backbone.View.extend({tagName:"g",initialize:function(l){this.options=l;this.options.bg_stroke="ccc";this.options.loading_bg_fill="000";this.options.bg_fill="ccc";this.options.chroms_layout=this._chroms_layout();this.options.data_bounds=[];this.options.scale=1;this.options.parent_elt=j.select(this.$el[0])},render:function(){var p=this.options.parent_elt;if(!p){console.log("no parent elt")}var o=this.options.chroms_layout,r=j.svg.arc().innerRadius(this.options.radius_bounds[0]).outerRadius(this.options.radius_bounds[1]),l=p.selectAll("g").data(o).enter().append("svg:g"),n=l.append("path").attr("d",r).attr("class","chrom-background").style("stroke",this.options.bg_stroke).style("fill",this.options.loading_bg_fill);n.append("title").text(function(t){return t.data.chrom});var m=this,q=m.options.track.get("data_manager"),s=(q?q.data_is_ready():true);$.when(s).then(function(){$.when(m._render_data(p)).then(function(){var t=m.options.track.get("prefs"),u=t.block_color;if(!u){u=t.color}p.selectAll("path.chrom-data").style("stroke",u).style("fill",u);n.style("fill",m.options.bg_fill)})})},update_radius_bounds:function(r){this.options.radius_bounds=r;var p=j.svg.arc().innerRadius(this.options.radius_bounds[0]).outerRadius(this.options.radius_bounds[1]);this.options.parent_elt.selectAll("g>path.chrom-background").transition().duration(1000).attr("d",p);var m=this.options.track,o=this.options.chroms_layout,l=this.options.parent_elt.selectAll("g>path.chrom-data"),q=l[0].length;if(q>0){var n=this;$.when(m.get("data_manager").get_genome_wide_data(this.options.genome)).then(function(t){var s=g.reject(g.map(t,function(u,v){var w=null,x=n._compute_path_data(o[v],u);if(x){w=x(u.data)}return w}),function(u){return u===null});l.each(function(v,u){j.select(this).transition().duration(1000).attr("d",s[u])})})}},update_scale:function(o){var n=this.options.scale;this.options.scale=o;if(o<=n){return}var m=this,l=new k();this.options.parent_elt.selectAll("path.chrom-data").filter(function(q,p){return l.is_visible(this)}).each(function(u,r){var t=j.select(this),q=t.attr("chrom"),s=m.options.genome.get_chrom_region(q),p=m.options.track.get("data_manager").get_more_detailed_data(s,"Coverage",0,o);$.when(p).then(function(y){t.remove();m._update_data_bounds();var x=g.find(m.options.chroms_layout,function(z){return z.data.chrom===q});var v=m.options.track.get("prefs"),w=v.block_color;if(!w){w=v.color}m._render_chrom_data(m.options.parent_elt,x,y).style("stroke",w).style("fill",w)})});return m},_update_data_bounds:function(){},_render_data:function(o){var n=this,m=this.options.chroms_layout,l=this.options.track,p=$.Deferred();$.when(l.get("data_manager").get_genome_wide_data(this.options.genome)).then(function(q){n.options.data_bounds=n.get_data_bounds(q);layout_and_data=g.zip(m,q),chroms_data_layout=g.map(layout_and_data,function(r){var s=r[0],t=r[1];return n._render_chrom_data(o,s,t)});p.resolve(o)});return p},_render_chrom_data:function(l,m,n){},_compute_path_data:function(m,l){},_chroms_layout:function(){var m=this.options.genome.get_chroms_info(),o=j.layout.pie().value(function(q){return q.len}).sort(null),p=o(m),l=this.options.total_gap/m.length,n=g.map(p,function(s,r){var q=s.endAngle-l;s.endAngle=(q>s.startAngle?q:s.startAngle);return s});return n}});var b=i.extend({initialize:function(l){i.prototype.initialize.call(this,l);this.options.bg_stroke="fff";this.options.bg_fill="fff"},_render_data:function(m){var l=m.selectAll("g");l.selectAll("path").attr("id",function(n){return"label-"+n.data.chrom});l.append("svg:text").filter(function(n){return n.endAngle-n.startAngle>0.08}).attr("text-anchor","middle").append("svg:textPath").attr("xlink:href",function(n){return"#label-"+n.data.chrom}).attr("startOffset","25%").text(function(n){return n.data.chrom})}});var f=i.extend({_render_chrom_data:function(l,o,m){var p=this._compute_path_data(o,m);if(!p){return null}var n=l.datum(m.data),q=n.append("path").attr("class","chrom-data").attr("chrom",o.data.chrom).attr("d",p);return q},_compute_path_data:function(o,n){if(typeof n==="string"||!n.data||n.data.length===0){return null}var l=j.scale.linear().domain(this.options.data_bounds).range(this.options.radius_bounds);var p=j.scale.linear().domain([0,n.data.length]).range([o.startAngle,o.endAngle]);var m=j.svg.line.radial().interpolate("linear").radius(function(q){return l(q[1])}).angle(function(r,q){return p(q)});return j.svg.area.radial().interpolate(m.interpolate()).innerRadius(l(0)).outerRadius(m.radius()).angle(m.angle())},get_data_bounds:function(l){}});var e=f.extend({get_data_bounds:function(m){var l=g.map(m,function(n){if(typeof n==="string"||!n.max){return 0}return n.max});return[0,(l&&typeof l!=="string"?g.max(l):0)]}});var d=f.extend({get_data_bounds:function(m){var l=g.flatten(g.map(m,function(n){if(n){return g.map(n.data,function(o){return o[1]})}else{return 0}}));return[g.min(l),g.max(l)]}});return{CircsterView:a}});
\ No newline at end of file
+define(["libs/underscore","libs/d3","viz/visualization"],function(g,j,h){var k=Backbone.Model.extend({is_visible:function(o,l){var m=o.getBoundingClientRect(),n=$("svg")[0].getBoundingClientRect();if(m.right<0||m.left>n.right||m.bottom<0||m.top>n.bottom){return false}return true}});var c=Backbone.Model.extend({defaults:{prefs:{color:"#ccc"}}});var a=Backbone.View.extend({className:"circster",initialize:function(l){this.total_gap=l.total_gap;this.genome=l.genome;this.dataset_arc_height=l.dataset_arc_height;this.track_gap=5;this.label_arc_height=20;this.scale=1;this.track_views=null;this.model.get("tracks").on("add",this.add_track,this);this.model.get("tracks").on("remove",this.remove_track,this)},get_tracks_bounds:function(){var n=this.dataset_arc_height,l=Math.min(this.$el.width(),this.$el.height()),p=l/2-this.model.get("tracks").length*(this.dataset_arc_height+this.track_gap)-(this.label_arc_height+this.track_gap),o=j.range(p,l/2,this.dataset_arc_height+this.track_gap);var m=this;return g.map(o,function(q){return[q,q+m.dataset_arc_height]})},render:function(){var o=this,q=this.dataset_arc_height,r=o.$el.width(),l=o.$el.height(),p=this.model.get("tracks"),s=this.get_tracks_bounds(),n=j.select(o.$el[0]).append("svg").attr("width",r).attr("height",l).attr("pointer-events","all").append("svg:g").call(j.behavior.zoom().on("zoom",function(){var t=j.event.scale;n.attr("transform","translate("+j.event.translate+") scale("+t+")");if(o.scale!==t){if(o.zoom_drag_timeout){clearTimeout(o.zoom_drag_timeout)}o.zoom_drag_timeout=setTimeout(function(){g.each(o.track_views,function(u){u.update_scale(t)})},400)}})).attr("transform","translate("+r/2+","+l/2+")").append("svg:g").attr("class","tracks");this.track_views=p.map(function(t,u){track_view_class=(t.get("track_type")==="LineTrack"?d:e);return new track_view_class({el:n.append("g")[0],track:t,radius_bounds:s[u],genome:o.genome,total_gap:o.total_gap})});g.each(this.track_views,function(t){t.render()});var m=s[p.length];m[1]=m[0];this.label_track_view=new b({el:n.append("g")[0],track:new c(),radius_bounds:m,genome:o.genome,total_gap:o.total_gap});this.label_track_view.render()},add_track:function(p){var o=this.get_tracks_bounds();g.each(this.track_views,function(r,s){r.update_radius_bounds(o[s])});var n=this.track_views.length,q=(p.get("track_type")==="LineTrack"?d:e),l=new q({el:j.select("g.tracks").append("g")[0],track:p,radius_bounds:o[n],genome:this.genome,total_gap:this.total_gap});l.render();this.track_views.push(l);var m=o[o.length-1];m[1]=m[0];this.label_track_view.update_radius_bounds(m)},remove_track:function(m,o,n){var l=this.track_views[n.index];this.track_views.splice(n.index,1);l.$el.remove();var p=this.get_tracks_bounds();g.each(this.track_views,function(q,r){q.update_radius_bounds(p[r])})}});var i=Backbone.View.extend({tagName:"g",initialize:function(l){this.bg_stroke="ccc";this.loading_bg_fill="000";this.bg_fill="ccc";this.total_gap=l.total_gap;this.track=l.track;this.radius_bounds=l.radius_bounds;this.genome=l.genome;this.chroms_layout=this._chroms_layout();this.data_bounds=[];this.scale=1;this.parent_elt=j.select(this.$el[0])},render:function(){var p=this.parent_elt;if(!p){console.log("no parent elt")}var o=this.chroms_layout,r=j.svg.arc().innerRadius(this.radius_bounds[0]).outerRadius(this.radius_bounds[1]),l=p.selectAll("g").data(o).enter().append("svg:g"),n=l.append("path").attr("d",r).attr("class","chrom-background").style("stroke",this.bg_stroke).style("fill",this.loading_bg_fill);n.append("title").text(function(t){return t.data.chrom});var m=this,q=m.track.get("data_manager"),s=(q?q.data_is_ready():true);$.when(s).then(function(){$.when(m._render_data(p)).then(function(){n.style("fill",m.bg_fill)})})},update_radius_bounds:function(m){this.radius_bounds=m;var l=j.svg.arc().innerRadius(this.radius_bounds[0]).outerRadius(this.radius_bounds[1]);this.parent_elt.selectAll("g>path.chrom-background").transition().duration(1000).attr("d",l);this._transition_chrom_data()},update_scale:function(o){var n=this.scale;this.scale=o;if(o<=n){return}var m=this,l=new k();this.parent_elt.selectAll("path.chrom-data").filter(function(q,p){return l.is_visible(this)}).each(function(v,r){var u=j.select(this),q=u.attr("chrom"),t=m.genome.get_chrom_region(q),s=m.track.get("data_manager"),p;if(!s.can_get_more_detailed_data(t)){return}p=m.track.get("data_manager").get_more_detailed_data(t,"Coverage",0,o);$.when(p).then(function(z){u.remove();m._update_data_bounds();var y=g.find(m.chroms_layout,function(A){return A.data.chrom===q});var w=m.track.get("prefs"),x=w.block_color;if(!x){x=w.color}m._render_chrom_data(m.parent_elt,y,z).style("stroke",x).style("fill",x)})});return m},_transition_chrom_data:function(){var m=this.track,o=this.chroms_layout,l=this.parent_elt.selectAll("g>path.chrom-data"),p=l[0].length;if(p>0){var n=this;$.when(m.get("data_manager").get_genome_wide_data(this.genome)).then(function(r){var q=g.reject(g.map(r,function(s,t){var u=null,v=n._get_path_function(o[t],s);if(v){u=v(s.data)}return u}),function(s){return s===null});l.each(function(t,s){j.select(this).transition().duration(1000).attr("d",q[s])})})}},_update_data_bounds:function(){var l=this.data_bounds;this.data_bounds=this.get_data_bounds(this.track.get("data_manager").get_genome_wide_data(this.genome));if(this.data_bounds[0]<l[0]||this.data_bounds[1]>l[1]){this._transition_chrom_data()}},_render_data:function(o){var n=this,m=this.chroms_layout,l=this.track,p=$.Deferred();$.when(l.get("data_manager").get_genome_wide_data(this.genome)).then(function(s){n.data_bounds=n.get_data_bounds(s);layout_and_data=g.zip(m,s),chroms_data_layout=g.map(layout_and_data,function(t){var u=t[0],v=t[1];return n._render_chrom_data(o,u,v)});var q=l.get("config"),r=q.get_value("block_color");if(!r){r=q.get_value("color")}n.parent_elt.selectAll("path.chrom-data").style("stroke",r).style("fill",r);p.resolve(o)});return p},_render_chrom_data:function(l,m,n){},_get_path_function:function(m,l){},_chroms_layout:function(){var m=this.genome.get_chroms_info(),o=j.layout.pie().value(function(q){return q.len}).sort(null),p=o(m),l=this.total_gap/m.length,n=g.map(p,function(s,r){var q=s.endAngle-l;s.endAngle=(q>s.startAngle?q:s.startAngle);return s});return n}});var b=i.extend({initialize:function(l){i.prototype.initialize.call(this,l);this.bg_stroke="fff";this.bg_fill="fff"},_render_data:function(m){var l=m.selectAll("g");l.selectAll("path").attr("id",function(n){return"label-"+n.data.chrom});l.append("svg:text").filter(function(n){return n.endAngle-n.startAngle>0.08}).attr("text-anchor","middle").append("svg:textPath").attr("xlink:href",function(n){return"#label-"+n.data.chrom}).attr("startOffset","25%").text(function(n){return n.data.chrom})}});var f=i.extend({_render_chrom_data:function(l,o,m){var p=this._get_path_function(o,m);if(!p){return null}var n=l.datum(m.data),q=n.append("path").attr("class","chrom-data").attr("chrom",o.data.chrom).attr("d",p);return q},_get_path_function:function(o,n){if(typeof n==="string"||!n.data||n.data.length===0){return null}var l=j.scale.linear().domain(this.data_bounds).range(this.radius_bounds);var p=j.scale.linear().domain([0,n.data.length]).range([o.startAngle,o.endAngle]);var m=j.svg.line.radial().interpolate("linear").radius(function(q){return l(q[1])}).angle(function(r,q){return p(q)});return j.svg.area.radial().interpolate(m.interpolate()).innerRadius(l(0)).outerRadius(m.radius()).angle(m.angle())},get_data_bounds:function(l){}});var e=f.extend({get_data_bounds:function(m){var l=g.map(m,function(n){if(typeof n==="string"||!n.max){return 0}return n.max});return[0,(l&&typeof l!=="string"?g.max(l):0)]}});var d=f.extend({get_data_bounds:function(m){var l=g.flatten(g.map(m,function(n){if(n){return g.map(n.data,function(o){return o[1]})}else{return 0}}));return[g.min(l),g.max(l)]}});return{CircsterView:a}});
\ No newline at end of file
diff -r 043012c62cfca6a30694445d47790726736c7032 -r d2c998e06f0ef7b117bf2e05150bbed877d5dcb3 static/scripts/packed/viz/trackster_ui.js
--- a/static/scripts/packed/viz/trackster_ui.js
+++ b/static/scripts/packed/viz/trackster_ui.js
@@ -1,1 +1,1 @@
-define(["base","libs/underscore","viz/trackster/slotting","viz/trackster/painters","viz/trackster/tracks","viz/visualization"],function(g,c,h,e,b,d){var a=b.object_from_template;var f=g.Base.extend({initialize:function(j){this.baseURL=j},createButtonMenu:function(){var j=this,k=create_icon_buttons_menu([{icon_class:"plus-button",title:"Add tracks",on_click:function(){d.select_datasets(select_datasets_url,add_track_async_url,view.dbkey,function(l){c.each(l,function(m){view.add_drawable(a(m,view,view))})})}},{icon_class:"block--plus",title:"Add group",on_click:function(){view.add_drawable(new b.DrawableGroup(view,view,{name:"New Group"}))}},{icon_class:"bookmarks",title:"Bookmarks",on_click:function(){parent.force_right_panel(($("div#right").css("right")=="0px"?"hide":"show"))}},{icon_class:"globe",title:"Circster",on_click:function(){window.location=j.baseURL+"visualization/circster?id="+view.vis_id}},{icon_class:"disk--arrow",title:"Save",on_click:function(){show_modal("Saving...","progress");var l=[];$(".bookmark").each(function(){l.push({position:$(this).children(".position").text(),annotation:$(this).children(".annotation").text()})});var m=(view.overview_drawable?view.overview_drawable.name:null),n={id:view.vis_id,title:view.name,dbkey:view.dbkey,type:"trackster",datasets:view.to_dict(),viewport:{chrom:view.chrom,start:view.low,end:view.high,overview:m},bookmarks:l};$.ajax({url:galaxy_paths.get("visualization_url"),type:"POST",dataType:"json",data:{vis_json:JSON.stringify(n)}}).success(function(o){hide_modal();view.vis_id=o.vis_id;view.has_changes=false;window.history.pushState({},"",o.url+window.location.hash)}).error(function(){show_modal("Could Not Save","Could not save visualization. Please try again later.",{Close:hide_modal})})}},{icon_class:"cross-circle",title:"Close",on_click:function(){window.location=j.baseURL+"visualization/list"}}],{tooltip_config:{placement:"bottom"}});this.buttonMenu=k;return k},add_bookmarks:function(){var j=this,k=this.baseURL;show_modal("Select dataset for new bookmarks","progress");$.ajax({url:this.baseURL+"/visualization/list_histories",data:{"f-dbkey":view.dbkey},error:function(){alert("Grid failed")},success:function(l){show_modal("Select dataset for new bookmarks",l,{Cancel:function(){hide_modal()},Insert:function(){$("input[name=id]:checked,input[name=ldda_ids]:checked").first().each(function(){var m,n=$(this).val();if($(this).attr("name")==="id"){m={hda_id:n}}else{m={ldda_id:n}}$.ajax({url:this.baseURL+"/visualization/bookmarks_from_dataset",data:m,dataType:"json"}).then(function(o){for(i=0;i<o.data.length;i++){var p=o.data[i];j.add_bookmark(p[0],p[1])}})});hide_modal()}})}})},add_bookmark:function(n,l,j){var p=$("#bookmarks-container"),r=$("<div/>").addClass("bookmark").appendTo(p);var s=$("<div/>").addClass("position").appendTo(r),o=$("<a href=''/>").text(n).appendTo(s).click(function(){view.go_to(n);return false}),m=$("<div/>").text(l).appendTo(r);if(j){var q=$("<div/>").addClass("delete-icon-container").prependTo(r).click(function(){r.slideUp("fast");r.remove();view.has_changes=true;return false}),k=$("<a href=''/>").addClass("icon-button delete").appendTo(q);m.make_text_editable({num_rows:3,use_textarea:true,help_text:"Edit bookmark note"}).addClass("annotation")}view.has_changes=true;return r},create_visualization:function(o,j,n,p,m){var l=this,k=new b.View(o);k.editor=true;$.when(k.load_chroms_deferred).then(function(){if(j){var y=j.chrom,q=j.start,v=j.end,s=j.overview;if(y&&(q!==undefined)&&v){k.change_chrom(y,q,v)}}if(n){var t,r,u;for(var w=0;w<n.length;w++){k.add_drawable(a(n[w],k,k))}}k.update_intro_div();var z;for(var w=0;w<k.drawables.length;w++){if(k.drawables[w].name===s){k.set_overview(k.drawables[w]);break}}if(p){var x;for(var w=0;w<p.length;w++){x=p[w];l.add_bookmark(x.position,x.annotation,m)}}k.has_changes=false});return k},init_keyboard_nav:function(j){$(document).keydown(function(k){if($(k.srcElement).is(":input")){return}switch(k.which){case 37:j.move_fraction(0.25);break;case 38:var l=Math.round(j.viewport_container.height()/15);j.viewport_container.scrollTop(j.viewport_container.scrollTop()-20);break;case 39:j.move_fraction(-0.25);break;case 40:var l=Math.round(j.viewport_container.height()/15);j.viewport_container.scrollTop(j.viewport_container.scrollTop()+20);break}})}});return{object_from_template:a,TracksterUI:f}});
\ No newline at end of file
+define(["base","libs/underscore","viz/trackster/slotting","viz/trackster/painters","viz/trackster/tracks","viz/visualization"],function(g,c,h,e,b,d){var a=b.object_from_template;var f=g.Base.extend({initialize:function(j){this.baseURL=j},createButtonMenu:function(){var j=this,k=create_icon_buttons_menu([{icon_class:"plus-button",title:"Add tracks",on_click:function(){d.select_datasets(select_datasets_url,add_track_async_url,view.dbkey,function(l){c.each(l,function(m){view.add_drawable(a(m,view,view))})})}},{icon_class:"block--plus",title:"Add group",on_click:function(){view.add_drawable(new b.DrawableGroup(view,view,{name:"New Group"}))}},{icon_class:"bookmarks",title:"Bookmarks",on_click:function(){parent.force_right_panel(($("div#right").css("right")=="0px"?"hide":"show"))}},{icon_class:"globe",title:"Circster",on_click:function(){window.location=j.baseURL+"visualization/circster?id="+view.vis_id}},{icon_class:"disk--arrow",title:"Save",on_click:function(){show_modal("Saving...","progress");var l=[];$(".bookmark").each(function(){l.push({position:$(this).children(".position").text(),annotation:$(this).children(".annotation").text()})});var m=(view.overview_drawable?view.overview_drawable.name:null),n={view:view.to_dict(),viewport:{chrom:view.chrom,start:view.low,end:view.high,overview:m},bookmarks:l};$.ajax({url:galaxy_paths.get("visualization_url"),type:"POST",dataType:"json",data:{id:view.vis_id,title:view.name,dbkey:view.dbkey,type:"trackster",vis_json:JSON.stringify(n)}}).success(function(o){hide_modal();view.vis_id=o.vis_id;view.has_changes=false;window.history.pushState({},"",o.url+window.location.hash)}).error(function(){show_modal("Could Not Save","Could not save visualization. Please try again later.",{Close:hide_modal})})}},{icon_class:"cross-circle",title:"Close",on_click:function(){window.location=j.baseURL+"visualization/list"}}],{tooltip_config:{placement:"bottom"}});this.buttonMenu=k;return k},add_bookmarks:function(){var j=this,k=this.baseURL;show_modal("Select dataset for new bookmarks","progress");$.ajax({url:this.baseURL+"/visualization/list_histories",data:{"f-dbkey":view.dbkey},error:function(){alert("Grid failed")},success:function(l){show_modal("Select dataset for new bookmarks",l,{Cancel:function(){hide_modal()},Insert:function(){$("input[name=id]:checked,input[name=ldda_ids]:checked").first().each(function(){var m,n=$(this).val();if($(this).attr("name")==="id"){m={hda_id:n}}else{m={ldda_id:n}}$.ajax({url:this.baseURL+"/visualization/bookmarks_from_dataset",data:m,dataType:"json"}).then(function(o){for(i=0;i<o.data.length;i++){var p=o.data[i];j.add_bookmark(p[0],p[1])}})});hide_modal()}})}})},add_bookmark:function(n,l,j){var p=$("#bookmarks-container"),r=$("<div/>").addClass("bookmark").appendTo(p);var s=$("<div/>").addClass("position").appendTo(r),o=$("<a href=''/>").text(n).appendTo(s).click(function(){view.go_to(n);return false}),m=$("<div/>").text(l).appendTo(r);if(j){var q=$("<div/>").addClass("delete-icon-container").prependTo(r).click(function(){r.slideUp("fast");r.remove();view.has_changes=true;return false}),k=$("<a href=''/>").addClass("icon-button delete").appendTo(q);m.make_text_editable({num_rows:3,use_textarea:true,help_text:"Edit bookmark note"}).addClass("annotation")}view.has_changes=true;return r},create_visualization:function(o,j,n,p,m){var l=this,k=new b.View(o);k.editor=true;$.when(k.load_chroms_deferred).then(function(){if(j){var y=j.chrom,q=j.start,v=j.end,s=j.overview;if(y&&(q!==undefined)&&v){k.change_chrom(y,q,v)}}if(n){var t,r,u;for(var w=0;w<n.length;w++){k.add_drawable(a(n[w],k,k))}}k.update_intro_div();var z;for(var w=0;w<k.drawables.length;w++){if(k.drawables[w].name===s){k.set_overview(k.drawables[w]);break}}if(p){var x;for(var w=0;w<p.length;w++){x=p[w];l.add_bookmark(x.position,x.annotation,m)}}k.has_changes=false});return k},init_keyboard_nav:function(j){$(document).keydown(function(k){if($(k.srcElement).is(":input")){return}switch(k.which){case 37:j.move_fraction(0.25);break;case 38:var l=Math.round(j.viewport_container.height()/15);j.viewport_container.scrollTop(j.viewport_container.scrollTop()-20);break;case 39:j.move_fraction(-0.25);break;case 40:var l=Math.round(j.viewport_container.height()/15);j.viewport_container.scrollTop(j.viewport_container.scrollTop()+20);break}})}});return{object_from_template:a,TracksterUI:f}});
\ No newline at end of file
diff -r 043012c62cfca6a30694445d47790726736c7032 -r d2c998e06f0ef7b117bf2e05150bbed877d5dcb3 static/scripts/packed/viz/visualization.js
--- a/static/scripts/packed/viz/visualization.js
+++ b/static/scripts/packed/viz/visualization.js
@@ -1,1 +1,1 @@
-define(["libs/underscore","mvc/data","viz/trackster/util","utils/config"],function(s,i,l,p){var a=function(u,x,v,w){$.ajax({url:u,data:(v?{"f-dbkey":v}:{}),error:function(){alert("Grid failed")},success:function(y){show_modal("Select datasets for new tracks",y,{Cancel:function(){hide_modal()},Add:function(){var z=[];$("input[name=id]:checked,input[name=ldda_ids]:checked").each(function(){var A={data_type:"track_config",hda_ldda:"hda"},B=$(this).val();if($(this).attr("name")!=="id"){A.hda_ldda="ldda"}z[z.length]=$.ajax({url:x+"/"+B,data:A,dataType:"json"})});$.when.apply($,z).then(function(){var A=(arguments[0] instanceof Array?$.map(arguments,function(B){return B[0]}):[arguments[0]]);w(A)});hide_modal()}})}})};var j=function(u){return("isResolved" in u)};var f=function(u){this.default_font=u!==undefined?u:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};s.extend(f.prototype,{load_pattern:function(u,y){var v=this.patterns,w=this.dummy_context,x=new Image();x.src=galaxy_paths.attributes.image_path+y;x.onload=function(){v[u]=w.createPattern(x,"repeat")}},get_pattern:function(u){return this.patterns[u]},new_canvas:function(){var u=$("<canvas/>")[0];if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(u)}u.manager=this;return u}});var q=Backbone.Model.extend({defaults:{num_elements:20,obj_cache:null,key_ary:null},initialize:function(u){this.clear()},get_elt:function(v){var w=this.attributes.obj_cache,x=this.attributes.key_ary,u=x.indexOf(v);if(u!==-1){if(w[v].stale){x.splice(u,1);delete w[v]}else{this.move_key_to_end(v,u)}}return w[v]},set_elt:function(v,x){var y=this.attributes.obj_cache,z=this.attributes.key_ary,w=this.attributes.num_elements;if(!y[v]){if(z.length>=w){var u=z.shift();delete y[u]}z.push(v)}y[v]=x;return x},move_key_to_end:function(v,u){this.attributes.key_ary.splice(u,1);this.attributes.key_ary.push(v)},clear:function(){this.attributes.obj_cache={};this.attributes.key_ary=[]},size:function(){return this.attributes.key_ary.length}});var d=q.extend({defaults:s.extend({},q.prototype.defaults,{dataset:null,init_data:null,filters_manager:null,data_type:"data",data_mode_compatible:function(u,v){return true},can_subset:function(u){return false}}),initialize:function(u){q.prototype.initialize.call(this);var v=this.get("init_data");if(v){this.add_data(v)}},add_data:function(u){if(this.get("num_elements")<u.length){this.set("num_elements",u.length)}var v=this;s.each(u,function(w){v.set_data(w.region,w)})},data_is_ready:function(){var x=this.get("dataset"),w=$.Deferred(),u=(this.get("data_type")=="raw_data"?"state":this.get("data_type")=="data"?"converted_datasets_state":"error"),v=new l.ServerStateDeferred({ajax_settings:{url:this.get("dataset").url(),data:{hda_ldda:x.get("hda_ldda"),data_type:u},dataType:"json"},interval:5000,success_fn:function(y){return y!=="pending"}});$.when(v.go()).then(function(y){w.resolve(y==="ok"||y==="data")});return w},search_features:function(u){var v=this.get("dataset"),w={query:u,hda_ldda:v.get("hda_ldda"),data_type:"features"};return $.getJSON(v.url(),w)},load_data:function(C,B,v,A){var y=this.get("dataset"),x={data_type:this.get("data_type"),chrom:C.get("chrom"),low:C.get("start"),high:C.get("end"),mode:B,resolution:v,hda_ldda:y.get("hda_ldda")};$.extend(x,A);var E=this.get("filters_manager");if(E){var F=[];var u=E.filters;for(var z=0;z<u.length;z++){F.push(u[z].name)}x.filter_cols=JSON.stringify(F)}var w=this,D=$.getJSON(y.url(),x,function(G){w.set_data(C,G)});this.set_data(C,D);return D},get_data:function(A,z,w,y){var B=this.get_elt(A);if(B&&(j(B)||this.get("data_mode_compatible")(B,z))){return B}var C=this.get("key_ary"),v=this.get("obj_cache"),D,u;for(var x=0;x<C.length;x++){D=C[x];u=new g({from_str:D});if(u.contains(A)){B=v[D];if(j(B)||(this.get("data_mode_compatible")(B,z)&&this.get("can_subset")(B))){this.move_key_to_end(D,x);return B}}}return this.load_data(A,z,w,y)},set_data:function(v,u){this.set_elt(v,u)},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(C,B,x,A,y){var E=this._mark_stale(C);if(!(E&&this.get("data_mode_compatible")(E,B))){console.log("ERROR: problem with getting more data: current data is not compatible");return}var w=C.get("start");if(y===this.DEEP_DATA_REQ){$.extend(A,{start_val:E.data.length+1})}else{if(y===this.BROAD_DATA_REQ){w=(E.max_high?E.max_high:E.data[E.data.length-1][2])+1}}var D=C.copy().set("start",w);var v=this,z=this.load_data(D,B,x,A),u=$.Deferred();this.set_data(C,u);$.when(z).then(function(F){if(F.data){F.data=E.data.concat(F.data);if(F.max_low){F.max_low=E.max_low}if(F.message){F.message=F.message.replace(/[0-9]+/,F.data.length)}}v.set_data(C,F);u.resolve(F)});return u},get_more_detailed_data:function(x,z,v,y,w){var u=this._mark_stale(x);if(!u){console.log("ERROR getting more detailed data: no current data");return}if(!w){w={}}if(u.dataset_type==="bigwig"){w.num_samples=u.data.length*y}else{if(u.dataset_type==="summary_tree"){w.level=Math.min(u.level-1,2)}}return this.load_data(x,z,v,w)},_mark_stale:function(v){var u=this.get_elt(v);if(!u){console.log("ERROR: no data to mark as stale: ",this.get("dataset"),v.toString())}u.stale=true;return u},get_genome_wide_data:function(u){var w=this,y=true,x=s.map(u.get("chroms_info").chrom_info,function(A){var z=w.get_elt(new g({chrom:A.chrom,start:0,end:A.len}));if(!z){y=false}return z});if(y){return x}var v=$.Deferred();$.getJSON(this.get("dataset").url(),{data_type:"genome_data"},function(z){w.add_data(z.data);v.resolve(z.data)});return v},get_elt:function(u){return q.prototype.get_elt.call(this,u.toString())},set_elt:function(v,u){return q.prototype.set_elt.call(this,v.toString(),u)}});var n=d.extend({initialize:function(u){var v=new Backbone.Model();v.urlRoot=u.data_url;this.set("dataset",v)},load_data:function(w,x,u,v){if(u>1){return{data:null}}return d.prototype.load_data.call(this,w,x,u,v)}});var c=Backbone.Model.extend({defaults:{name:null,key:null,chroms_info:null},initialize:function(u){this.id=u.dbkey},get_chroms_info:function(){return this.attributes.chroms_info.chrom_info},get_chrom_region:function(u){var v=s.find(this.get_chroms_info(),function(w){return w.chrom==u});return new g({chrom:v.chrom,end:v.len})}});var g=Backbone.RelationalModel.extend({defaults:{chrom:null,start:0,end:0,DIF_CHROMS:1000,BEFORE:1001,CONTAINS:1002,OVERLAP_START:1003,OVERLAP_END:1004,CONTAINED_BY:1005,AFTER:1006},initialize:function(v){if(v.from_str){var x=v.from_str.split(":"),w=x[0],u=x[1].split("-");this.set({chrom:w,start:parseInt(u[0],10),end:parseInt(u[1],10)})}},copy:function(){return new g({chrom:this.get("chrom"),start:this.get("start"),end:this.get("end")})},length:function(){return this.get("end")-this.get("start")},toString:function(){return this.get("chrom")+":"+this.get("start")+"-"+this.get("end")},toJSON:function(){return{chrom:this.get("chrom"),start:this.get("start"),end:this.get("end")}},compute_overlap:function(B){var v=this.get("chrom"),A=B.get("chrom"),z=this.get("start"),x=B.get("start"),y=this.get("end"),w=B.get("end"),u;if(v&&A&&v!==A){return this.get("DIF_CHROMS")}if(z<x){if(y<x){u=this.get("BEFORE")}else{if(y<=w){u=this.get("OVERLAP_START")}else{u=this.get("CONTAINS")}}}else{if(z>w){u=this.get("AFTER")}else{if(y<=w){u=this.get("CONTAINED_BY")}else{u=this.get("OVERLAP_END")}}}return u},contains:function(u){return this.compute_overlap(u)===this.get("CONTAINS")},overlaps:function(u){return s.intersection([this.compute_overlap(u)],[this.get("DIF_CHROMS"),this.get("BEFORE"),this.get("AFTER")]).length===0}});var m=Backbone.Collection.extend({model:g});var e=Backbone.RelationalModel.extend({defaults:{region:null,note:""},relations:[{type:Backbone.HasOne,key:"region",relatedModel:g}]});var r=Backbone.Collection.extend({model:e});var t=i.Dataset.extend({initialize:function(u){this.set("id",u.dataset_id);this.set("settings",p.ConfigSettingCollection.from_config_dict(u.prefs));var v=this.get("preloaded_data");if(v){v=v.data}else{v=[]}this.set("data_manager",new d({dataset:this,init_data:v}))}});var o=Backbone.RelationalModel.extend({defaults:{title:"",type:""},url:function(){return galaxy_paths.get("visualization_url")},save:function(){return $.ajax({url:this.url(),type:"POST",dataType:"json",data:{vis_json:JSON.stringify(this)}})}});var k=o.extend({defaults:s.extend({},o.prototype.defaults,{dbkey:"",tracks:null,bookmarks:null,viewport:null}),relations:[{type:Backbone.HasMany,key:"tracks",relatedModel:t}],add_tracks:function(u){this.get("tracks").add(u)}});var b=Backbone.Model.extend({});var h=Backbone.Router.extend({initialize:function(v){this.view=v.view;this.route(/([\w]+)$/,"change_location");this.route(/([\w]+\:[\d,]+-[\d,]+)$/,"change_location");var u=this;u.view.on("navigate",function(w){u.navigate(w)})},change_location:function(u){this.view.go_to(u)}});return{BackboneTrack:t,BrowserBookmark:e,BrowserBookmarkCollection:r,Cache:q,CanvasManager:f,Genome:c,GenomeDataManager:d,GenomeRegion:g,GenomeRegionCollection:m,GenomeVisualization:k,ReferenceTrackDataManager:n,TrackBrowserRouter:h,TrackConfig:b,Visualization:o,select_datasets:a}});
\ No newline at end of file
+define(["libs/underscore","mvc/data","viz/trackster/util","utils/config"],function(s,i,l,p){var a=function(u,x,v,w){$.ajax({url:u,data:(v?{"f-dbkey":v}:{}),error:function(){alert("Grid failed")},success:function(y){show_modal("Select datasets for new tracks",y,{Cancel:function(){hide_modal()},Add:function(){var z=[];$("input[name=id]:checked,input[name=ldda_ids]:checked").each(function(){var A={data_type:"track_config",hda_ldda:"hda"},B=$(this).val();if($(this).attr("name")!=="id"){A.hda_ldda="ldda"}z[z.length]=$.ajax({url:x+"/"+B,data:A,dataType:"json"})});$.when.apply($,z).then(function(){var A=(arguments[0] instanceof Array?$.map(arguments,function(B){return B[0]}):[arguments[0]]);w(A)});hide_modal()}})}})};var j=function(u){return("isResolved" in u)};var f=function(u){this.default_font=u!==undefined?u:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};s.extend(f.prototype,{load_pattern:function(u,y){var v=this.patterns,w=this.dummy_context,x=new Image();x.src=galaxy_paths.attributes.image_path+y;x.onload=function(){v[u]=w.createPattern(x,"repeat")}},get_pattern:function(u){return this.patterns[u]},new_canvas:function(){var u=$("<canvas/>")[0];if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(u)}u.manager=this;return u}});var q=Backbone.Model.extend({defaults:{num_elements:20,obj_cache:null,key_ary:null},initialize:function(u){this.clear()},get_elt:function(v){var w=this.attributes.obj_cache,x=this.attributes.key_ary,u=x.indexOf(v);if(u!==-1){if(w[v].stale){x.splice(u,1);delete w[v]}else{this.move_key_to_end(v,u)}}return w[v]},set_elt:function(v,x){var y=this.attributes.obj_cache,z=this.attributes.key_ary,w=this.attributes.num_elements;if(!y[v]){if(z.length>=w){var u=z.shift();delete y[u]}z.push(v)}y[v]=x;return x},move_key_to_end:function(v,u){this.attributes.key_ary.splice(u,1);this.attributes.key_ary.push(v)},clear:function(){this.attributes.obj_cache={};this.attributes.key_ary=[]},size:function(){return this.attributes.key_ary.length}});var d=q.extend({defaults:s.extend({},q.prototype.defaults,{dataset:null,init_data:null,filters_manager:null,data_type:"data",data_mode_compatible:function(u,v){return true},can_subset:function(u){return false}}),initialize:function(u){q.prototype.initialize.call(this);var v=this.get("init_data");if(v){this.add_data(v)}},add_data:function(u){if(this.get("num_elements")<u.length){this.set("num_elements",u.length)}var v=this;s.each(u,function(w){v.set_data(w.region,w)})},data_is_ready:function(){var x=this.get("dataset"),w=$.Deferred(),u=(this.get("data_type")=="raw_data"?"state":this.get("data_type")=="data"?"converted_datasets_state":"error"),v=new l.ServerStateDeferred({ajax_settings:{url:this.get("dataset").url(),data:{hda_ldda:x.get("hda_ldda"),data_type:u},dataType:"json"},interval:5000,success_fn:function(y){return y!=="pending"}});$.when(v.go()).then(function(y){w.resolve(y==="ok"||y==="data")});return w},search_features:function(u){var v=this.get("dataset"),w={query:u,hda_ldda:v.get("hda_ldda"),data_type:"features"};return $.getJSON(v.url(),w)},load_data:function(C,B,v,A){var y=this.get("dataset"),x={data_type:this.get("data_type"),chrom:C.get("chrom"),low:C.get("start"),high:C.get("end"),mode:B,resolution:v,hda_ldda:y.get("hda_ldda")};$.extend(x,A);var E=this.get("filters_manager");if(E){var F=[];var u=E.filters;for(var z=0;z<u.length;z++){F.push(u[z].name)}x.filter_cols=JSON.stringify(F)}var w=this,D=$.getJSON(y.url(),x,function(G){w.set_data(C,G)});this.set_data(C,D);return D},get_data:function(A,z,w,y){var B=this.get_elt(A);if(B&&(j(B)||this.get("data_mode_compatible")(B,z))){return B}var C=this.get("key_ary"),v=this.get("obj_cache"),D,u;for(var x=0;x<C.length;x++){D=C[x];u=new g({from_str:D});if(u.contains(A)){B=v[D];if(j(B)||(this.get("data_mode_compatible")(B,z)&&this.get("can_subset")(B))){this.move_key_to_end(D,x);return B}}}return this.load_data(A,z,w,y)},set_data:function(v,u){this.set_elt(v,u)},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(C,B,x,A,y){var E=this._mark_stale(C);if(!(E&&this.get("data_mode_compatible")(E,B))){console.log("ERROR: problem with getting more data: current data is not compatible");return}var w=C.get("start");if(y===this.DEEP_DATA_REQ){$.extend(A,{start_val:E.data.length+1})}else{if(y===this.BROAD_DATA_REQ){w=(E.max_high?E.max_high:E.data[E.data.length-1][2])+1}}var D=C.copy().set("start",w);var v=this,z=this.load_data(D,B,x,A),u=$.Deferred();this.set_data(C,u);$.when(z).then(function(F){if(F.data){F.data=E.data.concat(F.data);if(F.max_low){F.max_low=E.max_low}if(F.message){F.message=F.message.replace(/[0-9]+/,F.data.length)}}v.set_data(C,F);u.resolve(F)});return u},can_get_more_detailed_data:function(v){var u=this.get_elt(v);return(u.dataset_type==="bigwig"&&u.data.length<8000)},get_more_detailed_data:function(x,z,v,y,w){var u=this._mark_stale(x);if(!u){console.log("ERROR getting more detailed data: no current data");return}if(!w){w={}}if(u.dataset_type==="bigwig"){w.num_samples=1000*y}else{if(u.dataset_type==="summary_tree"){w.level=Math.min(u.level-1,2)}}return this.load_data(x,z,v,w)},_mark_stale:function(v){var u=this.get_elt(v);if(!u){console.log("ERROR: no data to mark as stale: ",this.get("dataset"),v.toString())}u.stale=true;return u},get_genome_wide_data:function(u){var w=this,y=true,x=s.map(u.get("chroms_info").chrom_info,function(A){var z=w.get_elt(new g({chrom:A.chrom,start:0,end:A.len}));if(!z){y=false}return z});if(y){return x}var v=$.Deferred();$.getJSON(this.get("dataset").url(),{data_type:"genome_data"},function(z){w.add_data(z.data);v.resolve(z.data)});return v},get_elt:function(u){return q.prototype.get_elt.call(this,u.toString())},set_elt:function(v,u){return q.prototype.set_elt.call(this,v.toString(),u)}});var n=d.extend({initialize:function(u){var v=new Backbone.Model();v.urlRoot=u.data_url;this.set("dataset",v)},load_data:function(w,x,u,v){if(u>1){return{data:null}}return d.prototype.load_data.call(this,w,x,u,v)}});var c=Backbone.Model.extend({defaults:{name:null,key:null,chroms_info:null},initialize:function(u){this.id=u.dbkey},get_chroms_info:function(){return this.attributes.chroms_info.chrom_info},get_chrom_region:function(u){var v=s.find(this.get_chroms_info(),function(w){return w.chrom==u});return new g({chrom:v.chrom,end:v.len})}});var g=Backbone.RelationalModel.extend({defaults:{chrom:null,start:0,end:0,DIF_CHROMS:1000,BEFORE:1001,CONTAINS:1002,OVERLAP_START:1003,OVERLAP_END:1004,CONTAINED_BY:1005,AFTER:1006},initialize:function(v){if(v.from_str){var x=v.from_str.split(":"),w=x[0],u=x[1].split("-");this.set({chrom:w,start:parseInt(u[0],10),end:parseInt(u[1],10)})}},copy:function(){return new g({chrom:this.get("chrom"),start:this.get("start"),end:this.get("end")})},length:function(){return this.get("end")-this.get("start")},toString:function(){return this.get("chrom")+":"+this.get("start")+"-"+this.get("end")},toJSON:function(){return{chrom:this.get("chrom"),start:this.get("start"),end:this.get("end")}},compute_overlap:function(B){var v=this.get("chrom"),A=B.get("chrom"),z=this.get("start"),x=B.get("start"),y=this.get("end"),w=B.get("end"),u;if(v&&A&&v!==A){return this.get("DIF_CHROMS")}if(z<x){if(y<x){u=this.get("BEFORE")}else{if(y<=w){u=this.get("OVERLAP_START")}else{u=this.get("CONTAINS")}}}else{if(z>w){u=this.get("AFTER")}else{if(y<=w){u=this.get("CONTAINED_BY")}else{u=this.get("OVERLAP_END")}}}return u},contains:function(u){return this.compute_overlap(u)===this.get("CONTAINS")},overlaps:function(u){return s.intersection([this.compute_overlap(u)],[this.get("DIF_CHROMS"),this.get("BEFORE"),this.get("AFTER")]).length===0}});var m=Backbone.Collection.extend({model:g});var e=Backbone.RelationalModel.extend({defaults:{region:null,note:""},relations:[{type:Backbone.HasOne,key:"region",relatedModel:g}]});var r=Backbone.Collection.extend({model:e});var t=i.Dataset.extend({initialize:function(u){this.set("id",u.dataset_id);this.set("config",p.ConfigSettingCollection.from_config_dict(u.prefs));this.get("config").add([{key:"name",value:this.get("name")},{key:"color"}]);var v=this.get("preloaded_data");if(v){v=v.data}else{v=[]}this.set("data_manager",new d({dataset:this,init_data:v}))}});var o=Backbone.RelationalModel.extend({defaults:{title:"",type:""},url:galaxy_paths.get("visualization_url"),save:function(){return $.ajax({url:this.url(),type:"POST",dataType:"json",data:{vis_json:JSON.stringify(this)}})}});var k=o.extend({defaults:s.extend({},o.prototype.defaults,{dbkey:"",tracks:null,bookmarks:null,viewport:null}),relations:[{type:Backbone.HasMany,key:"tracks",relatedModel:t}],add_tracks:function(u){this.get("tracks").add(u)}});var b=Backbone.Model.extend({});var h=Backbone.Router.extend({initialize:function(v){this.view=v.view;this.route(/([\w]+)$/,"change_location");this.route(/([\w]+\:[\d,]+-[\d,]+)$/,"change_location");var u=this;u.view.on("navigate",function(w){u.navigate(w)})},change_location:function(u){this.view.go_to(u)}});return{BackboneTrack:t,BrowserBookmark:e,BrowserBookmarkCollection:r,Cache:q,CanvasManager:f,Genome:c,GenomeDataManager:d,GenomeRegion:g,GenomeRegionCollection:m,GenomeVisualization:k,ReferenceTrackDataManager:n,TrackBrowserRouter:h,TrackConfig:b,Visualization:o,select_datasets:a}});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/c12c81db523f/
changeset: c12c81db523f
user: jgoecks
date: 2012-10-20 19:16:22
summary: Make Trackster use generic visualization save functionality.
affected #: 5 files
diff -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 -r c12c81db523f4d7b959cfe550c0cb4f5bf6c7765 lib/galaxy/webapps/galaxy/controllers/visualization.py
--- a/lib/galaxy/webapps/galaxy/controllers/visualization.py
+++ b/lib/galaxy/webapps/galaxy/controllers/visualization.py
@@ -719,27 +719,6 @@
'''
return trans.fill_template( 'tracks/browser.mako', config=viz_config, add_dataset=new_dataset )
- @web.json
- def save_trackster( self, trans, vis_json ):
- """
- Save a visualization; if visualization does not have an ID, a new
- visualization is created. Returns JSON of visualization.
- """
-
- # TODO: Need from_dict to convert json to Visualization object.
- vis_config = from_json_string( vis_json )
- config = {
- 'view': vis_config[ 'datasets' ],
- 'bookmarks': vis_config[ 'bookmarks' ],
- 'viewport': vis_config[ 'viewport' ]
- }
- type = vis_config[ 'type' ]
- id = vis_config.get( 'id', None )
- title = vis_config[ 'title' ]
- dbkey = vis_config[ 'dbkey' ]
- annotation = vis_config.get( 'annotation', None )
- return self.save_visualization( trans, config, type, id, title, dbkey, annotation )
-
@web.expose
def circster( self, trans, id=None, hda_ldda=None, dataset_id=None, dbkey=None ):
"""
diff -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 -r c12c81db523f4d7b959cfe550c0cb4f5bf6c7765 static/scripts/mvc/data.js
--- a/static/scripts/mvc/data.js
+++ b/static/scripts/mvc/data.js
@@ -1,4 +1,5 @@
define(["libs/backbone/backbone-relational"], function() {
+
/**
* A dataset. In Galaxy, datasets are associated with a history, so
* this object is also known as a HistoryDatasetAssociation.
diff -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 -r c12c81db523f4d7b959cfe550c0cb4f5bf6c7765 static/scripts/viz/trackster_ui.js
--- a/static/scripts/viz/trackster_ui.js
+++ b/static/scripts/viz/trackster_ui.js
@@ -56,11 +56,7 @@
// FIXME: give unique IDs to Drawables and save overview as ID.
var overview_track_name = (view.overview_drawable ? view.overview_drawable.name : null),
viz_config = {
- 'id': view.vis_id,
- 'title': view.name,
- 'dbkey': view.dbkey,
- 'type': 'trackster',
- 'datasets': view.to_dict(),
+ 'view': view.to_dict(),
'viewport': { 'chrom': view.chrom, 'start': view.low , 'end': view.high, 'overview': overview_track_name },
'bookmarks': bookmarks
};
@@ -70,6 +66,10 @@
type: "POST",
dataType: "json",
data: {
+ 'id': view.vis_id,
+ 'title': view.name,
+ 'dbkey': view.dbkey,
+ 'type': 'trackster',
vis_json: JSON.stringify(viz_config)
}
}).success(function(vis_info) {
diff -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 -r c12c81db523f4d7b959cfe550c0cb4f5bf6c7765 static/scripts/viz/visualization.js
--- a/static/scripts/viz/visualization.js
+++ b/static/scripts/viz/visualization.js
@@ -764,12 +764,8 @@
type: ''
},
- // Use function because visualization_url changes depending on viz.
- // FIXME: all visualizations should save to the same URL (and hence
- // this function won't be needed).
- url: function() {
- return galaxy_paths.get("visualization_url");
- },
+ // No API to create/save visualization yet, so use this path:
+ url: galaxy_paths.get("visualization_url"),
/**
* POSTs visualization's JSON to its URL using the parameter 'vis_json'
diff -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 -r c12c81db523f4d7b959cfe550c0cb4f5bf6c7765 templates/tracks/browser.mako
--- a/templates/tracks/browser.mako
+++ b/templates/tracks/browser.mako
@@ -39,13 +39,6 @@
require( ["base", "viz/visualization", "viz/trackster_ui", "viz/trackster/tracks"],
function( base, visualization, trackster_ui, tracks ) {
- //
- // Place URLs here so that url_for can be used to generate them.
- //
- galaxy_paths.set({
- visualization_url: "${h.url_for( action='save_trackster' )}"
- });
-
${render_trackster_js_vars()}
// FIXME: deliberate global required for now due to requireJS integration.
https://bitbucket.org/galaxy/galaxy-central/changeset/afc8e9345268/
changeset: afc8e9345268
user: jgoecks
date: 2012-10-20 20:40:42
summary: Better data handling when downloading history export files.
affected #: 1 file
diff -r c12c81db523f4d7b959cfe550c0cb4f5bf6c7765 -r afc8e93452687063301398854dbcf0d450c8558c lib/galaxy/webapps/galaxy/controllers/history.py
--- a/lib/galaxy/webapps/galaxy/controllers/history.py
+++ b/lib/galaxy/webapps/galaxy/controllers/history.py
@@ -664,7 +664,7 @@
else:
trans.response.set_content_type( 'application/x-tar' )
trans.response.headers["Content-Disposition"] = 'attachment; filename="%s"' % ( hname )
- return trans.app.object_store.get_data(jeha.dataset)
+ return open( trans.app.object_store.get_filename( jeha.dataset ) )
elif jeha.job.state in [ model.Job.states.RUNNING, model.Job.states.QUEUED, model.Job.states.WAITING ]:
return trans.show_message( "Still exporting history %(n)s; please check back soon. Link: <a href='%(s)s'>%(s)s</a>" \
% ( { 'n' : history.name, 's' : url_for( action="export_archive", id=id, qualified=True ) } ) )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/87a113b8473f/
changeset: 87a113b8473f
user: jgoecks
date: 2012-10-19 20:02:23
summary: Set up track config in BackboneTrack objects and use config in Circster.
affected #: 3 files
diff -r 083d480bf5e35009f01e9439f11aa7e68716e429 -r 87a113b8473f2d69d3c0c3393a46a9f968ac234e static/scripts/utils/config.js
--- a/static/scripts/utils/config.js
+++ b/static/scripts/utils/config.js
@@ -4,28 +4,19 @@
* A configuration setting. Currently key is used as id.
*/
var ConfigSetting = Backbone.Model.extend({
- defaults: {
- key: null,
- value: null,
- type: 'text',
- label: null,
- options: null,
- hidden: false
- },
-
initialize: function(options) {
// Use key as id for now.
var key = this.get('key');
this.set('id', key);
// Set defaults based on key.
- var defaults = _.find(ConfigSetting.known_settings, function(s) { return s.key === key; });
+ var defaults = _.find(ConfigSetting.known_settings_defaults, function(s) { return s.key === key; });
if (defaults) {
this.set(_.extend({}, defaults, options));
}
- // If type color, get random color.
- if (this.get('type') === 'color') {
+ // If type color and no value, get random color.
+ if (this.get('type') === 'color' && !this.get('value')) {
this.set('value', util_mod.get_random_color());
}
@@ -50,22 +41,22 @@
this.set('value');
}
}, {
- // Keep a master list of settings. This list is useful to fetching attributes based on key.
- known_settings: [
+ // This is a master list of default settings for known settings.
+ known_settings_defaults: [
{ key: 'name', label: 'Name', type: 'text', default_value: '' },
- { key: 'color', label: 'Color', type: 'color', default_value: undefined },
- { key: 'min_value', label: 'Min Value', type: 'float', default_value: undefined },
- { key: 'max_value', label: 'Max Value', type: 'float', default_value: undefined },
+ { key: 'color', label: 'Color', type: 'color', default_value: null },
+ { key: 'min_value', label: 'Min Value', type: 'float', default_value: null },
+ { key: 'max_value', label: 'Max Value', type: 'float', default_value: null },
{ key: 'mode', type: 'string', default_value: this.mode, hidden: true },
{ key: 'height', type: 'int', default_value: 32, hidden: true },
{ key: 'pos_color', label: 'Positive Color', type: 'color', default_value: "4169E1" },
{ key: 'negative_color', label: 'Negative Color', type: 'color', default_value: "FF8C00" },
- { key: 'block_color', label: 'Block color', type: 'color', default_value: undefined },
+ { key: 'block_color', label: 'Block color', type: 'color', default_value: null },
{ key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' },
{ key: 'show_insertions', label: 'Show insertions', type: 'bool', default_value: false },
{ key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true },
{ key: 'mode', type: 'string', default_value: this.mode, hidden: true },
- { key: 'reverse_strand_color', label: 'Antisense strand color', type: 'color', default_value: undefined },
+ { key: 'reverse_strand_color', label: 'Antisense strand color', type: 'color', default_value: null },
{ key: 'show_differences', label: 'Show differences only', type: 'bool', default_value: true },
{ key: 'histogram_max', label: 'Histogram maximum', type: 'float', default_value: null, help: 'Clear value to set automatically' },
{ key: 'mode', type: 'string', default_value: this.mode, hidden: true }
@@ -92,24 +83,15 @@
},
/**
- * Restore settings' values from a dictionary of key-value pairs.
- * This function is needed for backwards compatibility.
- */
- restore_values: function(values) {
- var self = this;
- _.keys(values, function(key) {
- var setting = self.find(function(s) { return s.get('key') === key; });
- if (setting) {
- setting.set('value', values.key);
- }
- });
- },
-
- /**
- * Returns value for a given key.
+ * Returns value for a given key. Returns undefined if there is no setting with the specified key.
*/
get_value: function(key) {
- return this.get(key).get('value');
+ var s = this.get(key);
+ if (s) {
+ return s.get('value');
+ }
+
+ return undefined;
}
}, {
/**
diff -r 083d480bf5e35009f01e9439f11aa7e68716e429 -r 87a113b8473f2d69d3c0c3393a46a9f968ac234e static/scripts/viz/circster.js
--- a/static/scripts/viz/circster.js
+++ b/static/scripts/viz/circster.js
@@ -251,13 +251,6 @@
// When data is ready, render track.
$.when(data_ready_deferred).then(function() {
$.when(self._render_data(track_parent_elt)).then(function() {
- // Apply prefs to all track data.
- // TODO: move to _render_data?
- var prefs = self.options.track.get('prefs'),
- block_color = prefs.block_color;
- if (!block_color) { block_color = prefs.color; }
- track_parent_elt.selectAll('path.chrom-data').style('stroke', block_color).style('fill', block_color);
-
chroms_paths.style("fill", self.options.bg_fill);
});
});
@@ -393,6 +386,12 @@
return self._render_chrom_data(svg, chrom_arc, data);
});
+ // Apply prefs to all track data.
+ var config = track.get('config'),
+ block_color = config.get_value('block_color');;
+ if (!block_color) { block_color = config.get_value('color'); }
+ self.options.parent_elt.selectAll('path.chrom-data').style('stroke', block_color).style('fill', block_color);
+
rendered_deferred.resolve(svg);
});
diff -r 083d480bf5e35009f01e9439f11aa7e68716e429 -r 87a113b8473f2d69d3c0c3393a46a9f968ac234e static/scripts/viz/visualization.js
--- a/static/scripts/viz/visualization.js
+++ b/static/scripts/viz/visualization.js
@@ -731,9 +731,16 @@
this.set('id', options.dataset_id);
// -- Set up config settings. --
- this.set('settings', config_mod.ConfigSettingCollection.from_config_dict(options.prefs));
- // Set up data manager.
+ this.set('config', config_mod.ConfigSettingCollection.from_config_dict(options.prefs));
+
+ // Set up some minimal config.
+ this.get('config').add( [
+ { key: 'name', value: this.get('name') },
+ { key: 'color' }
+ ] );
+
+ // -- Set up data manager. --
var preloaded_data = this.get('preloaded_data');
if (preloaded_data) {
preloaded_data = preloaded_data.data;
https://bitbucket.org/galaxy/galaxy-central/changeset/d0e40dd01870/
changeset: d0e40dd01870
user: jgoecks
date: 2012-10-20 03:07:56
summary: Circster: add programmatic support for removing tracks.
affected #: 1 file
diff -r 87a113b8473f2d69d3c0c3393a46a9f968ac234e -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 static/scripts/viz/circster.js
--- a/static/scripts/viz/circster.js
+++ b/static/scripts/viz/circster.js
@@ -50,8 +50,9 @@
this.scale = 1;
this.track_views = null;
- // When track added to the model, add to view as well.
+ // When tracks added to/removed from model, update view.
this.model.get('tracks').on('add', this.add_track, this);
+ this.model.get('tracks').on('remove', this.remove_track, this);
},
/**
@@ -158,8 +159,6 @@
* Render a single track on the outside of the current visualization.
*/
add_track: function(new_track) {
- // TODO: Reset scale and zoom.
-
// Recompute and update track bounds.
var new_track_bounds = this.get_tracks_bounds();
_.each(this.track_views, function(track_view, i) {
@@ -186,6 +185,23 @@
var track_bounds = new_track_bounds[ new_track_bounds.length-1 ];
track_bounds[1] = track_bounds[0];
this.label_track_view.update_radius_bounds(track_bounds);
+ },
+
+ /**
+ * Remove a track from the view.
+ */
+ remove_track: function(track, tracks, options) {
+ // -- Remove track from view. --
+ var track_view = this.track_views[options.index];
+ this.track_views.splice(options.index, 1);
+ track_view.$el.remove();
+
+ // Recompute and update track bounds.
+ var new_track_bounds = this.get_tracks_bounds();
+ _.each(this.track_views, function(track_view, i) {
+ //console.log(self.get_tracks_bounds(), i);
+ track_view.update_radius_bounds(new_track_bounds[i]);
+ });
}
});
https://bitbucket.org/galaxy/galaxy-central/changeset/e26fec7ee17f/
changeset: e26fec7ee17f
user: jgoecks
date: 2012-10-20 03:08:16
summary: merge
affected #: 16 files
diff -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 lib/galaxy/datatypes/data.py
--- a/lib/galaxy/datatypes/data.py
+++ b/lib/galaxy/datatypes/data.py
@@ -536,7 +536,9 @@
TODO: Do we need to merge gzip files using gzjoin? cat seems to work,
but might be brittle. Need to revisit this.
"""
- if len(split_files) == 1:
+ if not split_files:
+ raise ValueError('Asked to merge zero files as %s' % output_file)
+ elif len(split_files) == 1:
cmd = 'mv -f %s %s' % ( split_files[0], output_file )
else:
cmd = 'cat %s > %s' % ( ' '.join(split_files), output_file )
diff -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 lib/galaxy/jobs/splitters/multi.py
--- a/lib/galaxy/jobs/splitters/multi.py
+++ b/lib/galaxy/jobs/splitters/multi.py
@@ -115,6 +115,7 @@
try:
working_directory = job_wrapper.working_directory
task_dirs = [os.path.join(working_directory, x) for x in os.listdir(working_directory) if x.startswith('task_')]
+ assert task_dirs, "Should be at least one sub-task!"
# TODO: Output datasets can be very complex. This doesn't handle metadata files
outputs = job_wrapper.get_output_hdas_and_fnames()
pickone_done = []
@@ -129,10 +130,18 @@
# Just include those files f in the output list for which the
# file f exists; some files may not exist if a task fails.
output_files = [ f for f in output_files if os.path.exists(f) ]
- log.debug('files %s ' % output_files)
- output_type.merge(output_files, output_file_name)
- log.debug('merge finished: %s' % output_file_name)
- pass # TODO: merge all the files
+ if output_files:
+ log.debug('files %s ' % output_files)
+ if len(output_files) < len(task_dirs):
+ log.debug('merging only %i out of expected %i files for %s'
+ % (len(output_files), len(task_dirs), output_file_name))
+ output_type.merge(output_files, output_file_name)
+ log.debug('merge finished: %s' % output_file_name)
+ else:
+ msg = 'nothing to merge for %s (expected %i files)' \
+ % (output_file_name, len(task_dirs))
+ log.debug(msg)
+ stderr += msg + "\n"
elif output in pickone_outputs:
# just pick one of them
if output not in pickone_done:
diff -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 lib/galaxy/webapps/community/controllers/admin.py
--- a/lib/galaxy/webapps/community/controllers/admin.py
+++ b/lib/galaxy/webapps/community/controllers/admin.py
@@ -7,7 +7,7 @@
from galaxy.util import inflector
from galaxy.util.shed_util import get_changectx_for_changeset, get_configured_ui
from common import *
-from repository import RepositoryListGrid, CategoryListGrid
+from repository import RepositoryGrid, CategoryGrid
from galaxy import eggs
eggs.require( 'mercurial' )
@@ -17,7 +17,7 @@
log = logging.getLogger( __name__ )
-class UserListGrid( grids.Grid ):
+class UserGrid( grids.Grid ):
# TODO: move this to an admin_common controller since it is virtually the same in the galaxy webapp.
class UserLoginColumn( grids.TextColumn ):
def get_value( self, trans, grid, user ):
@@ -66,10 +66,10 @@
default_sort_key = "email"
columns = [
UserLoginColumn( "Email",
- key="email",
- link=( lambda item: dict( operation="information", id=item.id ) ),
- attach_popup=True,
- filterable="advanced" ),
+ key="email",
+ link=( lambda item: dict( operation="information", id=item.id ) ),
+ attach_popup=True,
+ filterable="advanced" ),
UserNameColumn( "User Name",
key="username",
attach_popup=False,
@@ -116,7 +116,7 @@
def get_current_item( self, trans, **kwargs ):
return trans.user
-class RoleListGrid( grids.Grid ):
+class RoleGrid( grids.Grid ):
# TODO: move this to an admin_common controller since it is virtually the same in the galaxy webapp.
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, role ):
@@ -207,7 +207,7 @@
def apply_query_filter( self, trans, query, **kwd ):
return query.filter( model.Role.type != model.Role.types.PRIVATE )
-class GroupListGrid( grids.Grid ):
+class GroupGrid( grids.Grid ):
# TODO: move this to an admin_common controller since it is virtually the same in the galaxy webapp.
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, group ):
@@ -278,34 +278,35 @@
preserve_state = False
use_paging = True
-class ManageCategoryListGrid( CategoryListGrid ):
- columns = [ col for col in CategoryListGrid.columns ]
+class ManageCategoryGrid( CategoryGrid ):
+ columns = [ col for col in CategoryGrid.columns ]
# Override the NameColumn to include an Edit link
- columns[ 0 ] = CategoryListGrid.NameColumn( "Name",
- key="Category.name",
- link=( lambda item: dict( operation="Edit", id=item.id ) ),
- model_class=model.Category,
- attach_popup=False )
+ columns[ 0 ] = CategoryGrid.NameColumn( "Name",
+ key="Category.name",
+ link=( lambda item: dict( operation="Edit", id=item.id ) ),
+ model_class=model.Category,
+ attach_popup=False )
global_actions = [
grids.GridAction( "Add new category",
dict( controller='admin', action='manage_categories', operation='create' ) )
]
-class AdminRepositoryListGrid( RepositoryListGrid ):
- columns = [ RepositoryListGrid.NameColumn( "Name",
- key="name",
- link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
- attach_popup=True ),
- RepositoryListGrid.DescriptionColumn( "Synopsis",
- key="description",
- attach_popup=False ),
- RepositoryListGrid.MetadataRevisionColumn( "Metadata Revisions" ),
- RepositoryListGrid.UserColumn( "Owner",
- model_class=model.User,
- link=( lambda item: dict( operation="repositories_by_user", id=item.id ) ),
- attach_popup=False,
- key="User.username" ),
- RepositoryListGrid.EmailAlertsColumn( "Alert", attach_popup=False ),
+class AdminRepositoryGrid( RepositoryGrid ):
+ columns = [ RepositoryGrid.NameColumn( "Name",
+ key="name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=True ),
+ RepositoryGrid.DescriptionColumn( "Synopsis",
+ key="description",
+ attach_popup=False ),
+ RepositoryGrid.MetadataRevisionColumn( "Metadata Revisions" ),
+ RepositoryGrid.UserColumn( "Owner",
+ model_class=model.User,
+ link=( lambda item: dict( operation="repositories_by_user", id=item.id ) ),
+ attach_popup=False,
+ key="User.username" ),
+ RepositoryGrid.EmailAlertsColumn( "Alert", attach_popup=False ),
+ RepositoryGrid.DeprecatedColumn( "Deprecated", attach_popup=False ),
# Columns that are valid for filtering but are not visible.
grids.DeletedColumn( "Deleted",
key="deleted",
@@ -316,7 +317,7 @@
key="free-text-search",
visible=False,
filterable="standard" ) )
- operations = [ operation for operation in RepositoryListGrid.operations ]
+ operations = [ operation for operation in RepositoryGrid.operations ]
operations.append( grids.GridOperation( "Delete",
allow_multiple=False,
condition=( lambda item: not item.deleted ),
@@ -327,7 +328,7 @@
async_compatible=False ) )
standard_filters = []
-class RepositoryMetadataListGrid( grids.Grid ):
+class RepositoryMetadataGrid( grids.Grid ):
class IdColumn( grids.IntegerColumn ):
def get_value( self, trans, grid, repository_metadata ):
return repository_metadata.id
@@ -414,17 +415,18 @@
preserve_state = False
use_paging = True
def build_initial_query( self, trans, **kwd ):
- return trans.sa_session.query( self.model_class ) \
- .join( model.Repository.table )
+ return trans.sa_session.query( model.RepositoryMetadata ) \
+ .join( model.Repository.table ) \
+ .filter( model.Repository.table.c.deprecated == False )
class AdminController( BaseUIController, Admin ):
- user_list_grid = UserListGrid()
- role_list_grid = RoleListGrid()
- group_list_grid = GroupListGrid()
- manage_category_list_grid = ManageCategoryListGrid()
- repository_list_grid = AdminRepositoryListGrid()
- repository_metadata_list_grid = RepositoryMetadataListGrid()
+ user_list_grid = UserGrid()
+ role_list_grid = RoleGrid()
+ group_list_grid = GroupGrid()
+ manage_category_grid = ManageCategoryGrid()
+ repository_grid = AdminRepositoryGrid()
+ repository_metadata_grid = RepositoryMetadataGrid()
@web.expose
@web.require_admin
@@ -477,7 +479,7 @@
return self.delete_repository( trans, **kwd )
elif operation == "undelete":
return self.undelete_repository( trans, **kwd )
- # The changeset_revision_select_field in the RepositoryListGrid performs a refresh_on_change
+ # The changeset_revision_select_field in the RepositoryGrid performs a refresh_on_change
# which sends in request parameters like changeset_revison_1, changeset_revision_2, etc. One
# of the many select fields on the grid performed the refresh_on_change, so we loop through
# all of the received values to see which value is not the repository tip. If we find it, we
@@ -495,7 +497,7 @@
id=trans.security.encode_id( repository.id ),
changeset_revision=v ) )
# Render the list view
- return self.repository_list_grid( trans, **kwd )
+ return self.repository_grid( trans, **kwd )
@web.expose
@web.require_admin
def browse_repository_metadata( self, trans, **kwd ):
@@ -515,7 +517,7 @@
return trans.response.send_redirect( web.url_for( controller='repository',
action='browse_repositories',
**kwd ) )
- return self.repository_metadata_list_grid( trans, **kwd )
+ return self.repository_metadata_grid( trans, **kwd )
@web.expose
@web.require_admin
def create_category( self, trans, **kwd ):
@@ -645,9 +647,9 @@
@web.require_admin
def manage_categories( self, trans, **kwd ):
if 'f-free-text-search' in kwd:
- # Trick to enable searching repository name, description from the CategoryListGrid.
- # What we've done is rendered the search box for the RepositoryListGrid on the grid.mako
- # template for the CategoryListGrid. See ~/templates/webapps/community/category/grid.mako.
+ # Trick to enable searching repository name, description from the CategoryGrid.
+ # What we've done is rendered the search box for the RepositoryGrid on the grid.mako
+ # template for the CategoryGrid. See ~/templates/webapps/community/category/grid.mako.
# Since we are searching repositories and not categories, redirect to browse_repositories().
return trans.response.send_redirect( web.url_for( controller='admin',
action='browse_repositories',
@@ -674,7 +676,7 @@
return trans.response.send_redirect( web.url_for( controller='admin',
action='edit_category',
**kwd ) )
- return self.manage_category_list_grid( trans, **kwd )
+ return self.manage_category_grid( trans, **kwd )
@web.expose
@web.require_admin
def regenerate_statistics( self, trans, **kwd ):
@@ -732,7 +734,8 @@
multiple=True,
display='checkboxes' )
for repository in trans.sa_session.query( trans.model.Repository ) \
- .filter( trans.model.Repository.table.c.deleted == False ) \
+ .filter( and_( trans.model.Repository.table.c.deleted == False,
+ trans.model.Repository.table.c.deprecated == False ) ) \
.order_by( trans.model.Repository.table.c.name,
trans.model.Repository.table.c.user_id ):
owner = repository.user.username
diff -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 lib/galaxy/webapps/community/controllers/repository.py
--- a/lib/galaxy/webapps/community/controllers/repository.py
+++ b/lib/galaxy/webapps/community/controllers/repository.py
@@ -25,7 +25,7 @@
VALID_REPOSITORYNAME_RE = re.compile( "^[a-z0-9\_]+$" )
-class CategoryListGrid( grids.Grid ):
+class CategoryGrid( grids.Grid ):
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, category ):
return category.name
@@ -65,14 +65,14 @@
preserve_state = False
use_paging = True
-class ValidCategoryListGrid( CategoryListGrid ):
+class ValidCategoryGrid( CategoryGrid ):
class RepositoriesColumn( grids.TextColumn ):
def get_value( self, trans, grid, category ):
if category.repositories:
viewable_repositories = 0
for rca in category.repositories:
repository = rca.repository
- if repository.downloadable_revisions:
+ if not repository.deprecated and repository.downloadable_revisions:
viewable_repositories += 1
return viewable_repositories
return 0
@@ -81,13 +81,13 @@
template='/webapps/community/category/valid_grid.mako'
default_sort_key = "name"
columns = [
- CategoryListGrid.NameColumn( "Name",
- key="Category.name",
- link=( lambda item: dict( operation="valid_repositories_by_category", id=item.id ) ),
- attach_popup=False ),
- CategoryListGrid.DescriptionColumn( "Description",
- key="Category.description",
- attach_popup=False ),
+ CategoryGrid.NameColumn( "Name",
+ key="Category.name",
+ link=( lambda item: dict( operation="valid_repositories_by_category", id=item.id ) ),
+ attach_popup=False ),
+ CategoryGrid.DescriptionColumn( "Description",
+ key="Category.description",
+ attach_popup=False ),
# Columns that are valid for filtering but are not visible.
RepositoriesColumn( "Valid repositories",
model_class=model.Repository,
@@ -102,7 +102,7 @@
preserve_state = False
use_paging = True
-class RepositoryListGrid( grids.Grid ):
+class RepositoryGrid( grids.Grid ):
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
return repository.name
@@ -188,6 +188,11 @@
if trans.user and repository.email_alerts and trans.user.email in from_json_string( repository.email_alerts ):
return 'yes'
return ''
+ class DeprecatedColumn( grids.TextColumn ):
+ def get_value( self, trans, grid, repository ):
+ if repository.deprecated:
+ return 'yes'
+ return ''
# Grid definition
title = "Repositories"
model_class = model.Repository
@@ -248,21 +253,83 @@
.outerjoin( model.RepositoryCategoryAssociation.table ) \
.outerjoin( model.Category.table )
-class EmailAlertsRepositoryListGrid( RepositoryListGrid ):
+class RepositoriesIOwnGrid( RepositoryGrid ):
+ title = "Repositories I own"
columns = [
- RepositoryListGrid.NameColumn( "Name",
- key="name",
- link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ RepositoryGrid.NameColumn( "Name",
+ key="name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=True ),
+ RepositoryGrid.MetadataRevisionColumn( "Metadata Revisions" ),
+ RepositoryGrid.TipRevisionColumn( "Tip Revision" ),
+ RepositoryGrid.CategoryColumn( "Category",
+ model_class=model.Category,
+ key="Category.name",
attach_popup=False ),
- RepositoryListGrid.DescriptionColumn( "Synopsis",
- key="description",
- attach_popup=False ),
- RepositoryListGrid.UserColumn( "Owner",
- model_class=model.User,
- link=( lambda item: dict( operation="repositories_by_user", id=item.id ) ),
- attach_popup=False,
- key="User.username" ),
- RepositoryListGrid.EmailAlertsColumn( "Alert", attach_popup=False ),
+ RepositoryGrid.DeprecatedColumn( "Deprecated" )
+ ]
+ columns.append( grids.MulticolFilterColumn( "Search repository name",
+ cols_to_filter=[ columns[0] ],
+ key="free-text-search",
+ visible=False,
+ filterable="standard" ) )
+ operations = [ grids.GridOperation( "Mark as deprecated",
+ allow_multiple=False,
+ condition=( lambda item: not item.deleted and not item.deprecated ),
+ async_compatible=False ),
+ grids.GridOperation( "Mark as not deprecated",
+ allow_multiple=False,
+ condition=( lambda item: not item.deleted and item.deprecated ),
+ async_compatible=False ) ]
+ def build_initial_query( self, trans, **kwd ):
+ return trans.sa_session.query( model.Repository ) \
+ .filter( model.Repository.table.c.user_id == trans.user.id ) \
+ .join( model.User.table ) \
+ .outerjoin( model.RepositoryCategoryAssociation.table ) \
+ .outerjoin( model.Category.table )
+
+class DeprecatedRepositoriesIOwnGrid( RepositoriesIOwnGrid ):
+ title = "Deprecated repositories I own"
+ columns = [
+ RepositoriesIOwnGrid.NameColumn( "Name",
+ key="name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=True ),
+ RepositoriesIOwnGrid.MetadataRevisionColumn( "Metadata Revisions" ),
+ RepositoriesIOwnGrid.TipRevisionColumn( "Tip Revision" ),
+ RepositoriesIOwnGrid.CategoryColumn( "Category",
+ model_class=model.Category,
+ key="Category.name",
+ attach_popup=False ),
+ ]
+ columns.append( grids.MulticolFilterColumn( "Search repository name",
+ cols_to_filter=[ columns[0] ],
+ key="free-text-search",
+ visible=False,
+ filterable="standard" ) )
+ def build_initial_query( self, trans, **kwd ):
+ return trans.sa_session.query( model.Repository ) \
+ .filter( and_( model.Repository.table.c.user_id == trans.user.id,
+ model.Repository.table.c.deprecated == True ) ) \
+ .join( model.User.table ) \
+ .outerjoin( model.RepositoryCategoryAssociation.table ) \
+ .outerjoin( model.Category.table )
+
+class EmailAlertsRepositoryGrid( RepositoryGrid ):
+ columns = [
+ RepositoryGrid.NameColumn( "Name",
+ key="name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=False ),
+ RepositoryGrid.DescriptionColumn( "Synopsis",
+ key="description",
+ attach_popup=False ),
+ RepositoryGrid.UserColumn( "Owner",
+ model_class=model.User,
+ link=( lambda item: dict( operation="repositories_by_user", id=item.id ) ),
+ attach_popup=False,
+ key="User.username" ),
+ RepositoryGrid.EmailAlertsColumn( "Alert", attach_popup=False ),
# Columns that are valid for filtering but are not visible.
grids.DeletedColumn( "Deleted",
key="deleted",
@@ -277,29 +344,67 @@
grids.GridAction( "User preferences", dict( controller='user', action='index', cntrller='repository' ) )
]
-class WritableRepositoryListGrid( RepositoryListGrid ):
+class MyWritableRepositoriesGrid( RepositoryGrid ):
+ # This grid filters out repositories that have been marked as deprecated.
+ columns = [
+ RepositoryGrid.NameColumn( "Name",
+ key="name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=True ),
+ RepositoryGrid.MetadataRevisionColumn( "Metadata Revisions" ),
+ RepositoryGrid.TipRevisionColumn( "Tip Revision" ),
+ RepositoryGrid.UserColumn( "Owner",
+ model_class=model.User,
+ link=( lambda item: dict( operation="repositories_by_user", id=item.id ) ),
+ attach_popup=False,
+ key="User.username" ),
+ RepositoryGrid.EmailAlertsColumn( "Alert", attach_popup=False ),
+ # Columns that are valid for filtering but are not visible.
+ RepositoryGrid.EmailColumn( "Email",
+ model_class=model.User,
+ key="email",
+ visible=False ),
+ RepositoryGrid.RepositoryCategoryColumn( "Category",
+ model_class=model.Category,
+ key="Category.name",
+ visible=False ),
+ grids.DeletedColumn( "Deleted",
+ key="deleted",
+ visible=False,
+ filterable="advanced" )
+ ]
+ columns.append( grids.MulticolFilterColumn( "Search repository name",
+ cols_to_filter=[ columns[0] ],
+ key="free-text-search",
+ visible=False,
+ filterable="standard" ) )
+ operations = [ grids.GridOperation( "Receive email alerts",
+ allow_multiple=False,
+ condition=( lambda item: not item.deleted ),
+ async_compatible=False ) ]
def build_initial_query( self, trans, **kwd ):
# TODO: improve performance by adding a db table associating users with repositories for which they have write access.
- username = kwd[ 'username' ]
+ username = trans.user.username
clause_list = []
- for repository in trans.sa_session.query( self.model_class ) \
- .filter( self.model_class.table.c.deleted == False ):
+ for repository in trans.sa_session.query( model.Repository ) \
+ .filter( and_( model.Repository.table.c.deprecated == False,
+ model.Repository.table.c.deleted == False ) ):
allow_push = repository.allow_push
if allow_push:
allow_push_usernames = allow_push.split( ',' )
if username in allow_push_usernames:
- clause_list.append( self.model_class.table.c.id == repository.id )
+ clause_list.append( model.Repository.table.c.id == repository.id )
if clause_list:
- return trans.sa_session.query( self.model_class ) \
+ return trans.sa_session.query( model.Repository ) \
.filter( or_( *clause_list ) ) \
.join( model.User.table ) \
.outerjoin( model.RepositoryCategoryAssociation.table ) \
.outerjoin( model.Category.table )
# Return an empty query.
- return trans.sa_session.query( self.model_class ) \
- .filter( self.model_class.table.c.id < 0 )
+ return []
-class ValidRepositoryListGrid( RepositoryListGrid ):
+class ValidRepositoryGrid( RepositoryGrid ):
+ # This grid filters out repositories that have been marked as deprecated.
class CategoryColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
rval = '<ul>'
@@ -330,16 +435,16 @@
return ''
title = "Valid repositories"
columns = [
- RepositoryListGrid.NameColumn( "Name",
- key="name",
- attach_popup=True ),
- RepositoryListGrid.DescriptionColumn( "Synopsis",
- key="description",
- attach_popup=False ),
+ RepositoryGrid.NameColumn( "Name",
+ key="name",
+ attach_popup=True ),
+ RepositoryGrid.DescriptionColumn( "Synopsis",
+ key="description",
+ attach_popup=False ),
RevisionColumn( "Installable Revisions" ),
- RepositoryListGrid.UserColumn( "Owner",
- model_class=model.User,
- attach_popup=False ),
+ RepositoryGrid.UserColumn( "Owner",
+ model_class=model.User,
+ attach_popup=False ),
# Columns that are valid for filtering but are not visible.
RepositoryCategoryColumn( "Category",
model_class=model.Category,
@@ -355,22 +460,25 @@
def build_initial_query( self, trans, **kwd ):
if 'id' in kwd:
# The user is browsing categories of valid repositories, so filter the request by the received id, which is a category id.
- return trans.sa_session.query( self.model_class ) \
+ return trans.sa_session.query( model.Repository ) \
+ .filter( model.Repository.table.c.deprecated == False ) \
.join( model.RepositoryMetadata.table ) \
.join( model.User.table ) \
.join( model.RepositoryCategoryAssociation.table ) \
.join( model.Category.table ) \
.filter( and_( model.Category.table.c.id == trans.security.decode_id( kwd[ 'id' ] ),
model.RepositoryMetadata.table.c.downloadable == True ) )
- # The user performed a free text search on the ValidCategoryListGrid.
- return trans.sa_session.query( self.model_class ) \
+ # The user performed a free text search on the ValidCategoryGrid.
+ return trans.sa_session.query( model.Repository ) \
+ .filter( model.Repository.table.c.deprecated == False ) \
.join( model.RepositoryMetadata.table ) \
.join( model.User.table ) \
.outerjoin( model.RepositoryCategoryAssociation.table ) \
.outerjoin( model.Category.table ) \
.filter( model.RepositoryMetadata.table.c.downloadable == True )
-class MatchedRepositoryListGrid( grids.Grid ):
+class MatchedRepositoryGrid( grids.Grid ):
+ # This grid filters out repositories that have been marked as deprecated.
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository_metadata ):
return repository_metadata.repository.name
@@ -413,38 +521,38 @@
if match_tuples:
for match_tuple in match_tuples:
repository_id, changeset_revision = match_tuple
- clause_list.append( "%s=%d and %s='%s'" % ( self.model_class.table.c.repository_id,
+ clause_list.append( "%s=%d and %s='%s'" % ( model.RepositoryMetadata.table.c.repository_id,
int( repository_id ),
- self.model_class.table.c.changeset_revision,
+ model.RepositoryMetadata.table.c.changeset_revision,
changeset_revision ) )
- return trans.sa_session.query( self.model_class ) \
+ return trans.sa_session.query( model.RepositoryMetadata ) \
.join( model.Repository ) \
+ .filter( model.Repository.table.c.deprecated == False ) \
.join( model.User.table ) \
.filter( or_( *clause_list ) ) \
.order_by( model.Repository.name )
# Return an empty query
- return trans.sa_session.query( self.model_class ) \
- .join( model.Repository ) \
- .join( model.User.table ) \
- .filter( self.model_class.table.c.repository_id == 0 )
+ return []
-class InstallMatchedRepositoryListGrid( MatchedRepositoryListGrid ):
- columns = [ col for col in MatchedRepositoryListGrid.columns ]
+class InstallMatchedRepositoryGrid( MatchedRepositoryGrid ):
+ columns = [ col for col in MatchedRepositoryGrid.columns ]
# Override the NameColumn
- columns[ 0 ] = MatchedRepositoryListGrid.NameColumn( "Name",
- link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
- attach_popup=False )
+ columns[ 0 ] = MatchedRepositoryGrid.NameColumn( "Name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=False )
class RepositoryController( BaseUIController, ItemRatings ):
- install_matched_repository_list_grid = InstallMatchedRepositoryListGrid()
- matched_repository_list_grid = MatchedRepositoryListGrid()
- valid_repository_list_grid = ValidRepositoryListGrid()
- repository_list_grid = RepositoryListGrid()
- email_alerts_repository_list_grid = EmailAlertsRepositoryListGrid()
- category_list_grid = CategoryListGrid()
- valid_category_list_grid = ValidCategoryListGrid()
- writable_repository_list_grid = WritableRepositoryListGrid()
+ install_matched_repository_grid = InstallMatchedRepositoryGrid()
+ matched_repository_grid = MatchedRepositoryGrid()
+ valid_repository_grid = ValidRepositoryGrid()
+ repository_grid = RepositoryGrid()
+ email_alerts_repository_grid = EmailAlertsRepositoryGrid()
+ category_grid = CategoryGrid()
+ valid_category_grid = ValidCategoryGrid()
+ my_writable_repositories_grid = MyWritableRepositoriesGrid()
+ repositories_i_own_grid = RepositoriesIOwnGrid()
+ deprecated_repositories_i_own_grid = DeprecatedRepositoriesIOwnGrid()
def __add_hgweb_config_entry( self, trans, repository, repository_path ):
# Add an entry in the hgweb.config file for a new repository. An entry looks something like:
@@ -470,8 +578,8 @@
def browse_categories( self, trans, **kwd ):
# The request came from the tool shed.
if 'f-free-text-search' in kwd:
- # Trick to enable searching repository name, description from the CategoryListGrid. What we've done is rendered the search box for the
- # RepositoryListGrid on the grid.mako template for the CategoryListGrid. See ~/templates/webapps/community/category/grid.mako. Since we
+ # Trick to enable searching repository name, description from the CategoryGrid. What we've done is rendered the search box for the
+ # RepositoryGrid on the grid.mako template for the CategoryGrid. See ~/templates/webapps/community/category/grid.mako. Since we
# are searching repositories and not categories, redirect to browse_repositories().
if 'id' in kwd and 'f-free-text-search' in kwd and kwd[ 'id' ] == kwd[ 'f-free-text-search' ]:
# The value of 'id' has been set to the search string, which is a repository name. We'll try to get the desired encoded repository id to pass on.
@@ -491,7 +599,7 @@
return trans.response.send_redirect( web.url_for( controller='repository',
action='browse_repositories',
**kwd ) )
- return self.category_list_grid( trans, **kwd )
+ return self.category_grid( trans, **kwd )
@web.expose
def browse_invalid_tools( self, trans, **kwd ):
params = util.Params( kwd )
@@ -564,13 +672,27 @@
for k, v in kwd.items():
if k.startswith( 'f-' ):
del kwd[ k ]
- kwd[ 'f-email' ] = trans.user.email
+ return self.repositories_i_own_grid( trans, **kwd )
+ elif operation == "deprecated_repositories_i_own":
+ # Eliminate the current filters if any exist.
+ for k, v in kwd.items():
+ if k.startswith( 'f-' ):
+ del kwd[ k ]
+ return self.deprecated_repositories_i_own_grid( trans, **kwd )
+ elif operation in [ 'mark as deprecated', 'mark as not deprecated' ]:
+ # Eliminate the current filters if any exist.
+ for k, v in kwd.items():
+ if k.startswith( 'f-' ):
+ del kwd[ k ]
+ kwd[ 'mark_deprecated' ] = operation == 'mark as deprecated'
+ return trans.response.send_redirect( web.url_for( controller='repository',
+ action='deprecate',
+ **kwd ) )
elif operation == "reviewed_repositories_i_own":
return trans.response.send_redirect( web.url_for( controller='repository_review',
action='reviewed_repositories_i_own' ) )
- elif operation == "writable_repositories":
- kwd[ 'username' ] = trans.user.username
- return self.writable_repository_list_grid( trans, **kwd )
+ elif operation == "my_writable_repositories":
+ return self.my_writable_repositories_grid( trans, **kwd )
elif operation == "repositories_by_category":
# Eliminate the current filters if any exist.
for k, v in kwd.items():
@@ -590,7 +712,7 @@
kwd[ 'message' ] = 'You must be logged in to set email alerts.'
kwd[ 'status' ] = 'error'
del kwd[ 'operation' ]
- # The changeset_revision_select_field in the RepositoryListGrid performs a refresh_on_change
+ # The changeset_revision_select_field in the RepositoryGrid performs a refresh_on_change
# which sends in request parameters like changeset_revison_1, changeset_revision_2, etc. One
# of the many select fields on the grid performed the refresh_on_change, so we loop through
# all of the received values to see which value is not the repository tip. If we find it, we
@@ -607,7 +729,7 @@
operation='view_or_manage_repository',
id=trans.security.encode_id( repository.id ),
changeset_revision=v ) )
- return self.repository_list_grid( trans, **kwd )
+ return self.repository_grid( trans, **kwd )
@web.expose
def browse_repository( self, trans, id, **kwd ):
params = util.Params( kwd )
@@ -637,7 +759,7 @@
if kwd[ 'f-free-text-search' ] == 'All':
# The user performed a search, then clicked the "x" to eliminate the search criteria.
new_kwd = {}
- return self.valid_category_list_grid( trans, **new_kwd )
+ return self.valid_category_grid( trans, **new_kwd )
# Since we are searching valid repositories and not categories, redirect to browse_valid_repositories().
if 'id' in kwd and 'f-free-text-search' in kwd and kwd[ 'id' ] == kwd[ 'f-free-text-search' ]:
# The value of 'id' has been set to the search string, which is a repository name.
@@ -658,7 +780,7 @@
return trans.response.send_redirect( web.url_for( controller='repository',
action='browse_valid_repositories',
**kwd ) )
- return self.valid_category_list_grid( trans, **kwd )
+ return self.valid_category_grid( trans, **kwd )
@web.expose
def browse_valid_repositories( self, trans, **kwd ):
galaxy_url = kwd.get( 'galaxy_url', None )
@@ -667,7 +789,7 @@
# The user browsed to a category and then entered a search string, so get the category associated with it's value.
category_name = kwd[ 'f-Category.name' ]
category = get_category_by_name( trans, category_name )
- # Set the id value in kwd since it is required by the ValidRepositoryListGrid.build_initial_query method.
+ # Set the id value in kwd since it is required by the ValidRepositoryGrid.build_initial_query method.
kwd[ 'id' ] = trans.security.encode_id( category.id )
if galaxy_url:
trans.set_cookie( galaxy_url, name='toolshedgalaxyurl' )
@@ -690,7 +812,7 @@
category_id = kwd.get( 'id', None )
category = get_category( trans, category_id )
kwd[ 'f-Category.name' ] = category.name
- # The changeset_revision_select_field in the ValidRepositoryListGrid performs a refresh_on_change which sends in request parameters like
+ # The changeset_revision_select_field in the ValidRepositoryGrid performs a refresh_on_change which sends in request parameters like
# changeset_revison_1, changeset_revision_2, etc. One of the many select fields on the grid performed the refresh_on_change, so we loop
# through all of the received values to see which value is not the repository tip. If we find it, we know the refresh_on_change occurred
# and we have the necessary repository id and change set revision to pass on.
@@ -708,11 +830,11 @@
url_args = dict( action='browse_valid_repositories',
operation='preview_tools_in_changeset',
repository_id=repository_id )
- self.valid_repository_list_grid.operations = [ grids.GridOperation( "Preview and install",
+ self.valid_repository_grid.operations = [ grids.GridOperation( "Preview and install",
url_args=url_args,
allow_multiple=False,
async_compatible=False ) ]
- return self.valid_repository_list_grid( trans, **kwd )
+ return self.valid_repository_grid( trans, **kwd )
def __build_allow_push_select_field( self, trans, current_push_list, selected_value='none' ):
options = []
for user in trans.sa_session.query( trans.model.User ):
@@ -931,6 +1053,27 @@
message=message,
status=status )
@web.expose
+ @web.require_login( "deprecate repository" )
+ def deprecate( self, trans, **kwd ):
+ params = util.Params( kwd )
+ message = util.restore_text( params.get( 'message', '' ) )
+ status = params.get( 'status', 'done' )
+ repository_id = params.get( 'id', None )
+ repository = get_repository( trans, repository_id )
+ mark_deprecated = util.string_as_bool( params.get( 'mark_deprecated', False ) )
+ repository.deprecated = mark_deprecated
+ trans.sa_session.add( repository )
+ trans.sa_session.flush()
+ if mark_deprecated:
+ message = 'The repository <b>%s</b> has been marked as deprecated.' % repository.name
+ else:
+ message = 'The repository <b>%s</b> has been marked as not deprecated.' % repository.name
+ trans.response.send_redirect( web.url_for( controller='repository',
+ action='browse_repositories',
+ operation='repositories_i_own',
+ message=message,
+ status=status ) )
+ @web.expose
def display_tool( self, trans, repository_id, tool_config, changeset_revision, **kwd ):
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
@@ -1049,16 +1192,16 @@
dict( controller='repository', action='find_tools' ) ),
grids.GridAction( "Search for workflows",
dict( controller='repository', action='find_workflows' ) ) ]
- self.install_matched_repository_list_grid.global_actions = global_actions
+ self.install_matched_repository_grid.global_actions = global_actions
install_url_args = dict( controller='repository', action='find_tools' )
operations = [ grids.GridOperation( "Install", url_args=install_url_args, allow_multiple=True, async_compatible=False ) ]
- self.install_matched_repository_list_grid.operations = operations
- return self.install_matched_repository_list_grid( trans, **kwd )
+ self.install_matched_repository_grid.operations = operations
+ return self.install_matched_repository_grid( trans, **kwd )
else:
kwd[ 'message' ] = "tool id: <b>%s</b><br/>tool name: <b>%s</b><br/>tool version: <b>%s</b><br/>exact matches only: <b>%s</b>" % \
( self.__stringify( tool_ids ), self.__stringify( tool_names ), self.__stringify( tool_versions ), str( exact_matches_checked ) )
- self.matched_repository_list_grid.title = "Repositories with matching tools"
- return self.matched_repository_list_grid( trans, **kwd )
+ self.matched_repository_grid.title = "Repositories with matching tools"
+ return self.matched_repository_grid( trans, **kwd )
else:
message = "No search performed - each field must contain the same number of comma-separated items."
status = "error"
@@ -1135,16 +1278,16 @@
dict( controller='repository', action='find_tools' ) ),
grids.GridAction( "Search for workflows",
dict( controller='repository', action='find_workflows' ) ) ]
- self.install_matched_repository_list_grid.global_actions = global_actions
+ self.install_matched_repository_grid.global_actions = global_actions
install_url_args = dict( controller='repository', action='find_workflows' )
operations = [ grids.GridOperation( "Install", url_args=install_url_args, allow_multiple=True, async_compatible=False ) ]
- self.install_matched_repository_list_grid.operations = operations
- return self.install_matched_repository_list_grid( trans, **kwd )
+ self.install_matched_repository_grid.operations = operations
+ return self.install_matched_repository_grid( trans, **kwd )
else:
kwd[ 'message' ] = "workflow name: <b>%s</b><br/>exact matches only: <b>%s</b>" % \
( self.__stringify( workflow_names ), str( exact_matches_checked ) )
- self.matched_repository_list_grid.title = "Repositories with matching workflows"
- return self.matched_repository_list_grid( trans, **kwd )
+ self.matched_repository_grid.title = "Repositories with matching workflows"
+ return self.matched_repository_grid( trans, **kwd )
else:
message = "No search performed - each field must contain the same number of comma-separated items."
status = "error"
@@ -1407,17 +1550,24 @@
status = params.get( 'status', 'done' )
# See if there are any RepositoryMetadata records since menu items require them.
repository_metadata = trans.sa_session.query( model.RepositoryMetadata ).first()
- # See if the current user owns any repositories that have been reviewed.
+ current_user = trans.user
has_reviewed_repositories = False
- current_user = trans.user
+ has_deprecated_repositories = False
if current_user:
+ # See if the current user owns any repositories that have been reviewed.
for repository in current_user.active_repositories:
if repository.reviewed_revisions:
has_reviewed_repositories = True
break
+ # See if the current user has any repositories that have been marked as deprecated.
+ for repository in current_user.active_repositories:
+ if repository.deprecated:
+ has_deprecated_repositories = True
+ break
return trans.fill_template( '/webapps/community/index.mako',
repository_metadata=repository_metadata,
has_reviewed_repositories=has_reviewed_repositories,
+ has_deprecated_repositories=has_deprecated_repositories,
message=message,
status=status )
@web.expose
@@ -1738,7 +1888,8 @@
kwd[ 'message' ] = 'You must be logged in to set email alerts.'
kwd[ 'status' ] = 'error'
del kwd[ 'operation' ]
- return self.email_alerts_repository_list_grid( trans, **kwd )
+ self.email_alerts_repository_grid.title = "Set email alerts for repository changes"
+ return self.email_alerts_repository_grid( trans, **kwd )
def __new_state( self, trans, all_pages=False ):
"""
Create a new `DefaultToolState` for this tool. It will not be initialized
diff -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 lib/galaxy/webapps/community/controllers/repository_review.py
--- a/lib/galaxy/webapps/community/controllers/repository_review.py
+++ b/lib/galaxy/webapps/community/controllers/repository_review.py
@@ -7,7 +7,7 @@
from galaxy.model.orm import *
from sqlalchemy.sql.expression import func
from common import *
-from repository import RepositoryListGrid
+from repository import RepositoryGrid
from galaxy.util.shed_util import get_configured_ui
from galaxy.util.odict import odict
@@ -48,36 +48,33 @@
preserve_state = False
use_paging = True
-class RepositoriesWithReviewsGrid( RepositoryListGrid ):
+class RepositoriesWithReviewsGrid( RepositoryGrid ):
+ # This grid filters out repositories that have been marked as deprecated.
class ReviewersColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
+ rval = ''
if repository.reviewers:
- rval = ''
for user in repository.reviewers:
- rval += '%s<br/>' % user.username
- return rval
- return ''
- title = "All reviewed Repositories"
+ rval += '<a class="view-info" href="repository_reviews_by_user?id=%s">' % trans.security.encode_id( user.id )
+ rval += '%s</a> | ' % user.username
+ rval = rval.rstrip( ' | ' )
+ return rval
+ title = "All reviewed repositories"
model_class = model.Repository
template='/webapps/community/repository_review/grid.mako'
default_sort_key = "Repository.name"
columns = [
- RepositoryListGrid.NameColumn( "Repository name",
- key="name",
- link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
- attach_popup=True ),
- RepositoryListGrid.DescriptionColumn( "Synopsis",
- key="description",
- attach_popup=False ),
- RepositoryListGrid.WithReviewsRevisionColumn( "Reviewed revisions" ),
- RepositoryListGrid.WithoutReviewsRevisionColumn( "Revisions for review" ),
- RepositoryListGrid.UserColumn( "Owner",
- attach_popup=False ),
- ReviewersColumn( "Reviewers",
- attach_popup=False )
+ RepositoryGrid.NameColumn( "Repository name",
+ key="name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=True ),
+ RepositoryGrid.WithReviewsRevisionColumn( "Reviewed revisions" ),
+ RepositoryGrid.WithoutReviewsRevisionColumn( "Revisions for review" ),
+ RepositoryGrid.UserColumn( "Owner", attach_popup=False ),
+ ReviewersColumn( "Reviewers", attach_popup=False )
]
- columns.append( grids.MulticolFilterColumn( "Search repository name, description",
- cols_to_filter=[ columns[0], columns[1] ],
+ columns.append( grids.MulticolFilterColumn( "Search repository name",
+ cols_to_filter=[ columns[0] ],
key="free-text-search",
visible=False,
filterable="standard" ) )
@@ -89,12 +86,14 @@
]
def build_initial_query( self, trans, **kwd ):
return trans.sa_session.query( model.Repository ) \
+ .filter( model.Repository.table.c.deprecated == False ) \
.join( ( model.RepositoryReview.table, model.RepositoryReview.table.c.repository_id == model.Repository.table.c.id ) ) \
.join( ( model.User.table, model.User.table.c.id == model.Repository.table.c.user_id ) ) \
.outerjoin( ( model.ComponentReview.table, model.ComponentReview.table.c.repository_review_id == model.RepositoryReview.table.c.id ) ) \
.outerjoin( ( model.Component.table, model.Component.table.c.id == model.ComponentReview.table.c.component_id ) )
class RepositoriesWithoutReviewsGrid( RepositoriesWithReviewsGrid ):
+ # This grid filters out repositories that have been marked as deprecated.
title = "Repositories with no reviews"
columns = [
RepositoriesWithReviewsGrid.NameColumn( "Repository name",
@@ -119,12 +118,15 @@
async_compatible=False ) ]
def build_initial_query( self, trans, **kwd ):
return trans.sa_session.query( model.Repository ) \
- .filter( model.Repository.reviews == None ) \
+ .filter( and_( model.Repository.table.c.deprecated == False,
+ model.Repository.reviews == None ) ) \
.join( model.User.table )
class RepositoriesReviewedByMeGrid( RepositoriesWithReviewsGrid ):
+ # This grid filters out repositories that have been marked as deprecated.
def build_initial_query( self, trans, **kwd ):
return trans.sa_session.query( model.Repository ) \
+ .filter( model.Repository.table.c.deprecated == False ) \
.join( ( model.RepositoryReview.table, model.RepositoryReview.table.c.repository_id == model.Repository.table.c.id ) ) \
.filter( model.RepositoryReview.table.c.user_id == trans.user.id ) \
.join( ( model.User.table, model.User.table.c.id == model.RepositoryReview.table.c.user_id ) ) \
@@ -132,6 +134,7 @@
.outerjoin( ( model.Component.table, model.Component.table.c.id == model.ComponentReview.table.c.component_id ) )
class RepositoryReviewsByUserGrid( grids.Grid ):
+ # This grid filters out repositories that have been marked as deprecated.
class RepositoryNameColumn( grids.TextColumn ):
def get_value( self, trans, grid, review ):
return review.repository.name
@@ -166,33 +169,61 @@
default_sort_key = 'repository_id'
columns = [
RepositoryNameColumn( "Repository Name",
- model_class=model.Repository,
- key="Repository.name",
- attach_popup=False ),
+ model_class=model.Repository,
+ key="Repository.name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=True ),
RepositoryDescriptionColumn( "Description",
- model_class=model.Repository,
- key="Repository.description",
- attach_popup=False ),
- RevisionColumn( "Revision",
- attach_popup=False ),
- RatingColumn( "Rating",
- attach_popup=False )
+ model_class=model.Repository,
+ key="Repository.description",
+ attach_popup=False ),
+ RevisionColumn( "Revision", attach_popup=False ),
+ RatingColumn( "Rating", attach_popup=False ),
]
# Override these
default_filter = {}
global_actions = []
- operations = []
+ operations = [
+ grids.GridOperation( "Inspect repository revisions",
+ allow_multiple=False,
+ condition=( lambda item: not item.deleted ),
+ async_compatible=False )
+ ]
standard_filters = []
num_rows_per_page = 50
preserve_state = False
use_paging = True
def build_initial_query( self, trans, **kwd ):
user_id = trans.security.decode_id( kwd[ 'id' ] )
- return trans.sa_session.query( self.model_class ) \
+ return trans.sa_session.query( model.RepositoryReview ) \
.filter( and_( model.RepositoryReview.table.c.deleted == False, \
- model.RepositoryReview.table.c.user_id == user_id ) )
+ model.RepositoryReview.table.c.user_id == user_id ) ) \
+ .join( ( model.Repository.table, model.RepositoryReview.table.c.repository_id == model.Repository.table.c.id ) ) \
+ .filter( model.Repository.table.c.deprecated == False )
class ReviewedRepositoriesIOwnGrid( RepositoriesWithReviewsGrid ):
+ title = "Reviewed repositories I own"
+ columns = [
+ RepositoriesWithReviewsGrid.NameColumn( "Repository name",
+ key="name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=True ),
+ RepositoriesWithReviewsGrid.WithReviewsRevisionColumn( "Reviewed revisions" ),
+ RepositoriesWithReviewsGrid.WithoutReviewsRevisionColumn( "Revisions for review" ),
+ RepositoriesWithReviewsGrid.ReviewersColumn( "Reviewers", attach_popup=False ),
+ RepositoryGrid.DeprecatedColumn( "Deprecated" )
+ ]
+ columns.append( grids.MulticolFilterColumn( "Search repository name",
+ cols_to_filter=[ columns[0] ],
+ key="free-text-search",
+ visible=False,
+ filterable="standard" ) )
+ operations = [
+ grids.GridOperation( "Inspect repository revisions",
+ allow_multiple=False,
+ condition=( lambda item: not item.deleted ),
+ async_compatible=False )
+ ]
def build_initial_query( self, trans, **kwd ):
return trans.sa_session.query( model.Repository ) \
.join( ( model.RepositoryReview.table, model.RepositoryReview.table.c.repository_id == model.Repository.table.c.id ) ) \
@@ -655,10 +686,26 @@
@web.expose
@web.require_login( "repository reviews by user" )
def repository_reviews_by_user( self, trans, **kwd ):
- # The user may not be the current user. The value of the received id is the encoded user id.
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
+
+ if 'operation' in kwd:
+ operation = kwd['operation'].lower()
+ # The value of the received id is the encoded review id.
+ review = get_review( trans, kwd[ 'id' ] )
+ repository = review.repository
+ kwd[ 'id' ] = trans.security.encode_id( repository.id )
+ if operation == "inspect repository revisions":
+ return trans.response.send_redirect( web.url_for( controller='repository_review',
+ action='manage_repository_reviews',
+ **kwd ) )
+ if operation == "view_or_manage_repository":
+ kwd[ 'changeset_revision' ] = review.changeset_revision
+ return trans.response.send_redirect( web.url_for( controller='repository_review',
+ action='view_or_manage_repository',
+ **kwd ) )
+ # The user may not be the current user. The value of the received id is the encoded user id.
user = get_user( trans, kwd[ 'id' ] )
self.repository_reviews_by_user_grid.title = "All repository revision reviews for user '%s'" % user.username
return self.repository_reviews_by_user_grid( trans, **kwd )
@@ -668,6 +715,13 @@
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
+ # The value of the received id is the encoded repository id.
+ if 'operation' in kwd:
+ operation = kwd['operation'].lower()
+ if operation == "view_or_manage_repository":
+ return trans.response.send_redirect( web.url_for( controller='repository_review',
+ action='view_or_manage_repository',
+ **kwd ) )
return self.reviewed_repositories_i_own_grid( trans, **kwd )
@web.expose
@web.require_login( "select previous review" )
diff -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 lib/galaxy/webapps/community/model/__init__.py
--- a/lib/galaxy/webapps/community/model/__init__.py
+++ b/lib/galaxy/webapps/community/model/__init__.py
@@ -109,7 +109,8 @@
MARKED_FOR_REMOVAL = 'r',
MARKED_FOR_ADDITION = 'a',
NOT_TRACKED = '?' )
- def __init__( self, name=None, description=None, long_description=None, user_id=None, private=False, email_alerts=None, times_downloaded=0 ):
+ def __init__( self, name=None, description=None, long_description=None, user_id=None, private=False, email_alerts=None, times_downloaded=0,
+ deprecated=False ):
self.name = name or "Unnamed repository"
self.description = description
self.long_description = long_description
@@ -117,6 +118,7 @@
self.private = private
self.email_alerts = email_alerts
self.times_downloaded = times_downloaded
+ self.deprecated = deprecated
@property
def repo_path( self ):
# Repository locations on disk are defined in the hgweb.config file
diff -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 lib/galaxy/webapps/community/model/mapping.py
--- a/lib/galaxy/webapps/community/model/mapping.py
+++ b/lib/galaxy/webapps/community/model/mapping.py
@@ -111,7 +111,8 @@
Column( "private", Boolean, default=False ),
Column( "deleted", Boolean, index=True, default=False ),
Column( "email_alerts", JSONType, nullable=True ),
- Column( "times_downloaded", Integer ) )
+ Column( "times_downloaded", Integer ),
+ Column( "deprecated", Boolean, default=False ) )
RepositoryMetadata.table = Table( "repository_metadata", metadata,
Column( "id", Integer, primary_key=True ),
@@ -218,7 +219,10 @@
properties=dict( children=relation(Tag, backref=backref( 'parent', remote_side=[ Tag.table.c.id ] ) ) ) )
assign_mapper( context, Category, Category.table,
- properties=dict( repositories=relation( RepositoryCategoryAssociation ) ) )
+ properties=dict( repositories=relation( RepositoryCategoryAssociation,
+ secondary=Repository.table,
+ primaryjoin=( Category.table.c.id == RepositoryCategoryAssociation.table.c.category_id ),
+ secondaryjoin=( ( RepositoryCategoryAssociation.table.c.repository_id == Repository.table.c.id ) & ( Repository.table.c.deprecated == False ) ) ) ) )
assign_mapper( context, Repository, Repository.table,
properties = dict(
diff -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 lib/galaxy/webapps/community/model/migrate/versions/0014_add_deprecated_column.py
--- /dev/null
+++ b/lib/galaxy/webapps/community/model/migrate/versions/0014_add_deprecated_column.py
@@ -0,0 +1,53 @@
+"""
+Migration script to add the deprecated column to the repository table.
+"""
+
+from sqlalchemy import *
+from sqlalchemy.orm import *
+from migrate import *
+from migrate.changeset import *
+
+# Need our custom types, but don't import anything else from model
+from galaxy.model.custom_types import *
+
+import sys, logging
+log = logging.getLogger( __name__ )
+log.setLevel(logging.DEBUG)
+handler = logging.StreamHandler( sys.stdout )
+format = "%(name)s %(levelname)s %(asctime)s %(message)s"
+formatter = logging.Formatter( format )
+handler.setFormatter( formatter )
+log.addHandler( handler )
+
+metadata = MetaData( migrate_engine )
+db_session = scoped_session( sessionmaker( bind=migrate_engine, autoflush=False, autocommit=True ) )
+
+def upgrade():
+ print __doc__
+ metadata.reflect()
+ # Create and initialize imported column in job table.
+ Repository_table = Table( "repository", metadata, autoload=True )
+ c = Column( "deprecated", Boolean, default=False )
+ try:
+ # Create
+ c.create( Repository_table )
+ assert c is Repository_table.c.deprecated
+ # Initialize.
+ if migrate_engine.name == 'mysql' or migrate_engine.name == 'sqlite':
+ default_false = "0"
+ elif migrate_engine.name == 'postgres':
+ default_false = "false"
+ db_session.execute( "UPDATE repository SET deprecated=%s" % default_false )
+ except Exception, e:
+ print "Adding deprecated column to the repository table failed: %s" % str( e )
+ log.debug( "Adding deprecated column to the repository table failed: %s" % str( e ) )
+
+def downgrade():
+ metadata.reflect()
+ # Drop email_alerts column from repository table.
+ Repository_table = Table( "repository", metadata, autoload=True )
+ try:
+ Repository_table.c.deprecated.drop()
+ except Exception, e:
+ print "Dropping column deprecated from the repository table failed: %s" % str( e )
+ log.debug( "Dropping column deprecated from the repository table failed: %s" % str( e ) )
diff -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 templates/webapps/community/category/grid.mako
--- a/templates/webapps/community/category/grid.mako
+++ b/templates/webapps/community/category/grid.mako
@@ -49,8 +49,8 @@
<%def name="grid_body( grid )"><%
- from galaxy.webapps.community.controllers.repository import RepositoryListGrid
- repo_grid = RepositoryListGrid()
+ from galaxy.webapps.community.controllers.repository import RepositoryGrid
+ repo_grid = RepositoryGrid()
%>
${self.make_grid( grid, repo_grid )}
</%def>
diff -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 templates/webapps/community/category/valid_grid.mako
--- a/templates/webapps/community/category/valid_grid.mako
+++ b/templates/webapps/community/category/valid_grid.mako
@@ -48,8 +48,8 @@
<%def name="grid_body( grid )"><%
- from galaxy.webapps.community.controllers.repository import ValidRepositoryListGrid
- repo_grid = ValidRepositoryListGrid()
+ from galaxy.webapps.community.controllers.repository import ValidRepositoryGrid
+ repo_grid = ValidRepositoryGrid()
%>
${self.make_grid( grid, repo_grid )}
</%def>
diff -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 templates/webapps/community/index.mako
--- a/templates/webapps/community/index.mako
+++ b/templates/webapps/community/index.mako
@@ -78,8 +78,13 @@
<a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories', operation='reviewed_repositories_i_own' )}">Reviewed repositories I own</a></div>
%endif
+ %if has_deprecated_repositories:
+ <div class="toolTitle">
+ <a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories', operation='deprecated_repositories_i_own' )}">Deprecated repositories I own</a>
+ </div>
+ %endif
<div class="toolTitle">
- <a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories', operation='writable_repositories' )}">My writable repositories</a>
+ <a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories', operation='my_writable_repositories' )}">My writable repositories</a></div><div class="toolTitle"><a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_invalid_tools', cntrller='repository' )}">My invalid tools</a>
diff -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 templates/webapps/community/repository/manage_repository.mako
--- a/templates/webapps/community/repository/manage_repository.mako
+++ b/templates/webapps/community/repository/manage_repository.mako
@@ -7,22 +7,25 @@
from galaxy.web.framework.helpers import time_ago
is_admin = trans.user_is_admin()
is_new = repository.is_new
+ is_deprecated = repository.deprecated
can_contact_owner = trans.user and trans.user != repository.user
- can_push = trans.app.security_agent.can_push( trans.user, repository )
+ can_push = not is_deprecated and trans.app.security_agent.can_push( trans.user, repository )
can_upload = can_push
- can_download = not is_new and ( not is_malicious or can_push )
+ can_download = not is_deprecated and not is_new and ( not is_malicious or can_push )
can_browse_contents = not is_new
- can_set_metadata = not is_new
- can_rate = not is_new and trans.user and repository.user != trans.user
+ can_set_metadata = not is_new and not is_deprecated
+ can_rate = not is_new and not is_deprecated and trans.user and repository.user != trans.user
can_view_change_log = not is_new
if can_push:
browse_label = 'Browse or delete repository tip files'
else:
browse_label = 'Browse repository tip files'
can_set_malicious = metadata and can_set_metadata and is_admin and changeset_revision == repository.tip
- can_reset_all_metadata = is_admin and len( repo ) > 0
+ can_deprecate = not is_new and trans.user and ( is_admin or repository.user == trans.user ) and not is_deprecated
+ can_undeprecate = trans.user and ( is_admin or repository.user == trans.user ) and is_deprecated
+ can_reset_all_metadata = not is_deprecated and is_admin and len( repo ) > 0
has_readme = metadata and 'readme' in metadata
- can_review_repository = trans.app.security_agent.user_can_review_repositories( trans.user )
+ can_review_repository = not is_deprecated and trans.app.security_agent.user_can_review_repositories( trans.user )
reviewing_repository = cntrller and cntrller == 'repository_review'
if changeset_revision == repository.tip:
tip_str = 'repository tip'
@@ -87,6 +90,12 @@
%if can_reset_all_metadata:
<a class="action-button" href="${h.url_for( controller='repository', action='reset_all_metadata', id=trans.security.encode_id( repository.id ) )}">Reset all repository metadata</a>
%endif
+ %if can_deprecate:
+ <a class="action-button" href="${h.url_for( controller='repository', action='deprecate', id=trans.security.encode_id( repository.id ), mark_deprecated=True )}">Mark repository as deprecated</a>
+ %endif
+ %if can_undeprecate:
+ <a class="action-button" href="${h.url_for( controller='repository', action='deprecate', id=trans.security.encode_id( repository.id ), mark_deprecated=False )}">Mark repository as not deprecated</a>
+ %endif
%if can_download:
<a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision, file_type='gz' )}">Download as a .tar.gz file</a><a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision, file_type='bz2' )}">Download as a .tar.bz2 file</a>
@@ -101,6 +110,12 @@
${render_msg( message, status )}
%endif
+%if repository.deprecated:
+ <div class="warningmessage">
+ This repository has been marked as deprecated, so some tool shed features may be restricted.
+ </div>
+%endif
+
%if len( changeset_revision_select_field.options ) > 1:
<div class="toolForm"><div class="toolFormTitle">Repository revision</div>
@@ -122,7 +137,7 @@
<p/>
%endif
<div class="toolForm">
- <div class="toolFormTitle">${repository.name}</div>
+ <div class="toolFormTitle">Repository '${repository.name}'</div><div class="toolFormBody"><form name="edit_repository" id="edit_repository" action="${h.url_for( controller='repository', action='manage_repository', id=trans.security.encode_id( repository.id ) )}" method="post" >
%if can_download:
diff -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 templates/webapps/community/repository/view_repository.mako
--- a/templates/webapps/community/repository/view_repository.mako
+++ b/templates/webapps/community/repository/view_repository.mako
@@ -6,11 +6,12 @@
<%
from galaxy.web.framework.helpers import time_ago
is_new = repository.is_new
+ is_deprecated = repository.deprecated
can_contact_owner = trans.user and trans.user != repository.user
- can_push = trans.app.security_agent.can_push( trans.user, repository )
- can_rate = not is_new and trans.user and repository.user != trans.user
+ can_push = not is_deprecated and trans.app.security_agent.can_push( trans.user, repository )
+ can_rate = not is_deprecated and not is_new and trans.user and repository.user != trans.user
can_upload = can_push
- can_download = not is_new and ( not is_malicious or can_push )
+ can_download = not is_deprecated and not is_new and ( not is_malicious or can_push )
can_browse_contents = trans.webapp.name == 'community' and not is_new
can_view_change_log = trans.webapp.name == 'community' and not is_new
if can_push:
@@ -19,7 +20,7 @@
browse_label = 'Browse repository tip files'
has_readme = metadata and 'readme' in metadata
reviewing_repository = cntrller and cntrller == 'repository_review'
- can_review_repository = trans.app.security_agent.user_can_review_repositories( trans.user )
+ can_review_repository = not is_deprecated and trans.app.security_agent.user_can_review_repositories( trans.user )
%><%!
@@ -100,6 +101,12 @@
${render_msg( message, status )}
%endif
+%if repository.deprecated:
+ <div class="warningmessage">
+ This repository has been marked as deprecated, so some tool shed features may be restricted.
+ </div>
+%endif
+
%if len( changeset_revision_select_field.options ) > 1:
<div class="toolForm"><div class="toolFormTitle">Repository revision</div>
@@ -123,7 +130,7 @@
<p/>
%endif
<div class="toolForm">
- <div class="toolFormTitle">${repository.name}</div>
+ <div class="toolFormTitle">Repository '${repository.name}'</div><div class="toolFormBody">
%if can_download:
<div class="form-row">
diff -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 templates/webapps/community/repository/view_tool_metadata.mako
--- a/templates/webapps/community/repository/view_tool_metadata.mako
+++ b/templates/webapps/community/repository/view_tool_metadata.mako
@@ -110,7 +110,7 @@
<p/>
%if can_download:
<div class="toolForm">
- <div class="toolFormTitle">${repository.name}</div>
+ <div class="toolFormTitle">Repository '${repository.name}'</div><div class="toolFormBody"><div class="form-row"><label>Clone this repository:</label>
diff -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 tools/genomespace/genomespace_file_browser.py
--- a/tools/genomespace/genomespace_file_browser.py
+++ b/tools/genomespace/genomespace_file_browser.py
@@ -39,6 +39,7 @@
'gmt': 'gmt',
'gct': 'gct'}
+VALID_CHARS = '.-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '
def chunk_write( source_stream, target_stream, source_method = "read", target_method="write" ):
source_method = getattr( source_stream, source_method )
@@ -113,6 +114,7 @@
name = name[len( file_url_prefix ):]
file_numbers.append( int( name ) )
file_numbers.sort()
+ used_filenames = []
for file_num in file_numbers:
url_key = "%s%i" % ( file_url_prefix, file_num )
download_url = datasource_params.get( url_key, None )
@@ -135,8 +137,14 @@
parsed_url = urlparse.urlparse( download_url )
query_params = urlparse.parse_qs( parsed_url[4] )
filename = urllib.unquote_plus( parsed_url[2].split( '/' )[-1] )
+ if not filename:
+ filename = download_url
if output_filename is None:
- output_filename = os.path.join( datasource_params['__new_file_path__'], 'primary_%i_output%i_visible_%s' % ( hda_id, file_num, galaxy_ext ) )
+ filename = ''.join( c in VALID_CHARS and c or '-' for c in filename )
+ while filename in used_filenames:
+ filename = "-%s" % filename
+ used_filenames.append( filename )
+ output_filename = os.path.join( datasource_params['__new_file_path__'], 'primary_%i_%s_visible_%s' % ( hda_id, filename, galaxy_ext ) )
else:
if dataset_id is not None:
metadata_parameter_file.write( "%s\n" % simplejson.dumps( dict( type = 'dataset',
diff -r d0e40dd01870b6b408d64d25c57edbd1f7b39288 -r e26fec7ee17feb082efe7c9f815c5821f07e0f32 tools/genomespace/genomespace_importer.py
--- a/tools/genomespace/genomespace_importer.py
+++ b/tools/genomespace/genomespace_importer.py
@@ -43,7 +43,7 @@
'gmt': 'gmt',
'gct': 'gct'}
-VALID_CHARS = '.-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
+VALID_CHARS = '.-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '
def chunk_write( source_stream, target_stream, source_method = "read", target_method="write" ):
source_method = getattr( source_stream, source_method )
@@ -112,6 +112,7 @@
datatypes_registry = Registry()
datatypes_registry.load_datatypes( root_dir = json_params[ 'job_config' ][ 'GALAXY_ROOT_DIR' ], config = json_params[ 'job_config' ][ 'GALAXY_DATATYPES_CONF_FILE' ] )
url_param = datasource_params.get( file_url_name, None )
+ used_filenames = []
for download_url in url_param.split( ',' ):
using_temp_file = False
parsed_url = urlparse.urlparse( download_url )
@@ -129,6 +130,8 @@
parsed_url = urlparse.urlparse( download_url )
query_params = urlparse.parse_qs( parsed_url[4] )
filename = urllib.unquote_plus( parsed_url[2].split( '/' )[-1] )
+ if not filename:
+ filename = download_url
if output_filename is None:
#need to use a temp file here, because we do not know the ext yet
using_temp_file = True
@@ -179,7 +182,11 @@
name = "GenomeSpace importer on %s" % ( filename ) ) ) )
#if using tmp file, move the file to the new file path dir to get scooped up later
if using_temp_file:
- shutil.move( output_filename, os.path.join( datasource_params['__new_file_path__'], 'primary_%i_output%s_visible_%s' % ( hda_id, ''.join( c in VALID_CHARS and c or '-' for c in filename ), file_type ) ) )
+ filename = ''.join( c in VALID_CHARS and c or '-' for c in filename )
+ while filename in used_filenames:
+ filename = "-%s" % filename
+ used_filenames.append( filename )
+ shutil.move( output_filename, os.path.join( datasource_params['__new_file_path__'], 'primary_%i_%s_visible_%s' % ( hda_id, filename, file_type ) ) )
dataset_id = None #only one primary dataset available
output_filename = None #only have one filename available
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/946fd73d6f76/
changeset: 946fd73d6f76
branch: zero-merge
user: natefoo
date: 2012-10-19 22:27:48
summary: Closed branch zero-merge.
affected #: 0 files
https://bitbucket.org/galaxy/galaxy-central/changeset/bf642ff506b6/
changeset: bf642ff506b6
user: natefoo
date: 2012-10-19 22:28:19
summary: merge zero-merge to default.
affected #: 0 files
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
19 Oct '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/144ae945768a/
changeset: 144ae945768a
user: greg
date: 2012-10-19 22:25:08
summary: Some tool she drepository grid cleanup, and add the ability to mark a repository as deprecated / undeprecated. Repositories in the tool shed that are marked as deprecated have restricted tool shed features and will not be included in several queries.
affected #: 12 files
diff -r ae9d794074bcc4732601e480ff54d53b0b2ee6e7 -r 144ae945768aea03c56f80cb4d6db953fa88cbaf lib/galaxy/webapps/community/controllers/admin.py
--- a/lib/galaxy/webapps/community/controllers/admin.py
+++ b/lib/galaxy/webapps/community/controllers/admin.py
@@ -7,7 +7,7 @@
from galaxy.util import inflector
from galaxy.util.shed_util import get_changectx_for_changeset, get_configured_ui
from common import *
-from repository import RepositoryListGrid, CategoryListGrid
+from repository import RepositoryGrid, CategoryGrid
from galaxy import eggs
eggs.require( 'mercurial' )
@@ -17,7 +17,7 @@
log = logging.getLogger( __name__ )
-class UserListGrid( grids.Grid ):
+class UserGrid( grids.Grid ):
# TODO: move this to an admin_common controller since it is virtually the same in the galaxy webapp.
class UserLoginColumn( grids.TextColumn ):
def get_value( self, trans, grid, user ):
@@ -66,10 +66,10 @@
default_sort_key = "email"
columns = [
UserLoginColumn( "Email",
- key="email",
- link=( lambda item: dict( operation="information", id=item.id ) ),
- attach_popup=True,
- filterable="advanced" ),
+ key="email",
+ link=( lambda item: dict( operation="information", id=item.id ) ),
+ attach_popup=True,
+ filterable="advanced" ),
UserNameColumn( "User Name",
key="username",
attach_popup=False,
@@ -116,7 +116,7 @@
def get_current_item( self, trans, **kwargs ):
return trans.user
-class RoleListGrid( grids.Grid ):
+class RoleGrid( grids.Grid ):
# TODO: move this to an admin_common controller since it is virtually the same in the galaxy webapp.
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, role ):
@@ -207,7 +207,7 @@
def apply_query_filter( self, trans, query, **kwd ):
return query.filter( model.Role.type != model.Role.types.PRIVATE )
-class GroupListGrid( grids.Grid ):
+class GroupGrid( grids.Grid ):
# TODO: move this to an admin_common controller since it is virtually the same in the galaxy webapp.
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, group ):
@@ -278,34 +278,35 @@
preserve_state = False
use_paging = True
-class ManageCategoryListGrid( CategoryListGrid ):
- columns = [ col for col in CategoryListGrid.columns ]
+class ManageCategoryGrid( CategoryGrid ):
+ columns = [ col for col in CategoryGrid.columns ]
# Override the NameColumn to include an Edit link
- columns[ 0 ] = CategoryListGrid.NameColumn( "Name",
- key="Category.name",
- link=( lambda item: dict( operation="Edit", id=item.id ) ),
- model_class=model.Category,
- attach_popup=False )
+ columns[ 0 ] = CategoryGrid.NameColumn( "Name",
+ key="Category.name",
+ link=( lambda item: dict( operation="Edit", id=item.id ) ),
+ model_class=model.Category,
+ attach_popup=False )
global_actions = [
grids.GridAction( "Add new category",
dict( controller='admin', action='manage_categories', operation='create' ) )
]
-class AdminRepositoryListGrid( RepositoryListGrid ):
- columns = [ RepositoryListGrid.NameColumn( "Name",
- key="name",
- link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
- attach_popup=True ),
- RepositoryListGrid.DescriptionColumn( "Synopsis",
- key="description",
- attach_popup=False ),
- RepositoryListGrid.MetadataRevisionColumn( "Metadata Revisions" ),
- RepositoryListGrid.UserColumn( "Owner",
- model_class=model.User,
- link=( lambda item: dict( operation="repositories_by_user", id=item.id ) ),
- attach_popup=False,
- key="User.username" ),
- RepositoryListGrid.EmailAlertsColumn( "Alert", attach_popup=False ),
+class AdminRepositoryGrid( RepositoryGrid ):
+ columns = [ RepositoryGrid.NameColumn( "Name",
+ key="name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=True ),
+ RepositoryGrid.DescriptionColumn( "Synopsis",
+ key="description",
+ attach_popup=False ),
+ RepositoryGrid.MetadataRevisionColumn( "Metadata Revisions" ),
+ RepositoryGrid.UserColumn( "Owner",
+ model_class=model.User,
+ link=( lambda item: dict( operation="repositories_by_user", id=item.id ) ),
+ attach_popup=False,
+ key="User.username" ),
+ RepositoryGrid.EmailAlertsColumn( "Alert", attach_popup=False ),
+ RepositoryGrid.DeprecatedColumn( "Deprecated", attach_popup=False ),
# Columns that are valid for filtering but are not visible.
grids.DeletedColumn( "Deleted",
key="deleted",
@@ -316,7 +317,7 @@
key="free-text-search",
visible=False,
filterable="standard" ) )
- operations = [ operation for operation in RepositoryListGrid.operations ]
+ operations = [ operation for operation in RepositoryGrid.operations ]
operations.append( grids.GridOperation( "Delete",
allow_multiple=False,
condition=( lambda item: not item.deleted ),
@@ -327,7 +328,7 @@
async_compatible=False ) )
standard_filters = []
-class RepositoryMetadataListGrid( grids.Grid ):
+class RepositoryMetadataGrid( grids.Grid ):
class IdColumn( grids.IntegerColumn ):
def get_value( self, trans, grid, repository_metadata ):
return repository_metadata.id
@@ -414,17 +415,18 @@
preserve_state = False
use_paging = True
def build_initial_query( self, trans, **kwd ):
- return trans.sa_session.query( self.model_class ) \
- .join( model.Repository.table )
+ return trans.sa_session.query( model.RepositoryMetadata ) \
+ .join( model.Repository.table ) \
+ .filter( model.Repository.table.c.deprecated == False )
class AdminController( BaseUIController, Admin ):
- user_list_grid = UserListGrid()
- role_list_grid = RoleListGrid()
- group_list_grid = GroupListGrid()
- manage_category_list_grid = ManageCategoryListGrid()
- repository_list_grid = AdminRepositoryListGrid()
- repository_metadata_list_grid = RepositoryMetadataListGrid()
+ user_list_grid = UserGrid()
+ role_list_grid = RoleGrid()
+ group_list_grid = GroupGrid()
+ manage_category_grid = ManageCategoryGrid()
+ repository_grid = AdminRepositoryGrid()
+ repository_metadata_grid = RepositoryMetadataGrid()
@web.expose
@web.require_admin
@@ -477,7 +479,7 @@
return self.delete_repository( trans, **kwd )
elif operation == "undelete":
return self.undelete_repository( trans, **kwd )
- # The changeset_revision_select_field in the RepositoryListGrid performs a refresh_on_change
+ # The changeset_revision_select_field in the RepositoryGrid performs a refresh_on_change
# which sends in request parameters like changeset_revison_1, changeset_revision_2, etc. One
# of the many select fields on the grid performed the refresh_on_change, so we loop through
# all of the received values to see which value is not the repository tip. If we find it, we
@@ -495,7 +497,7 @@
id=trans.security.encode_id( repository.id ),
changeset_revision=v ) )
# Render the list view
- return self.repository_list_grid( trans, **kwd )
+ return self.repository_grid( trans, **kwd )
@web.expose
@web.require_admin
def browse_repository_metadata( self, trans, **kwd ):
@@ -515,7 +517,7 @@
return trans.response.send_redirect( web.url_for( controller='repository',
action='browse_repositories',
**kwd ) )
- return self.repository_metadata_list_grid( trans, **kwd )
+ return self.repository_metadata_grid( trans, **kwd )
@web.expose
@web.require_admin
def create_category( self, trans, **kwd ):
@@ -645,9 +647,9 @@
@web.require_admin
def manage_categories( self, trans, **kwd ):
if 'f-free-text-search' in kwd:
- # Trick to enable searching repository name, description from the CategoryListGrid.
- # What we've done is rendered the search box for the RepositoryListGrid on the grid.mako
- # template for the CategoryListGrid. See ~/templates/webapps/community/category/grid.mako.
+ # Trick to enable searching repository name, description from the CategoryGrid.
+ # What we've done is rendered the search box for the RepositoryGrid on the grid.mako
+ # template for the CategoryGrid. See ~/templates/webapps/community/category/grid.mako.
# Since we are searching repositories and not categories, redirect to browse_repositories().
return trans.response.send_redirect( web.url_for( controller='admin',
action='browse_repositories',
@@ -674,7 +676,7 @@
return trans.response.send_redirect( web.url_for( controller='admin',
action='edit_category',
**kwd ) )
- return self.manage_category_list_grid( trans, **kwd )
+ return self.manage_category_grid( trans, **kwd )
@web.expose
@web.require_admin
def regenerate_statistics( self, trans, **kwd ):
@@ -732,7 +734,8 @@
multiple=True,
display='checkboxes' )
for repository in trans.sa_session.query( trans.model.Repository ) \
- .filter( trans.model.Repository.table.c.deleted == False ) \
+ .filter( and_( trans.model.Repository.table.c.deleted == False,
+ trans.model.Repository.table.c.deprecated == False ) ) \
.order_by( trans.model.Repository.table.c.name,
trans.model.Repository.table.c.user_id ):
owner = repository.user.username
diff -r ae9d794074bcc4732601e480ff54d53b0b2ee6e7 -r 144ae945768aea03c56f80cb4d6db953fa88cbaf lib/galaxy/webapps/community/controllers/repository.py
--- a/lib/galaxy/webapps/community/controllers/repository.py
+++ b/lib/galaxy/webapps/community/controllers/repository.py
@@ -25,7 +25,7 @@
VALID_REPOSITORYNAME_RE = re.compile( "^[a-z0-9\_]+$" )
-class CategoryListGrid( grids.Grid ):
+class CategoryGrid( grids.Grid ):
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, category ):
return category.name
@@ -65,14 +65,14 @@
preserve_state = False
use_paging = True
-class ValidCategoryListGrid( CategoryListGrid ):
+class ValidCategoryGrid( CategoryGrid ):
class RepositoriesColumn( grids.TextColumn ):
def get_value( self, trans, grid, category ):
if category.repositories:
viewable_repositories = 0
for rca in category.repositories:
repository = rca.repository
- if repository.downloadable_revisions:
+ if not repository.deprecated and repository.downloadable_revisions:
viewable_repositories += 1
return viewable_repositories
return 0
@@ -81,13 +81,13 @@
template='/webapps/community/category/valid_grid.mako'
default_sort_key = "name"
columns = [
- CategoryListGrid.NameColumn( "Name",
- key="Category.name",
- link=( lambda item: dict( operation="valid_repositories_by_category", id=item.id ) ),
- attach_popup=False ),
- CategoryListGrid.DescriptionColumn( "Description",
- key="Category.description",
- attach_popup=False ),
+ CategoryGrid.NameColumn( "Name",
+ key="Category.name",
+ link=( lambda item: dict( operation="valid_repositories_by_category", id=item.id ) ),
+ attach_popup=False ),
+ CategoryGrid.DescriptionColumn( "Description",
+ key="Category.description",
+ attach_popup=False ),
# Columns that are valid for filtering but are not visible.
RepositoriesColumn( "Valid repositories",
model_class=model.Repository,
@@ -102,7 +102,7 @@
preserve_state = False
use_paging = True
-class RepositoryListGrid( grids.Grid ):
+class RepositoryGrid( grids.Grid ):
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
return repository.name
@@ -188,6 +188,11 @@
if trans.user and repository.email_alerts and trans.user.email in from_json_string( repository.email_alerts ):
return 'yes'
return ''
+ class DeprecatedColumn( grids.TextColumn ):
+ def get_value( self, trans, grid, repository ):
+ if repository.deprecated:
+ return 'yes'
+ return ''
# Grid definition
title = "Repositories"
model_class = model.Repository
@@ -248,21 +253,83 @@
.outerjoin( model.RepositoryCategoryAssociation.table ) \
.outerjoin( model.Category.table )
-class EmailAlertsRepositoryListGrid( RepositoryListGrid ):
+class RepositoriesIOwnGrid( RepositoryGrid ):
+ title = "Repositories I own"
columns = [
- RepositoryListGrid.NameColumn( "Name",
- key="name",
- link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ RepositoryGrid.NameColumn( "Name",
+ key="name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=True ),
+ RepositoryGrid.MetadataRevisionColumn( "Metadata Revisions" ),
+ RepositoryGrid.TipRevisionColumn( "Tip Revision" ),
+ RepositoryGrid.CategoryColumn( "Category",
+ model_class=model.Category,
+ key="Category.name",
attach_popup=False ),
- RepositoryListGrid.DescriptionColumn( "Synopsis",
- key="description",
- attach_popup=False ),
- RepositoryListGrid.UserColumn( "Owner",
- model_class=model.User,
- link=( lambda item: dict( operation="repositories_by_user", id=item.id ) ),
- attach_popup=False,
- key="User.username" ),
- RepositoryListGrid.EmailAlertsColumn( "Alert", attach_popup=False ),
+ RepositoryGrid.DeprecatedColumn( "Deprecated" )
+ ]
+ columns.append( grids.MulticolFilterColumn( "Search repository name",
+ cols_to_filter=[ columns[0] ],
+ key="free-text-search",
+ visible=False,
+ filterable="standard" ) )
+ operations = [ grids.GridOperation( "Mark as deprecated",
+ allow_multiple=False,
+ condition=( lambda item: not item.deleted and not item.deprecated ),
+ async_compatible=False ),
+ grids.GridOperation( "Mark as not deprecated",
+ allow_multiple=False,
+ condition=( lambda item: not item.deleted and item.deprecated ),
+ async_compatible=False ) ]
+ def build_initial_query( self, trans, **kwd ):
+ return trans.sa_session.query( model.Repository ) \
+ .filter( model.Repository.table.c.user_id == trans.user.id ) \
+ .join( model.User.table ) \
+ .outerjoin( model.RepositoryCategoryAssociation.table ) \
+ .outerjoin( model.Category.table )
+
+class DeprecatedRepositoriesIOwnGrid( RepositoriesIOwnGrid ):
+ title = "Deprecated repositories I own"
+ columns = [
+ RepositoriesIOwnGrid.NameColumn( "Name",
+ key="name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=True ),
+ RepositoriesIOwnGrid.MetadataRevisionColumn( "Metadata Revisions" ),
+ RepositoriesIOwnGrid.TipRevisionColumn( "Tip Revision" ),
+ RepositoriesIOwnGrid.CategoryColumn( "Category",
+ model_class=model.Category,
+ key="Category.name",
+ attach_popup=False ),
+ ]
+ columns.append( grids.MulticolFilterColumn( "Search repository name",
+ cols_to_filter=[ columns[0] ],
+ key="free-text-search",
+ visible=False,
+ filterable="standard" ) )
+ def build_initial_query( self, trans, **kwd ):
+ return trans.sa_session.query( model.Repository ) \
+ .filter( and_( model.Repository.table.c.user_id == trans.user.id,
+ model.Repository.table.c.deprecated == True ) ) \
+ .join( model.User.table ) \
+ .outerjoin( model.RepositoryCategoryAssociation.table ) \
+ .outerjoin( model.Category.table )
+
+class EmailAlertsRepositoryGrid( RepositoryGrid ):
+ columns = [
+ RepositoryGrid.NameColumn( "Name",
+ key="name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=False ),
+ RepositoryGrid.DescriptionColumn( "Synopsis",
+ key="description",
+ attach_popup=False ),
+ RepositoryGrid.UserColumn( "Owner",
+ model_class=model.User,
+ link=( lambda item: dict( operation="repositories_by_user", id=item.id ) ),
+ attach_popup=False,
+ key="User.username" ),
+ RepositoryGrid.EmailAlertsColumn( "Alert", attach_popup=False ),
# Columns that are valid for filtering but are not visible.
grids.DeletedColumn( "Deleted",
key="deleted",
@@ -277,29 +344,67 @@
grids.GridAction( "User preferences", dict( controller='user', action='index', cntrller='repository' ) )
]
-class WritableRepositoryListGrid( RepositoryListGrid ):
+class MyWritableRepositoriesGrid( RepositoryGrid ):
+ # This grid filters out repositories that have been marked as deprecated.
+ columns = [
+ RepositoryGrid.NameColumn( "Name",
+ key="name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=True ),
+ RepositoryGrid.MetadataRevisionColumn( "Metadata Revisions" ),
+ RepositoryGrid.TipRevisionColumn( "Tip Revision" ),
+ RepositoryGrid.UserColumn( "Owner",
+ model_class=model.User,
+ link=( lambda item: dict( operation="repositories_by_user", id=item.id ) ),
+ attach_popup=False,
+ key="User.username" ),
+ RepositoryGrid.EmailAlertsColumn( "Alert", attach_popup=False ),
+ # Columns that are valid for filtering but are not visible.
+ RepositoryGrid.EmailColumn( "Email",
+ model_class=model.User,
+ key="email",
+ visible=False ),
+ RepositoryGrid.RepositoryCategoryColumn( "Category",
+ model_class=model.Category,
+ key="Category.name",
+ visible=False ),
+ grids.DeletedColumn( "Deleted",
+ key="deleted",
+ visible=False,
+ filterable="advanced" )
+ ]
+ columns.append( grids.MulticolFilterColumn( "Search repository name",
+ cols_to_filter=[ columns[0] ],
+ key="free-text-search",
+ visible=False,
+ filterable="standard" ) )
+ operations = [ grids.GridOperation( "Receive email alerts",
+ allow_multiple=False,
+ condition=( lambda item: not item.deleted ),
+ async_compatible=False ) ]
def build_initial_query( self, trans, **kwd ):
# TODO: improve performance by adding a db table associating users with repositories for which they have write access.
- username = kwd[ 'username' ]
+ username = trans.user.username
clause_list = []
- for repository in trans.sa_session.query( self.model_class ) \
- .filter( self.model_class.table.c.deleted == False ):
+ for repository in trans.sa_session.query( model.Repository ) \
+ .filter( and_( model.Repository.table.c.deprecated == False,
+ model.Repository.table.c.deleted == False ) ):
allow_push = repository.allow_push
if allow_push:
allow_push_usernames = allow_push.split( ',' )
if username in allow_push_usernames:
- clause_list.append( self.model_class.table.c.id == repository.id )
+ clause_list.append( model.Repository.table.c.id == repository.id )
if clause_list:
- return trans.sa_session.query( self.model_class ) \
+ return trans.sa_session.query( model.Repository ) \
.filter( or_( *clause_list ) ) \
.join( model.User.table ) \
.outerjoin( model.RepositoryCategoryAssociation.table ) \
.outerjoin( model.Category.table )
# Return an empty query.
- return trans.sa_session.query( self.model_class ) \
- .filter( self.model_class.table.c.id < 0 )
+ return []
-class ValidRepositoryListGrid( RepositoryListGrid ):
+class ValidRepositoryGrid( RepositoryGrid ):
+ # This grid filters out repositories that have been marked as deprecated.
class CategoryColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
rval = '<ul>'
@@ -330,16 +435,16 @@
return ''
title = "Valid repositories"
columns = [
- RepositoryListGrid.NameColumn( "Name",
- key="name",
- attach_popup=True ),
- RepositoryListGrid.DescriptionColumn( "Synopsis",
- key="description",
- attach_popup=False ),
+ RepositoryGrid.NameColumn( "Name",
+ key="name",
+ attach_popup=True ),
+ RepositoryGrid.DescriptionColumn( "Synopsis",
+ key="description",
+ attach_popup=False ),
RevisionColumn( "Installable Revisions" ),
- RepositoryListGrid.UserColumn( "Owner",
- model_class=model.User,
- attach_popup=False ),
+ RepositoryGrid.UserColumn( "Owner",
+ model_class=model.User,
+ attach_popup=False ),
# Columns that are valid for filtering but are not visible.
RepositoryCategoryColumn( "Category",
model_class=model.Category,
@@ -355,22 +460,25 @@
def build_initial_query( self, trans, **kwd ):
if 'id' in kwd:
# The user is browsing categories of valid repositories, so filter the request by the received id, which is a category id.
- return trans.sa_session.query( self.model_class ) \
+ return trans.sa_session.query( model.Repository ) \
+ .filter( model.Repository.table.c.deprecated == False ) \
.join( model.RepositoryMetadata.table ) \
.join( model.User.table ) \
.join( model.RepositoryCategoryAssociation.table ) \
.join( model.Category.table ) \
.filter( and_( model.Category.table.c.id == trans.security.decode_id( kwd[ 'id' ] ),
model.RepositoryMetadata.table.c.downloadable == True ) )
- # The user performed a free text search on the ValidCategoryListGrid.
- return trans.sa_session.query( self.model_class ) \
+ # The user performed a free text search on the ValidCategoryGrid.
+ return trans.sa_session.query( model.Repository ) \
+ .filter( model.Repository.table.c.deprecated == False ) \
.join( model.RepositoryMetadata.table ) \
.join( model.User.table ) \
.outerjoin( model.RepositoryCategoryAssociation.table ) \
.outerjoin( model.Category.table ) \
.filter( model.RepositoryMetadata.table.c.downloadable == True )
-class MatchedRepositoryListGrid( grids.Grid ):
+class MatchedRepositoryGrid( grids.Grid ):
+ # This grid filters out repositories that have been marked as deprecated.
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository_metadata ):
return repository_metadata.repository.name
@@ -413,38 +521,38 @@
if match_tuples:
for match_tuple in match_tuples:
repository_id, changeset_revision = match_tuple
- clause_list.append( "%s=%d and %s='%s'" % ( self.model_class.table.c.repository_id,
+ clause_list.append( "%s=%d and %s='%s'" % ( model.RepositoryMetadata.table.c.repository_id,
int( repository_id ),
- self.model_class.table.c.changeset_revision,
+ model.RepositoryMetadata.table.c.changeset_revision,
changeset_revision ) )
- return trans.sa_session.query( self.model_class ) \
+ return trans.sa_session.query( model.RepositoryMetadata ) \
.join( model.Repository ) \
+ .filter( model.Repository.table.c.deprecated == False ) \
.join( model.User.table ) \
.filter( or_( *clause_list ) ) \
.order_by( model.Repository.name )
# Return an empty query
- return trans.sa_session.query( self.model_class ) \
- .join( model.Repository ) \
- .join( model.User.table ) \
- .filter( self.model_class.table.c.repository_id == 0 )
+ return []
-class InstallMatchedRepositoryListGrid( MatchedRepositoryListGrid ):
- columns = [ col for col in MatchedRepositoryListGrid.columns ]
+class InstallMatchedRepositoryGrid( MatchedRepositoryGrid ):
+ columns = [ col for col in MatchedRepositoryGrid.columns ]
# Override the NameColumn
- columns[ 0 ] = MatchedRepositoryListGrid.NameColumn( "Name",
- link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
- attach_popup=False )
+ columns[ 0 ] = MatchedRepositoryGrid.NameColumn( "Name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=False )
class RepositoryController( BaseUIController, ItemRatings ):
- install_matched_repository_list_grid = InstallMatchedRepositoryListGrid()
- matched_repository_list_grid = MatchedRepositoryListGrid()
- valid_repository_list_grid = ValidRepositoryListGrid()
- repository_list_grid = RepositoryListGrid()
- email_alerts_repository_list_grid = EmailAlertsRepositoryListGrid()
- category_list_grid = CategoryListGrid()
- valid_category_list_grid = ValidCategoryListGrid()
- writable_repository_list_grid = WritableRepositoryListGrid()
+ install_matched_repository_grid = InstallMatchedRepositoryGrid()
+ matched_repository_grid = MatchedRepositoryGrid()
+ valid_repository_grid = ValidRepositoryGrid()
+ repository_grid = RepositoryGrid()
+ email_alerts_repository_grid = EmailAlertsRepositoryGrid()
+ category_grid = CategoryGrid()
+ valid_category_grid = ValidCategoryGrid()
+ my_writable_repositories_grid = MyWritableRepositoriesGrid()
+ repositories_i_own_grid = RepositoriesIOwnGrid()
+ deprecated_repositories_i_own_grid = DeprecatedRepositoriesIOwnGrid()
def __add_hgweb_config_entry( self, trans, repository, repository_path ):
# Add an entry in the hgweb.config file for a new repository. An entry looks something like:
@@ -470,8 +578,8 @@
def browse_categories( self, trans, **kwd ):
# The request came from the tool shed.
if 'f-free-text-search' in kwd:
- # Trick to enable searching repository name, description from the CategoryListGrid. What we've done is rendered the search box for the
- # RepositoryListGrid on the grid.mako template for the CategoryListGrid. See ~/templates/webapps/community/category/grid.mako. Since we
+ # Trick to enable searching repository name, description from the CategoryGrid. What we've done is rendered the search box for the
+ # RepositoryGrid on the grid.mako template for the CategoryGrid. See ~/templates/webapps/community/category/grid.mako. Since we
# are searching repositories and not categories, redirect to browse_repositories().
if 'id' in kwd and 'f-free-text-search' in kwd and kwd[ 'id' ] == kwd[ 'f-free-text-search' ]:
# The value of 'id' has been set to the search string, which is a repository name. We'll try to get the desired encoded repository id to pass on.
@@ -491,7 +599,7 @@
return trans.response.send_redirect( web.url_for( controller='repository',
action='browse_repositories',
**kwd ) )
- return self.category_list_grid( trans, **kwd )
+ return self.category_grid( trans, **kwd )
@web.expose
def browse_invalid_tools( self, trans, **kwd ):
params = util.Params( kwd )
@@ -564,13 +672,27 @@
for k, v in kwd.items():
if k.startswith( 'f-' ):
del kwd[ k ]
- kwd[ 'f-email' ] = trans.user.email
+ return self.repositories_i_own_grid( trans, **kwd )
+ elif operation == "deprecated_repositories_i_own":
+ # Eliminate the current filters if any exist.
+ for k, v in kwd.items():
+ if k.startswith( 'f-' ):
+ del kwd[ k ]
+ return self.deprecated_repositories_i_own_grid( trans, **kwd )
+ elif operation in [ 'mark as deprecated', 'mark as not deprecated' ]:
+ # Eliminate the current filters if any exist.
+ for k, v in kwd.items():
+ if k.startswith( 'f-' ):
+ del kwd[ k ]
+ kwd[ 'mark_deprecated' ] = operation == 'mark as deprecated'
+ return trans.response.send_redirect( web.url_for( controller='repository',
+ action='deprecate',
+ **kwd ) )
elif operation == "reviewed_repositories_i_own":
return trans.response.send_redirect( web.url_for( controller='repository_review',
action='reviewed_repositories_i_own' ) )
- elif operation == "writable_repositories":
- kwd[ 'username' ] = trans.user.username
- return self.writable_repository_list_grid( trans, **kwd )
+ elif operation == "my_writable_repositories":
+ return self.my_writable_repositories_grid( trans, **kwd )
elif operation == "repositories_by_category":
# Eliminate the current filters if any exist.
for k, v in kwd.items():
@@ -590,7 +712,7 @@
kwd[ 'message' ] = 'You must be logged in to set email alerts.'
kwd[ 'status' ] = 'error'
del kwd[ 'operation' ]
- # The changeset_revision_select_field in the RepositoryListGrid performs a refresh_on_change
+ # The changeset_revision_select_field in the RepositoryGrid performs a refresh_on_change
# which sends in request parameters like changeset_revison_1, changeset_revision_2, etc. One
# of the many select fields on the grid performed the refresh_on_change, so we loop through
# all of the received values to see which value is not the repository tip. If we find it, we
@@ -607,7 +729,7 @@
operation='view_or_manage_repository',
id=trans.security.encode_id( repository.id ),
changeset_revision=v ) )
- return self.repository_list_grid( trans, **kwd )
+ return self.repository_grid( trans, **kwd )
@web.expose
def browse_repository( self, trans, id, **kwd ):
params = util.Params( kwd )
@@ -637,7 +759,7 @@
if kwd[ 'f-free-text-search' ] == 'All':
# The user performed a search, then clicked the "x" to eliminate the search criteria.
new_kwd = {}
- return self.valid_category_list_grid( trans, **new_kwd )
+ return self.valid_category_grid( trans, **new_kwd )
# Since we are searching valid repositories and not categories, redirect to browse_valid_repositories().
if 'id' in kwd and 'f-free-text-search' in kwd and kwd[ 'id' ] == kwd[ 'f-free-text-search' ]:
# The value of 'id' has been set to the search string, which is a repository name.
@@ -658,7 +780,7 @@
return trans.response.send_redirect( web.url_for( controller='repository',
action='browse_valid_repositories',
**kwd ) )
- return self.valid_category_list_grid( trans, **kwd )
+ return self.valid_category_grid( trans, **kwd )
@web.expose
def browse_valid_repositories( self, trans, **kwd ):
galaxy_url = kwd.get( 'galaxy_url', None )
@@ -667,7 +789,7 @@
# The user browsed to a category and then entered a search string, so get the category associated with it's value.
category_name = kwd[ 'f-Category.name' ]
category = get_category_by_name( trans, category_name )
- # Set the id value in kwd since it is required by the ValidRepositoryListGrid.build_initial_query method.
+ # Set the id value in kwd since it is required by the ValidRepositoryGrid.build_initial_query method.
kwd[ 'id' ] = trans.security.encode_id( category.id )
if galaxy_url:
trans.set_cookie( galaxy_url, name='toolshedgalaxyurl' )
@@ -690,7 +812,7 @@
category_id = kwd.get( 'id', None )
category = get_category( trans, category_id )
kwd[ 'f-Category.name' ] = category.name
- # The changeset_revision_select_field in the ValidRepositoryListGrid performs a refresh_on_change which sends in request parameters like
+ # The changeset_revision_select_field in the ValidRepositoryGrid performs a refresh_on_change which sends in request parameters like
# changeset_revison_1, changeset_revision_2, etc. One of the many select fields on the grid performed the refresh_on_change, so we loop
# through all of the received values to see which value is not the repository tip. If we find it, we know the refresh_on_change occurred
# and we have the necessary repository id and change set revision to pass on.
@@ -708,11 +830,11 @@
url_args = dict( action='browse_valid_repositories',
operation='preview_tools_in_changeset',
repository_id=repository_id )
- self.valid_repository_list_grid.operations = [ grids.GridOperation( "Preview and install",
+ self.valid_repository_grid.operations = [ grids.GridOperation( "Preview and install",
url_args=url_args,
allow_multiple=False,
async_compatible=False ) ]
- return self.valid_repository_list_grid( trans, **kwd )
+ return self.valid_repository_grid( trans, **kwd )
def __build_allow_push_select_field( self, trans, current_push_list, selected_value='none' ):
options = []
for user in trans.sa_session.query( trans.model.User ):
@@ -931,6 +1053,27 @@
message=message,
status=status )
@web.expose
+ @web.require_login( "deprecate repository" )
+ def deprecate( self, trans, **kwd ):
+ params = util.Params( kwd )
+ message = util.restore_text( params.get( 'message', '' ) )
+ status = params.get( 'status', 'done' )
+ repository_id = params.get( 'id', None )
+ repository = get_repository( trans, repository_id )
+ mark_deprecated = util.string_as_bool( params.get( 'mark_deprecated', False ) )
+ repository.deprecated = mark_deprecated
+ trans.sa_session.add( repository )
+ trans.sa_session.flush()
+ if mark_deprecated:
+ message = 'The repository <b>%s</b> has been marked as deprecated.' % repository.name
+ else:
+ message = 'The repository <b>%s</b> has been marked as not deprecated.' % repository.name
+ trans.response.send_redirect( web.url_for( controller='repository',
+ action='browse_repositories',
+ operation='repositories_i_own',
+ message=message,
+ status=status ) )
+ @web.expose
def display_tool( self, trans, repository_id, tool_config, changeset_revision, **kwd ):
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
@@ -1049,16 +1192,16 @@
dict( controller='repository', action='find_tools' ) ),
grids.GridAction( "Search for workflows",
dict( controller='repository', action='find_workflows' ) ) ]
- self.install_matched_repository_list_grid.global_actions = global_actions
+ self.install_matched_repository_grid.global_actions = global_actions
install_url_args = dict( controller='repository', action='find_tools' )
operations = [ grids.GridOperation( "Install", url_args=install_url_args, allow_multiple=True, async_compatible=False ) ]
- self.install_matched_repository_list_grid.operations = operations
- return self.install_matched_repository_list_grid( trans, **kwd )
+ self.install_matched_repository_grid.operations = operations
+ return self.install_matched_repository_grid( trans, **kwd )
else:
kwd[ 'message' ] = "tool id: <b>%s</b><br/>tool name: <b>%s</b><br/>tool version: <b>%s</b><br/>exact matches only: <b>%s</b>" % \
( self.__stringify( tool_ids ), self.__stringify( tool_names ), self.__stringify( tool_versions ), str( exact_matches_checked ) )
- self.matched_repository_list_grid.title = "Repositories with matching tools"
- return self.matched_repository_list_grid( trans, **kwd )
+ self.matched_repository_grid.title = "Repositories with matching tools"
+ return self.matched_repository_grid( trans, **kwd )
else:
message = "No search performed - each field must contain the same number of comma-separated items."
status = "error"
@@ -1135,16 +1278,16 @@
dict( controller='repository', action='find_tools' ) ),
grids.GridAction( "Search for workflows",
dict( controller='repository', action='find_workflows' ) ) ]
- self.install_matched_repository_list_grid.global_actions = global_actions
+ self.install_matched_repository_grid.global_actions = global_actions
install_url_args = dict( controller='repository', action='find_workflows' )
operations = [ grids.GridOperation( "Install", url_args=install_url_args, allow_multiple=True, async_compatible=False ) ]
- self.install_matched_repository_list_grid.operations = operations
- return self.install_matched_repository_list_grid( trans, **kwd )
+ self.install_matched_repository_grid.operations = operations
+ return self.install_matched_repository_grid( trans, **kwd )
else:
kwd[ 'message' ] = "workflow name: <b>%s</b><br/>exact matches only: <b>%s</b>" % \
( self.__stringify( workflow_names ), str( exact_matches_checked ) )
- self.matched_repository_list_grid.title = "Repositories with matching workflows"
- return self.matched_repository_list_grid( trans, **kwd )
+ self.matched_repository_grid.title = "Repositories with matching workflows"
+ return self.matched_repository_grid( trans, **kwd )
else:
message = "No search performed - each field must contain the same number of comma-separated items."
status = "error"
@@ -1407,17 +1550,24 @@
status = params.get( 'status', 'done' )
# See if there are any RepositoryMetadata records since menu items require them.
repository_metadata = trans.sa_session.query( model.RepositoryMetadata ).first()
- # See if the current user owns any repositories that have been reviewed.
+ current_user = trans.user
has_reviewed_repositories = False
- current_user = trans.user
+ has_deprecated_repositories = False
if current_user:
+ # See if the current user owns any repositories that have been reviewed.
for repository in current_user.active_repositories:
if repository.reviewed_revisions:
has_reviewed_repositories = True
break
+ # See if the current user has any repositories that have been marked as deprecated.
+ for repository in current_user.active_repositories:
+ if repository.deprecated:
+ has_deprecated_repositories = True
+ break
return trans.fill_template( '/webapps/community/index.mako',
repository_metadata=repository_metadata,
has_reviewed_repositories=has_reviewed_repositories,
+ has_deprecated_repositories=has_deprecated_repositories,
message=message,
status=status )
@web.expose
@@ -1738,7 +1888,8 @@
kwd[ 'message' ] = 'You must be logged in to set email alerts.'
kwd[ 'status' ] = 'error'
del kwd[ 'operation' ]
- return self.email_alerts_repository_list_grid( trans, **kwd )
+ self.email_alerts_repository_grid.title = "Set email alerts for repository changes"
+ return self.email_alerts_repository_grid( trans, **kwd )
def __new_state( self, trans, all_pages=False ):
"""
Create a new `DefaultToolState` for this tool. It will not be initialized
diff -r ae9d794074bcc4732601e480ff54d53b0b2ee6e7 -r 144ae945768aea03c56f80cb4d6db953fa88cbaf lib/galaxy/webapps/community/controllers/repository_review.py
--- a/lib/galaxy/webapps/community/controllers/repository_review.py
+++ b/lib/galaxy/webapps/community/controllers/repository_review.py
@@ -7,7 +7,7 @@
from galaxy.model.orm import *
from sqlalchemy.sql.expression import func
from common import *
-from repository import RepositoryListGrid
+from repository import RepositoryGrid
from galaxy.util.shed_util import get_configured_ui
from galaxy.util.odict import odict
@@ -48,36 +48,33 @@
preserve_state = False
use_paging = True
-class RepositoriesWithReviewsGrid( RepositoryListGrid ):
+class RepositoriesWithReviewsGrid( RepositoryGrid ):
+ # This grid filters out repositories that have been marked as deprecated.
class ReviewersColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
+ rval = ''
if repository.reviewers:
- rval = ''
for user in repository.reviewers:
- rval += '%s<br/>' % user.username
- return rval
- return ''
- title = "All reviewed Repositories"
+ rval += '<a class="view-info" href="repository_reviews_by_user?id=%s">' % trans.security.encode_id( user.id )
+ rval += '%s</a> | ' % user.username
+ rval = rval.rstrip( ' | ' )
+ return rval
+ title = "All reviewed repositories"
model_class = model.Repository
template='/webapps/community/repository_review/grid.mako'
default_sort_key = "Repository.name"
columns = [
- RepositoryListGrid.NameColumn( "Repository name",
- key="name",
- link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
- attach_popup=True ),
- RepositoryListGrid.DescriptionColumn( "Synopsis",
- key="description",
- attach_popup=False ),
- RepositoryListGrid.WithReviewsRevisionColumn( "Reviewed revisions" ),
- RepositoryListGrid.WithoutReviewsRevisionColumn( "Revisions for review" ),
- RepositoryListGrid.UserColumn( "Owner",
- attach_popup=False ),
- ReviewersColumn( "Reviewers",
- attach_popup=False )
+ RepositoryGrid.NameColumn( "Repository name",
+ key="name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=True ),
+ RepositoryGrid.WithReviewsRevisionColumn( "Reviewed revisions" ),
+ RepositoryGrid.WithoutReviewsRevisionColumn( "Revisions for review" ),
+ RepositoryGrid.UserColumn( "Owner", attach_popup=False ),
+ ReviewersColumn( "Reviewers", attach_popup=False )
]
- columns.append( grids.MulticolFilterColumn( "Search repository name, description",
- cols_to_filter=[ columns[0], columns[1] ],
+ columns.append( grids.MulticolFilterColumn( "Search repository name",
+ cols_to_filter=[ columns[0] ],
key="free-text-search",
visible=False,
filterable="standard" ) )
@@ -89,12 +86,14 @@
]
def build_initial_query( self, trans, **kwd ):
return trans.sa_session.query( model.Repository ) \
+ .filter( model.Repository.table.c.deprecated == False ) \
.join( ( model.RepositoryReview.table, model.RepositoryReview.table.c.repository_id == model.Repository.table.c.id ) ) \
.join( ( model.User.table, model.User.table.c.id == model.Repository.table.c.user_id ) ) \
.outerjoin( ( model.ComponentReview.table, model.ComponentReview.table.c.repository_review_id == model.RepositoryReview.table.c.id ) ) \
.outerjoin( ( model.Component.table, model.Component.table.c.id == model.ComponentReview.table.c.component_id ) )
class RepositoriesWithoutReviewsGrid( RepositoriesWithReviewsGrid ):
+ # This grid filters out repositories that have been marked as deprecated.
title = "Repositories with no reviews"
columns = [
RepositoriesWithReviewsGrid.NameColumn( "Repository name",
@@ -119,12 +118,15 @@
async_compatible=False ) ]
def build_initial_query( self, trans, **kwd ):
return trans.sa_session.query( model.Repository ) \
- .filter( model.Repository.reviews == None ) \
+ .filter( and_( model.Repository.table.c.deprecated == False,
+ model.Repository.reviews == None ) ) \
.join( model.User.table )
class RepositoriesReviewedByMeGrid( RepositoriesWithReviewsGrid ):
+ # This grid filters out repositories that have been marked as deprecated.
def build_initial_query( self, trans, **kwd ):
return trans.sa_session.query( model.Repository ) \
+ .filter( model.Repository.table.c.deprecated == False ) \
.join( ( model.RepositoryReview.table, model.RepositoryReview.table.c.repository_id == model.Repository.table.c.id ) ) \
.filter( model.RepositoryReview.table.c.user_id == trans.user.id ) \
.join( ( model.User.table, model.User.table.c.id == model.RepositoryReview.table.c.user_id ) ) \
@@ -132,6 +134,7 @@
.outerjoin( ( model.Component.table, model.Component.table.c.id == model.ComponentReview.table.c.component_id ) )
class RepositoryReviewsByUserGrid( grids.Grid ):
+ # This grid filters out repositories that have been marked as deprecated.
class RepositoryNameColumn( grids.TextColumn ):
def get_value( self, trans, grid, review ):
return review.repository.name
@@ -166,33 +169,61 @@
default_sort_key = 'repository_id'
columns = [
RepositoryNameColumn( "Repository Name",
- model_class=model.Repository,
- key="Repository.name",
- attach_popup=False ),
+ model_class=model.Repository,
+ key="Repository.name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=True ),
RepositoryDescriptionColumn( "Description",
- model_class=model.Repository,
- key="Repository.description",
- attach_popup=False ),
- RevisionColumn( "Revision",
- attach_popup=False ),
- RatingColumn( "Rating",
- attach_popup=False )
+ model_class=model.Repository,
+ key="Repository.description",
+ attach_popup=False ),
+ RevisionColumn( "Revision", attach_popup=False ),
+ RatingColumn( "Rating", attach_popup=False ),
]
# Override these
default_filter = {}
global_actions = []
- operations = []
+ operations = [
+ grids.GridOperation( "Inspect repository revisions",
+ allow_multiple=False,
+ condition=( lambda item: not item.deleted ),
+ async_compatible=False )
+ ]
standard_filters = []
num_rows_per_page = 50
preserve_state = False
use_paging = True
def build_initial_query( self, trans, **kwd ):
user_id = trans.security.decode_id( kwd[ 'id' ] )
- return trans.sa_session.query( self.model_class ) \
+ return trans.sa_session.query( model.RepositoryReview ) \
.filter( and_( model.RepositoryReview.table.c.deleted == False, \
- model.RepositoryReview.table.c.user_id == user_id ) )
+ model.RepositoryReview.table.c.user_id == user_id ) ) \
+ .join( ( model.Repository.table, model.RepositoryReview.table.c.repository_id == model.Repository.table.c.id ) ) \
+ .filter( model.Repository.table.c.deprecated == False )
class ReviewedRepositoriesIOwnGrid( RepositoriesWithReviewsGrid ):
+ title = "Reviewed repositories I own"
+ columns = [
+ RepositoriesWithReviewsGrid.NameColumn( "Repository name",
+ key="name",
+ link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
+ attach_popup=True ),
+ RepositoriesWithReviewsGrid.WithReviewsRevisionColumn( "Reviewed revisions" ),
+ RepositoriesWithReviewsGrid.WithoutReviewsRevisionColumn( "Revisions for review" ),
+ RepositoriesWithReviewsGrid.ReviewersColumn( "Reviewers", attach_popup=False ),
+ RepositoryGrid.DeprecatedColumn( "Deprecated" )
+ ]
+ columns.append( grids.MulticolFilterColumn( "Search repository name",
+ cols_to_filter=[ columns[0] ],
+ key="free-text-search",
+ visible=False,
+ filterable="standard" ) )
+ operations = [
+ grids.GridOperation( "Inspect repository revisions",
+ allow_multiple=False,
+ condition=( lambda item: not item.deleted ),
+ async_compatible=False )
+ ]
def build_initial_query( self, trans, **kwd ):
return trans.sa_session.query( model.Repository ) \
.join( ( model.RepositoryReview.table, model.RepositoryReview.table.c.repository_id == model.Repository.table.c.id ) ) \
@@ -655,10 +686,26 @@
@web.expose
@web.require_login( "repository reviews by user" )
def repository_reviews_by_user( self, trans, **kwd ):
- # The user may not be the current user. The value of the received id is the encoded user id.
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
+
+ if 'operation' in kwd:
+ operation = kwd['operation'].lower()
+ # The value of the received id is the encoded review id.
+ review = get_review( trans, kwd[ 'id' ] )
+ repository = review.repository
+ kwd[ 'id' ] = trans.security.encode_id( repository.id )
+ if operation == "inspect repository revisions":
+ return trans.response.send_redirect( web.url_for( controller='repository_review',
+ action='manage_repository_reviews',
+ **kwd ) )
+ if operation == "view_or_manage_repository":
+ kwd[ 'changeset_revision' ] = review.changeset_revision
+ return trans.response.send_redirect( web.url_for( controller='repository_review',
+ action='view_or_manage_repository',
+ **kwd ) )
+ # The user may not be the current user. The value of the received id is the encoded user id.
user = get_user( trans, kwd[ 'id' ] )
self.repository_reviews_by_user_grid.title = "All repository revision reviews for user '%s'" % user.username
return self.repository_reviews_by_user_grid( trans, **kwd )
@@ -668,6 +715,13 @@
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
+ # The value of the received id is the encoded repository id.
+ if 'operation' in kwd:
+ operation = kwd['operation'].lower()
+ if operation == "view_or_manage_repository":
+ return trans.response.send_redirect( web.url_for( controller='repository_review',
+ action='view_or_manage_repository',
+ **kwd ) )
return self.reviewed_repositories_i_own_grid( trans, **kwd )
@web.expose
@web.require_login( "select previous review" )
diff -r ae9d794074bcc4732601e480ff54d53b0b2ee6e7 -r 144ae945768aea03c56f80cb4d6db953fa88cbaf lib/galaxy/webapps/community/model/__init__.py
--- a/lib/galaxy/webapps/community/model/__init__.py
+++ b/lib/galaxy/webapps/community/model/__init__.py
@@ -109,7 +109,8 @@
MARKED_FOR_REMOVAL = 'r',
MARKED_FOR_ADDITION = 'a',
NOT_TRACKED = '?' )
- def __init__( self, name=None, description=None, long_description=None, user_id=None, private=False, email_alerts=None, times_downloaded=0 ):
+ def __init__( self, name=None, description=None, long_description=None, user_id=None, private=False, email_alerts=None, times_downloaded=0,
+ deprecated=False ):
self.name = name or "Unnamed repository"
self.description = description
self.long_description = long_description
@@ -117,6 +118,7 @@
self.private = private
self.email_alerts = email_alerts
self.times_downloaded = times_downloaded
+ self.deprecated = deprecated
@property
def repo_path( self ):
# Repository locations on disk are defined in the hgweb.config file
diff -r ae9d794074bcc4732601e480ff54d53b0b2ee6e7 -r 144ae945768aea03c56f80cb4d6db953fa88cbaf lib/galaxy/webapps/community/model/mapping.py
--- a/lib/galaxy/webapps/community/model/mapping.py
+++ b/lib/galaxy/webapps/community/model/mapping.py
@@ -111,7 +111,8 @@
Column( "private", Boolean, default=False ),
Column( "deleted", Boolean, index=True, default=False ),
Column( "email_alerts", JSONType, nullable=True ),
- Column( "times_downloaded", Integer ) )
+ Column( "times_downloaded", Integer ),
+ Column( "deprecated", Boolean, default=False ) )
RepositoryMetadata.table = Table( "repository_metadata", metadata,
Column( "id", Integer, primary_key=True ),
@@ -218,7 +219,10 @@
properties=dict( children=relation(Tag, backref=backref( 'parent', remote_side=[ Tag.table.c.id ] ) ) ) )
assign_mapper( context, Category, Category.table,
- properties=dict( repositories=relation( RepositoryCategoryAssociation ) ) )
+ properties=dict( repositories=relation( RepositoryCategoryAssociation,
+ secondary=Repository.table,
+ primaryjoin=( Category.table.c.id == RepositoryCategoryAssociation.table.c.category_id ),
+ secondaryjoin=( ( RepositoryCategoryAssociation.table.c.repository_id == Repository.table.c.id ) & ( Repository.table.c.deprecated == False ) ) ) ) )
assign_mapper( context, Repository, Repository.table,
properties = dict(
diff -r ae9d794074bcc4732601e480ff54d53b0b2ee6e7 -r 144ae945768aea03c56f80cb4d6db953fa88cbaf lib/galaxy/webapps/community/model/migrate/versions/0014_add_deprecated_column.py
--- /dev/null
+++ b/lib/galaxy/webapps/community/model/migrate/versions/0014_add_deprecated_column.py
@@ -0,0 +1,53 @@
+"""
+Migration script to add the deprecated column to the repository table.
+"""
+
+from sqlalchemy import *
+from sqlalchemy.orm import *
+from migrate import *
+from migrate.changeset import *
+
+# Need our custom types, but don't import anything else from model
+from galaxy.model.custom_types import *
+
+import sys, logging
+log = logging.getLogger( __name__ )
+log.setLevel(logging.DEBUG)
+handler = logging.StreamHandler( sys.stdout )
+format = "%(name)s %(levelname)s %(asctime)s %(message)s"
+formatter = logging.Formatter( format )
+handler.setFormatter( formatter )
+log.addHandler( handler )
+
+metadata = MetaData( migrate_engine )
+db_session = scoped_session( sessionmaker( bind=migrate_engine, autoflush=False, autocommit=True ) )
+
+def upgrade():
+ print __doc__
+ metadata.reflect()
+ # Create and initialize imported column in job table.
+ Repository_table = Table( "repository", metadata, autoload=True )
+ c = Column( "deprecated", Boolean, default=False )
+ try:
+ # Create
+ c.create( Repository_table )
+ assert c is Repository_table.c.deprecated
+ # Initialize.
+ if migrate_engine.name == 'mysql' or migrate_engine.name == 'sqlite':
+ default_false = "0"
+ elif migrate_engine.name == 'postgres':
+ default_false = "false"
+ db_session.execute( "UPDATE repository SET deprecated=%s" % default_false )
+ except Exception, e:
+ print "Adding deprecated column to the repository table failed: %s" % str( e )
+ log.debug( "Adding deprecated column to the repository table failed: %s" % str( e ) )
+
+def downgrade():
+ metadata.reflect()
+ # Drop email_alerts column from repository table.
+ Repository_table = Table( "repository", metadata, autoload=True )
+ try:
+ Repository_table.c.deprecated.drop()
+ except Exception, e:
+ print "Dropping column deprecated from the repository table failed: %s" % str( e )
+ log.debug( "Dropping column deprecated from the repository table failed: %s" % str( e ) )
diff -r ae9d794074bcc4732601e480ff54d53b0b2ee6e7 -r 144ae945768aea03c56f80cb4d6db953fa88cbaf templates/webapps/community/category/grid.mako
--- a/templates/webapps/community/category/grid.mako
+++ b/templates/webapps/community/category/grid.mako
@@ -49,8 +49,8 @@
<%def name="grid_body( grid )"><%
- from galaxy.webapps.community.controllers.repository import RepositoryListGrid
- repo_grid = RepositoryListGrid()
+ from galaxy.webapps.community.controllers.repository import RepositoryGrid
+ repo_grid = RepositoryGrid()
%>
${self.make_grid( grid, repo_grid )}
</%def>
diff -r ae9d794074bcc4732601e480ff54d53b0b2ee6e7 -r 144ae945768aea03c56f80cb4d6db953fa88cbaf templates/webapps/community/category/valid_grid.mako
--- a/templates/webapps/community/category/valid_grid.mako
+++ b/templates/webapps/community/category/valid_grid.mako
@@ -48,8 +48,8 @@
<%def name="grid_body( grid )"><%
- from galaxy.webapps.community.controllers.repository import ValidRepositoryListGrid
- repo_grid = ValidRepositoryListGrid()
+ from galaxy.webapps.community.controllers.repository import ValidRepositoryGrid
+ repo_grid = ValidRepositoryGrid()
%>
${self.make_grid( grid, repo_grid )}
</%def>
diff -r ae9d794074bcc4732601e480ff54d53b0b2ee6e7 -r 144ae945768aea03c56f80cb4d6db953fa88cbaf templates/webapps/community/index.mako
--- a/templates/webapps/community/index.mako
+++ b/templates/webapps/community/index.mako
@@ -78,8 +78,13 @@
<a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories', operation='reviewed_repositories_i_own' )}">Reviewed repositories I own</a></div>
%endif
+ %if has_deprecated_repositories:
+ <div class="toolTitle">
+ <a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories', operation='deprecated_repositories_i_own' )}">Deprecated repositories I own</a>
+ </div>
+ %endif
<div class="toolTitle">
- <a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories', operation='writable_repositories' )}">My writable repositories</a>
+ <a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories', operation='my_writable_repositories' )}">My writable repositories</a></div><div class="toolTitle"><a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_invalid_tools', cntrller='repository' )}">My invalid tools</a>
diff -r ae9d794074bcc4732601e480ff54d53b0b2ee6e7 -r 144ae945768aea03c56f80cb4d6db953fa88cbaf templates/webapps/community/repository/manage_repository.mako
--- a/templates/webapps/community/repository/manage_repository.mako
+++ b/templates/webapps/community/repository/manage_repository.mako
@@ -7,22 +7,25 @@
from galaxy.web.framework.helpers import time_ago
is_admin = trans.user_is_admin()
is_new = repository.is_new
+ is_deprecated = repository.deprecated
can_contact_owner = trans.user and trans.user != repository.user
- can_push = trans.app.security_agent.can_push( trans.user, repository )
+ can_push = not is_deprecated and trans.app.security_agent.can_push( trans.user, repository )
can_upload = can_push
- can_download = not is_new and ( not is_malicious or can_push )
+ can_download = not is_deprecated and not is_new and ( not is_malicious or can_push )
can_browse_contents = not is_new
- can_set_metadata = not is_new
- can_rate = not is_new and trans.user and repository.user != trans.user
+ can_set_metadata = not is_new and not is_deprecated
+ can_rate = not is_new and not is_deprecated and trans.user and repository.user != trans.user
can_view_change_log = not is_new
if can_push:
browse_label = 'Browse or delete repository tip files'
else:
browse_label = 'Browse repository tip files'
can_set_malicious = metadata and can_set_metadata and is_admin and changeset_revision == repository.tip
- can_reset_all_metadata = is_admin and len( repo ) > 0
+ can_deprecate = not is_new and trans.user and ( is_admin or repository.user == trans.user ) and not is_deprecated
+ can_undeprecate = trans.user and ( is_admin or repository.user == trans.user ) and is_deprecated
+ can_reset_all_metadata = not is_deprecated and is_admin and len( repo ) > 0
has_readme = metadata and 'readme' in metadata
- can_review_repository = trans.app.security_agent.user_can_review_repositories( trans.user )
+ can_review_repository = not is_deprecated and trans.app.security_agent.user_can_review_repositories( trans.user )
reviewing_repository = cntrller and cntrller == 'repository_review'
if changeset_revision == repository.tip:
tip_str = 'repository tip'
@@ -87,6 +90,12 @@
%if can_reset_all_metadata:
<a class="action-button" href="${h.url_for( controller='repository', action='reset_all_metadata', id=trans.security.encode_id( repository.id ) )}">Reset all repository metadata</a>
%endif
+ %if can_deprecate:
+ <a class="action-button" href="${h.url_for( controller='repository', action='deprecate', id=trans.security.encode_id( repository.id ), mark_deprecated=True )}">Mark repository as deprecated</a>
+ %endif
+ %if can_undeprecate:
+ <a class="action-button" href="${h.url_for( controller='repository', action='deprecate', id=trans.security.encode_id( repository.id ), mark_deprecated=False )}">Mark repository as not deprecated</a>
+ %endif
%if can_download:
<a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision, file_type='gz' )}">Download as a .tar.gz file</a><a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision, file_type='bz2' )}">Download as a .tar.bz2 file</a>
@@ -101,6 +110,12 @@
${render_msg( message, status )}
%endif
+%if repository.deprecated:
+ <div class="warningmessage">
+ This repository has been marked as deprecated, so some tool shed features may be restricted.
+ </div>
+%endif
+
%if len( changeset_revision_select_field.options ) > 1:
<div class="toolForm"><div class="toolFormTitle">Repository revision</div>
@@ -122,7 +137,7 @@
<p/>
%endif
<div class="toolForm">
- <div class="toolFormTitle">${repository.name}</div>
+ <div class="toolFormTitle">Repository '${repository.name}'</div><div class="toolFormBody"><form name="edit_repository" id="edit_repository" action="${h.url_for( controller='repository', action='manage_repository', id=trans.security.encode_id( repository.id ) )}" method="post" >
%if can_download:
diff -r ae9d794074bcc4732601e480ff54d53b0b2ee6e7 -r 144ae945768aea03c56f80cb4d6db953fa88cbaf templates/webapps/community/repository/view_repository.mako
--- a/templates/webapps/community/repository/view_repository.mako
+++ b/templates/webapps/community/repository/view_repository.mako
@@ -6,11 +6,12 @@
<%
from galaxy.web.framework.helpers import time_ago
is_new = repository.is_new
+ is_deprecated = repository.deprecated
can_contact_owner = trans.user and trans.user != repository.user
- can_push = trans.app.security_agent.can_push( trans.user, repository )
- can_rate = not is_new and trans.user and repository.user != trans.user
+ can_push = not is_deprecated and trans.app.security_agent.can_push( trans.user, repository )
+ can_rate = not is_deprecated and not is_new and trans.user and repository.user != trans.user
can_upload = can_push
- can_download = not is_new and ( not is_malicious or can_push )
+ can_download = not is_deprecated and not is_new and ( not is_malicious or can_push )
can_browse_contents = trans.webapp.name == 'community' and not is_new
can_view_change_log = trans.webapp.name == 'community' and not is_new
if can_push:
@@ -19,7 +20,7 @@
browse_label = 'Browse repository tip files'
has_readme = metadata and 'readme' in metadata
reviewing_repository = cntrller and cntrller == 'repository_review'
- can_review_repository = trans.app.security_agent.user_can_review_repositories( trans.user )
+ can_review_repository = not is_deprecated and trans.app.security_agent.user_can_review_repositories( trans.user )
%><%!
@@ -100,6 +101,12 @@
${render_msg( message, status )}
%endif
+%if repository.deprecated:
+ <div class="warningmessage">
+ This repository has been marked as deprecated, so some tool shed features may be restricted.
+ </div>
+%endif
+
%if len( changeset_revision_select_field.options ) > 1:
<div class="toolForm"><div class="toolFormTitle">Repository revision</div>
@@ -123,7 +130,7 @@
<p/>
%endif
<div class="toolForm">
- <div class="toolFormTitle">${repository.name}</div>
+ <div class="toolFormTitle">Repository '${repository.name}'</div><div class="toolFormBody">
%if can_download:
<div class="form-row">
diff -r ae9d794074bcc4732601e480ff54d53b0b2ee6e7 -r 144ae945768aea03c56f80cb4d6db953fa88cbaf templates/webapps/community/repository/view_tool_metadata.mako
--- a/templates/webapps/community/repository/view_tool_metadata.mako
+++ b/templates/webapps/community/repository/view_tool_metadata.mako
@@ -110,7 +110,7 @@
<p/>
%if can_download:
<div class="toolForm">
- <div class="toolFormTitle">${repository.name}</div>
+ <div class="toolFormTitle">Repository '${repository.name}'</div><div class="toolFormBody"><div class="form-row"><label>Clone this repository:</label>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
4 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/4daa56624e2a/
changeset: 4daa56624e2a
branch: zero-merge
user: peterjc
date: 2012-10-19 15:02:54
summary: Error when attempt to merge zero files.
Previously the code would try to call cat with no arguments,
which would wait for stdin and so do nothing and stall.
This error condition could be triggered with a cluster job
when Galaxy didn't get any output back.
affected #: 1 file
diff -r 4cd4f8bef29d17a7bca74e235031060e2289ebdc -r 4daa56624e2a7dbe16c3024eb0871040d1f98b8d lib/galaxy/datatypes/data.py
--- a/lib/galaxy/datatypes/data.py
+++ b/lib/galaxy/datatypes/data.py
@@ -536,7 +536,9 @@
TODO: Do we need to merge gzip files using gzjoin? cat seems to work,
but might be brittle. Need to revisit this.
"""
- if len(split_files) == 1:
+ if not split_files:
+ raise ValueError('Asked to merge zero files as %s' % output_file)
+ elif len(split_files) == 1:
cmd = 'mv -f %s %s' % ( split_files[0], output_file )
else:
cmd = 'cat %s > %s' % ( ' '.join(split_files), output_file )
https://bitbucket.org/galaxy/galaxy-central/changeset/273c02b75ac1/
changeset: 273c02b75ac1
branch: zero-merge
user: peterjc
date: 2012-10-19 15:51:37
summary: Don't attempt to merge zero files
affected #: 1 file
diff -r 4daa56624e2a7dbe16c3024eb0871040d1f98b8d -r 273c02b75ac110937c3a0045785df41cef863fff lib/galaxy/jobs/splitters/multi.py
--- a/lib/galaxy/jobs/splitters/multi.py
+++ b/lib/galaxy/jobs/splitters/multi.py
@@ -115,6 +115,7 @@
try:
working_directory = job_wrapper.working_directory
task_dirs = [os.path.join(working_directory, x) for x in os.listdir(working_directory) if x.startswith('task_')]
+ assert task_dirs, "Should be at least one sub-task!"
# TODO: Output datasets can be very complex. This doesn't handle metadata files
outputs = job_wrapper.get_output_hdas_and_fnames()
pickone_done = []
@@ -129,10 +130,16 @@
# Just include those files f in the output list for which the
# file f exists; some files may not exist if a task fails.
output_files = [ f for f in output_files if os.path.exists(f) ]
- log.debug('files %s ' % output_files)
- output_type.merge(output_files, output_file_name)
- log.debug('merge finished: %s' % output_file_name)
- pass # TODO: merge all the files
+ if output_files:
+ log.debug('files %s ' % output_files)
+ if len(output_files) < len(task_dirs):
+ log.debug('merging only %i out of expected %i files for %s'
+ % (len(output_files), len(task_dirs), output_file_name))
+ output_type.merge(output_files, output_file_name)
+ log.debug('merge finished: %s' % output_file_name)
+ else:
+ log.debug('nothing to merge for %s (expected %i files)'
+ % (output_file_name, len(task_dirs)))
elif output in pickone_outputs:
# just pick one of them
if output not in pickone_done:
https://bitbucket.org/galaxy/galaxy-central/changeset/dbd7336b62c9/
changeset: dbd7336b62c9
branch: zero-merge
user: peterjc
date: 2012-10-19 16:23:02
summary: Log nothing to merge to stderr
affected #: 1 file
diff -r 273c02b75ac110937c3a0045785df41cef863fff -r dbd7336b62c9abf939ea4081482c744b56838e31 lib/galaxy/jobs/splitters/multi.py
--- a/lib/galaxy/jobs/splitters/multi.py
+++ b/lib/galaxy/jobs/splitters/multi.py
@@ -138,8 +138,10 @@
output_type.merge(output_files, output_file_name)
log.debug('merge finished: %s' % output_file_name)
else:
- log.debug('nothing to merge for %s (expected %i files)'
- % (output_file_name, len(task_dirs)))
+ msg = 'nothing to merge for %s (expected %i files)' \
+ % (output_file_name, len(task_dirs))
+ log.debug(msg)
+ stderr += msg + "\n"
elif output in pickone_outputs:
# just pick one of them
if output not in pickone_done:
https://bitbucket.org/galaxy/galaxy-central/changeset/ae9d794074bc/
changeset: ae9d794074bc
user: smcmanus
date: 2012-10-19 21:53:49
summary: Merged in peterjc/galaxy-central/zero-merge (pull request #78)
affected #: 2 files
diff -r 6db344e2ce554f4332b048dd41bb158e26c49fed -r ae9d794074bcc4732601e480ff54d53b0b2ee6e7 lib/galaxy/datatypes/data.py
--- a/lib/galaxy/datatypes/data.py
+++ b/lib/galaxy/datatypes/data.py
@@ -536,7 +536,9 @@
TODO: Do we need to merge gzip files using gzjoin? cat seems to work,
but might be brittle. Need to revisit this.
"""
- if len(split_files) == 1:
+ if not split_files:
+ raise ValueError('Asked to merge zero files as %s' % output_file)
+ elif len(split_files) == 1:
cmd = 'mv -f %s %s' % ( split_files[0], output_file )
else:
cmd = 'cat %s > %s' % ( ' '.join(split_files), output_file )
diff -r 6db344e2ce554f4332b048dd41bb158e26c49fed -r ae9d794074bcc4732601e480ff54d53b0b2ee6e7 lib/galaxy/jobs/splitters/multi.py
--- a/lib/galaxy/jobs/splitters/multi.py
+++ b/lib/galaxy/jobs/splitters/multi.py
@@ -115,6 +115,7 @@
try:
working_directory = job_wrapper.working_directory
task_dirs = [os.path.join(working_directory, x) for x in os.listdir(working_directory) if x.startswith('task_')]
+ assert task_dirs, "Should be at least one sub-task!"
# TODO: Output datasets can be very complex. This doesn't handle metadata files
outputs = job_wrapper.get_output_hdas_and_fnames()
pickone_done = []
@@ -129,10 +130,18 @@
# Just include those files f in the output list for which the
# file f exists; some files may not exist if a task fails.
output_files = [ f for f in output_files if os.path.exists(f) ]
- log.debug('files %s ' % output_files)
- output_type.merge(output_files, output_file_name)
- log.debug('merge finished: %s' % output_file_name)
- pass # TODO: merge all the files
+ if output_files:
+ log.debug('files %s ' % output_files)
+ if len(output_files) < len(task_dirs):
+ log.debug('merging only %i out of expected %i files for %s'
+ % (len(output_files), len(task_dirs), output_file_name))
+ output_type.merge(output_files, output_file_name)
+ log.debug('merge finished: %s' % output_file_name)
+ else:
+ msg = 'nothing to merge for %s (expected %i files)' \
+ % (output_file_name, len(task_dirs))
+ log.debug(msg)
+ stderr += msg + "\n"
elif output in pickone_outputs:
# just pick one of them
if output not in pickone_done:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dan: Minor enhancements for GenomeSpace import naming of secondary files.
by Bitbucket 19 Oct '12
by Bitbucket 19 Oct '12
19 Oct '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/6db344e2ce55/
changeset: 6db344e2ce55
user: dan
date: 2012-10-19 21:26:51
summary: Minor enhancements for GenomeSpace import naming of secondary files.
affected #: 2 files
diff -r 083d480bf5e35009f01e9439f11aa7e68716e429 -r 6db344e2ce554f4332b048dd41bb158e26c49fed tools/genomespace/genomespace_file_browser.py
--- a/tools/genomespace/genomespace_file_browser.py
+++ b/tools/genomespace/genomespace_file_browser.py
@@ -39,6 +39,7 @@
'gmt': 'gmt',
'gct': 'gct'}
+VALID_CHARS = '.-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '
def chunk_write( source_stream, target_stream, source_method = "read", target_method="write" ):
source_method = getattr( source_stream, source_method )
@@ -113,6 +114,7 @@
name = name[len( file_url_prefix ):]
file_numbers.append( int( name ) )
file_numbers.sort()
+ used_filenames = []
for file_num in file_numbers:
url_key = "%s%i" % ( file_url_prefix, file_num )
download_url = datasource_params.get( url_key, None )
@@ -135,8 +137,14 @@
parsed_url = urlparse.urlparse( download_url )
query_params = urlparse.parse_qs( parsed_url[4] )
filename = urllib.unquote_plus( parsed_url[2].split( '/' )[-1] )
+ if not filename:
+ filename = download_url
if output_filename is None:
- output_filename = os.path.join( datasource_params['__new_file_path__'], 'primary_%i_output%i_visible_%s' % ( hda_id, file_num, galaxy_ext ) )
+ filename = ''.join( c in VALID_CHARS and c or '-' for c in filename )
+ while filename in used_filenames:
+ filename = "-%s" % filename
+ used_filenames.append( filename )
+ output_filename = os.path.join( datasource_params['__new_file_path__'], 'primary_%i_%s_visible_%s' % ( hda_id, filename, galaxy_ext ) )
else:
if dataset_id is not None:
metadata_parameter_file.write( "%s\n" % simplejson.dumps( dict( type = 'dataset',
diff -r 083d480bf5e35009f01e9439f11aa7e68716e429 -r 6db344e2ce554f4332b048dd41bb158e26c49fed tools/genomespace/genomespace_importer.py
--- a/tools/genomespace/genomespace_importer.py
+++ b/tools/genomespace/genomespace_importer.py
@@ -43,7 +43,7 @@
'gmt': 'gmt',
'gct': 'gct'}
-VALID_CHARS = '.-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
+VALID_CHARS = '.-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '
def chunk_write( source_stream, target_stream, source_method = "read", target_method="write" ):
source_method = getattr( source_stream, source_method )
@@ -112,6 +112,7 @@
datatypes_registry = Registry()
datatypes_registry.load_datatypes( root_dir = json_params[ 'job_config' ][ 'GALAXY_ROOT_DIR' ], config = json_params[ 'job_config' ][ 'GALAXY_DATATYPES_CONF_FILE' ] )
url_param = datasource_params.get( file_url_name, None )
+ used_filenames = []
for download_url in url_param.split( ',' ):
using_temp_file = False
parsed_url = urlparse.urlparse( download_url )
@@ -129,6 +130,8 @@
parsed_url = urlparse.urlparse( download_url )
query_params = urlparse.parse_qs( parsed_url[4] )
filename = urllib.unquote_plus( parsed_url[2].split( '/' )[-1] )
+ if not filename:
+ filename = download_url
if output_filename is None:
#need to use a temp file here, because we do not know the ext yet
using_temp_file = True
@@ -179,7 +182,11 @@
name = "GenomeSpace importer on %s" % ( filename ) ) ) )
#if using tmp file, move the file to the new file path dir to get scooped up later
if using_temp_file:
- shutil.move( output_filename, os.path.join( datasource_params['__new_file_path__'], 'primary_%i_output%s_visible_%s' % ( hda_id, ''.join( c in VALID_CHARS and c or '-' for c in filename ), file_type ) ) )
+ filename = ''.join( c in VALID_CHARS and c or '-' for c in filename )
+ while filename in used_filenames:
+ filename = "-%s" % filename
+ used_filenames.append( filename )
+ shutil.move( output_filename, os.path.join( datasource_params['__new_file_path__'], 'primary_%i_%s_visible_%s' % ( hda_id, filename, file_type ) ) )
dataset_id = None #only one primary dataset available
output_filename = None #only have one filename available
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/083d480bf5e3/
changeset: 083d480bf5e3
user: natefoo
date: 2012-10-19 18:56:10
summary: Retry pbs_submit if it fails.
affected #: 1 file
diff -r 8bcc04c4b710dbf4173a5fba6d2a3111e7c2b511 -r 083d480bf5e35009f01e9439f11aa7e68716e429 lib/galaxy/jobs/runners/pbs.py
--- a/lib/galaxy/jobs/runners/pbs.py
+++ b/lib/galaxy/jobs/runners/pbs.py
@@ -310,13 +310,19 @@
galaxy_job_id = job_wrapper.get_id_tag()
log.debug("(%s) submitting file %s" % ( galaxy_job_id, job_file ) )
log.debug("(%s) command is: %s" % ( galaxy_job_id, command_line ) )
- job_id = pbs.pbs_submit(c, job_attrs, job_file, pbs_queue_name, None)
- pbs.pbs_disconnect(c)
- # check to see if it submitted
- if not job_id:
+ tries = 0
+ while tries < 5:
+ job_id = pbs.pbs_submit(c, job_attrs, job_file, pbs_queue_name, None)
+ tries += 1
+ if job_id:
+ pbs.pbs_disconnect(c)
+ break
errno, text = pbs.error()
- log.debug( "(%s) pbs_submit failed, PBS error %d: %s" % (galaxy_job_id, errno, text) )
+ log.warning( "(%s) pbs_submit failed (try %d/5), PBS error %d: %s" % (galaxy_job_id, tries, errno, text) )
+ time.sleep(2)
+ else:
+ log.error( "(%s) All attempts to submit job failed" % galaxy_job_id )
job_wrapper.fail( "Unable to run this job due to a cluster error, please retry it later" )
return
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0