galaxy-commits
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 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
- 15302 discussions
commit/galaxy-central: greg: Add help text to the tool shed repository upload form to advertise John Chilton's recent enhancement allowing for mercurial repository urls staring with hg:// or hgs://.
by Bitbucket 23 Oct '12
by Bitbucket 23 Oct '12
23 Oct '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/bad5602cdf99/
changeset: bad5602cdf99
user: greg
date: 2012-10-23 20:59:31
summary: Add help text to the tool shed repository upload form to advertise John Chilton's recent enhancement allowing for mercurial repository urls staring with hg:// or hgs://.
affected #: 2 files
diff -r 5ae989999225b9edf884de6dfe23a2e82f9de403 -r bad5602cdf998dff9c2aecf478dc4ed1a797a023 lib/galaxy/webapps/community/controllers/upload.py
--- a/lib/galaxy/webapps/community/controllers/upload.py
+++ b/lib/galaxy/webapps/community/controllers/upload.py
@@ -48,13 +48,12 @@
message = 'No files were entered on the upload form.'
status = 'error'
uploaded_file = None
- elif url and url.startswith("hg"):
- # Use mercurial clone to fetch repository, contents will then
- # be copied over.
+ elif url and url.startswith( 'hg' ):
+ # Use mercurial clone to fetch repository, contents will then be copied over.
uploaded_directory = tempfile.mkdtemp()
- repo_url = "http%s" % url[len("hg"):]
- repo_url = repo_url.encode('ascii', 'replace')
- commands.clone(get_configured_ui(), repo_url, uploaded_directory)
+ repo_url = 'http%s' % url[ len( 'hg' ): ]
+ repo_url = repo_url.encode( 'ascii', 'replace' )
+ commands.clone( get_configured_ui(), repo_url, uploaded_directory )
elif url:
valid_url = True
try:
diff -r 5ae989999225b9edf884de6dfe23a2e82f9de403 -r bad5602cdf998dff9c2aecf478dc4ed1a797a023 templates/webapps/community/repository/upload.mako
--- a/templates/webapps/community/repository/upload.mako
+++ b/templates/webapps/community/repository/upload.mako
@@ -85,7 +85,10 @@
<input name="url" type="textfield" value="${url | h}" size="40"/></div><div class="toolParamHelp" style="clear: both;">
- Enter a URL to upload your files via http.
+ Enter a URL to upload your files via http. URLs that point to mercurial repositories (URLs that start with hg:// or hgs://)
+ are allowed. This mechanism results in the tip revision of an external mercurial repository being added to the tool shed
+ repository as a single new changeset. The revision history of the originating external mercurial repository is not uploaded
+ to the tool shed repository.
</div><div style="clear: both"></div></div>
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
23 Oct '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/5ae989999225/
changeset: 5ae989999225
user: greg
date: 2012-10-23 20:38:38
summary: Fix for managing tool shed repository reviews.
affected #: 1 file
diff -r 1d8578333bd37d7fd84f276d115f414bbde0b607 -r 5ae989999225b9edf884de6dfe23a2e82f9de403 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
@@ -654,7 +654,7 @@
repo_dir = repository.repo_path
repo = hg.repository( get_configured_ui(), repo_dir )
metadata_revision_hashes = [ metadata_revision.changeset_revision for metadata_revision in repository.metadata_revisions ]
- reviewed_revision_hashes = [ reviewed_revisions.changeset_revision for reviewed_revisions in repository.reviewed_revisions ]
+ reviewed_revision_hashes = [ review.changeset_revision for review in repository.reviews ]
reviews_dict = odict()
for changeset in get_reversed_changelog_changesets( repo ):
ctx = repo.changectx( changeset )
@@ -667,7 +667,10 @@
# Determine if the current user can add a review to this revision.
can_add_review = trans.user not in [ repository_review.user for repository_review in repository_reviews ]
repository_metadata = get_repository_metadata_by_changeset_revision( trans, repository_id, changeset_revision )
- repository_metadata_reviews = util.listify( repository_metadata.reviews )
+ if repository_metadata:
+ repository_metadata_reviews = util.listify( repository_metadata.reviews )
+ else:
+ repository_metadata_reviews = []
else:
repository_reviews = []
repository_metadata_reviews = []
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
23 Oct '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/1d8578333bd3/
changeset: 1d8578333bd3
user: greg
date: 2012-10-23 19:43:08
summary: Fix for RepositoriesWithReviewsGrid columns.
affected #: 2 files
diff -r 7a0c93ca036bcd7a8ed33ed15dec95205974f46e -r 1d8578333bd37d7fd84f276d115f414bbde0b607 lib/galaxy/webapps/community/controllers/repository.py
--- a/lib/galaxy/webapps/community/controllers/repository.py
+++ b/lib/galaxy/webapps/community/controllers/repository.py
@@ -120,20 +120,6 @@
elif len( select_field.options ) == 1:
return select_field.options[ 0 ][ 0 ]
return ''
- class WithoutReviewsRevisionColumn( grids.GridColumn ):
- def __init__( self, col_name ):
- grids.GridColumn.__init__( self, col_name )
- def get_value( self, trans, grid, repository ):
- # Restrict the options to revisions that have not yet been reviewed.
- repository_metadata_revisions = get_repository_metadata_revisions_for_review( repository, reviewed=False )
- if repository_metadata_revisions:
- rval = ''
- for repository_metadata in repository_metadata_revisions:
- rev, label, changeset_revision = get_rev_label_changeset_revision_from_repository_metadata( repository_metadata, repository=repository )
- rval += '<a href="manage_repository_reviews_of_revision'
- rval += '?id=%s&changeset_revision=%s">%s</a><br/>' % ( trans.security.encode_id( repository.id ), changeset_revision, label )
- return rval
- return ''
class TipRevisionColumn( grids.GridColumn ):
def __init__( self, col_name ):
grids.GridColumn.__init__( self, col_name )
diff -r 7a0c93ca036bcd7a8ed33ed15dec95205974f46e -r 1d8578333bd37d7fd84f276d115f414bbde0b607 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
@@ -51,8 +51,6 @@
class RepositoriesWithReviewsGrid( RepositoryGrid ):
# This grid filters out repositories that have been marked as deprecated.
class WithReviewsRevisionColumn( grids.GridColumn ):
- def __init__( self, col_name ):
- grids.GridColumn.__init__( self, col_name )
def get_value( self, trans, grid, repository ):
# Restrict to revisions that have been reviewed.
if repository.reviews:
@@ -65,6 +63,18 @@
rval += '?id=%s&changeset_revision=%s">%s</a><br/>' % ( trans.security.encode_id( repository.id ), changeset_revision, label )
return rval
return ''
+ class WithoutReviewsRevisionColumn( grids.GridColumn ):
+ def get_value( self, trans, grid, repository ):
+ # Restrict the options to revisions that have not yet been reviewed.
+ repository_metadata_revisions = get_repository_metadata_revisions_for_review( repository, reviewed=False )
+ if repository_metadata_revisions:
+ rval = ''
+ for repository_metadata in repository_metadata_revisions:
+ rev, label, changeset_revision = get_rev_label_changeset_revision_from_repository_metadata( repository_metadata, repository=repository )
+ rval += '<a href="manage_repository_reviews_of_revision'
+ rval += '?id=%s&changeset_revision=%s">%s</a><br/>' % ( trans.security.encode_id( repository.id ), changeset_revision, label )
+ return rval
+ return ''
class ReviewersColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
rval = ''
@@ -84,7 +94,7 @@
link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
attach_popup=True ),
WithReviewsRevisionColumn( "Reviewed revisions" ),
- RepositoryGrid.WithoutReviewsRevisionColumn( "Revisions for review" ),
+ WithoutReviewsRevisionColumn( "Revisions for review" ),
RepositoryGrid.UserColumn( "Owner", attach_popup=False ),
ReviewersColumn( "Reviewers", attach_popup=False )
]
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: greg: Alllow non-admin users to see metadata revisions when viewing a repository changelog in the tool shed.
by Bitbucket 23 Oct '12
by Bitbucket 23 Oct '12
23 Oct '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/7a0c93ca036b/
changeset: 7a0c93ca036b
user: greg
date: 2012-10-23 19:38:34
summary: Alllow non-admin users to see metadata revisions when viewing a repository changelog in the tool shed.
affected #: 1 file
diff -r 26017976e4e9d5de317e0b1ef29423effdbe5e24 -r 7a0c93ca036bcd7a8ed33ed15dec95205974f46e templates/webapps/community/repository/view_changelog.mako
--- a/templates/webapps/community/repository/view_changelog.mako
+++ b/templates/webapps/community/repository/view_changelog.mako
@@ -114,14 +114,14 @@
has_metadata_str = '<table border="0"><tr><td bgcolor="#D8D8D8">Repository metadata is associated with this change set.</td></tr></table>'
else:
has_metadata_str = ''
+ display_date = changeset[ 'display_date' ]
%>
- <% display_date = changeset[ 'display_date' ] %>
%if test_date != display_date:
<tr colspan="2"><td bgcolor="#D8D8D8">${display_date}</td></tr>
%endif
<tr><td>
- %if is_admin and has_metadata_str:
+ %if has_metadata_str:
<div class="form-row">
${has_metadata_str}
</div>
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/283776e0ad29/
changeset: 283776e0ad29
user: jgoecks
date: 2012-10-23 19:30:26
summary: Make DiagonalHeatMapTrack compatible with recent refactoring.
affected #: 1 file
diff -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a -r 283776e0ad29cd9638d5be726fe051d985922c48 static/scripts/viz/trackster/tracks.js
--- a/static/scripts/viz/trackster/tracks.js
+++ b/static/scripts/viz/trackster/tracks.js
@@ -3686,17 +3686,14 @@
/**
* Draw LineTrack tile.
*/
- draw_tile: function(result, ctx, mode, resolution, tile_index, w_scale) {
+ draw_tile: function(result, ctx, mode, resolution, region, w_scale) {
// Paint onto canvas.
var
canvas = ctx.canvas,
- tile_bounds = this._get_tile_bounds(tile_index, resolution),
- tile_low = tile_bounds[0],
- tile_high = tile_bounds[1],
- painter = new painters.DiagonalHeatmapPainter(result.data, tile_low, tile_high, this.prefs, mode);
+ painter = new painters.DiagonalHeatmapPainter(result.data, region.get('start'), region.get('end'), this.prefs, mode);
painter.draw(ctx, canvas.width, canvas.height, w_scale);
- return new Tile(this, tile_index, resolution, canvas, result.data);
+ return new Tile(this, region, resolution, canvas, result.data);
}
});
https://bitbucket.org/galaxy/galaxy-central/changeset/26017976e4e9/
changeset: 26017976e4e9
user: jgoecks
date: 2012-10-23 19:30:56
summary: Automated Merge
affected #: 3 files
diff -r 283776e0ad29cd9638d5be726fe051d985922c48 -r 26017976e4e9d5de317e0b1ef29423effdbe5e24 lib/galaxy/webapps/community/controllers/repository.py
--- a/lib/galaxy/webapps/community/controllers/repository.py
+++ b/lib/galaxy/webapps/community/controllers/repository.py
@@ -20,6 +20,8 @@
from galaxy import eggs
eggs.require('mercurial')
from mercurial import hg, ui, patch, commands
+eggs.require('markupsafe')
+from markupsafe import escape as escape_html
log = logging.getLogger( __name__ )
@@ -105,7 +107,7 @@
class RepositoryGrid( grids.Grid ):
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
- return repository.name
+ return escape_html( repository.name )
class MetadataRevisionColumn( grids.GridColumn ):
def __init__( self, col_name ):
grids.GridColumn.__init__( self, col_name )
@@ -137,10 +139,10 @@
grids.GridColumn.__init__( self, col_name )
def get_value( self, trans, grid, repository ):
"""Display the repository tip revision label."""
- return repository.revision
+ return escape_html( repository.revision )
class DescriptionColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
- return repository.description
+ return escape_html( repository.description )
class CategoryColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
rval = '<ul>'
@@ -161,7 +163,7 @@
class UserColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
if repository.user:
- return repository.user.username
+ return escape_html( repository.user.username )
return 'no user'
class EmailColumn( grids.TextColumn ):
def filter( self, trans, user, query, column_filter ):
diff -r 283776e0ad29cd9638d5be726fe051d985922c48 -r 26017976e4e9d5de317e0b1ef29423effdbe5e24 templates/webapps/community/common/common.mako
--- a/templates/webapps/community/common/common.mako
+++ b/templates/webapps/community/common/common.mako
@@ -1,5 +1,7 @@
<%def name="escape_html_add_breaks( value )"><%
+ from galaxy import eggs
+ eggs.require('markupsafe')
import markupsafe
value = str( markupsafe.escape( value ) ).replace( '\n', '<br/>' )
%>
diff -r 283776e0ad29cd9638d5be726fe051d985922c48 -r 26017976e4e9d5de317e0b1ef29423effdbe5e24 test/base/twilltestcase.py
--- a/test/base/twilltestcase.py
+++ b/test/base/twilltestcase.py
@@ -746,9 +746,9 @@
temp_local = tempfile.NamedTemporaryFile( suffix='.sam', prefix='local_bam_converted_to_sam_' )
fd, temp_temp = tempfile.mkstemp( suffix='.sam', prefix='history_bam_converted_to_sam_' )
os.close( fd )
- p = subprocess.Popen( args="samtools view -h %s -o %s" % ( local_name, temp_local.name ), shell=True )
+ p = subprocess.Popen( args='samtools view -h -o "%s" "%s"' % ( temp_local.name, local_name ), shell=True )
assert not p.wait(), 'Converting local (test-data) bam to sam failed'
- p = subprocess.Popen( args="samtools view -h %s -o %s" % ( temp_name, temp_temp ), shell=True )
+ p = subprocess.Popen( args='samtools view -h -o "%s" "%s"' % ( temp_temp, temp_name ), shell=True )
assert not p.wait(), 'Converting history bam to sam failed'
os.remove( temp_name )
return temp_local, temp_temp
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: Tweak for functional tests of BAM outputs on Macs.
by Bitbucket 23 Oct '12
by Bitbucket 23 Oct '12
23 Oct '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/72484a95b873/
changeset: 72484a95b873
user: dan
date: 2012-10-23 18:28:22
summary: Tweak for functional tests of BAM outputs on Macs.
affected #: 1 file
diff -r 8f82e2c36ec3da564aa0cdc507adad19e295b317 -r 72484a95b8732bf391ded562d9c26f4b61f51b43 test/base/twilltestcase.py
--- a/test/base/twilltestcase.py
+++ b/test/base/twilltestcase.py
@@ -746,9 +746,9 @@
temp_local = tempfile.NamedTemporaryFile( suffix='.sam', prefix='local_bam_converted_to_sam_' )
fd, temp_temp = tempfile.mkstemp( suffix='.sam', prefix='history_bam_converted_to_sam_' )
os.close( fd )
- p = subprocess.Popen( args="samtools view -h %s -o %s" % ( local_name, temp_local.name ), shell=True )
+ p = subprocess.Popen( args='samtools view -h -o "%s" "%s"' % ( temp_local.name, local_name ), shell=True )
assert not p.wait(), 'Converting local (test-data) bam to sam failed'
- p = subprocess.Popen( args="samtools view -h %s -o %s" % ( temp_name, temp_temp ), shell=True )
+ p = subprocess.Popen( args='samtools view -h -o "%s" "%s"' % ( temp_temp, temp_name ), shell=True )
assert not p.wait(), 'Converting history bam to sam failed'
os.remove( temp_name )
return temp_local, temp_temp
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/847bafa6c4aa/
changeset: 847bafa6c4aa
user: dan
date: 2012-10-23 17:26:27
summary: HTML escape user defined values in repository grid.
affected #: 1 file
diff -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a -r 847bafa6c4aa94cb41e87f842081693f7526cf44 lib/galaxy/webapps/community/controllers/repository.py
--- a/lib/galaxy/webapps/community/controllers/repository.py
+++ b/lib/galaxy/webapps/community/controllers/repository.py
@@ -20,6 +20,8 @@
from galaxy import eggs
eggs.require('mercurial')
from mercurial import hg, ui, patch, commands
+eggs.require('markupsafe')
+from markupsafe import escape as escape_html
log = logging.getLogger( __name__ )
@@ -105,7 +107,7 @@
class RepositoryGrid( grids.Grid ):
class NameColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
- return repository.name
+ return escape_html( repository.name )
class MetadataRevisionColumn( grids.GridColumn ):
def __init__( self, col_name ):
grids.GridColumn.__init__( self, col_name )
@@ -137,10 +139,10 @@
grids.GridColumn.__init__( self, col_name )
def get_value( self, trans, grid, repository ):
"""Display the repository tip revision label."""
- return repository.revision
+ return escape_html( repository.revision )
class DescriptionColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
- return repository.description
+ return escape_html( repository.description )
class CategoryColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
rval = '<ul>'
@@ -161,7 +163,7 @@
class UserColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
if repository.user:
- return repository.user.username
+ return escape_html( repository.user.username )
return 'no user'
class EmailColumn( grids.TextColumn ):
def filter( self, trans, user, query, column_filter ):
https://bitbucket.org/galaxy/galaxy-central/changeset/8f82e2c36ec3/
changeset: 8f82e2c36ec3
user: dan
date: 2012-10-23 17:26:27
summary: Tweak for escape_html_add_breaks
affected #: 1 file
diff -r 847bafa6c4aa94cb41e87f842081693f7526cf44 -r 8f82e2c36ec3da564aa0cdc507adad19e295b317 templates/webapps/community/common/common.mako
--- a/templates/webapps/community/common/common.mako
+++ b/templates/webapps/community/common/common.mako
@@ -1,5 +1,7 @@
<%def name="escape_html_add_breaks( value )"><%
+ from galaxy import eggs
+ eggs.require('markupsafe')
import markupsafe
value = str( markupsafe.escape( value ) ).replace( '\n', '<br/>' )
%>
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/2c261f6401e9/
changeset: 2c261f6401e9
user: jgoecks
date: 2012-10-23 17:01:31
summary: Update ChromosomeInteraction datatype metadata.
affected #: 1 file
diff -r 06b3b644188a29b78e8400298c67472b5b6bd790 -r 2c261f6401e9693cf7cc5d8749f9b59a9d9cee9e lib/galaxy/datatypes/interval.py
--- a/lib/galaxy/datatypes/interval.py
+++ b/lib/galaxy/datatypes/interval.py
@@ -1313,15 +1313,18 @@
file_ext = "chrint"
- column_names = [ 'Chrom', 'Start1', 'End1', 'Start2', 'End2', 'Value' ]
+ column_names = [ 'Chrom1', 'Start1', 'End1', 'Chrom2', 'Start2', 'End2', 'Value' ]
"""Add metadata elements"""
- MetadataElement( name="chromCol", default=1, desc="Chrom column", param=metadata.ColumnParameter )
+ MetadataElement( name="chrom1Col", default=1, desc="Chrom1 column", param=metadata.ColumnParameter )
MetadataElement( name="start1Col", default=2, desc="Start1 column", param=metadata.ColumnParameter )
MetadataElement( name="end1Col", default=3, desc="End1 column", param=metadata.ColumnParameter )
- MetadataElement( name="start2Col", default=2, desc="Start2 column", param=metadata.ColumnParameter )
- MetadataElement( name="end2Col", default=3, desc="End2 column", param=metadata.ColumnParameter )
- MetadataElement( name="columns", default=3, desc="Number of columns", readonly=True, visible=False )
+ MetadataElement( name="chrom2Col", default=4, desc="Chrom2 column", param=metadata.ColumnParameter )
+ MetadataElement( name="start2Col", default=5, desc="Start2 column", param=metadata.ColumnParameter )
+ MetadataElement( name="end2Col", default=6, desc="End2 column", param=metadata.ColumnParameter )
+ MetadataElement( name="valueCol", default=7, desc="Value column", param=metadata.ColumnParameter )
+
+ MetadataElement( name="columns", default=7, desc="Number of columns", readonly=True, visible=False )
def sniff( self, filename ):
return False
https://bitbucket.org/galaxy/galaxy-central/changeset/d79eb7e1d7cb/
changeset: d79eb7e1d7cb
user: jgoecks
date: 2012-10-23 17:06:27
summary: Circster: use chords to denote chromosome interactions data.
affected #: 7 files
diff -r 2c261f6401e9693cf7cc5d8749f9b59a9d9cee9e -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 lib/galaxy/visualization/data_providers/genome.py
--- a/lib/galaxy/visualization/data_providers/genome.py
+++ b/lib/galaxy/visualization/data_providers/genome.py
@@ -347,11 +347,18 @@
tabix = ctabix.Tabixfile(bgzip_fname, index_filename=self.converted_dataset.file_name)
- # If chrom not in data, try alternative.
- if chrom not in tabix.contigs:
+ # Get iterator using either naming scheme.
+ iterator = iter( [] )
+ if chrom in tabix.contigs:
+ iterator = tabix.fetch(reference=chrom, start=start, end=end)
+ else:
+ # Try alternative naming scheme.
chrom = _convert_between_ucsc_and_ensemble_naming( chrom )
-
- return tabix.fetch(reference=chrom, start=start, end=end)
+ if chrom in tabix.contigs:
+ iterator = tabix.fetch(reference=chrom, start=start, end=end)
+
+ return iterator
+
def write_data_to_file( self, regions, filename ):
out = open( filename, "w" )
@@ -1457,11 +1464,11 @@
feature = line.split()
length = len( feature )
- s1 = int( feature[1] ),
- e1 = int( feature[2] ),
- c = feature[3],
- s2 = int( feature[4] ),
- e2 = int( feature[5] ),
+ s1 = int( feature[1] )
+ e1 = int( feature[2] )
+ c = feature[3]
+ s2 = int( feature[4] )
+ e2 = int( feature[5] )
v = float( feature[6] )
# Feature initialization.
@@ -1480,7 +1487,7 @@
return 50000;
class ChromatinInteractionsTabixDataProvider( TabixDataProvider, ChromatinInteractionsDataProvider ):
- def get_iterator( self, chrom, start, end ):
+ def get_iterator( self, chrom, start=0, end=sys.maxint ):
"""
"""
# Modify start as needed to get earlier interactions with start region.
@@ -1493,7 +1500,7 @@
c = feature[3]
s2 = int( feature[4] )
e2 = int( feature[5] )
- if ( ( c == chrom ) and ( s1 < end and e1 > start ) and ( s2 < end and e2 > start ) ):
+ if ( s1 <= end and e1 >= start ) and ( s2 <= end and e2 >= start ):
yield line
return filter( TabixDataProvider.get_iterator( self, chrom, start, end ) )
diff -r 2c261f6401e9693cf7cc5d8749f9b59a9d9cee9e -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -602,7 +602,7 @@
return visualization
- def _get_genome_data( self, trans, dataset, dbkey=None ):
+ def _get_genome_data( self, trans, dataset, dbkey=None, source='index' ):
"""
Returns genome-wide data for dataset if available; if not, message is returned.
"""
@@ -615,7 +615,7 @@
query_dbkey = dbkey
chroms_info = self.app.genomes.chroms( trans, dbkey=query_dbkey )
- # If there are no messages (messages indicate data is not ready/available), preload data.
+ # If there are no messages (messages indicate data is not ready/available), get data.
messages_list = [ data_source_dict[ 'message' ] for data_source_dict in data_sources.values() ]
message = get_highest_priority_msg( messages_list )
if message:
@@ -623,7 +623,7 @@
else:
data_provider = trans.app.data_provider_registry.get_data_provider( trans,
original_dataset=dataset,
- source='index' )
+ source=source )
# HACK: pass in additional params, which are only used for summary tree data, not BBI data.
rval = data_provider.get_genome_data( chroms_info, level=4, detail_cutoff=0, draw_cutoff=0 )
diff -r 2c261f6401e9693cf7cc5d8749f9b59a9d9cee9e -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 lib/galaxy/webapps/galaxy/controllers/visualization.py
--- a/lib/galaxy/webapps/galaxy/controllers/visualization.py
+++ b/lib/galaxy/webapps/galaxy/controllers/visualization.py
@@ -8,6 +8,7 @@
from galaxy.visualization.genomes import decode_dbkey
from galaxy.visualization.genome.visual_analytics import get_dataset_job
from galaxy.visualization.data_providers.phyloviz import PhylovizDataProvider
+from galaxy.datatypes.interval import ChromatinInteractions
from .library import LibraryListGrid
@@ -748,11 +749,16 @@
chroms_info = self.app.genomes.chroms( trans, dbkey=dbkey )
genome = { 'dbkey': dbkey, 'chroms_info': chroms_info }
- # Add genome-wide summary tree data to each track in viz.
+ # Add genome-wide data to each track in viz.
tracks = viz_config.get( 'tracks', [] )
for track in tracks:
dataset = self.get_hda_or_ldda( trans, track[ 'hda_ldda'], track[ 'dataset_id' ] )
- genome_data = self._get_genome_data( trans, dataset, dbkey )
+ # HACK: chromatin interactions tracks use data as source.
+ source = 'index'
+ if isinstance( dataset.datatype, ChromatinInteractions ):
+ source = 'data'
+
+ genome_data = self._get_genome_data( trans, dataset, dbkey, source=source )
if not isinstance( genome_data, str ):
track[ 'preloaded_data' ] = genome_data
diff -r 2c261f6401e9693cf7cc5d8749f9b59a9d9cee9e -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 static/scripts/viz/circster.js
--- a/static/scripts/viz/circster.js
+++ b/static/scripts/viz/circster.js
@@ -48,23 +48,46 @@
this.track_gap = 5;
this.label_arc_height = 20;
this.scale = 1;
- this.track_views = null;
+ this.circular_views = null;
+ this.chords_views = null;
// 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);
+ this.get_circular_tracks();
+ },
+
+ // HACKs: using track_type for circular/chord distinction in the functions below for now.
+
+ /**
+ * Returns tracks to be rendered using circular view.
+ */
+ get_circular_tracks: function() {
+ return this.model.get('tracks').filter(function(track) {
+ return track.get('track_type') !== 'DiagonalHeatmapTrack';
+ });
+ },
+
+ /**
+ * Returns tracks to be rendered using chords view.
+ */
+ get_chord_tracks: function() {
+ return this.model.get('tracks').filter(function(track) {
+ return track.get('track_type') === 'DiagonalHeatmapTrack';
+ });
},
/**
* Returns a list of tracks' radius bounds.
*/
get_tracks_bounds: function() {
- var dataset_arc_height = this.dataset_arc_height,
+ var circular_tracks = this.get_circular_tracks();
+ dataset_arc_height = this.dataset_arc_height,
min_dimension = Math.min(this.$el.width(), this.$el.height()),
// Compute radius start based on model, will be centered
// and fit entirely inside element by default.
radius_start = min_dimension / 2 -
- this.model.get('tracks').length * (this.dataset_arc_height + this.track_gap) -
+ circular_tracks.length * (this.dataset_arc_height + this.track_gap) -
(this.label_arc_height + this.track_gap),
// Compute range of track starting radii.
@@ -77,12 +100,16 @@
});
},
+ /**
+ * Renders circular tracks, chord tracks, and label tracks.
+ */
render: function() {
var self = this,
dataset_arc_height = this.dataset_arc_height,
width = self.$el.width(),
height = self.$el.height(),
- tracks = this.model.get('tracks'),
+ circular_tracks = this.get_circular_tracks(),
+ chords_tracks = this.get_chord_tracks(),
tracks_bounds = this.get_tracks_bounds(),
// Set up SVG element.
@@ -108,7 +135,7 @@
}
self.zoom_drag_timeout = setTimeout(function() {
// Render more detail in tracks' visible elements.
- _.each(self.track_views, function(view) {
+ _.each(self.circular_views, function(view) {
view.update_scale(scale);
});
}, 400);
@@ -117,32 +144,46 @@
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
.append('svg:g').attr('class', 'tracks');
-
- // -- Render each dataset in the visualization. --
+ // -- Render circular tracks. --
// Create a view for each track in the visualiation and render.
- this.track_views = tracks.map(function(track, index) {
- track_view_class = (track.get('track_type') === 'LineTrack' ?
+ this.circular_views = circular_tracks.map(function(track, index) {
+ var track_view_class = (track.get('track_type') === 'LineTrack' ?
CircsterBigWigTrackView :
- CircsterSummaryTreeTrackView );
+ CircsterSummaryTreeTrackView ),
+ view = new track_view_class({
+ el: svg.append('g')[0],
+ track: track,
+ radius_bounds: tracks_bounds[index],
+ genome: self.genome,
+ total_gap: self.total_gap
+ });
- return new track_view_class({
+ view.render();
+
+ return view;
+ });
+
+ // -- Render chords tracks. --
+
+ this.chords_views = chords_tracks.map(function(track) {
+ var view = new CircsterChromInteractionsTrackView({
el: svg.append('g')[0],
track: track,
- radius_bounds: tracks_bounds[index],
+ radius_bounds: tracks_bounds[0],
genome: self.genome,
total_gap: self.total_gap
});
+
+ view.render();
+
+ return view;
});
- _.each(this.track_views, function(view) {
- view.render();
- });
-
- // -- Render chromosome labels. --
+ // -- Render label tracks. --
// Set radius start = end for track bounds.
- var track_bounds = tracks_bounds[tracks.length];
+ var track_bounds = tracks_bounds[circular_tracks.length];
track_bounds[1] = track_bounds[0];
this.label_track_view = new CircsterLabelTrackView({
el: svg.append('g')[0],
@@ -161,13 +202,12 @@
add_track: function(new_track) {
// 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);
+ _.each(this.circular_views, function(track_view, i) {
track_view.update_radius_bounds(new_track_bounds[i]);
});
// Render new track.
- var track_index = this.track_views.length,
+ var track_index = this.circular_views.length,
track_view_class = (new_track.get('track_type') === 'LineTrack' ?
CircsterBigWigTrackView :
CircsterSummaryTreeTrackView ),
@@ -179,7 +219,7 @@
total_gap: this.total_gap
});
track_view.render();
- this.track_views.push(track_view);
+ this.circular_views.push(track_view);
// Update label track.
var track_bounds = new_track_bounds[ new_track_bounds.length-1 ];
@@ -192,14 +232,13 @@
*/
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);
+ var track_view = this.circular_views[options.index];
+ this.circular_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);
+ _.each(this.circular_views, function(track_view, i) {
track_view.update_radius_bounds(new_track_bounds[i]);
});
}
@@ -581,7 +620,7 @@
});
/**
- * Bigwig track view in Circster
+ * Bigwig track view in Circster.
*/
var CircsterBigWigTrackView = CircsterQuantitativeTrackView.extend({
@@ -604,6 +643,74 @@
}
});
+/**
+ * Chromosome interactions track view in Circster.
+ */
+var CircsterChromInteractionsTrackView = CircsterTrackView.extend({
+
+ render: function() {
+ var self = this;
+
+ // When data is ready, render track.
+ $.when(self.track.get('data_manager').data_is_ready()).then(function() {
+ // Convert genome-wide data in chord data.
+ $.when(self.track.get('data_manager').get_genome_wide_data(self.genome)).then(function(genome_wide_data) {
+ var chord_data = [],
+ chroms_info = self.genome.get_chroms_info();
+ // Convert chromosome data into chord data.
+ _.each(genome_wide_data, function(chrom_data, index) {
+ // Map each interaction into chord data.
+ var cur_chrom = chroms_info[index].chrom;
+ var chrom_chord_data = _.map(chrom_data.data, function(datum) {
+ // Each datum is an interaction/chord.
+ var source_angle = self._get_region_angle(cur_chrom, datum[1]),
+ target_angle = self._get_region_angle(datum[3], datum[4]);
+ return {
+ source: {
+ startAngle: source_angle,
+ endAngle: source_angle + 0.01
+ },
+ target: {
+ startAngle: target_angle,
+ endAngle: target_angle + 0.01
+ }
+ };
+ });
+
+ chord_data = chord_data.concat(chrom_chord_data);
+ });
+
+ self.parent_elt.append("g")
+ .attr("class", "chord")
+ .selectAll("path")
+ .data(chord_data)
+ .enter().append("path")
+ .style("fill", '000')
+ .attr("d", d3.svg.chord().radius(self.radius_bounds[0]))
+ .style("opacity", 1);
+ });
+ });
+ },
+
+ /**
+ * Returns radians for a genomic position.
+ */
+ _get_region_angle: function(chrom, position) {
+ // Find chrom angle data
+ var chrom_angle_data = _.find(this.chroms_layout, function(chrom_layout) {
+ return chrom_layout.data.chrom === chrom;
+ });
+
+ // Return angle at position.
+ return chrom_angle_data.endAngle -
+ (
+ (chrom_angle_data.endAngle - chrom_angle_data.startAngle) *
+ (chrom_angle_data.data.len - position) / chrom_angle_data.data.len
+ );
+ }
+
+});
+
// Module exports.
return {
CircsterView: CircsterView
diff -r 2c261f6401e9693cf7cc5d8749f9b59a9d9cee9e -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 static/scripts/viz/trackster/tracks.js
--- a/static/scripts/viz/trackster/tracks.js
+++ b/static/scripts/viz/trackster/tracks.js
@@ -905,7 +905,7 @@
// Introduction div shown when there are no tracks.
this.intro_div = $("<div/>").addClass("intro").appendTo(this.viewport_container).hide();
var add_tracks_button = $("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function () {
- visualization.select_datasets(select_datasets_url, add_track_async_url, view.dbkey, function(tracks) {
+ visualization.select_datasets(select_datasets_url, add_track_async_url, { 'f-dbkey': view.dbkey }, function(tracks) {
_.each(tracks, function(track) {
view.add_drawable( object_from_template(track, view, view) );
});
diff -r 2c261f6401e9693cf7cc5d8749f9b59a9d9cee9e -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 static/scripts/viz/trackster_ui.js
--- a/static/scripts/viz/trackster_ui.js
+++ b/static/scripts/viz/trackster_ui.js
@@ -20,7 +20,7 @@
var self = this,
menu = create_icon_buttons_menu([
{ icon_class: 'plus-button', title: 'Add tracks', on_click: function() {
- visualization.select_datasets(select_datasets_url, add_track_async_url, view.dbkey, function(tracks) {
+ visualization.select_datasets(select_datasets_url, add_track_async_url, { 'f-dbkey': view.dbkey }, function(tracks) {
_.each(tracks, function(track) {
view.add_drawable( object_from_template(track, view, view) );
});
diff -r 2c261f6401e9693cf7cc5d8749f9b59a9d9cee9e -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 static/scripts/viz/visualization.js
--- a/static/scripts/viz/visualization.js
+++ b/static/scripts/viz/visualization.js
@@ -3,8 +3,6 @@
/**
* Model, view, and controller objects for Galaxy visualization framework.
- *
- * Required libraries: Backbone, jQuery
*
* Models have no references to views, instead using events to indicate state
* changes; this is advantageous because multiple views can use the same object
@@ -16,11 +14,10 @@
* track definitions are obtained from the server and the success_fn is called with the list of
* definitions for selected datasets.
*/
-var select_datasets = function(dataset_url, add_track_async_url, dbkey, success_fn) {
+var select_datasets = function(dataset_url, add_track_async_url, filters, success_fn) {
$.ajax({
url: dataset_url,
- // Filter by dbkey if available.
- data: ( dbkey ? { 'f-dbkey': dbkey } : {} ),
+ data: filters,
error: function() { alert( "Grid failed" ); },
success: function(table_html) {
show_modal(
https://bitbucket.org/galaxy/galaxy-central/changeset/6b0cc1c4f105/
changeset: 6b0cc1c4f105
user: jgoecks
date: 2012-10-23 17:09:19
summary: Automated merge
affected #: 34 files
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/admin/statistics.mako
--- a/templates/webapps/community/admin/statistics.mako
+++ b/templates/webapps/community/admin/statistics.mako
@@ -16,35 +16,35 @@
</tr><tr><td>Total repositories</td>
- <td>${trans.app.shed_counter.repositories}</td>
+ <td>${trans.app.shed_counter.repositories | h}</td></tr><tr><td>Empty repositories</td>
- <td>${trans.app.shed_counter.new_repositories}</td>
+ <td>${trans.app.shed_counter.new_repositories | h}</td></tr><tr><td>Deleted repositories</td>
- <td>${trans.app.shed_counter.deleted_repositories}</td>
+ <td>${trans.app.shed_counter.deleted_repositories | h}</td></tr><tr><td>Valid tools</td>
- <td>${trans.app.shed_counter.valid_tools}</td>
+ <td>${trans.app.shed_counter.valid_tools | h}</td></tr><tr><td>Invalid tools</td>
- <td>${trans.app.shed_counter.invalid_tools}</td>
+ <td>${trans.app.shed_counter.invalid_tools | h}</td></tr><tr><td>Workflows</td>
- <td>${trans.app.shed_counter.workflows}</td>
+ <td>${trans.app.shed_counter.workflows | h}</td></tr><tr><td>Proprietary datatypes</td>
- <td>${trans.app.shed_counter.proprietary_datatypes}</td>
+ <td>${trans.app.shed_counter.proprietary_datatypes | h}</td></tr><tr><td>Total clones</td>
- <td>${trans.app.shed_counter.total_clones}</td>
+ <td>${trans.app.shed_counter.total_clones | h}</td></tr></table></div>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/base_panels.mako
--- a/templates/webapps/community/base_panels.mako
+++ b/templates/webapps/community/base_panels.mako
@@ -50,10 +50,10 @@
${menu_item[0]}
%elif len ( menu_item ) == 2:
<% name, link = menu_item %>
- <a href="${link}">${name}</a>
+ <a href="${link}">${name | h}</a>
%else:
<% name, link, target = menu_item %>
- <a target="${target}" href="${link}">${name}</a>
+ <a target="${target}" href="${link}">${name | h}</a>
%endif
</li>
%endif
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/category/create_category.mako
--- a/templates/webapps/community/category/create_category.mako
+++ b/templates/webapps/community/category/create_category.mako
@@ -20,11 +20,11 @@
<form name="create_category_form" id="create_category_form" action="${h.url_for( action='create_category' )}" method="post" ><div class="form-row"><label>Name:</label>
- <input name="name" type="textfield" value="${name}" size=40"/>
+ <input name="name" type="textfield" value="${name | h}" size=40"/></div><div class="form-row"><label>Description:</label>
- <input name="description" type="textfield" value="${description}" size=40"/>
+ <input name="description" type="textfield" value="${description | h}" size=40"/></div><div class="form-row"><input type="submit" name="create_category_button" value="Save"/>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/category/edit_category.mako
--- a/templates/webapps/community/category/edit_category.mako
+++ b/templates/webapps/community/category/edit_category.mako
@@ -12,14 +12,14 @@
<div class="form-row"><label>Name:</label><div style="float: left; width: 250px; margin-right: 10px;">
- <input type="text" name="name" value="${category.name}" size="40"/>
+ <input type="text" name="name" value="${category.name | h}" size="40"/></div><div style="clear: both"></div></div><div class="form-row"><label>Description:</label><div style="float: left; width: 250px; margin-right: 10px;">
- <input name="description" type="textfield" value="${category.description}" size=40"/>
+ <input name="description" type="textfield" value="${category.description | h}" size=40"/></div><div style="clear: both"></div></div>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/category/grid.mako
--- a/templates/webapps/community/category/grid.mako
+++ b/templates/webapps/community/category/grid.mako
@@ -14,13 +14,13 @@
<ul class="manage-table-actions">
%if len( grid.global_actions ) < 4:
%for action in grid.global_actions:
- <li><a class="action-button" href="${h.url_for( **action.url_args )}">${action.label}</a></li>
+ <li><a class="action-button" href="${h.url_for( **action.url_args )}">${action.label | h}</a></li>
%endfor
%else:
<li><a class="action-button" id="action-8675309-popup" class="menubutton">Actions</a></li><div popupmenu="action-8675309-popup">
%for action in grid.global_actions:
- <a class="action-button" href="${h.url_for( **action.url_args )}">${action.label}</a>
+ <a class="action-button" href="${h.url_for( **action.url_args )}">${action.label | h}</a>
%endfor
</div>
%endif
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/category/valid_grid.mako
--- a/templates/webapps/community/category/valid_grid.mako
+++ b/templates/webapps/community/category/valid_grid.mako
@@ -13,13 +13,13 @@
<ul class="manage-table-actions">
%if len( grid.global_actions ) < 4:
%for action in grid.global_actions:
- <li><a class="action-button" href="${h.url_for( **action.url_args )}">${action.label}</a></li>
+ <li><a class="action-button" href="${h.url_for( **action.url_args )}">${action.label | h}</a></li>
%endfor
%else:
<li><a class="action-button" id="action-8675309-popup" class="menubutton">Actions</a></li><div popupmenu="action-8675309-popup">
%for action in grid.global_actions:
- <a class="action-button" href="${h.url_for( **action.url_args )}">${action.label}</a>
+ <a class="action-button" href="${h.url_for( **action.url_args )}">${action.label | h}</a>
%endfor
</div>
%endif
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/common/common.mako
--- a/templates/webapps/community/common/common.mako
+++ b/templates/webapps/community/common/common.mako
@@ -1,3 +1,11 @@
+<%def name="escape_html_add_breaks( value )">
+ <%
+ import markupsafe
+ value = str( markupsafe.escape( value ) ).replace( '\n', '<br/>' )
+ %>
+ ${value}
+</%def>
+
<%def name="render_star_rating( name, rating, disabled=False )"><%
if disabled:
@@ -15,7 +23,6 @@
</%def><%def name="render_readme( readme_text )">
- <% readme_text = readme_text.replace( '\n', '<br/>' ) %><style type="text/css">
#readme_table{ table-layout:fixed;
width:100%;
@@ -31,7 +38,7 @@
<div class="toolFormBody"><div class="form-row"><table id="readme_table">
- <tr><td>${readme_text}</td></tr>
+ <tr><td>${ escape_html_add_breaks( readme_text ) }</td></tr></table></div></div>
@@ -39,7 +46,6 @@
</%def><%def name="render_long_description( description_text )">
- <% description_text = description_text.replace( '\n', '<br/>' ) %><style type="text/css">
#description_table{ table-layout:fixed;
width:100%;
@@ -53,7 +59,7 @@
<div class="form-row"><label>Detailed description:</label><table id="description_table">
- <tr><td>${description_text}</td></tr>
+ <tr><td>${ escape_html_add_breaks( description_text ) }</td></tr></table><div style="clear: both"></div></div>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/common/view_readme.mako
--- a/templates/webapps/community/common/view_readme.mako
+++ b/templates/webapps/community/common/view_readme.mako
@@ -40,7 +40,7 @@
<a class="action-button" href="${h.url_for( controller='repository', action='rate_repository', id=trans.app.security.encode_id( repository.id ) )}">Rate repository</a>
%endif
%if can_browse_contents:
- <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label | h}</a>
%endif
%if can_contact_owner:
<a class="action-button" href="${h.url_for( controller='repository', action='contact_owner', id=trans.security.encode_id( repository.id ) )}">Contact repository owner</a>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/index.mako
--- a/templates/webapps/community/index.mako
+++ b/templates/webapps/community/index.mako
@@ -39,7 +39,7 @@
<%def name="left_panel()"><% can_review_repositories = trans.app.security_agent.user_can_review_repositories( trans.user ) %><div class="unified-panel-header" unselectable="on">
- <div class='unified-panel-header-inner'>${trans.app.shed_counter.valid_tools} valid tools on ${trans.app.shed_counter.generation_time}</div>
+ <div class='unified-panel-header-inner'>${trans.app.shed_counter.valid_tools | h} valid tools on ${trans.app.shed_counter.generation_time | h}</div></div><div class="page-container" style="padding: 10px;"><div class="toolMenu">
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository/browse_invalid_tools.mako
--- a/templates/webapps/community/repository/browse_invalid_tools.mako
+++ b/templates/webapps/community/repository/browse_invalid_tools.mako
@@ -24,9 +24,9 @@
${invalid_tool_config}
</a></td>
- <td>${repository_name}</td>
- <td>${repository_owner}</td>
- <td>${changeset_revision}</td>
+ <td>${repository_name | h}</td>
+ <td>${repository_owner | h}</td>
+ <td>${changeset_revision | h}</td></tr>
%endfor
</table>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository/browse_repository.mako
--- a/templates/webapps/community/repository/browse_repository.mako
+++ b/templates/webapps/community/repository/browse_repository.mako
@@ -101,7 +101,7 @@
%if can_browse_contents:
<div class="toolForm">
- <div class="toolFormTitle">Browse ${repository.name} revision ${repository.tip} (repository tip)</div>
+ <div class="toolFormTitle">Browse ${repository.name | h} revision ${repository.tip | h} (repository tip)</div>
%if can_download:
<div class="form-row"><label>Clone this repository:</label>
@@ -124,7 +124,7 @@
<label>Message:</label><div class="form-row-input">
%if commit_message:
- <textarea name="commit_message" rows="3" cols="35">${commit_message}</textarea>
+ <textarea name="commit_message" rows="3" cols="35">${commit_message | h}</textarea>
%else:
<textarea name="commit_message" rows="3" cols="35"></textarea>
%endif
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository/common.mako
--- a/templates/webapps/community/repository/common.mako
+++ b/templates/webapps/community/repository/common.mako
@@ -126,9 +126,9 @@
type = requirements_dict[ 'type' ]
%><tr>
- <td>${name}</td>
- <td>${version}</td>
- <td>${type}</td>
+ <td>${name | h}</td>
+ <td>${version | h}</td>
+ <td>${type | h}</td></tr>
%endif
%endfor
@@ -154,8 +154,8 @@
<% environment_settings = tool_dependencies[ 'set_environment' ] %>
%for requirements_dict in environment_settings:
<tr>
- <td>${requirements_dict[ 'name' ]}</td>
- <td>${requirements_dict[ 'type' ]}</td>
+ <td>${requirements_dict[ 'name' ] | h}</td>
+ <td>${requirements_dict[ 'type' ] | h}</td></tr>
%endfor
</table>
@@ -190,8 +190,8 @@
<a class="action-button" href="${h.url_for( controller='repository', action='view_tool_metadata', repository_id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision, tool_id=tool_dict[ 'id' ] )}">View tool metadata</a></div></td>
- <td>${tool_dict[ 'description' ]}</td>
- <td>${tool_dict[ 'version' ]}</td>
+ <td>${tool_dict[ 'description' ] | h}</td>
+ <td>${tool_dict[ 'version' ] | h}</td><td><%
if 'requirements' in tool_dict:
@@ -206,7 +206,7 @@
requirements_str += '%s (%s), ' % ( requirement_dict[ 'name' ], requirement_dict[ 'type' ] )
requirements_str = requirements_str.rstrip( ', ' )
%>
- ${requirements_str}
+ ${requirements_str | h}
%else:
none
%endif
@@ -233,7 +233,7 @@
<tr><td><a class="view-info" href="${h.url_for( controller='repository', action='load_invalid_tool', repository_id=trans.security.encode_id( repository.id ), tool_config=invalid_tool_config, changeset_revision=changeset_revision )}">
- ${invalid_tool_config}
+ ${invalid_tool_config | h}
</a></td></tr>
@@ -274,7 +274,7 @@
%><tr><td>
- <a href="${h.url_for( controller='workflow', action='view_workflow', repository_metadata_id=repository_metadata_id, workflow_name=tool_shed_encode( workflow_name ) )}">${workflow_name}</a>
+ <a href="${h.url_for( controller='workflow', action='view_workflow', repository_metadata_id=repository_metadata_id, workflow_name=tool_shed_encode( workflow_name ) )}">${workflow_name | h}</a></td><td>
%if steps:
@@ -283,8 +283,8 @@
unknown
%endif
</td>
- <td>${format_version}</td>
- <td>${annotation}</td>
+ <td>${format_version | h}</td>
+ <td>${annotation | h}</td></tr>
%endfor
</table>
@@ -317,10 +317,10 @@
subclass = datatypes_dict.get( 'subclass', ' ' )
%><tr>
- <td>${extension}</td>
- <td>${dtype}</td>
- <td>${mimetype}</td>
- <td>${subclass}</td>
+ <td>${extension | h}</td>
+ <td>${dtype | h}</td>
+ <td>${mimetype | h}</td>
+ <td>${subclass | h}</td></tr>
%endfor
</table>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository/contact_owner.mako
--- a/templates/webapps/community/repository/contact_owner.mako
+++ b/templates/webapps/community/repository/contact_owner.mako
@@ -50,7 +50,7 @@
<a class="action-button" href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">View change log</a>
%endif
%if can_browse_contents:
- <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label | h}</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=repository.tip, file_type='gz' )}">Download as a .tar.gz file</a>
@@ -66,7 +66,7 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">Contact the owner of the repository named '${repository.name}'</div>
+ <div class="toolFormTitle">Contact the owner of the repository named '${repository.name | h}'</div><div class="toolFormBody"><div class="form-row">
This feature is intended to streamline appropriate communication between
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository/create_repository.mako
--- a/templates/webapps/community/repository/create_repository.mako
+++ b/templates/webapps/community/repository/create_repository.mako
@@ -20,18 +20,18 @@
<form name="create_repository_form" id="create_repository_form" action="${h.url_for( controller='repository', action='create_repository' )}" method="post" ><div class="form-row"><label>Name:</label>
- <input name="name" type="textfield" value="${name}" size="40"/>
+ <input name="name" type="textfield" value="${name | h}" size="40"/><div style="clear: both"></div></div><div class="form-row"><label>Synopsis:</label>
- <input name="description" type="textfield" value="${description}" size="80"/>
+ <input name="description" type="textfield" value="${description | h}" size="80"/><div style="clear: both"></div></div><div class="form-row"><label>Detailed description:</label>
%if long_description:
- <pre><textarea name="long_description" rows="3" cols="80">${long_description}</textarea></pre>
+ <pre><textarea name="long_description" rows="3" cols="80">${long_description | h}</textarea></pre>
%else:
<textarea name="long_description" rows="3" cols="80"></textarea>
%endif
@@ -43,9 +43,9 @@
<select name="category_id" multiple>
%for category in categories:
%if category.id in selected_categories:
- <option value="${trans.security.encode_id( category.id )}" selected>${category.name}</option>
+ <option value="${trans.security.encode_id( category.id )}" selected>${category.name | h}</option>
%else:
- <option value="${trans.security.encode_id( category.id )}">${category.name}</option>
+ <option value="${trans.security.encode_id( category.id )}">${category.name | h}</option>
%endif
%endfor
</select>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository/find_tools.mako
--- a/templates/webapps/community/repository/find_tools.mako
+++ b/templates/webapps/community/repository/find_tools.mako
@@ -35,17 +35,17 @@
<form name="find_tools" id="find_tools" action="${h.url_for( controller='repository', action='find_tools' )}" method="post" ><div class="form-row"><label>Tool id:</label>
- <input name="tool_id" type="textfield" value="${tool_id}" size="40"/>
+ <input name="tool_id" type="textfield" value="${tool_id | h}" size="40"/></div><div style="clear: both"></div><div class="form-row"><label>Tool name:</label>
- <input name="tool_name" type="textfield" value="${tool_name}" size="40"/>
+ <input name="tool_name" type="textfield" value="${tool_name | h}" size="40"/></div><div style="clear: both"></div><div class="form-row"><label>Tool version:</label>
- <input name="tool_version" type="textfield" value="${tool_version}" size="40"/>
+ <input name="tool_version" type="textfield" value="${tool_version | h}" size="40"/></div><div style="clear: both"></div><div class="form-row">
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository/find_workflows.mako
--- a/templates/webapps/community/repository/find_workflows.mako
+++ b/templates/webapps/community/repository/find_workflows.mako
@@ -34,7 +34,7 @@
<div style="clear: both"></div><div class="form-row"><label>Workflow name:</label>
- <input name="workflow_name" type="textfield" value="${workflow_name}" size="40"/>
+ <input name="workflow_name" type="textfield" value="${workflow_name | h}" size="40"/></div><div style="clear: both"></div><div class="form-row">
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository/manage_repository.mako
--- a/templates/webapps/community/repository/manage_repository.mako
+++ b/templates/webapps/community/repository/manage_repository.mako
@@ -82,7 +82,7 @@
<a class="action-button" href="${h.url_for( controller='repository', action='rate_repository', id=trans.app.security.encode_id( repository.id ) )}">Rate repository</a>
%endif
%if can_browse_contents:
- <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label | h}</a>
%endif
%if can_contact_owner:
<a class="action-button" href="${h.url_for( controller='repository', action='contact_owner', id=trans.security.encode_id( repository.id ) )}">Contact repository owner</a>
@@ -137,7 +137,7 @@
<p/>
%endif
<div class="toolForm">
- <div class="toolFormTitle">Repository '${repository.name}'</div>
+ <div class="toolFormTitle">Repository '${repository.name | h}'</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:
@@ -151,7 +151,7 @@
%if repository.times_downloaded > 0:
${repository.name}
%else:
- <input name="repo_name" type="textfield" value="${repository.name}" size="40"/>
+ <input name="repo_name" type="textfield" value="${repository.name | h}" size="40"/>
%endif
<div class="toolParamHelp" style="clear: both;">
Repository names cannot be changed if the repository has been cloned.
@@ -160,13 +160,13 @@
</div><div class="form-row"><label>Synopsis:</label>
- <input name="description" type="textfield" value="${description}" size="80"/>
+ <input name="description" type="textfield" value="${description | h}" size="80"/><div style="clear: both"></div></div><div class="form-row"><label>Detailed description:</label>
%if long_description:
- <pre><textarea name="long_description" rows="3" cols="80">${long_description}</textarea></pre>
+ <pre><textarea name="long_description" rows="3" cols="80">${long_description | h}</textarea></pre>
%else:
<textarea name="long_description" rows="3" cols="80"></textarea>
%endif
@@ -175,27 +175,27 @@
<div class="form-row"><label>Revision:</label>
%if can_view_change_log:
- <a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${revision_label}</a>
+ <a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${revision_label | h}</a>
%else:
- ${revision_label}
+ ${revision_label | h}
%endif
</div><div class="form-row"><label>Owner:</label>
- ${repository.user.username}
+ ${repository.user.username | h}
</div><div class="form-row"><label>Times downloaded:</label>
- ${repository.times_downloaded}
+ ${repository.times_downloaded | h}
</div>
%if is_admin:
<div class="form-row"><label>Location:</label>
- ${repository.repo_path}
+ ${repository.repo_path | h}
</div><div class="form-row"><label>Deleted:</label>
- ${repository.deleted}
+ ${repository.deleted | h}
</div>
%endif
<div class="form-row">
@@ -215,9 +215,9 @@
<select name="category_id" multiple>
%for category in categories:
%if category.id in selected_categories:
- <option value="${trans.security.encode_id( category.id )}" selected>${category.name}</option>
+ <option value="${trans.security.encode_id( category.id )}" selected>${category.name | h}</option>
%else:
- <option value="${trans.security.encode_id( category.id )}">${category.name}</option>
+ <option value="${trans.security.encode_id( category.id )}">${category.name | h}</option>
%endif
%endfor
</select>
@@ -258,14 +258,14 @@
<div class="toolFormBody"><table class="grid"><tr>
- <td>${repository.user.username}</td>
+ <td>${repository.user.username | h}</td><td>owner</td><td> </td></tr>
%for username in current_allow_push_list:
%if username != repository.user.username:
<tr>
- <td>${username}</td>
+ <td>${username | h}</td><td>write</td><td><a class="action-button" href="${h.url_for( controller='repository', action='manage_repository', id=trans.security.encode_id( repository.id ), user_access_button='Remove', remove_auth=username )}">remove</a></tr>
@@ -295,7 +295,7 @@
<div class="toolFormBody"><div class="form-row"><label>Times Rated:</label>
- ${num_ratings}
+ ${num_ratings | h}
<div style="clear: both"></div></div><div class="form-row">
@@ -329,9 +329,9 @@
%><tr><td>${render_star_rating( name, review.rating, disabled=True )}</td>
- <td><pre>${review.comment}</pre></td>
+ <td><pre>${review.comment | h}</pre></td><td>${time_ago( review.update_time )}</td>
- <td>${review.user.username}</td>
+ <td>${review.user.username | h}</td></tr>
%endfor
</table>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository/preview_tools_in_changeset.mako
--- a/templates/webapps/community/repository/preview_tools_in_changeset.mako
+++ b/templates/webapps/community/repository/preview_tools_in_changeset.mako
@@ -53,7 +53,7 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">Repository ${repository.name}</div>
+ <div class="toolFormTitle">Repository ${repository.name | h}</div><div class="toolFormBody">
%if len( changeset_revision_select_field.options ) > 1:
<form name="change_revision" id="change_revision" action="${h.url_for( controller='repository', action='preview_tools_in_changeset', repository_id=trans.security.encode_id( repository.id ) )}" method="post" >
@@ -64,7 +64,7 @@
else:
tip_str = ''
%>
- ${changeset_revision_select_field.get_html()} <i>${tip_str}</i>
+ ${changeset_revision_select_field.get_html()} <i>${tip_str | h}</i><div class="toolParamHelp" style="clear: both;">
Select a revision to inspect and download versions of tools from this repository.
</div>
@@ -73,7 +73,7 @@
%else:
<div class="form-row"><label>Revision:</label>
- ${revision_label}
+ ${revision_label | h}
</div>
%endif
</div>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository/rate_repository.mako
--- a/templates/webapps/community/repository/rate_repository.mako
+++ b/templates/webapps/community/repository/rate_repository.mako
@@ -91,7 +91,7 @@
<a class="action-button" href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">View change log</a>
%endif
%if can_browse_contents:
- <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label | h}</a>
%endif
%if can_contact_owner:
<a class="action-button" href="${h.url_for( controller='repository', action='contact_owner', id=trans.security.encode_id( repository.id ) )}">Contact repository owner</a>
@@ -107,7 +107,7 @@
%if repository.user != trans.user:
<div class="toolForm">
- <div class="toolFormTitle">${repository.name}</div>
+ <div class="toolFormTitle">${repository.name | h}</div>
%if can_download:
<div class="form-row"><label>Clone this repository:</label>
@@ -117,17 +117,17 @@
<div class="toolFormBody"><div class="form-row"><label>Description:</label>
- ${repository.description}
+ ${repository.description | h}
<div style="clear: both"></div></div><div class="form-row"><label>Version:</label>
- ${repository.revision}
+ ${repository.revision | h}
<div style="clear: both"></div></div><div class="form-row"><label>Owner:</label>
- ${repository.user.username}
+ ${repository.user.username | h}
<div style="clear: both"></div></div></div>
@@ -139,7 +139,7 @@
<form id="rate_repository" name="rate_repository" action="${h.url_for( controller='repository', action='rate_repository', id=trans.security.encode_id( repository.id ) )}" method="post"><div class="form-row"><label>Times Rated:</label>
- ${num_ratings}
+ ${num_ratings | h}
<div style="clear: both"></div></div><div class="form-row">
@@ -162,7 +162,7 @@
<label>Review:</label>
%if rra and rra.comment:
<div class="form-row-input">
- <pre><textarea name="comment" rows="5" cols="80">${rra.comment}</textarea></pre>
+ <pre><textarea name="comment" rows="5" cols="80">${rra.comment | h}</textarea></pre></div>
%else:
<div class="form-row-input">
@@ -202,9 +202,9 @@
%><tr><td>${render_star_rating( name, review.rating, disabled=True )}</td>
- <td><pre>${review.comment}</pre></td>
+ <td><pre>${review.comment | h}</pre></td><td>${time_ago( review.update_time )}</td>
- <td>${review.user.username}</td>
+ <td>${review.user.username | h}</td></tr>
%endfor
</table>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository/tool_form.mako
--- a/templates/webapps/community/repository/tool_form.mako
+++ b/templates/webapps/community/repository/tool_form.mako
@@ -177,8 +177,8 @@
%endif
%if tool:
- <div class="toolForm" id="${tool.id}">
- <div class="toolFormTitle">${tool.name} (version ${tool.version})</div>
+ <div class="toolForm" id="${tool.id | h}">
+ <div class="toolFormTitle">${tool.name | h} (version ${tool.version | h})</div><div class="toolFormBody"><form id="tool_form" name="tool_form" action="" method="get"><input type="hidden" name="tool_state" value="${util.object_to_string( tool_state.encode( tool, app ) )}">
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository/upload.mako
--- a/templates/webapps/community/repository/upload.mako
+++ b/templates/webapps/community/repository/upload.mako
@@ -82,7 +82,7 @@
<div class="form-row"><label>Url:</label><div class="form-row-input">
- <input name="url" type="textfield" value="${url}" size="40"/>
+ <input name="url" type="textfield" value="${url | h}" size="40"/></div><div class="toolParamHelp" style="clear: both;">
Enter a URL to upload your files via http.
@@ -141,7 +141,7 @@
<label>Change set commit message:</label><div class="form-row-input">
%if commit_message:
- <pre><textarea name="commit_message" rows="3" cols="35">${commit_message}</textarea></pre>
+ <pre><textarea name="commit_message" rows="3" cols="35">${commit_message | h}</textarea></pre>
%else:
<textarea name="commit_message" rows="3" cols="35"></textarea>
%endif
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository/view_changelog.mako
--- a/templates/webapps/community/repository/view_changelog.mako
+++ b/templates/webapps/community/repository/view_changelog.mako
@@ -78,7 +78,7 @@
%if can_download:
<div class="toolForm">
- <div class="toolFormTitle">${repository.name}</div>
+ <div class="toolFormTitle">${repository.name | h}</div><div class="toolFormBody"><div class="form-row"><label>Clone this repository:</label>
@@ -95,7 +95,7 @@
else:
title_str = '%s changesets' % repository.name
%>
- <div class="toolFormTitle">${title_str}</div>
+ <div class="toolFormTitle">${title_str | h}</div><% test_date = None %><div class="toolFormBody"><table class="grid">
@@ -128,23 +128,23 @@
%endif
<div class="form-row"><label>Description:</label>
- <a href="${h.url_for( controller='repository', action='view_changeset', id=trans.security.encode_id( repository.id ), ctx_str=ctx_str )}">${changeset[ 'description' ]}</a>
+ <a href="${h.url_for( controller='repository', action='view_changeset', id=trans.security.encode_id( repository.id ), ctx_str=ctx_str )}">${changeset[ 'description' ] | h}</a></div><div class="form-row"><label>Commit:</label>
- <a href="${h.url_for( controller='repository', action='view_changeset', id=trans.security.encode_id( repository.id ), ctx_str=ctx_str )}">${changeset_str}</a>
+ <a href="${h.url_for( controller='repository', action='view_changeset', id=trans.security.encode_id( repository.id ), ctx_str=ctx_str )}">${changeset_str | h}</a></div><div class="form-row"><label>Parent:</label>
%if ctx_parent_str == 'None':
${ctx_parent_str}
%else:
- <a href="${h.url_for( controller='repository', action='view_changeset', id=trans.security.encode_id( repository.id ), ctx_str=ctx_parent )}">${ctx_parent_str}</a>
+ <a href="${h.url_for( controller='repository', action='view_changeset', id=trans.security.encode_id( repository.id ), ctx_str=ctx_parent )}">${ctx_parent_str | h}</a>
%endif
</div><div class="form-row"><label>Commited by:</label>
- ${changeset[ 'user' ].split()[0]}
+ ${changeset[ 'user' ].split()[0] | h}
</div><div class="form-row"><label>Pushed:</label>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository/view_changeset.mako
--- a/templates/webapps/community/repository/view_changeset.mako
+++ b/templates/webapps/community/repository/view_changeset.mako
@@ -82,7 +82,7 @@
%if can_download:
<div class="toolForm">
- <div class="toolFormTitle">${repository.name}</div>
+ <div class="toolFormTitle">${repository.name | h}</div><div class="toolFormBody"><div class="form-row"><label>Clone this repository:</label>
@@ -99,7 +99,7 @@
else:
title_str = '%s changeset %s' % ( repository.name, ctx )
%>
- <div class="toolFormTitle">${title_str}</div>
+ <div class="toolFormTitle">${title_str | h}</div><div class="toolFormBody"><table class="grid">
%if modified:
@@ -107,7 +107,7 @@
<td><b>modified:</b>
%for item in modified:
- <br/><a href="#${item}">${item}</a>
+ <br/><a href="#${item}">${item | h}</a>
%endfor
</td></tr>
@@ -117,7 +117,7 @@
<td><b>added:</b>
%for item in added:
- <br/><a href="#${item}">${item}</a>
+ <br/><a href="#${item}">${item | h}</a>
%endfor
</td></tr>
@@ -127,7 +127,7 @@
<td><b>removed:</b>
%for item in removed:
- <br/><a href="#${item}">${item}</a>
+ <br/><a href="#${item}">${item | h}</a>
%endfor
</td></tr>
@@ -137,7 +137,7 @@
<td><b>deleted:</b>
%for item in deleted:
- <br/><a href="#${item}">${item}</a>
+ <br/><a href="#${item}">${item | h}</a>
%endfor
</td></tr>
@@ -147,7 +147,7 @@
<td><b>unknown:</b>
%for item in unknown:
- <br/><a href="#${item}">${item}</a>
+ <br/><a href="#${item}">${item | h}</a>
%endfor
}</td></tr>
@@ -157,7 +157,7 @@
<td><b>ignored:</b>
%for item in ignored:
- <br/><a href="#${item}">${item}</a>
+ <br/><a href="#${item}">${item | h}</a>
%endfor
</td></tr>
@@ -167,7 +167,7 @@
<td>
clean:
%for item in clean:
- <br/><a href="#${item}">${item}</a>
+ <br/><a href="#${item}">${item | h}</a>
%endfor
</td></tr>
@@ -177,7 +177,6 @@
# Read at most the first 10 lines of diff to determine the anchor
ctr = 0
lines = diff.split( '\n' )
- diff = diff.replace( '\n', '<br/>' )
anchor_str = ''
for line in lines:
if ctr > 9:
@@ -189,7 +188,7 @@
ctr += 1
%><tr><td bgcolor="#E0E0E0">${anchor_str}</td></tr>
- <tr><td>${diff}</td></tr>
+ <tr><td>${ escape_html_add_breaks( diff ) }</td></tr>
%endfor
</table></div>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository/view_repository.mako
--- a/templates/webapps/community/repository/view_repository.mako
+++ b/templates/webapps/community/repository/view_repository.mako
@@ -143,12 +143,12 @@
%if can_browse_contents:
<a href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${repository.name}</a>
%else:
- ${repository.name}
+ ${repository.name | h}
%endif
</div><div class="form-row"><label>Synopsis:</label>
- ${repository.description}
+ ${repository.description | h}
</div>
%if repository.long_description:
${render_long_description( repository.long_description )}
@@ -158,12 +158,12 @@
%if can_view_change_log:
<a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${revision_label}</a>
%else:
- ${revision_label}
+ ${revision_label | h}
%endif
</div><div class="form-row"><label>Owner:</label>
- ${repository.user.username}
+ ${repository.user.username | h}
</div><div class="form-row"><label>Times downloaded:</label>
@@ -172,7 +172,7 @@
%if trans.user_is_admin():
<div class="form-row"><label>Location:</label>
- ${repository.repo_path}
+ ${repository.repo_path | h}
</div><div class="form-row"><label>Deleted:</label>
@@ -189,7 +189,7 @@
<div class="toolFormBody">
%for rca in repository.categories:
<div class="form-row">
- ${rca.category.name}
+ ${rca.category.name | h}
</div>
%endfor
<div style="clear: both"></div>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a 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
@@ -140,35 +140,35 @@
%if 'description' in tool_metadata_dict:
<div class="form-row"><label>Description:</label>
- ${tool_metadata_dict[ 'description' ]}
+ ${tool_metadata_dict[ 'description' ] | h}
<div style="clear: both"></div></div>
%endif
%if 'id' in tool_metadata_dict:
<div class="form-row"><label>Id:</label>
- ${tool_metadata_dict[ 'id' ]}
+ ${tool_metadata_dict[ 'id' ] | h}
<div style="clear: both"></div></div>
%endif
%if 'guid' in tool_metadata_dict:
<div class="form-row"><label>Guid:</label>
- ${tool_metadata_dict[ 'guid' ]}
+ ${tool_metadata_dict[ 'guid' ] | h}
<div style="clear: both"></div></div>
%endif
%if 'version' in tool_metadata_dict:
<div class="form-row"><label>Version:</label>
- ${tool_metadata_dict[ 'version' ]}
+ ${tool_metadata_dict[ 'version' ] | h}
<div style="clear: both"></div></div>
%endif
%if 'version_string_cmd' in tool_metadata_dict:
<div class="form-row"><label>Version command string:</label>
- ${tool_metadata_dict[ 'version_string_cmd' ]}
+ ${tool_metadata_dict[ 'version_string_cmd' ] | h}
<div style="clear: both"></div></div>
%endif
@@ -184,9 +184,9 @@
<tr><td>
%if guid == tool_metadata_dict[ 'guid' ]:
- ${guid} <b>(this tool)</b>
+ ${guid | h} <b>(this tool)</b>
%else:
- ${guid}
+ ${guid | h}
%endif
</td></tr>
@@ -224,9 +224,9 @@
requirement_type = requirement_dict[ 'type' ] or 'not provided'
%><tr>
- <td>${requirement_name}</td>
- <td>${requirement_version}</td>
- <td>${requirement_type}</td>
+ <td>${requirement_name | h}</td>
+ <td>${requirement_version | h}</td>
+ <td>${requirement_type | h}</td></tr>
%endfor
</table>
@@ -245,27 +245,27 @@
</div><div class="form-row"><label>Command:</label>
- <pre>${tool.command}</pre>
+ <pre>${tool.command | h}</pre><div style="clear: both"></div></div><div class="form-row"><label>Interpreter:</label>
- ${tool.interpreter}
+ ${tool.interpreter | h}
<div style="clear: both"></div></div><div class="form-row"><label>Is multi-byte:</label>
- ${tool.is_multi_byte}
+ ${tool.is_multi_byte | h}
<div style="clear: both"></div></div><div class="form-row"><label>Forces a history refresh:</label>
- ${tool.force_history_refresh}
+ ${tool.force_history_refresh | h}
<div style="clear: both"></div></div><div class="form-row"><label>Parallelism:</label>
- ${tool.parallelism}
+ ${tool.parallelism | h}
<div style="clear: both"></div></div>
%endif
@@ -299,17 +299,17 @@
<td>${test_dict[ 'name' ]}</td><td>
%for input in inputs:
- <b>${input[0]}:</b> ${input[1]}<br/>
+ <b>${input[0]}:</b> ${input[1] | h}<br/>
%endfor
</td><td>
%for output in outputs:
- <b>${output[0]}:</b> ${output[1]}<br/>
+ <b>${output[0]}:</b> ${output[1] | h}<br/>
%endfor
</td><td>
%for required_file in required_files:
- ${required_file}<br/>
+ ${required_file | h}<br/>
%endfor
</td></tr>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository/view_workflow.mako
--- a/templates/webapps/community/repository/view_workflow.mako
+++ b/templates/webapps/community/repository/view_workflow.mako
@@ -96,7 +96,7 @@
${render_msg( message, status )}
%endif
-<div class="toolFormTitle">${workflow_name}</div>
+<div class="toolFormTitle">${workflow_name | h}</div><div class="form-row"><b>Boxes are red when tools are not available in this repository</b><div class="toolParamHelp" style="clear: both;">
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository_review/browse_review.mako
--- a/templates/webapps/community/repository_review/browse_review.mako
+++ b/templates/webapps/community/repository_review/browse_review.mako
@@ -34,7 +34,7 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">Review of repository '${repository.name}'</div>
+ <div class="toolFormTitle">Review of repository '${repository.name | h}'</div><div class="toolFormBody"><div class="form-row"><label>Reviewer:</label>
@@ -43,17 +43,17 @@
</div><div class="form-row"><label>Repository revision:</label>
- <a class="action-button" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=review.changeset_revision )}">${changeset_revision_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=review.changeset_revision )}">${changeset_revision_label | h}</a><div style="clear: both"></div></div><div class="form-row"><label>Repository owner:</label>
- ${repository.user.username}
+ ${repository.user.username | h}
<div style="clear: both"></div></div><div class="form-row"><label>Repository synopsis:</label>
- ${repository.description}
+ ${repository.description | h}
<div style="clear: both"></div></div><div class="form-row">
@@ -70,11 +70,10 @@
# Initialize star rating.
rating_name = '%s%srating' % ( component.name, STRSEP )
- review_comment = component_review.comment.replace( '\n', '<br/>' )
%><tr>
- <td bgcolor="#D8D8D8"><b>${component.name}</b></td>
- <td bgcolor="#D8D8D8">${component.description}</td>
+ <td bgcolor="#D8D8D8"><b>${component.name | h}</b></td>
+ <td bgcolor="#D8D8D8">${component.description | h}</td></tr><tr><td colspan="2">
@@ -93,7 +92,7 @@
<tr><td><div overflow-wrap:normal;overflow:hidden;word-break:keep-all;word-wrap:break-word;line-break:strict;>
- ${review_comment}
+ ${ escape_html_add_breaks( component_review.comment ) }
</div></td></tr>
@@ -101,7 +100,7 @@
<tr><td><label>Approved:</label>
- ${component_review.approved}
+ ${component_review.approved | h}
<div style="clear: both"></div></td></tr>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository_review/create_component.mako
--- a/templates/webapps/community/repository_review/create_component.mako
+++ b/templates/webapps/community/repository_review/create_component.mako
@@ -20,11 +20,11 @@
<form name="create_component" id="create_component" action="${h.url_for( controller='repository_review', action='create_component' )}" method="post" ><div class="form-row"><label>Name:</label>
- <input name="name" type="textfield" value="${name}" size=40"/>
+ <input name="name" type="textfield" value="${name | h}" size=40"/></div><div class="form-row"><label>Description:</label>
- <input name="description" type="textfield" value="${description}" size=40"/>
+ <input name="description" type="textfield" value="${description | h}" size=40"/></div><div class="form-row"><input type="submit" name="create_component_button" value="Save"/>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository_review/edit_component.mako
--- a/templates/webapps/community/repository_review/edit_component.mako
+++ b/templates/webapps/community/repository_review/edit_component.mako
@@ -12,14 +12,14 @@
<div class="form-row"><label>Name:</label><div style="float: left; width: 250px; margin-right: 10px;">
- ${component.name}
+ ${component.name | h}
</div><div style="clear: both"></div></div><div class="form-row"><label>Description:</label><div style="float: left; width: 250px; margin-right: 10px;">
- <input name="description" type="textfield" value="${component.description}" size=40"/>
+ <input name="description" type="textfield" value="${component.description | h}" size=40"/></div><div style="clear: both"></div></div>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository_review/edit_review.mako
--- a/templates/webapps/community/repository_review/edit_review.mako
+++ b/templates/webapps/community/repository_review/edit_review.mako
@@ -35,7 +35,7 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">My review of repository '${repository.name}'</div>
+ <div class="toolFormTitle">My review of repository '${repository.name | h}'</div><div class="toolFormBody"><form name="edit_review" action="${h.url_for( controller='repository_review', action='edit_review', id=trans.security.encode_id( review.id ) )}" method="post" ><div class="form-row">
@@ -45,12 +45,12 @@
</div><div class="form-row"><label>Repository owner:</label>
- ${repository.user.username}
+ ${repository.user.username | h}
<div style="clear: both"></div></div><div class="form-row"><label>Repository synopsis:</label>
- ${repository.description}
+ ${repository.description | h}
<div style="clear: both"></div></div><div class="form-row">
@@ -108,8 +108,8 @@
review_button_name = '%s%sreview_button' % ( component_name, STRSEP )
%><tr>
- <td bgcolor="#D8D8D8"><b>${component.name}</b></td>
- <td bgcolor="#D8D8D8">${component.description}</td>
+ <td bgcolor="#D8D8D8"><b>${component.name | h}</b></td>
+ <td bgcolor="#D8D8D8">${component.description | h}</td></tr><tr><td colspan="2">
@@ -128,7 +128,7 @@
<td><label>Comments:</label>
%if component_review:
- <pre><textarea name="${comment_name}" rows="3" cols="80">${comment}</textarea></pre>
+ <pre><textarea name="${comment_name}" rows="3" cols="80">${comment | h}</textarea></pre>
%else:
<textarea name="${comment_name}" rows="3" cols="80"></textarea>
%endif
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository_review/reviews_of_changeset_revision.mako
--- a/templates/webapps/community/repository_review/reviews_of_changeset_revision.mako
+++ b/templates/webapps/community/repository_review/reviews_of_changeset_revision.mako
@@ -73,16 +73,16 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">Revision reviews of repository '${repository.name}'</div>
+ <div class="toolFormTitle">Revision reviews of repository '${repository.name | h}'</div><div class="toolFormBody"><div class="form-row"><label>Revision:</label>
- <a class="action-button" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">${changeset_revision_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">${changeset_revision_label | h}</a><div style="clear: both"></div></div><div class="form-row"><label>Revision is installable:</label>
- ${installable_str}
+ ${installable_str | h}
<div style="clear: both"></div></div><div class="form-row">
@@ -109,7 +109,7 @@
<tr><td><div style="float:left;" class="menubutton split popup" id="${encoded_review_id}-popup">
- <a class="view-info" href="${h.url_for( controller='repository_review', action='repository_reviews_by_user', id=trans.security.encode_id( review.user.id ) )}">${review.user.username}</a>
+ <a class="view-info" href="${h.url_for( controller='repository_review', action='repository_reviews_by_user', id=trans.security.encode_id( review.user.id ) )}">${review.user.username | h}</a></div><div popupmenu="${encoded_review_id}-popup">
%if review.user == trans.user:
@@ -126,7 +126,7 @@
<td><input type="submit" name="approve_repository_review_button" value="Save"/></td></form>
%else:
- <td>${approved_str}</td>
+ <td>${approved_str | h}</td><td></td>
%endif
</tr>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository_review/reviews_of_repository.mako
--- a/templates/webapps/community/repository_review/reviews_of_repository.mako
+++ b/templates/webapps/community/repository_review/reviews_of_repository.mako
@@ -55,7 +55,7 @@
<a class="action-button" href="${h.url_for( controller='repository', action='rate_repository', id=trans.security.encode_id( repository.id ) )}">Rate repository</a>
%endif
%if can_browse_contents:
- <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">${browse_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">${browse_label | h}</a>
%endif
%if can_contact_owner:
<a class="action-button" href="${h.url_for( controller='repository', action='contact_owner', id=trans.security.encode_id( repository.id ) )}">Contact repository owner</a>
@@ -68,7 +68,7 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">${title}</div>
+ <div class="toolFormTitle">${title | h}</div><div class="toolFormBody"><div class="form-row"><table class="grid">
@@ -102,7 +102,7 @@
<tr><td><div style="float:left;" class="menubutton split popup" id="${changeset_revision}-popup">
- <a class="view-info" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">${changeset_revision_label}</a>
+ <a class="view-info" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">${changeset_revision_label | h}</a></div><div popupmenu="${changeset_revision}-popup">
%if repository_reviews:
@@ -113,7 +113,7 @@
</div></td><td>${reviewers_str}</td>
- <td>${installable_str}</td>
+ <td>${installable_str | h}</td></tr>
%endfor
</table>
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/repository_review/select_previous_review.mako
--- a/templates/webapps/community/repository_review/select_previous_review.mako
+++ b/templates/webapps/community/repository_review/select_previous_review.mako
@@ -67,23 +67,23 @@
%endif
<div class="warningmessage">
- You have elected to create a new review for revision <b>${changeset_revision_label}</b>of this repository. Since previous revisions have been reviewed,
+ You have elected to create a new review for revision <b>${changeset_revision_label | h}</b>of this repository. Since previous revisions have been reviewed,
you can select a previous review to copy to your new review, or click the <b>Create a review without copying</b> button.
</div><div class="toolForm">
- <div class="toolFormTitle">Select previous revision review of repository '${repository.name}'</div>
+ <div class="toolFormTitle">Select previous revision review of repository '${repository.name | h}'</div><div class="toolFormBody"><div class="form-row"><label>Revision for new review:</label>
- <a class="action-button" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">${changeset_revision_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">${changeset_revision_label | h}</a><div style="clear: both"></div></div><div class="form-row"><table class="grid"><tr></tr>
- <td bgcolor="#D8D8D8" colspan="4"><b>Previous revision reviews of repository '${repository.name}' that can be copied to your new review</b></td>
+ <td bgcolor="#D8D8D8" colspan="4"><b>Previous revision reviews of repository '${repository.name | h}' that can be copied to your new review</b></td><tr><th>Reviewer</th><th>Revision reviewed</th>
@@ -107,15 +107,15 @@
<tr><td><div style="float:left;" class="menubutton split popup" id="${encoded_review_id}-popup">
- <a class="view-info" href="${h.url_for( controller='repository_review', action='browse_review', id=encoded_review_id )}">${review.user.username}</a>
+ <a class="view-info" href="${h.url_for( controller='repository_review', action='browse_review', id=encoded_review_id )}">${review.user.username | h}</a></div><div popupmenu="${encoded_review_id}-popup"><a class="action-button" href="${h.url_for( controller='repository_review', action='create_review', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision, previous_review_id=encoded_review_id )}">Copy this review</a></div></td>
- <td>${previous_changeset_revision_label}</td>
+ <td>${previous_changeset_revision_label | h}</td><td>${render_star_rating( repository_rating_name, review.rating, disabled=True )}</td>
- <td>${approved_str}</td>
+ <td>${approved_str | h}</td></tr>
%endfor
%endfor
diff -r d79eb7e1d7cbcc1495a2680a19f33692adc7dfe2 -r 6b0cc1c4f105f9562066bcbad46ed00858e9372a templates/webapps/community/user/manage_email_alerts.mako
--- a/templates/webapps/community/user/manage_email_alerts.mako
+++ b/templates/webapps/community/user/manage_email_alerts.mako
@@ -42,8 +42,8 @@
</tr>
%for repository in email_alert_repositories:
<tr>
- <td>${repository.name}</td>
- <td>${repository.description}</td>
+ <td>${repository.name | h}</td>
+ <td>${repository.description | h}</td></tr>
%endfor
</table>
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
34 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/b22b643e77b9/
changeset: b22b643e77b9
user: dan
date: 2012-10-23 17:05:59
summary: Add helper method to allow html escaping and replacing newlines with breaks and use it for rendering readme and long description.
affected #: 1 file
diff -r 06b3b644188a29b78e8400298c67472b5b6bd790 -r b22b643e77b98544ac65becb16626be403578792 templates/webapps/community/common/common.mako
--- a/templates/webapps/community/common/common.mako
+++ b/templates/webapps/community/common/common.mako
@@ -1,3 +1,11 @@
+<%def name="escape_html_add_breaks( value )">
+ <%
+ import markupsafe
+ value = str( markupsafe.escape( value ) ).replace( '\n', '<br/>' )
+ %>
+ ${value}
+</%def>
+
<%def name="render_star_rating( name, rating, disabled=False )"><%
if disabled:
@@ -15,7 +23,6 @@
</%def><%def name="render_readme( readme_text )">
- <% readme_text = readme_text.replace( '\n', '<br/>' ) %><style type="text/css">
#readme_table{ table-layout:fixed;
width:100%;
@@ -31,7 +38,7 @@
<div class="toolFormBody"><div class="form-row"><table id="readme_table">
- <tr><td>${readme_text}</td></tr>
+ <tr><td>${ escape_html_add_breaks( readme_text ) }</td></tr></table></div></div>
@@ -39,7 +46,6 @@
</%def><%def name="render_long_description( description_text )">
- <% description_text = description_text.replace( '\n', '<br/>' ) %><style type="text/css">
#description_table{ table-layout:fixed;
width:100%;
@@ -53,7 +59,7 @@
<div class="form-row"><label>Detailed description:</label><table id="description_table">
- <tr><td>${description_text}</td></tr>
+ <tr><td>${ escape_html_add_breaks( description_text ) }</td></tr></table><div style="clear: both"></div></div>
https://bitbucket.org/galaxy/galaxy-central/changeset/dc8b436cba17/
changeset: dc8b436cba17
user: dan
date: 2012-10-23 17:05:59
summary: HTML escape values that could be set by the user in templates/webapps/community/admin/statistics.mako.
affected #: 1 file
diff -r b22b643e77b98544ac65becb16626be403578792 -r dc8b436cba17a907d9b5b3b2a79514f52f67256e templates/webapps/community/admin/statistics.mako
--- a/templates/webapps/community/admin/statistics.mako
+++ b/templates/webapps/community/admin/statistics.mako
@@ -16,35 +16,35 @@
</tr><tr><td>Total repositories</td>
- <td>${trans.app.shed_counter.repositories}</td>
+ <td>${trans.app.shed_counter.repositories | h}</td></tr><tr><td>Empty repositories</td>
- <td>${trans.app.shed_counter.new_repositories}</td>
+ <td>${trans.app.shed_counter.new_repositories | h}</td></tr><tr><td>Deleted repositories</td>
- <td>${trans.app.shed_counter.deleted_repositories}</td>
+ <td>${trans.app.shed_counter.deleted_repositories | h}</td></tr><tr><td>Valid tools</td>
- <td>${trans.app.shed_counter.valid_tools}</td>
+ <td>${trans.app.shed_counter.valid_tools | h}</td></tr><tr><td>Invalid tools</td>
- <td>${trans.app.shed_counter.invalid_tools}</td>
+ <td>${trans.app.shed_counter.invalid_tools | h}</td></tr><tr><td>Workflows</td>
- <td>${trans.app.shed_counter.workflows}</td>
+ <td>${trans.app.shed_counter.workflows | h}</td></tr><tr><td>Proprietary datatypes</td>
- <td>${trans.app.shed_counter.proprietary_datatypes}</td>
+ <td>${trans.app.shed_counter.proprietary_datatypes | h}</td></tr><tr><td>Total clones</td>
- <td>${trans.app.shed_counter.total_clones}</td>
+ <td>${trans.app.shed_counter.total_clones | h}</td></tr></table></div>
https://bitbucket.org/galaxy/galaxy-central/changeset/5a9c7d2c9914/
changeset: 5a9c7d2c9914
user: dan
date: 2012-10-23 17:05:59
summary: HTML escape values that could be set by the user in templates/webapps/community/base_panels.mako.
affected #: 1 file
diff -r dc8b436cba17a907d9b5b3b2a79514f52f67256e -r 5a9c7d2c9914bb7b4c2b9626b8722138dab1ac10 templates/webapps/community/base_panels.mako
--- a/templates/webapps/community/base_panels.mako
+++ b/templates/webapps/community/base_panels.mako
@@ -50,10 +50,10 @@
${menu_item[0]}
%elif len ( menu_item ) == 2:
<% name, link = menu_item %>
- <a href="${link}">${name}</a>
+ <a href="${link}">${name | h}</a>
%else:
<% name, link, target = menu_item %>
- <a target="${target}" href="${link}">${name}</a>
+ <a target="${target}" href="${link}">${name | h}</a>
%endif
</li>
%endif
https://bitbucket.org/galaxy/galaxy-central/changeset/30ba3eb8752d/
changeset: 30ba3eb8752d
user: dan
date: 2012-10-23 17:06:00
summary: HTML escape values that could be set by the user in templates/webapps/community/category/create_category.mako.
affected #: 1 file
diff -r 5a9c7d2c9914bb7b4c2b9626b8722138dab1ac10 -r 30ba3eb8752d2d81076bb262dfcdebc0c072cf32 templates/webapps/community/category/create_category.mako
--- a/templates/webapps/community/category/create_category.mako
+++ b/templates/webapps/community/category/create_category.mako
@@ -20,11 +20,11 @@
<form name="create_category_form" id="create_category_form" action="${h.url_for( action='create_category' )}" method="post" ><div class="form-row"><label>Name:</label>
- <input name="name" type="textfield" value="${name}" size=40"/>
+ <input name="name" type="textfield" value="${name | h}" size=40"/></div><div class="form-row"><label>Description:</label>
- <input name="description" type="textfield" value="${description}" size=40"/>
+ <input name="description" type="textfield" value="${description | h}" size=40"/></div><div class="form-row"><input type="submit" name="create_category_button" value="Save"/>
https://bitbucket.org/galaxy/galaxy-central/changeset/1763560b7737/
changeset: 1763560b7737
user: dan
date: 2012-10-23 17:06:00
summary: HTML escape values that could be set by the user in templates/webapps/community/category/edit_category.mako.
affected #: 1 file
diff -r 30ba3eb8752d2d81076bb262dfcdebc0c072cf32 -r 1763560b7737d656bdf2aa091b1c3979580c48a3 templates/webapps/community/category/edit_category.mako
--- a/templates/webapps/community/category/edit_category.mako
+++ b/templates/webapps/community/category/edit_category.mako
@@ -12,14 +12,14 @@
<div class="form-row"><label>Name:</label><div style="float: left; width: 250px; margin-right: 10px;">
- <input type="text" name="name" value="${category.name}" size="40"/>
+ <input type="text" name="name" value="${category.name | h}" size="40"/></div><div style="clear: both"></div></div><div class="form-row"><label>Description:</label><div style="float: left; width: 250px; margin-right: 10px;">
- <input name="description" type="textfield" value="${category.description}" size=40"/>
+ <input name="description" type="textfield" value="${category.description | h}" size=40"/></div><div style="clear: both"></div></div>
https://bitbucket.org/galaxy/galaxy-central/changeset/185c6185de86/
changeset: 185c6185de86
user: dan
date: 2012-10-23 17:06:00
summary: HTML escape values that could be set by the user in templates/webapps/community/category/grid.mako.
affected #: 1 file
diff -r 1763560b7737d656bdf2aa091b1c3979580c48a3 -r 185c6185de86b9aa282bdd80ab3f75adca6e4991 templates/webapps/community/category/grid.mako
--- a/templates/webapps/community/category/grid.mako
+++ b/templates/webapps/community/category/grid.mako
@@ -14,13 +14,13 @@
<ul class="manage-table-actions">
%if len( grid.global_actions ) < 4:
%for action in grid.global_actions:
- <li><a class="action-button" href="${h.url_for( **action.url_args )}">${action.label}</a></li>
+ <li><a class="action-button" href="${h.url_for( **action.url_args )}">${action.label | h}</a></li>
%endfor
%else:
<li><a class="action-button" id="action-8675309-popup" class="menubutton">Actions</a></li><div popupmenu="action-8675309-popup">
%for action in grid.global_actions:
- <a class="action-button" href="${h.url_for( **action.url_args )}">${action.label}</a>
+ <a class="action-button" href="${h.url_for( **action.url_args )}">${action.label | h}</a>
%endfor
</div>
%endif
https://bitbucket.org/galaxy/galaxy-central/changeset/a850f48f7ae6/
changeset: a850f48f7ae6
user: dan
date: 2012-10-23 17:06:00
summary: HTML escape values that could be set by the user in templates/webapps/community/category/valid_grid.mako.
affected #: 1 file
diff -r 185c6185de86b9aa282bdd80ab3f75adca6e4991 -r a850f48f7ae62221a3858f1445e4b1d11206598f templates/webapps/community/category/valid_grid.mako
--- a/templates/webapps/community/category/valid_grid.mako
+++ b/templates/webapps/community/category/valid_grid.mako
@@ -13,13 +13,13 @@
<ul class="manage-table-actions">
%if len( grid.global_actions ) < 4:
%for action in grid.global_actions:
- <li><a class="action-button" href="${h.url_for( **action.url_args )}">${action.label}</a></li>
+ <li><a class="action-button" href="${h.url_for( **action.url_args )}">${action.label | h}</a></li>
%endfor
%else:
<li><a class="action-button" id="action-8675309-popup" class="menubutton">Actions</a></li><div popupmenu="action-8675309-popup">
%for action in grid.global_actions:
- <a class="action-button" href="${h.url_for( **action.url_args )}">${action.label}</a>
+ <a class="action-button" href="${h.url_for( **action.url_args )}">${action.label | h}</a>
%endfor
</div>
%endif
https://bitbucket.org/galaxy/galaxy-central/changeset/92646b4f0ef6/
changeset: 92646b4f0ef6
user: dan
date: 2012-10-23 17:06:00
summary: HTML escape hg ces that could be set by the user in templates/webapps/community/common/view_readme.mako.
affected #: 1 file
diff -r a850f48f7ae62221a3858f1445e4b1d11206598f -r 92646b4f0ef669cdb74fa131c00084ad55a6ead2 templates/webapps/community/common/view_readme.mako
--- a/templates/webapps/community/common/view_readme.mako
+++ b/templates/webapps/community/common/view_readme.mako
@@ -40,7 +40,7 @@
<a class="action-button" href="${h.url_for( controller='repository', action='rate_repository', id=trans.app.security.encode_id( repository.id ) )}">Rate repository</a>
%endif
%if can_browse_contents:
- <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label | h}</a>
%endif
%if can_contact_owner:
<a class="action-button" href="${h.url_for( controller='repository', action='contact_owner', id=trans.security.encode_id( repository.id ) )}">Contact repository owner</a>
https://bitbucket.org/galaxy/galaxy-central/changeset/dc24ef2a00fb/
changeset: dc24ef2a00fb
user: dan
date: 2012-10-23 17:06:01
summary: HTML escape values that could be set by the user in templates/webapps/community/index.mako.
affected #: 1 file
diff -r 92646b4f0ef669cdb74fa131c00084ad55a6ead2 -r dc24ef2a00fb078959e7fdadc961663bcd280e7f templates/webapps/community/index.mako
--- a/templates/webapps/community/index.mako
+++ b/templates/webapps/community/index.mako
@@ -39,7 +39,7 @@
<%def name="left_panel()"><% can_review_repositories = trans.app.security_agent.user_can_review_repositories( trans.user ) %><div class="unified-panel-header" unselectable="on">
- <div class='unified-panel-header-inner'>${trans.app.shed_counter.valid_tools} valid tools on ${trans.app.shed_counter.generation_time}</div>
+ <div class='unified-panel-header-inner'>${trans.app.shed_counter.valid_tools | h} valid tools on ${trans.app.shed_counter.generation_time | h}</div></div><div class="page-container" style="padding: 10px;"><div class="toolMenu">
https://bitbucket.org/galaxy/galaxy-central/changeset/47f0fcbe6d64/
changeset: 47f0fcbe6d64
user: dan
date: 2012-10-23 17:06:05
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/browse_invalid_tools.mako.
affected #: 1 file
diff -r dc24ef2a00fb078959e7fdadc961663bcd280e7f -r 47f0fcbe6d6442c19170327c944266093b7445a6 templates/webapps/community/repository/browse_invalid_tools.mako
--- a/templates/webapps/community/repository/browse_invalid_tools.mako
+++ b/templates/webapps/community/repository/browse_invalid_tools.mako
@@ -24,9 +24,9 @@
${invalid_tool_config}
</a></td>
- <td>${repository_name}</td>
- <td>${repository_owner}</td>
- <td>${changeset_revision}</td>
+ <td>${repository_name | h}</td>
+ <td>${repository_owner | h}</td>
+ <td>${changeset_revision | h}</td></tr>
%endfor
</table>
https://bitbucket.org/galaxy/galaxy-central/changeset/4ede4449df8e/
changeset: 4ede4449df8e
user: dan
date: 2012-10-23 17:06:06
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/browse_repository.mako.
affected #: 1 file
diff -r 47f0fcbe6d6442c19170327c944266093b7445a6 -r 4ede4449df8e43cade2a9a5c395be9eeae586d38 templates/webapps/community/repository/browse_repository.mako
--- a/templates/webapps/community/repository/browse_repository.mako
+++ b/templates/webapps/community/repository/browse_repository.mako
@@ -101,7 +101,7 @@
%if can_browse_contents:
<div class="toolForm">
- <div class="toolFormTitle">Browse ${repository.name} revision ${repository.tip} (repository tip)</div>
+ <div class="toolFormTitle">Browse ${repository.name | h} revision ${repository.tip | h} (repository tip)</div>
%if can_download:
<div class="form-row"><label>Clone this repository:</label>
@@ -124,7 +124,7 @@
<label>Message:</label><div class="form-row-input">
%if commit_message:
- <textarea name="commit_message" rows="3" cols="35">${commit_message}</textarea>
+ <textarea name="commit_message" rows="3" cols="35">${commit_message | h}</textarea>
%else:
<textarea name="commit_message" rows="3" cols="35"></textarea>
%endif
https://bitbucket.org/galaxy/galaxy-central/changeset/d2b0c5110534/
changeset: d2b0c5110534
user: dan
date: 2012-10-23 17:06:06
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/common.mako.
affected #: 1 file
diff -r 4ede4449df8e43cade2a9a5c395be9eeae586d38 -r d2b0c51105347748ce6863ab0a217c86daa295c8 templates/webapps/community/repository/common.mako
--- a/templates/webapps/community/repository/common.mako
+++ b/templates/webapps/community/repository/common.mako
@@ -126,9 +126,9 @@
type = requirements_dict[ 'type' ]
%><tr>
- <td>${name}</td>
- <td>${version}</td>
- <td>${type}</td>
+ <td>${name | h}</td>
+ <td>${version | h}</td>
+ <td>${type | h}</td></tr>
%endif
%endfor
@@ -154,8 +154,8 @@
<% environment_settings = tool_dependencies[ 'set_environment' ] %>
%for requirements_dict in environment_settings:
<tr>
- <td>${requirements_dict[ 'name' ]}</td>
- <td>${requirements_dict[ 'type' ]}</td>
+ <td>${requirements_dict[ 'name' ] | h}</td>
+ <td>${requirements_dict[ 'type' ] | h}</td></tr>
%endfor
</table>
@@ -190,8 +190,8 @@
<a class="action-button" href="${h.url_for( controller='repository', action='view_tool_metadata', repository_id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision, tool_id=tool_dict[ 'id' ] )}">View tool metadata</a></div></td>
- <td>${tool_dict[ 'description' ]}</td>
- <td>${tool_dict[ 'version' ]}</td>
+ <td>${tool_dict[ 'description' ] | h}</td>
+ <td>${tool_dict[ 'version' ] | h}</td><td><%
if 'requirements' in tool_dict:
@@ -206,7 +206,7 @@
requirements_str += '%s (%s), ' % ( requirement_dict[ 'name' ], requirement_dict[ 'type' ] )
requirements_str = requirements_str.rstrip( ', ' )
%>
- ${requirements_str}
+ ${requirements_str | h}
%else:
none
%endif
@@ -233,7 +233,7 @@
<tr><td><a class="view-info" href="${h.url_for( controller='repository', action='load_invalid_tool', repository_id=trans.security.encode_id( repository.id ), tool_config=invalid_tool_config, changeset_revision=changeset_revision )}">
- ${invalid_tool_config}
+ ${invalid_tool_config | h}
</a></td></tr>
@@ -274,7 +274,7 @@
%><tr><td>
- <a href="${h.url_for( controller='workflow', action='view_workflow', repository_metadata_id=repository_metadata_id, workflow_name=tool_shed_encode( workflow_name ) )}">${workflow_name}</a>
+ <a href="${h.url_for( controller='workflow', action='view_workflow', repository_metadata_id=repository_metadata_id, workflow_name=tool_shed_encode( workflow_name ) )}">${workflow_name | h}</a></td><td>
%if steps:
@@ -283,8 +283,8 @@
unknown
%endif
</td>
- <td>${format_version}</td>
- <td>${annotation}</td>
+ <td>${format_version | h}</td>
+ <td>${annotation | h}</td></tr>
%endfor
</table>
@@ -317,10 +317,10 @@
subclass = datatypes_dict.get( 'subclass', ' ' )
%><tr>
- <td>${extension}</td>
- <td>${dtype}</td>
- <td>${mimetype}</td>
- <td>${subclass}</td>
+ <td>${extension | h}</td>
+ <td>${dtype | h}</td>
+ <td>${mimetype | h}</td>
+ <td>${subclass | h}</td></tr>
%endfor
</table>
https://bitbucket.org/galaxy/galaxy-central/changeset/a8ac1dbc787a/
changeset: a8ac1dbc787a
user: dan
date: 2012-10-23 17:06:06
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/contact_owner.mako.
affected #: 1 file
diff -r d2b0c51105347748ce6863ab0a217c86daa295c8 -r a8ac1dbc787aed0e81050a0ced93b6d97335f427 templates/webapps/community/repository/contact_owner.mako
--- a/templates/webapps/community/repository/contact_owner.mako
+++ b/templates/webapps/community/repository/contact_owner.mako
@@ -50,7 +50,7 @@
<a class="action-button" href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">View change log</a>
%endif
%if can_browse_contents:
- <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label | h}</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=repository.tip, file_type='gz' )}">Download as a .tar.gz file</a>
@@ -66,7 +66,7 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">Contact the owner of the repository named '${repository.name}'</div>
+ <div class="toolFormTitle">Contact the owner of the repository named '${repository.name | h}'</div><div class="toolFormBody"><div class="form-row">
This feature is intended to streamline appropriate communication between
https://bitbucket.org/galaxy/galaxy-central/changeset/80d3c1980287/
changeset: 80d3c1980287
user: dan
date: 2012-10-23 17:06:06
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/create_repository.mako.
affected #: 1 file
diff -r a8ac1dbc787aed0e81050a0ced93b6d97335f427 -r 80d3c198028702dbc06e6a3c965d9f98101c8632 templates/webapps/community/repository/create_repository.mako
--- a/templates/webapps/community/repository/create_repository.mako
+++ b/templates/webapps/community/repository/create_repository.mako
@@ -20,18 +20,18 @@
<form name="create_repository_form" id="create_repository_form" action="${h.url_for( controller='repository', action='create_repository' )}" method="post" ><div class="form-row"><label>Name:</label>
- <input name="name" type="textfield" value="${name}" size="40"/>
+ <input name="name" type="textfield" value="${name | h}" size="40"/><div style="clear: both"></div></div><div class="form-row"><label>Synopsis:</label>
- <input name="description" type="textfield" value="${description}" size="80"/>
+ <input name="description" type="textfield" value="${description | h}" size="80"/><div style="clear: both"></div></div><div class="form-row"><label>Detailed description:</label>
%if long_description:
- <pre><textarea name="long_description" rows="3" cols="80">${long_description}</textarea></pre>
+ <pre><textarea name="long_description" rows="3" cols="80">${long_description | h}</textarea></pre>
%else:
<textarea name="long_description" rows="3" cols="80"></textarea>
%endif
@@ -43,9 +43,9 @@
<select name="category_id" multiple>
%for category in categories:
%if category.id in selected_categories:
- <option value="${trans.security.encode_id( category.id )}" selected>${category.name}</option>
+ <option value="${trans.security.encode_id( category.id )}" selected>${category.name | h}</option>
%else:
- <option value="${trans.security.encode_id( category.id )}">${category.name}</option>
+ <option value="${trans.security.encode_id( category.id )}">${category.name | h}</option>
%endif
%endfor
</select>
https://bitbucket.org/galaxy/galaxy-central/changeset/4163748b0a93/
changeset: 4163748b0a93
user: dan
date: 2012-10-23 17:06:06
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/find_tools.mako.
affected #: 1 file
diff -r 80d3c198028702dbc06e6a3c965d9f98101c8632 -r 4163748b0a93004b390e1e53952e2ebce30ec750 templates/webapps/community/repository/find_tools.mako
--- a/templates/webapps/community/repository/find_tools.mako
+++ b/templates/webapps/community/repository/find_tools.mako
@@ -35,17 +35,17 @@
<form name="find_tools" id="find_tools" action="${h.url_for( controller='repository', action='find_tools' )}" method="post" ><div class="form-row"><label>Tool id:</label>
- <input name="tool_id" type="textfield" value="${tool_id}" size="40"/>
+ <input name="tool_id" type="textfield" value="${tool_id | h}" size="40"/></div><div style="clear: both"></div><div class="form-row"><label>Tool name:</label>
- <input name="tool_name" type="textfield" value="${tool_name}" size="40"/>
+ <input name="tool_name" type="textfield" value="${tool_name | h}" size="40"/></div><div style="clear: both"></div><div class="form-row"><label>Tool version:</label>
- <input name="tool_version" type="textfield" value="${tool_version}" size="40"/>
+ <input name="tool_version" type="textfield" value="${tool_version | h}" size="40"/></div><div style="clear: both"></div><div class="form-row">
https://bitbucket.org/galaxy/galaxy-central/changeset/119b61fcc0f2/
changeset: 119b61fcc0f2
user: dan
date: 2012-10-23 17:06:11
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/find_workflows.mako.
affected #: 1 file
diff -r 4163748b0a93004b390e1e53952e2ebce30ec750 -r 119b61fcc0f27eda4460a0a4debea1944bac1ba6 templates/webapps/community/repository/find_workflows.mako
--- a/templates/webapps/community/repository/find_workflows.mako
+++ b/templates/webapps/community/repository/find_workflows.mako
@@ -34,7 +34,7 @@
<div style="clear: both"></div><div class="form-row"><label>Workflow name:</label>
- <input name="workflow_name" type="textfield" value="${workflow_name}" size="40"/>
+ <input name="workflow_name" type="textfield" value="${workflow_name | h}" size="40"/></div><div style="clear: both"></div><div class="form-row">
https://bitbucket.org/galaxy/galaxy-central/changeset/c5c5b77e7beb/
changeset: c5c5b77e7beb
user: dan
date: 2012-10-23 17:06:11
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/manage_repository.mako.
affected #: 1 file
diff -r 119b61fcc0f27eda4460a0a4debea1944bac1ba6 -r c5c5b77e7bebb2587f1567385d58338fec604513 templates/webapps/community/repository/manage_repository.mako
--- a/templates/webapps/community/repository/manage_repository.mako
+++ b/templates/webapps/community/repository/manage_repository.mako
@@ -82,7 +82,7 @@
<a class="action-button" href="${h.url_for( controller='repository', action='rate_repository', id=trans.app.security.encode_id( repository.id ) )}">Rate repository</a>
%endif
%if can_browse_contents:
- <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label | h}</a>
%endif
%if can_contact_owner:
<a class="action-button" href="${h.url_for( controller='repository', action='contact_owner', id=trans.security.encode_id( repository.id ) )}">Contact repository owner</a>
@@ -137,7 +137,7 @@
<p/>
%endif
<div class="toolForm">
- <div class="toolFormTitle">Repository '${repository.name}'</div>
+ <div class="toolFormTitle">Repository '${repository.name | h}'</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:
@@ -151,7 +151,7 @@
%if repository.times_downloaded > 0:
${repository.name}
%else:
- <input name="repo_name" type="textfield" value="${repository.name}" size="40"/>
+ <input name="repo_name" type="textfield" value="${repository.name | h}" size="40"/>
%endif
<div class="toolParamHelp" style="clear: both;">
Repository names cannot be changed if the repository has been cloned.
@@ -160,13 +160,13 @@
</div><div class="form-row"><label>Synopsis:</label>
- <input name="description" type="textfield" value="${description}" size="80"/>
+ <input name="description" type="textfield" value="${description | h}" size="80"/><div style="clear: both"></div></div><div class="form-row"><label>Detailed description:</label>
%if long_description:
- <pre><textarea name="long_description" rows="3" cols="80">${long_description}</textarea></pre>
+ <pre><textarea name="long_description" rows="3" cols="80">${long_description | h}</textarea></pre>
%else:
<textarea name="long_description" rows="3" cols="80"></textarea>
%endif
@@ -175,27 +175,27 @@
<div class="form-row"><label>Revision:</label>
%if can_view_change_log:
- <a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${revision_label}</a>
+ <a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${revision_label | h}</a>
%else:
- ${revision_label}
+ ${revision_label | h}
%endif
</div><div class="form-row"><label>Owner:</label>
- ${repository.user.username}
+ ${repository.user.username | h}
</div><div class="form-row"><label>Times downloaded:</label>
- ${repository.times_downloaded}
+ ${repository.times_downloaded | h}
</div>
%if is_admin:
<div class="form-row"><label>Location:</label>
- ${repository.repo_path}
+ ${repository.repo_path | h}
</div><div class="form-row"><label>Deleted:</label>
- ${repository.deleted}
+ ${repository.deleted | h}
</div>
%endif
<div class="form-row">
@@ -215,9 +215,9 @@
<select name="category_id" multiple>
%for category in categories:
%if category.id in selected_categories:
- <option value="${trans.security.encode_id( category.id )}" selected>${category.name}</option>
+ <option value="${trans.security.encode_id( category.id )}" selected>${category.name | h}</option>
%else:
- <option value="${trans.security.encode_id( category.id )}">${category.name}</option>
+ <option value="${trans.security.encode_id( category.id )}">${category.name | h}</option>
%endif
%endfor
</select>
@@ -258,14 +258,14 @@
<div class="toolFormBody"><table class="grid"><tr>
- <td>${repository.user.username}</td>
+ <td>${repository.user.username | h}</td><td>owner</td><td> </td></tr>
%for username in current_allow_push_list:
%if username != repository.user.username:
<tr>
- <td>${username}</td>
+ <td>${username | h}</td><td>write</td><td><a class="action-button" href="${h.url_for( controller='repository', action='manage_repository', id=trans.security.encode_id( repository.id ), user_access_button='Remove', remove_auth=username )}">remove</a></tr>
@@ -295,7 +295,7 @@
<div class="toolFormBody"><div class="form-row"><label>Times Rated:</label>
- ${num_ratings}
+ ${num_ratings | h}
<div style="clear: both"></div></div><div class="form-row">
@@ -329,9 +329,9 @@
%><tr><td>${render_star_rating( name, review.rating, disabled=True )}</td>
- <td><pre>${review.comment}</pre></td>
+ <td><pre>${review.comment | h}</pre></td><td>${time_ago( review.update_time )}</td>
- <td>${review.user.username}</td>
+ <td>${review.user.username | h}</td></tr>
%endfor
</table>
https://bitbucket.org/galaxy/galaxy-central/changeset/645953b633e2/
changeset: 645953b633e2
user: dan
date: 2012-10-23 17:06:12
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/preview_tools_in_changeset.mako.
affected #: 1 file
diff -r c5c5b77e7bebb2587f1567385d58338fec604513 -r 645953b633e220d76128b4c68172549cd07d6dc8 templates/webapps/community/repository/preview_tools_in_changeset.mako
--- a/templates/webapps/community/repository/preview_tools_in_changeset.mako
+++ b/templates/webapps/community/repository/preview_tools_in_changeset.mako
@@ -53,7 +53,7 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">Repository ${repository.name}</div>
+ <div class="toolFormTitle">Repository ${repository.name | h}</div><div class="toolFormBody">
%if len( changeset_revision_select_field.options ) > 1:
<form name="change_revision" id="change_revision" action="${h.url_for( controller='repository', action='preview_tools_in_changeset', repository_id=trans.security.encode_id( repository.id ) )}" method="post" >
@@ -64,7 +64,7 @@
else:
tip_str = ''
%>
- ${changeset_revision_select_field.get_html()} <i>${tip_str}</i>
+ ${changeset_revision_select_field.get_html()} <i>${tip_str | h}</i><div class="toolParamHelp" style="clear: both;">
Select a revision to inspect and download versions of tools from this repository.
</div>
@@ -73,7 +73,7 @@
%else:
<div class="form-row"><label>Revision:</label>
- ${revision_label}
+ ${revision_label | h}
</div>
%endif
</div>
https://bitbucket.org/galaxy/galaxy-central/changeset/967d90f0fd7f/
changeset: 967d90f0fd7f
user: dan
date: 2012-10-23 17:06:12
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/rate_repository.mako.
affected #: 1 file
diff -r 645953b633e220d76128b4c68172549cd07d6dc8 -r 967d90f0fd7fe97acd0e636f1df99a0851e29527 templates/webapps/community/repository/rate_repository.mako
--- a/templates/webapps/community/repository/rate_repository.mako
+++ b/templates/webapps/community/repository/rate_repository.mako
@@ -91,7 +91,7 @@
<a class="action-button" href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">View change log</a>
%endif
%if can_browse_contents:
- <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${browse_label | h}</a>
%endif
%if can_contact_owner:
<a class="action-button" href="${h.url_for( controller='repository', action='contact_owner', id=trans.security.encode_id( repository.id ) )}">Contact repository owner</a>
@@ -107,7 +107,7 @@
%if repository.user != trans.user:
<div class="toolForm">
- <div class="toolFormTitle">${repository.name}</div>
+ <div class="toolFormTitle">${repository.name | h}</div>
%if can_download:
<div class="form-row"><label>Clone this repository:</label>
@@ -117,17 +117,17 @@
<div class="toolFormBody"><div class="form-row"><label>Description:</label>
- ${repository.description}
+ ${repository.description | h}
<div style="clear: both"></div></div><div class="form-row"><label>Version:</label>
- ${repository.revision}
+ ${repository.revision | h}
<div style="clear: both"></div></div><div class="form-row"><label>Owner:</label>
- ${repository.user.username}
+ ${repository.user.username | h}
<div style="clear: both"></div></div></div>
@@ -139,7 +139,7 @@
<form id="rate_repository" name="rate_repository" action="${h.url_for( controller='repository', action='rate_repository', id=trans.security.encode_id( repository.id ) )}" method="post"><div class="form-row"><label>Times Rated:</label>
- ${num_ratings}
+ ${num_ratings | h}
<div style="clear: both"></div></div><div class="form-row">
@@ -162,7 +162,7 @@
<label>Review:</label>
%if rra and rra.comment:
<div class="form-row-input">
- <pre><textarea name="comment" rows="5" cols="80">${rra.comment}</textarea></pre>
+ <pre><textarea name="comment" rows="5" cols="80">${rra.comment | h}</textarea></pre></div>
%else:
<div class="form-row-input">
@@ -202,9 +202,9 @@
%><tr><td>${render_star_rating( name, review.rating, disabled=True )}</td>
- <td><pre>${review.comment}</pre></td>
+ <td><pre>${review.comment | h}</pre></td><td>${time_ago( review.update_time )}</td>
- <td>${review.user.username}</td>
+ <td>${review.user.username | h}</td></tr>
%endfor
</table>
https://bitbucket.org/galaxy/galaxy-central/changeset/fdab5aaf2c7b/
changeset: fdab5aaf2c7b
user: dan
date: 2012-10-23 17:06:12
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/tool_form.mako.
affected #: 1 file
diff -r 967d90f0fd7fe97acd0e636f1df99a0851e29527 -r fdab5aaf2c7be522c8dbabcea2d9d8e89710c925 templates/webapps/community/repository/tool_form.mako
--- a/templates/webapps/community/repository/tool_form.mako
+++ b/templates/webapps/community/repository/tool_form.mako
@@ -177,8 +177,8 @@
%endif
%if tool:
- <div class="toolForm" id="${tool.id}">
- <div class="toolFormTitle">${tool.name} (version ${tool.version})</div>
+ <div class="toolForm" id="${tool.id | h}">
+ <div class="toolFormTitle">${tool.name | h} (version ${tool.version | h})</div><div class="toolFormBody"><form id="tool_form" name="tool_form" action="" method="get"><input type="hidden" name="tool_state" value="${util.object_to_string( tool_state.encode( tool, app ) )}">
https://bitbucket.org/galaxy/galaxy-central/changeset/364d8ba060c0/
changeset: 364d8ba060c0
user: dan
date: 2012-10-23 17:06:12
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/upload.mako.
affected #: 1 file
diff -r fdab5aaf2c7be522c8dbabcea2d9d8e89710c925 -r 364d8ba060c0cd039071842b7b4a1a78db6389ff templates/webapps/community/repository/upload.mako
--- a/templates/webapps/community/repository/upload.mako
+++ b/templates/webapps/community/repository/upload.mako
@@ -82,7 +82,7 @@
<div class="form-row"><label>Url:</label><div class="form-row-input">
- <input name="url" type="textfield" value="${url}" size="40"/>
+ <input name="url" type="textfield" value="${url | h}" size="40"/></div><div class="toolParamHelp" style="clear: both;">
Enter a URL to upload your files via http.
@@ -141,7 +141,7 @@
<label>Change set commit message:</label><div class="form-row-input">
%if commit_message:
- <pre><textarea name="commit_message" rows="3" cols="35">${commit_message}</textarea></pre>
+ <pre><textarea name="commit_message" rows="3" cols="35">${commit_message | h}</textarea></pre>
%else:
<textarea name="commit_message" rows="3" cols="35"></textarea>
%endif
https://bitbucket.org/galaxy/galaxy-central/changeset/7a9b86fd9eaf/
changeset: 7a9b86fd9eaf
user: dan
date: 2012-10-23 17:06:17
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/view_changelog.mako.
affected #: 1 file
diff -r 364d8ba060c0cd039071842b7b4a1a78db6389ff -r 7a9b86fd9eaf16ed57b75d771f86bc26e775945e templates/webapps/community/repository/view_changelog.mako
--- a/templates/webapps/community/repository/view_changelog.mako
+++ b/templates/webapps/community/repository/view_changelog.mako
@@ -78,7 +78,7 @@
%if can_download:
<div class="toolForm">
- <div class="toolFormTitle">${repository.name}</div>
+ <div class="toolFormTitle">${repository.name | h}</div><div class="toolFormBody"><div class="form-row"><label>Clone this repository:</label>
@@ -95,7 +95,7 @@
else:
title_str = '%s changesets' % repository.name
%>
- <div class="toolFormTitle">${title_str}</div>
+ <div class="toolFormTitle">${title_str | h}</div><% test_date = None %><div class="toolFormBody"><table class="grid">
@@ -128,23 +128,23 @@
%endif
<div class="form-row"><label>Description:</label>
- <a href="${h.url_for( controller='repository', action='view_changeset', id=trans.security.encode_id( repository.id ), ctx_str=ctx_str )}">${changeset[ 'description' ]}</a>
+ <a href="${h.url_for( controller='repository', action='view_changeset', id=trans.security.encode_id( repository.id ), ctx_str=ctx_str )}">${changeset[ 'description' ] | h}</a></div><div class="form-row"><label>Commit:</label>
- <a href="${h.url_for( controller='repository', action='view_changeset', id=trans.security.encode_id( repository.id ), ctx_str=ctx_str )}">${changeset_str}</a>
+ <a href="${h.url_for( controller='repository', action='view_changeset', id=trans.security.encode_id( repository.id ), ctx_str=ctx_str )}">${changeset_str | h}</a></div><div class="form-row"><label>Parent:</label>
%if ctx_parent_str == 'None':
${ctx_parent_str}
%else:
- <a href="${h.url_for( controller='repository', action='view_changeset', id=trans.security.encode_id( repository.id ), ctx_str=ctx_parent )}">${ctx_parent_str}</a>
+ <a href="${h.url_for( controller='repository', action='view_changeset', id=trans.security.encode_id( repository.id ), ctx_str=ctx_parent )}">${ctx_parent_str | h}</a>
%endif
</div><div class="form-row"><label>Commited by:</label>
- ${changeset[ 'user' ].split()[0]}
+ ${changeset[ 'user' ].split()[0] | h}
</div><div class="form-row"><label>Pushed:</label>
https://bitbucket.org/galaxy/galaxy-central/changeset/3740010dbe9e/
changeset: 3740010dbe9e
user: dan
date: 2012-10-23 17:06:17
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/view_changeset.mako.
affected #: 1 file
diff -r 7a9b86fd9eaf16ed57b75d771f86bc26e775945e -r 3740010dbe9eb5ae14cbee1ea0458b35e887eef2 templates/webapps/community/repository/view_changeset.mako
--- a/templates/webapps/community/repository/view_changeset.mako
+++ b/templates/webapps/community/repository/view_changeset.mako
@@ -82,7 +82,7 @@
%if can_download:
<div class="toolForm">
- <div class="toolFormTitle">${repository.name}</div>
+ <div class="toolFormTitle">${repository.name | h}</div><div class="toolFormBody"><div class="form-row"><label>Clone this repository:</label>
@@ -99,7 +99,7 @@
else:
title_str = '%s changeset %s' % ( repository.name, ctx )
%>
- <div class="toolFormTitle">${title_str}</div>
+ <div class="toolFormTitle">${title_str | h}</div><div class="toolFormBody"><table class="grid">
%if modified:
@@ -107,7 +107,7 @@
<td><b>modified:</b>
%for item in modified:
- <br/><a href="#${item}">${item}</a>
+ <br/><a href="#${item}">${item | h}</a>
%endfor
</td></tr>
@@ -117,7 +117,7 @@
<td><b>added:</b>
%for item in added:
- <br/><a href="#${item}">${item}</a>
+ <br/><a href="#${item}">${item | h}</a>
%endfor
</td></tr>
@@ -127,7 +127,7 @@
<td><b>removed:</b>
%for item in removed:
- <br/><a href="#${item}">${item}</a>
+ <br/><a href="#${item}">${item | h}</a>
%endfor
</td></tr>
@@ -137,7 +137,7 @@
<td><b>deleted:</b>
%for item in deleted:
- <br/><a href="#${item}">${item}</a>
+ <br/><a href="#${item}">${item | h}</a>
%endfor
</td></tr>
@@ -147,7 +147,7 @@
<td><b>unknown:</b>
%for item in unknown:
- <br/><a href="#${item}">${item}</a>
+ <br/><a href="#${item}">${item | h}</a>
%endfor
}</td></tr>
@@ -157,7 +157,7 @@
<td><b>ignored:</b>
%for item in ignored:
- <br/><a href="#${item}">${item}</a>
+ <br/><a href="#${item}">${item | h}</a>
%endfor
</td></tr>
@@ -167,7 +167,7 @@
<td>
clean:
%for item in clean:
- <br/><a href="#${item}">${item}</a>
+ <br/><a href="#${item}">${item | h}</a>
%endfor
</td></tr>
@@ -177,7 +177,6 @@
# Read at most the first 10 lines of diff to determine the anchor
ctr = 0
lines = diff.split( '\n' )
- diff = diff.replace( '\n', '<br/>' )
anchor_str = ''
for line in lines:
if ctr > 9:
@@ -189,7 +188,7 @@
ctr += 1
%><tr><td bgcolor="#E0E0E0">${anchor_str}</td></tr>
- <tr><td>${diff}</td></tr>
+ <tr><td>${ escape_html_add_breaks( diff ) }</td></tr>
%endfor
</table></div>
https://bitbucket.org/galaxy/galaxy-central/changeset/2acad55c0d8b/
changeset: 2acad55c0d8b
user: dan
date: 2012-10-23 17:06:17
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/view_repository.mako.
affected #: 1 file
diff -r 3740010dbe9eb5ae14cbee1ea0458b35e887eef2 -r 2acad55c0d8bb6d7c682298b591266be1cee27d0 templates/webapps/community/repository/view_repository.mako
--- a/templates/webapps/community/repository/view_repository.mako
+++ b/templates/webapps/community/repository/view_repository.mako
@@ -143,12 +143,12 @@
%if can_browse_contents:
<a href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ) )}">${repository.name}</a>
%else:
- ${repository.name}
+ ${repository.name | h}
%endif
</div><div class="form-row"><label>Synopsis:</label>
- ${repository.description}
+ ${repository.description | h}
</div>
%if repository.long_description:
${render_long_description( repository.long_description )}
@@ -158,12 +158,12 @@
%if can_view_change_log:
<a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${revision_label}</a>
%else:
- ${revision_label}
+ ${revision_label | h}
%endif
</div><div class="form-row"><label>Owner:</label>
- ${repository.user.username}
+ ${repository.user.username | h}
</div><div class="form-row"><label>Times downloaded:</label>
@@ -172,7 +172,7 @@
%if trans.user_is_admin():
<div class="form-row"><label>Location:</label>
- ${repository.repo_path}
+ ${repository.repo_path | h}
</div><div class="form-row"><label>Deleted:</label>
@@ -189,7 +189,7 @@
<div class="toolFormBody">
%for rca in repository.categories:
<div class="form-row">
- ${rca.category.name}
+ ${rca.category.name | h}
</div>
%endfor
<div style="clear: both"></div>
https://bitbucket.org/galaxy/galaxy-central/changeset/97ab217e3aac/
changeset: 97ab217e3aac
user: dan
date: 2012-10-23 17:06:17
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/view_tool_metadata.mako.
affected #: 1 file
diff -r 2acad55c0d8bb6d7c682298b591266be1cee27d0 -r 97ab217e3aace89120d9f34d171790c371b73f1b 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
@@ -140,35 +140,35 @@
%if 'description' in tool_metadata_dict:
<div class="form-row"><label>Description:</label>
- ${tool_metadata_dict[ 'description' ]}
+ ${tool_metadata_dict[ 'description' ] | h}
<div style="clear: both"></div></div>
%endif
%if 'id' in tool_metadata_dict:
<div class="form-row"><label>Id:</label>
- ${tool_metadata_dict[ 'id' ]}
+ ${tool_metadata_dict[ 'id' ] | h}
<div style="clear: both"></div></div>
%endif
%if 'guid' in tool_metadata_dict:
<div class="form-row"><label>Guid:</label>
- ${tool_metadata_dict[ 'guid' ]}
+ ${tool_metadata_dict[ 'guid' ] | h}
<div style="clear: both"></div></div>
%endif
%if 'version' in tool_metadata_dict:
<div class="form-row"><label>Version:</label>
- ${tool_metadata_dict[ 'version' ]}
+ ${tool_metadata_dict[ 'version' ] | h}
<div style="clear: both"></div></div>
%endif
%if 'version_string_cmd' in tool_metadata_dict:
<div class="form-row"><label>Version command string:</label>
- ${tool_metadata_dict[ 'version_string_cmd' ]}
+ ${tool_metadata_dict[ 'version_string_cmd' ] | h}
<div style="clear: both"></div></div>
%endif
@@ -184,9 +184,9 @@
<tr><td>
%if guid == tool_metadata_dict[ 'guid' ]:
- ${guid} <b>(this tool)</b>
+ ${guid | h} <b>(this tool)</b>
%else:
- ${guid}
+ ${guid | h}
%endif
</td></tr>
@@ -224,9 +224,9 @@
requirement_type = requirement_dict[ 'type' ] or 'not provided'
%><tr>
- <td>${requirement_name}</td>
- <td>${requirement_version}</td>
- <td>${requirement_type}</td>
+ <td>${requirement_name | h}</td>
+ <td>${requirement_version | h}</td>
+ <td>${requirement_type | h}</td></tr>
%endfor
</table>
@@ -245,27 +245,27 @@
</div><div class="form-row"><label>Command:</label>
- <pre>${tool.command}</pre>
+ <pre>${tool.command | h}</pre><div style="clear: both"></div></div><div class="form-row"><label>Interpreter:</label>
- ${tool.interpreter}
+ ${tool.interpreter | h}
<div style="clear: both"></div></div><div class="form-row"><label>Is multi-byte:</label>
- ${tool.is_multi_byte}
+ ${tool.is_multi_byte | h}
<div style="clear: both"></div></div><div class="form-row"><label>Forces a history refresh:</label>
- ${tool.force_history_refresh}
+ ${tool.force_history_refresh | h}
<div style="clear: both"></div></div><div class="form-row"><label>Parallelism:</label>
- ${tool.parallelism}
+ ${tool.parallelism | h}
<div style="clear: both"></div></div>
%endif
@@ -299,17 +299,17 @@
<td>${test_dict[ 'name' ]}</td><td>
%for input in inputs:
- <b>${input[0]}:</b> ${input[1]}<br/>
+ <b>${input[0]}:</b> ${input[1] | h}<br/>
%endfor
</td><td>
%for output in outputs:
- <b>${output[0]}:</b> ${output[1]}<br/>
+ <b>${output[0]}:</b> ${output[1] | h}<br/>
%endfor
</td><td>
%for required_file in required_files:
- ${required_file}<br/>
+ ${required_file | h}<br/>
%endfor
</td></tr>
https://bitbucket.org/galaxy/galaxy-central/changeset/44ccf4eb910c/
changeset: 44ccf4eb910c
user: dan
date: 2012-10-23 17:06:17
summary: HTML escape values that could be set by the user in templates/webapps/community/repository/view_workflow.mako.
affected #: 1 file
diff -r 97ab217e3aace89120d9f34d171790c371b73f1b -r 44ccf4eb910ce9e9ac8638675f403a80930a38fc templates/webapps/community/repository/view_workflow.mako
--- a/templates/webapps/community/repository/view_workflow.mako
+++ b/templates/webapps/community/repository/view_workflow.mako
@@ -96,7 +96,7 @@
${render_msg( message, status )}
%endif
-<div class="toolFormTitle">${workflow_name}</div>
+<div class="toolFormTitle">${workflow_name | h}</div><div class="form-row"><b>Boxes are red when tools are not available in this repository</b><div class="toolParamHelp" style="clear: both;">
https://bitbucket.org/galaxy/galaxy-central/changeset/3d7e5bbeaf8d/
changeset: 3d7e5bbeaf8d
user: dan
date: 2012-10-23 17:06:23
summary: HTML escape values that could be set by the user in templates/webapps/community/repository_review/browse_review.mako.
affected #: 1 file
diff -r 44ccf4eb910ce9e9ac8638675f403a80930a38fc -r 3d7e5bbeaf8d3e76a7857ce67e5540109fcf29ce templates/webapps/community/repository_review/browse_review.mako
--- a/templates/webapps/community/repository_review/browse_review.mako
+++ b/templates/webapps/community/repository_review/browse_review.mako
@@ -34,7 +34,7 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">Review of repository '${repository.name}'</div>
+ <div class="toolFormTitle">Review of repository '${repository.name | h}'</div><div class="toolFormBody"><div class="form-row"><label>Reviewer:</label>
@@ -43,17 +43,17 @@
</div><div class="form-row"><label>Repository revision:</label>
- <a class="action-button" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=review.changeset_revision )}">${changeset_revision_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=review.changeset_revision )}">${changeset_revision_label | h}</a><div style="clear: both"></div></div><div class="form-row"><label>Repository owner:</label>
- ${repository.user.username}
+ ${repository.user.username | h}
<div style="clear: both"></div></div><div class="form-row"><label>Repository synopsis:</label>
- ${repository.description}
+ ${repository.description | h}
<div style="clear: both"></div></div><div class="form-row">
@@ -70,11 +70,10 @@
# Initialize star rating.
rating_name = '%s%srating' % ( component.name, STRSEP )
- review_comment = component_review.comment.replace( '\n', '<br/>' )
%><tr>
- <td bgcolor="#D8D8D8"><b>${component.name}</b></td>
- <td bgcolor="#D8D8D8">${component.description}</td>
+ <td bgcolor="#D8D8D8"><b>${component.name | h}</b></td>
+ <td bgcolor="#D8D8D8">${component.description | h}</td></tr><tr><td colspan="2">
@@ -93,7 +92,7 @@
<tr><td><div overflow-wrap:normal;overflow:hidden;word-break:keep-all;word-wrap:break-word;line-break:strict;>
- ${review_comment}
+ ${ escape_html_add_breaks( component_review.comment ) }
</div></td></tr>
@@ -101,7 +100,7 @@
<tr><td><label>Approved:</label>
- ${component_review.approved}
+ ${component_review.approved | h}
<div style="clear: both"></div></td></tr>
https://bitbucket.org/galaxy/galaxy-central/changeset/2d86b224395e/
changeset: 2d86b224395e
user: dan
date: 2012-10-23 17:06:23
summary: HTML escape values that could be set by the user in templates/webapps/community/repository_review/create_component.mako.
affected #: 1 file
diff -r 3d7e5bbeaf8d3e76a7857ce67e5540109fcf29ce -r 2d86b224395ea5a3efb847bb67b4bb8a893c70cb templates/webapps/community/repository_review/create_component.mako
--- a/templates/webapps/community/repository_review/create_component.mako
+++ b/templates/webapps/community/repository_review/create_component.mako
@@ -20,11 +20,11 @@
<form name="create_component" id="create_component" action="${h.url_for( controller='repository_review', action='create_component' )}" method="post" ><div class="form-row"><label>Name:</label>
- <input name="name" type="textfield" value="${name}" size=40"/>
+ <input name="name" type="textfield" value="${name | h}" size=40"/></div><div class="form-row"><label>Description:</label>
- <input name="description" type="textfield" value="${description}" size=40"/>
+ <input name="description" type="textfield" value="${description | h}" size=40"/></div><div class="form-row"><input type="submit" name="create_component_button" value="Save"/>
https://bitbucket.org/galaxy/galaxy-central/changeset/afea7bdcd557/
changeset: afea7bdcd557
user: dan
date: 2012-10-23 17:06:23
summary: HTML escape values that could be set by the user in templates/webapps/community/repository_review/edit_component.mako.
affected #: 1 file
diff -r 2d86b224395ea5a3efb847bb67b4bb8a893c70cb -r afea7bdcd55755c780f9226e4b12a55dbbbd8591 templates/webapps/community/repository_review/edit_component.mako
--- a/templates/webapps/community/repository_review/edit_component.mako
+++ b/templates/webapps/community/repository_review/edit_component.mako
@@ -12,14 +12,14 @@
<div class="form-row"><label>Name:</label><div style="float: left; width: 250px; margin-right: 10px;">
- ${component.name}
+ ${component.name | h}
</div><div style="clear: both"></div></div><div class="form-row"><label>Description:</label><div style="float: left; width: 250px; margin-right: 10px;">
- <input name="description" type="textfield" value="${component.description}" size=40"/>
+ <input name="description" type="textfield" value="${component.description | h}" size=40"/></div><div style="clear: both"></div></div>
https://bitbucket.org/galaxy/galaxy-central/changeset/87ce7c44d11c/
changeset: 87ce7c44d11c
user: dan
date: 2012-10-23 17:06:23
summary: HTML escape values that could be set by the user in templates/webapps/community/repository_review/edit_review.mako.
affected #: 1 file
diff -r afea7bdcd55755c780f9226e4b12a55dbbbd8591 -r 87ce7c44d11c1d1c874c4564f0acfd32304dd3a4 templates/webapps/community/repository_review/edit_review.mako
--- a/templates/webapps/community/repository_review/edit_review.mako
+++ b/templates/webapps/community/repository_review/edit_review.mako
@@ -35,7 +35,7 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">My review of repository '${repository.name}'</div>
+ <div class="toolFormTitle">My review of repository '${repository.name | h}'</div><div class="toolFormBody"><form name="edit_review" action="${h.url_for( controller='repository_review', action='edit_review', id=trans.security.encode_id( review.id ) )}" method="post" ><div class="form-row">
@@ -45,12 +45,12 @@
</div><div class="form-row"><label>Repository owner:</label>
- ${repository.user.username}
+ ${repository.user.username | h}
<div style="clear: both"></div></div><div class="form-row"><label>Repository synopsis:</label>
- ${repository.description}
+ ${repository.description | h}
<div style="clear: both"></div></div><div class="form-row">
@@ -108,8 +108,8 @@
review_button_name = '%s%sreview_button' % ( component_name, STRSEP )
%><tr>
- <td bgcolor="#D8D8D8"><b>${component.name}</b></td>
- <td bgcolor="#D8D8D8">${component.description}</td>
+ <td bgcolor="#D8D8D8"><b>${component.name | h}</b></td>
+ <td bgcolor="#D8D8D8">${component.description | h}</td></tr><tr><td colspan="2">
@@ -128,7 +128,7 @@
<td><label>Comments:</label>
%if component_review:
- <pre><textarea name="${comment_name}" rows="3" cols="80">${comment}</textarea></pre>
+ <pre><textarea name="${comment_name}" rows="3" cols="80">${comment | h}</textarea></pre>
%else:
<textarea name="${comment_name}" rows="3" cols="80"></textarea>
%endif
https://bitbucket.org/galaxy/galaxy-central/changeset/a3b6a7ad9687/
changeset: a3b6a7ad9687
user: dan
date: 2012-10-23 17:06:23
summary: HTML escape values that could be set by the user in templates/webapps/community/repository_review/reviews_of_changeset_revision.mako.
affected #: 1 file
diff -r 87ce7c44d11c1d1c874c4564f0acfd32304dd3a4 -r a3b6a7ad9687d84f950078ebd9a4e797aa5f337e templates/webapps/community/repository_review/reviews_of_changeset_revision.mako
--- a/templates/webapps/community/repository_review/reviews_of_changeset_revision.mako
+++ b/templates/webapps/community/repository_review/reviews_of_changeset_revision.mako
@@ -73,16 +73,16 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">Revision reviews of repository '${repository.name}'</div>
+ <div class="toolFormTitle">Revision reviews of repository '${repository.name | h}'</div><div class="toolFormBody"><div class="form-row"><label>Revision:</label>
- <a class="action-button" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">${changeset_revision_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">${changeset_revision_label | h}</a><div style="clear: both"></div></div><div class="form-row"><label>Revision is installable:</label>
- ${installable_str}
+ ${installable_str | h}
<div style="clear: both"></div></div><div class="form-row">
@@ -109,7 +109,7 @@
<tr><td><div style="float:left;" class="menubutton split popup" id="${encoded_review_id}-popup">
- <a class="view-info" href="${h.url_for( controller='repository_review', action='repository_reviews_by_user', id=trans.security.encode_id( review.user.id ) )}">${review.user.username}</a>
+ <a class="view-info" href="${h.url_for( controller='repository_review', action='repository_reviews_by_user', id=trans.security.encode_id( review.user.id ) )}">${review.user.username | h}</a></div><div popupmenu="${encoded_review_id}-popup">
%if review.user == trans.user:
@@ -126,7 +126,7 @@
<td><input type="submit" name="approve_repository_review_button" value="Save"/></td></form>
%else:
- <td>${approved_str}</td>
+ <td>${approved_str | h}</td><td></td>
%endif
</tr>
https://bitbucket.org/galaxy/galaxy-central/changeset/887af9525287/
changeset: 887af9525287
user: dan
date: 2012-10-23 17:06:27
summary: HTML escape values that could be set by the user in templates/webapps/community/repository_review/reviews_of_repository.mako.
affected #: 1 file
diff -r a3b6a7ad9687d84f950078ebd9a4e797aa5f337e -r 887af9525287ea51e2286c9b00ce694cb68dd817 templates/webapps/community/repository_review/reviews_of_repository.mako
--- a/templates/webapps/community/repository_review/reviews_of_repository.mako
+++ b/templates/webapps/community/repository_review/reviews_of_repository.mako
@@ -55,7 +55,7 @@
<a class="action-button" href="${h.url_for( controller='repository', action='rate_repository', id=trans.security.encode_id( repository.id ) )}">Rate repository</a>
%endif
%if can_browse_contents:
- <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">${browse_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.security.encode_id( repository.id ) )}">${browse_label | h}</a>
%endif
%if can_contact_owner:
<a class="action-button" href="${h.url_for( controller='repository', action='contact_owner', id=trans.security.encode_id( repository.id ) )}">Contact repository owner</a>
@@ -68,7 +68,7 @@
%endif
<div class="toolForm">
- <div class="toolFormTitle">${title}</div>
+ <div class="toolFormTitle">${title | h}</div><div class="toolFormBody"><div class="form-row"><table class="grid">
@@ -102,7 +102,7 @@
<tr><td><div style="float:left;" class="menubutton split popup" id="${changeset_revision}-popup">
- <a class="view-info" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">${changeset_revision_label}</a>
+ <a class="view-info" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">${changeset_revision_label | h}</a></div><div popupmenu="${changeset_revision}-popup">
%if repository_reviews:
@@ -113,7 +113,7 @@
</div></td><td>${reviewers_str}</td>
- <td>${installable_str}</td>
+ <td>${installable_str | h}</td></tr>
%endfor
</table>
https://bitbucket.org/galaxy/galaxy-central/changeset/92237db0cd58/
changeset: 92237db0cd58
user: dan
date: 2012-10-23 17:06:27
summary: HTML escape values that could be set by the user in templates/webapps/community/repository_review/select_previous_review.mako.
affected #: 1 file
diff -r 887af9525287ea51e2286c9b00ce694cb68dd817 -r 92237db0cd58f97a24787d451ab5a4d9738452bd templates/webapps/community/repository_review/select_previous_review.mako
--- a/templates/webapps/community/repository_review/select_previous_review.mako
+++ b/templates/webapps/community/repository_review/select_previous_review.mako
@@ -67,23 +67,23 @@
%endif
<div class="warningmessage">
- You have elected to create a new review for revision <b>${changeset_revision_label}</b>of this repository. Since previous revisions have been reviewed,
+ You have elected to create a new review for revision <b>${changeset_revision_label | h}</b>of this repository. Since previous revisions have been reviewed,
you can select a previous review to copy to your new review, or click the <b>Create a review without copying</b> button.
</div><div class="toolForm">
- <div class="toolFormTitle">Select previous revision review of repository '${repository.name}'</div>
+ <div class="toolFormTitle">Select previous revision review of repository '${repository.name | h}'</div><div class="toolFormBody"><div class="form-row"><label>Revision for new review:</label>
- <a class="action-button" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">${changeset_revision_label}</a>
+ <a class="action-button" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">${changeset_revision_label | h}</a><div style="clear: both"></div></div><div class="form-row"><table class="grid"><tr></tr>
- <td bgcolor="#D8D8D8" colspan="4"><b>Previous revision reviews of repository '${repository.name}' that can be copied to your new review</b></td>
+ <td bgcolor="#D8D8D8" colspan="4"><b>Previous revision reviews of repository '${repository.name | h}' that can be copied to your new review</b></td><tr><th>Reviewer</th><th>Revision reviewed</th>
@@ -107,15 +107,15 @@
<tr><td><div style="float:left;" class="menubutton split popup" id="${encoded_review_id}-popup">
- <a class="view-info" href="${h.url_for( controller='repository_review', action='browse_review', id=encoded_review_id )}">${review.user.username}</a>
+ <a class="view-info" href="${h.url_for( controller='repository_review', action='browse_review', id=encoded_review_id )}">${review.user.username | h}</a></div><div popupmenu="${encoded_review_id}-popup"><a class="action-button" href="${h.url_for( controller='repository_review', action='create_review', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision, previous_review_id=encoded_review_id )}">Copy this review</a></div></td>
- <td>${previous_changeset_revision_label}</td>
+ <td>${previous_changeset_revision_label | h}</td><td>${render_star_rating( repository_rating_name, review.rating, disabled=True )}</td>
- <td>${approved_str}</td>
+ <td>${approved_str | h}</td></tr>
%endfor
%endfor
https://bitbucket.org/galaxy/galaxy-central/changeset/fba4cbb570ae/
changeset: fba4cbb570ae
user: dan
date: 2012-10-23 17:06:28
summary: HTML escape values that could be set by the user in templates/webapps/community/user/manage_email_alerts.mako.
affected #: 1 file
diff -r 92237db0cd58f97a24787d451ab5a4d9738452bd -r fba4cbb570ae95874383509edeaa6b5e955f8782 templates/webapps/community/user/manage_email_alerts.mako
--- a/templates/webapps/community/user/manage_email_alerts.mako
+++ b/templates/webapps/community/user/manage_email_alerts.mako
@@ -42,8 +42,8 @@
</tr>
%for repository in email_alert_repositories:
<tr>
- <td>${repository.name}</td>
- <td>${repository.description}</td>
+ <td>${repository.name | h}</td>
+ <td>${repository.description | h}</td></tr>
%endfor
</table>
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: greg: Fix for RepositoriesWithReviewsGrid, specifically the WithReviewsRevisionColumn.
by Bitbucket 23 Oct '12
by Bitbucket 23 Oct '12
23 Oct '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/06b3b644188a/
changeset: 06b3b644188a
user: greg
date: 2012-10-23 16:43:57
summary: Fix for RepositoriesWithReviewsGrid, specifically the WithReviewsRevisionColumn.
affected #: 4 files
diff -r f64b134738a929a05481d30c3135b7663f7f806d -r 06b3b644188a29b78e8400298c67472b5b6bd790 lib/galaxy/webapps/community/controllers/repository.py
--- a/lib/galaxy/webapps/community/controllers/repository.py
+++ b/lib/galaxy/webapps/community/controllers/repository.py
@@ -118,20 +118,6 @@
elif len( select_field.options ) == 1:
return select_field.options[ 0 ][ 0 ]
return ''
- class WithReviewsRevisionColumn( grids.GridColumn ):
- def __init__( self, col_name ):
- grids.GridColumn.__init__( self, col_name )
- def get_value( self, trans, grid, repository ):
- # Restrict to revisions that have been reviewed.
- repository_metadata_revisions = get_repository_metadata_revisions_for_review( repository, reviewed=True )
- if repository_metadata_revisions:
- rval = ''
- for repository_metadata in repository_metadata_revisions:
- rev, label, changeset_revision = get_rev_label_changeset_revision_from_repository_metadata( repository_metadata, repository=repository )
- rval += '<a href="manage_repository_reviews_of_revision'
- rval += '?id=%s&changeset_revision=%s">%s</a><br/>' % ( trans.security.encode_id( repository.id ), changeset_revision, label )
- return rval
- return ''
class WithoutReviewsRevisionColumn( grids.GridColumn ):
def __init__( self, col_name ):
grids.GridColumn.__init__( self, col_name )
diff -r f64b134738a929a05481d30c3135b7663f7f806d -r 06b3b644188a29b78e8400298c67472b5b6bd790 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
@@ -50,6 +50,21 @@
class RepositoriesWithReviewsGrid( RepositoryGrid ):
# This grid filters out repositories that have been marked as deprecated.
+ class WithReviewsRevisionColumn( grids.GridColumn ):
+ def __init__( self, col_name ):
+ grids.GridColumn.__init__( self, col_name )
+ def get_value( self, trans, grid, repository ):
+ # Restrict to revisions that have been reviewed.
+ if repository.reviews:
+ rval = ''
+ repo = hg.repository( get_configured_ui(), repository.repo_path )
+ for review in repository.reviews:
+ changeset_revision = review.changeset_revision
+ rev, label = get_rev_label_from_changeset_revision( repo, changeset_revision )
+ rval += '<a href="manage_repository_reviews_of_revision'
+ rval += '?id=%s&changeset_revision=%s">%s</a><br/>' % ( trans.security.encode_id( repository.id ), changeset_revision, label )
+ return rval
+ return ''
class ReviewersColumn( grids.TextColumn ):
def get_value( self, trans, grid, repository ):
rval = ''
@@ -68,7 +83,7 @@
key="name",
link=( lambda item: dict( operation="view_or_manage_repository", id=item.id ) ),
attach_popup=True ),
- RepositoryGrid.WithReviewsRevisionColumn( "Reviewed revisions" ),
+ WithReviewsRevisionColumn( "Reviewed revisions" ),
RepositoryGrid.WithoutReviewsRevisionColumn( "Revisions for review" ),
RepositoryGrid.UserColumn( "Owner", attach_popup=False ),
ReviewersColumn( "Reviewers", attach_popup=False )
@@ -718,6 +733,10 @@
# The value of the received id is the encoded repository id.
if 'operation' in kwd:
operation = kwd['operation'].lower()
+ 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":
return trans.response.send_redirect( web.url_for( controller='repository_review',
action='view_or_manage_repository',
diff -r f64b134738a929a05481d30c3135b7663f7f806d -r 06b3b644188a29b78e8400298c67472b5b6bd790 templates/webapps/community/repository_review/browse_review.mako
--- a/templates/webapps/community/repository_review/browse_review.mako
+++ b/templates/webapps/community/repository_review/browse_review.mako
@@ -84,7 +84,7 @@
<label>Private:</label>
${private_check_box.get_html( disabled=True )}
<div class="toolParamHelp" style="clear: both;">
- A private review can be accessed only by the owner of the repository and the IUC.
+ A private review can be accessed only by the owner of the repository and authorized repository reviewers.
</div><div style="clear: both"></div></td>
diff -r f64b134738a929a05481d30c3135b7663f7f806d -r 06b3b644188a29b78e8400298c67472b5b6bd790 templates/webapps/community/repository_review/edit_review.mako
--- a/templates/webapps/community/repository_review/edit_review.mako
+++ b/templates/webapps/community/repository_review/edit_review.mako
@@ -119,7 +119,7 @@
<label>Mark private:</label>
${private_check_box.get_html()}
<div class="toolParamHelp" style="clear: both;">
- A private review can be accessed only by the owner of the repository and the IUC.
+ A private review can be accessed only by the owner of the repository and authorized repository reviewers.
</div><div style="clear: both"></div></td>
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/e53f0a6bebd4/
changeset: e53f0a6bebd4
user: jgoecks
date: 2012-10-23 00:34:31
summary: Enable icon buttons to generate popup menus.
affected #: 1 file
diff -r 97816731e24bff2d825c7713787df2b0f2fc445f -r e53f0a6bebd4fd39b7e84671fcc7cd71889ea882 static/scripts/mvc/ui.js
--- a/static/scripts/mvc/ui.js
+++ b/static/scripts/mvc/ui.js
@@ -14,6 +14,7 @@
title: "",
icon_class: "",
on_click: null,
+ menu_options: null,
tooltip_config: {},
isMenuButton : true,
@@ -52,7 +53,7 @@
this.$el.replaceWith( newElem );
this.setElement( newElem );
-
+
return this;
},
@@ -106,6 +107,13 @@
if (button.attributes.tooltip_config) {
elt.tooltip(button.attributes.tooltip_config);
}
+
+ // If there are options, add popup menu to icon.
+ var menu_options = button.get('options');
+ if (menu_options) {
+ make_popupmenu(elt, menu_options);
+ }
+
});
return this;
}
https://bitbucket.org/galaxy/galaxy-central/changeset/f64b134738a9/
changeset: f64b134738a9
user: jgoecks
date: 2012-10-23 00:35:54
summary: Automated merge
affected #: 2 files
diff -r e53f0a6bebd4fd39b7e84671fcc7cd71889ea882 -r f64b134738a929a05481d30c3135b7663f7f806d lib/galaxy/webapps/galaxy/api/folder_contents.py
--- a/lib/galaxy/webapps/galaxy/api/folder_contents.py
+++ b/lib/galaxy/webapps/galaxy/api/folder_contents.py
@@ -59,7 +59,7 @@
# TODO: Find the API's path to this folder if necessary.
# This was needed in recursive descent, but it's not needed
# for "ls"-style content checking:
- if not folder or not ( trans.user_is_admin() or trans.app.security_agent.can_access_library_item( current_user_roles, folder ) ):
+ if not folder or not ( trans.user_is_admin() or trans.app.security_agent.can_access_library_item( current_user_roles, folder, trans.user ) ):
trans.response.status = 400
return "Invalid folder id ( %s ) specified." % str( folder_id )
diff -r e53f0a6bebd4fd39b7e84671fcc7cd71889ea882 -r f64b134738a929a05481d30c3135b7663f7f806d lib/galaxy/webapps/galaxy/api/folders.py
--- a/lib/galaxy/webapps/galaxy/api/folders.py
+++ b/lib/galaxy/webapps/galaxy/api/folders.py
@@ -50,7 +50,6 @@
moved here.
o payload's relevant params:
- - create_type: "file" or "folder" (required)
- folder_id: This is the parent folder's id (required)
"""
log.debug( "FoldersController.create: enter" )
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: smcmanus: Fixed bug in accessing /folders content as non-admin. Added comment.
by Bitbucket 22 Oct '12
by Bitbucket 22 Oct '12
22 Oct '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/f265985eaca2/
changeset: f265985eaca2
user: smcmanus
date: 2012-10-23 00:06:09
summary: Fixed bug in accessing /folders content as non-admin. Added comment.
affected #: 2 files
diff -r 97816731e24bff2d825c7713787df2b0f2fc445f -r f265985eaca2a5fad402810c2cf030ec26f89e97 lib/galaxy/webapps/galaxy/api/folder_contents.py
--- a/lib/galaxy/webapps/galaxy/api/folder_contents.py
+++ b/lib/galaxy/webapps/galaxy/api/folder_contents.py
@@ -59,7 +59,7 @@
# TODO: Find the API's path to this folder if necessary.
# This was needed in recursive descent, but it's not needed
# for "ls"-style content checking:
- if not folder or not ( trans.user_is_admin() or trans.app.security_agent.can_access_library_item( current_user_roles, folder ) ):
+ if not folder or not ( trans.user_is_admin() or trans.app.security_agent.can_access_library_item( current_user_roles, folder, trans.user ) ):
trans.response.status = 400
return "Invalid folder id ( %s ) specified." % str( folder_id )
diff -r 97816731e24bff2d825c7713787df2b0f2fc445f -r f265985eaca2a5fad402810c2cf030ec26f89e97 lib/galaxy/webapps/galaxy/api/folders.py
--- a/lib/galaxy/webapps/galaxy/api/folders.py
+++ b/lib/galaxy/webapps/galaxy/api/folders.py
@@ -50,7 +50,6 @@
moved here.
o payload's relevant params:
- - create_type: "file" or "folder" (required)
- folder_id: This is the parent folder's id (required)
"""
log.debug( "FoldersController.create: enter" )
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: greg: Fix styles for wrapping text in tool shed forms.
by Bitbucket 22 Oct '12
by Bitbucket 22 Oct '12
22 Oct '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/97816731e24b/
changeset: 97816731e24b
user: greg
date: 2012-10-22 21:06:55
summary: Fix styles for wrapping text in tool shed forms.
affected #: 3 files
diff -r 3f2e69afaf8cc02a35373e544ee426d8e2a41672 -r 97816731e24bff2d825c7713787df2b0f2fc445f lib/galaxy/webapps/community/controllers/repository.py
--- a/lib/galaxy/webapps/community/controllers/repository.py
+++ b/lib/galaxy/webapps/community/controllers/repository.py
@@ -2421,7 +2421,7 @@
except Exception, e:
raw_text = "Error locating and reading this repository's README file '%s': %s" % ( readme_file, str( e ) )
log.debug( raw_text )
- readme_text = translate_string( raw_text, to_html=True )
+ readme_text = raw_text
else:
readme_text = ''
is_malicious = changeset_is_malicious( trans, id, changeset_revision )
diff -r 3f2e69afaf8cc02a35373e544ee426d8e2a41672 -r 97816731e24bff2d825c7713787df2b0f2fc445f lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
--- a/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
+++ b/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
@@ -1205,7 +1205,7 @@
response = urllib2.urlopen( url )
raw_text = response.read()
response.close()
- readme_text = translate_string( raw_text, to_html=True )
+ readme_text = raw_text
else:
readme_text = ''
if trans.app.config.tool_dependency_dir is None:
diff -r 3f2e69afaf8cc02a35373e544ee426d8e2a41672 -r 97816731e24bff2d825c7713787df2b0f2fc445f templates/webapps/community/common/common.mako
--- a/templates/webapps/community/common/common.mako
+++ b/templates/webapps/community/common/common.mako
@@ -15,6 +15,7 @@
</%def><%def name="render_readme( readme_text )">
+ <% readme_text = readme_text.replace( '\n', '<br/>' ) %><style type="text/css">
#readme_table{ table-layout:fixed;
width:100%;
@@ -38,6 +39,7 @@
</%def><%def name="render_long_description( description_text )">
+ <% description_text = description_text.replace( '\n', '<br/>' ) %><style type="text/css">
#description_table{ table-layout:fixed;
width:100%;
@@ -51,7 +53,7 @@
<div class="form-row"><label>Detailed description:</label><table id="description_table">
- <tr><td><pre>${description_text}</pre></td></tr>
+ <tr><td>${description_text}</td></tr></table><div style="clear: both"></div></div>
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: jgoecks: Add chromatin interaction datatype to datatypes.conf, fix bug in data chrint data provider, and enable diagonal heat map track.
by Bitbucket 22 Oct '12
by Bitbucket 22 Oct '12
22 Oct '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/3f2e69afaf8c/
changeset: 3f2e69afaf8c
user: jgoecks
date: 2012-10-22 19:19:09
summary: Add chromatin interaction datatype to datatypes.conf, fix bug in data chrint data provider, and enable diagonal heat map track.
affected #: 3 files
diff -r 9018e5bb4e6e6de8b52683d2377d449b417269af -r 3f2e69afaf8cc02a35373e544ee426d8e2a41672 datatypes_conf.xml.sample
--- a/datatypes_conf.xml.sample
+++ b/datatypes_conf.xml.sample
@@ -43,6 +43,11 @@
<display file="ucsc/bigwig.xml" /><display file="igb/bigwig.xml" /></datatype>
+ <datatype extension="chrint" type="galaxy.datatypes.interval:ChromatinInteractions" display_in_upload="True">
+ <converter file="interval_to_bgzip_converter.xml" target_datatype="bgzip"/>
+ <converter file="interval_to_tabix_converter.xml" target_datatype="tabix" depends_on="bgzip"/>
+ <converter file="interval_to_summary_tree_converter.xml" target_datatype="summary_tree"/>
+ </datatype><!-- MSI added Datatypes --><datatype extension="csv" type="galaxy.datatypes.tabular:Tabular" subclass="True" display_in_upload="true" /><!-- FIXME: csv is 'tabular'ized data, but not 'tab-delimited'; the class used here is intended for 'tab-delimited' --><!-- End MSI added Datatypes -->
diff -r 9018e5bb4e6e6de8b52683d2377d449b417269af -r 3f2e69afaf8cc02a35373e544ee426d8e2a41672 lib/galaxy/visualization/data_providers/genome.py
--- a/lib/galaxy/visualization/data_providers/genome.py
+++ b/lib/galaxy/visualization/data_providers/genome.py
@@ -1444,7 +1444,7 @@
"""
Provides
"""
-
+
rval = []
message = None
for count, line in enumerate( iterator ):
@@ -1484,15 +1484,15 @@
"""
"""
# Modify start as needed to get earlier interactions with start region.
- start = max( 0, int( start) - 1000000 )
+ start = max( 0, int( start ) - 1000000 )
def filter( iter ):
for line in iter:
feature = line.split()
- s1 = int( feature[1] ),
- e1 = int( feature[2] ),
+ s1 = int( feature[1] )
+ e1 = int( feature[2] )
c = feature[3]
- s2 = int( feature[4] ),
- e2 = int( feature[5] ),
+ s2 = int( feature[4] )
+ e2 = int( feature[5] )
if ( ( c == chrom ) and ( s1 < end and e1 > start ) and ( s2 < end and e2 > start ) ):
yield line
return filter( TabixDataProvider.get_iterator( self, chrom, start, end ) )
diff -r 9018e5bb4e6e6de8b52683d2377d449b417269af -r 3f2e69afaf8cc02a35373e544ee426d8e2a41672 static/scripts/viz/trackster/tracks.js
--- a/static/scripts/viz/trackster/tracks.js
+++ b/static/scripts/viz/trackster/tracks.js
@@ -4156,7 +4156,7 @@
"FeatureTrack": FeatureTrack,
"VcfTrack": VcfTrack,
"ReadTrack": ReadTrack,
- // "DiagonalHeatmapTrack": DiagonalHeatmapTrack,
+ "DiagonalHeatmapTrack": DiagonalHeatmapTrack,
"CompositeTrack": CompositeTrack,
"DrawableGroup": DrawableGroup
};
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: jgoecks: Make trackster View object into a Backbone view.
by Bitbucket 22 Oct '12
by Bitbucket 22 Oct '12
22 Oct '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/9018e5bb4e6e/
changeset: 9018e5bb4e6e
user: jgoecks
date: 2012-10-22 18:33:30
summary: Make trackster View object into a Backbone view.
affected #: 2 files
diff -r 60fee5ee38fada926d010971e49623367b78362e -r 9018e5bb4e6e6de8b52683d2377d449b417269af static/scripts/viz/trackster/tracks.js
--- a/static/scripts/viz/trackster/tracks.js
+++ b/static/scripts/viz/trackster/tracks.js
@@ -854,34 +854,35 @@
});
/**
- * View object manages complete viz view, including tracks and user interactions.
+ * View object manages a trackster visualization, including tracks and user interactions.
* Events triggered:
* navigate: when browser view changes to a new locations
*/
-var View = function(obj_dict) {
- extend(obj_dict, {
- obj_type: "View"
- });
- DrawableCollection.call(this, "View", obj_dict.container, obj_dict);
- this.chrom = null;
- this.vis_id = obj_dict.vis_id;
- this.dbkey = obj_dict.dbkey;
- this.label_tracks = [];
- this.tracks_to_be_redrawn = [];
- this.max_low = 0;
- this.max_high = 0;
- this.zoom_factor = 3;
- this.min_separation = 30;
- this.has_changes = false;
- // Deferred object that indicates when view's chrom data has been loaded.
- this.load_chroms_deferred = null;
- this.init();
- this.canvas_manager = new visualization.CanvasManager( this.container.get(0).ownerDocument );
- this.reset();
-};
-_.extend( View.prototype, Backbone.Events);
-extend( View.prototype, DrawableCollection.prototype, {
- init: function() {
+var TracksterView = Backbone.View.extend({
+
+ initialize: function(obj_dict) {
+ extend(obj_dict, {
+ obj_type: "View"
+ });
+ DrawableCollection.call(this, "View", obj_dict.container, obj_dict);
+ this.chrom = null;
+ this.vis_id = obj_dict.vis_id;
+ this.dbkey = obj_dict.dbkey;
+ this.label_tracks = [];
+ this.tracks_to_be_redrawn = [];
+ this.max_low = 0;
+ this.max_high = 0;
+ this.zoom_factor = 3;
+ this.min_separation = 30;
+ this.has_changes = false;
+ // Deferred object that indicates when view's chrom data has been loaded.
+ this.load_chroms_deferred = null;
+ this.render();
+ this.canvas_manager = new visualization.CanvasManager( this.container.get(0).ownerDocument );
+ this.reset();
+ },
+
+ render: function() {
// Attribute init.
this.requested_redraw = false;
@@ -1101,7 +1102,11 @@
this.reset();
$(window).trigger("resize");
- },
+ }
+});
+
+// FIXME: need to use this approach to enable inheritance of DrawableCollection functions.
+extend( TracksterView.prototype, DrawableCollection.prototype, {
changed: function() {
this.has_changes = true;
},
@@ -4178,7 +4183,7 @@
};
return {
- View: View,
+ TracksterView: TracksterView,
DrawableGroup: DrawableGroup,
LineTrack: LineTrack,
FeatureTrack: FeatureTrack,
diff -r 60fee5ee38fada926d010971e49623367b78362e -r 9018e5bb4e6e6de8b52683d2377d449b417269af static/scripts/viz/trackster_ui.js
--- a/static/scripts/viz/trackster_ui.js
+++ b/static/scripts/viz/trackster_ui.js
@@ -186,7 +186,7 @@
// Create view.
var self = this,
- view = new tracks.View(view_config);
+ view = new tracks.TracksterView(view_config);
view.editor = true;
$.when( view.load_chroms_deferred ).then(function() {
// Viewport config.
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: jgoecks: Enable Tophat, Tophat2, and Cuffdiff to accept gene annotations in GFF3 format. Thanks to Jim Johnson.
by Bitbucket 22 Oct '12
by Bitbucket 22 Oct '12
22 Oct '12
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/changeset/60fee5ee38fa/
changeset: 60fee5ee38fa
user: jgoecks
date: 2012-10-22 16:52:48
summary: Enable Tophat, Tophat2, and Cuffdiff to accept gene annotations in GFF3 format. Thanks to Jim Johnson.
affected #: 3 files
diff -r 1dc4dd32eaf8b38da3e66bdc2de287f907b3605e -r 60fee5ee38fada926d010971e49623367b78362e tools/ngs_rna/cuffdiff_wrapper.xml
--- a/tools/ngs_rna/cuffdiff_wrapper.xml
+++ b/tools/ngs_rna/cuffdiff_wrapper.xml
@@ -72,7 +72,7 @@
</command><inputs>
- <param format="gtf" name="gtf_input" type="data" label="Transcripts" help="A transcript GTF file produced by cufflinks, cuffcompare, or other source."/>
+ <param format="gtf,gff3" name="gtf_input" type="data" label="Transcripts" help="A transcript GTF file produced by cufflinks, cuffcompare, or other source."/><conditional name="group_analysis"><param name="do_groups" type="select" label="Perform replicate analysis" help="Perform cuffdiff with replicates in each group."><option value="No">No</option>
diff -r 1dc4dd32eaf8b38da3e66bdc2de287f907b3605e -r 60fee5ee38fada926d010971e49623367b78362e tools/ngs_rna/tophat2_wrapper.xml
--- a/tools/ngs_rna/tophat2_wrapper.xml
+++ b/tools/ngs_rna/tophat2_wrapper.xml
@@ -210,7 +210,7 @@
</param><when value="No" /><when value="Yes">
- <param format="gtf" name="gene_annotation_model" type="data" label="Gene Model Annotations" help="TopHat will use the exon records in this file to build a set of known splice junctions for each gene, and will attempt to align reads to these junctions even if they would not normally be covered by the initial mapping."/>
+ <param format="gtf,gff3" name="gene_annotation_model" type="data" label="Gene Model Annotations" help="TopHat will use the exon records in this file to build a set of known splice junctions for each gene, and will attempt to align reads to these junctions even if they would not normally be covered by the initial mapping."/></when></conditional><conditional name="raw_juncs">
diff -r 1dc4dd32eaf8b38da3e66bdc2de287f907b3605e -r 60fee5ee38fada926d010971e49623367b78362e tools/ngs_rna/tophat_wrapper.xml
--- a/tools/ngs_rna/tophat_wrapper.xml
+++ b/tools/ngs_rna/tophat_wrapper.xml
@@ -224,7 +224,7 @@
</param><when value="No" /><when value="Yes">
- <param format="gtf" name="gene_annotation_model" type="data" label="Gene Model Annotations" help="TopHat will use the exon records in this file to build a set of known splice junctions for each gene, and will attempt to align reads to these junctions even if they would not normally be covered by the initial mapping."/>
+ <param format="gtf,gff3" name="gene_annotation_model" type="data" label="Gene Model Annotations" help="TopHat will use the exon records in this file to build a set of known splice junctions for each gene, and will attempt to align reads to these junctions even if they would not normally be covered by the initial mapping."/></when></conditional><conditional name="raw_juncs">
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/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