From 017e181063f419d61d5055b8fa2d19bb71453bf8 Mon Sep 17 00:00:00 2001 From: Greg Von Kuster Date: Fri, 12 Jun 2015 15:41:10 -0400 Subject: [PATCH 01/20] Add a GreaterThanZeroValidator for numeric tool parameters. --- lib/galaxy/tools/parameters/validation.py | 35 +++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/tools/parameters/validation.py b/lib/galaxy/tools/parameters/validation.py index 588949d63eb..132d439410d 100644 --- a/lib/galaxy/tools/parameters/validation.py +++ b/lib/galaxy/tools/parameters/validation.py @@ -324,6 +324,37 @@ class MetadataInDataTableColumnValidator( Validator ): raise ValueError( self.message ) +class GreaterThanZeroValidator( Validator ): + """ + Validator that ensures a number is greater than zero. + + >>> from galaxy.tools.parameters import ToolParameter + >>> p = ToolParameter.build( None, XML( ''' + ... + ... + ... + ... ''' ) ) + >>> t = p.validate( 1 ) + >>> t = p.validate( 0.5 ) + >>> t = p.validate( 0.0 ) + Traceback (most recent call last): + ... + ValueError: Value must be greater than zero + """ + + def __init__( self, message=None ): + self.message = message + + @classmethod + def from_element( cls, param, elem ): + return cls( elem.get( 'message', None ) ) + + def validate( self, value, history=None ): + if value <= 0: + if self.message is None: + self.message = "Value must be greater than zero" + raise ValueError( self.message ) + validator_types = dict( expression=ExpressionValidator, regex=RegexValidator, in_range=InRangeValidator, @@ -334,10 +365,10 @@ validator_types = dict( expression=ExpressionValidator, empty_field=EmptyTextfieldValidator, dataset_metadata_in_file=MetadataInFileColumnValidator, dataset_metadata_in_data_table=MetadataInDataTableColumnValidator, - dataset_ok_validator=DatasetOkValidator ) + dataset_ok_validator=DatasetOkValidator, + greater_than_zero=GreaterThanZeroValidator ) def get_suite(): """Get unittest suite for this module""" import doctest, sys return doctest.DocTestSuite( sys.modules[__name__] ) - From 2a7f1f741e466223cf3d1e7c414ede5ee7ac4c5a Mon Sep 17 00:00:00 2001 From: Greg Von Kuster Date: Mon, 15 Jun 2015 12:16:37 -0400 Subject: [PATCH 02/20] Enhance the InRangeValidator to enalbe the use of new strict_min and strict_max attributes which, if set to true, will exclude the range end points. For example, if strict_min is true, min < value, whereas if strict_min is false (the default), then min <= value. Combinations of strict_min and strict_max are allowed. --- lib/galaxy/tools/parameters/validation.py | 128 +++++++++++++++------- 1 file changed, 88 insertions(+), 40 deletions(-) diff --git a/lib/galaxy/tools/parameters/validation.py b/lib/galaxy/tools/parameters/validation.py index 132d439410d..0bab4837be8 100644 --- a/lib/galaxy/tools/parameters/validation.py +++ b/lib/galaxy/tools/parameters/validation.py @@ -5,25 +5,32 @@ Classes related to parameter validation. import os, re, logging from xml.etree.ElementTree import XML from galaxy import model +from galaxy import util log = logging.getLogger( __name__ ) + class LateValidationError( Exception ): + def __init__( self, message ): self.message = message + class Validator( object ): """ A validator checks that a value meets some conditions OR raises ValueError """ + @classmethod def from_element( cls, param, elem ): type = elem.get( 'type', None ) assert type is not None, "Required 'type' attribute missing from validator" return validator_types[type].from_element( param, elem ) + def validate( self, value, history=None ): raise TypeError( "Abstract Method" ) + class RegexValidator( Validator ): """ Validator that evaluates a regular expression @@ -41,18 +48,22 @@ class RegexValidator( Validator ): ... ValueError: Not gonna happen """ + @classmethod def from_element( cls, param, elem ): return cls( elem.get( 'message' ), elem.text ) + def __init__( self, message, expression ): self.message = message # Compile later. RE objects used to not be thread safe. Not sure about # the sre module. self.expression = expression + def validate( self, value, history=None ): if re.match( self.expression, value ) is None: raise ValueError( self.message ) + class ExpressionValidator( Validator ): """ Validator that evaluates a python expression using the value @@ -70,14 +81,17 @@ class ExpressionValidator( Validator ): ... ValueError: Not gonna happen """ + @classmethod def from_element( cls, param, elem ): return cls( elem.get( 'message' ), elem.text, elem.get( 'substitute_value_in_message' ) ) + def __init__( self, message, expression, substitute_value_in_message ): self.message = message self.substitute_value_in_message = substitute_value_in_message # Save compiled expression, code objects are thread safe (right?) self.expression = compile( expression, '', 'eval' ) + def validate( self, value, history=None ): if not( eval( self.expression, dict( value=value ) ) ): message = self.message @@ -85,6 +99,7 @@ class ExpressionValidator( Validator ): message = message % value raise ValueError( message ) + class InRangeValidator( Validator ): """ Validator that ensures a number is in a specific range @@ -92,10 +107,13 @@ class InRangeValidator( Validator ): >>> from galaxy.tools.parameters import ToolParameter >>> p = ToolParameter.build( None, XML( ''' ... - ... + ... ... ... ''' ) ) >>> t = p.validate( 10 ) + Traceback (most recent call last): + ... + ValueError: Not gonna happen >>> t = p.validate( 15 ) >>> t = p.validate( 20 ) >>> t = p.validate( 21 ) @@ -103,20 +121,54 @@ class InRangeValidator( Validator ): ... ValueError: Not gonna happen """ + @classmethod def from_element( cls, param, elem ): - return cls( elem.get( 'message', None ), elem.get( 'min' ), elem.get( 'max' ) ) - def __init__( self, message, range_min, range_max ): + return cls( elem.get( 'message', None ), elem.get( 'min' ), + elem.get( 'max' ), elem.get( 'strict_min', 'false' ), + elem.get( 'strict_max', 'false' ) ) + + def __init__( self, message, range_min, range_max, strict_min=False, strict_max=False ): + """ + When the optional strict_min and strict_max attributes are set + to true, the range excludes the end points (i.e., min < value < max), + while if set to False ( the default), then range includes the end points + (1.e., min <= value <= max). Combinations of strict_min and strict_max + values are allowed. + """ self.min = float( range_min if range_min is not None else '-inf' ) + self.strict_min = util.asbool( strict_min ) self.max = float( range_max if range_max is not None else 'inf' ) + self.strict_max = util.asbool( strict_max ) assert self.min <= self.max, 'min must be less than or equal to max' # Remove unneeded 0s and decimal from floats to make message pretty. self_min_str = str( self.min ).rstrip( '0' ).rstrip( '.' ) self_max_str = str( self.max ).rstrip( '0' ).rstrip( '.' ) - self.message = message or "Value must be between %s and %s" % ( self_min_str, self_max_str ) + op1 = '>=' + op2 = '<=' + if self.strict_min and self.strict_max: + op1 = '>' + op2 = '<' + if self.strict_min and not self.strict_max: + op1 = '>' + elif not self.strict_min and self.strict_max: + op2 = '<' + self.message = message or "Value must be %s %s and %s %s" % ( op1, self_min_str, op2, self_max_str ) + def validate( self, value, history=None ): - if not( self.min <= float( value ) <= self.max ): - raise ValueError( self.message ) + if self.strict_min and self.strict_max: + if not( self.min < float( value ) < self.max ): + raise ValueError( self.message ) + elif self.strict_min and not self.strict_max: + if not( self.min < float( value ) <= self.max ): + raise ValueError( self.message ) + elif not self.strict_min and self.strict_max: + if not( self.min <= float( value ) < self.max ): + raise ValueError( self.message ) + elif not self.strict_min and not self.strict_max: + if not( self.min <= float( value ) <= self.max ): + raise ValueError( self.message ) + class LengthValidator( Validator ): """ @@ -139,9 +191,11 @@ class LengthValidator( Validator ): ... ValueError: Must have length no more than 8 """ + @classmethod def from_element( cls, param, elem ): return cls( elem.get( 'message', None ), elem.get( 'min', None ), elem.get( 'max', None ) ) + def __init__( self, message, length_min, length_max ): self.message = message if length_min is not None: @@ -150,38 +204,47 @@ class LengthValidator( Validator ): length_max = int( length_max ) self.min = length_min self.max = length_max + def validate( self, value, history=None ): if self.min is not None and len( value ) < self.min: raise ValueError( self.message or ( "Must have length of at least %d" % self.min ) ) if self.max is not None and len( value ) > self.max: raise ValueError( self.message or ( "Must have length no more than %d" % self.max ) ) + class DatasetOkValidator( Validator ): """ Validator that checks if a dataset is in an 'ok' state """ + def __init__( self, message=None ): self.message = message + @classmethod def from_element( cls, param, elem ): return cls( elem.get( 'message', None ) ) + def validate( self, value, history=None ): if value and value.state != model.Dataset.states.OK: if self.message is None: self.message = "The selected dataset is still being generated, select another dataset or wait until it is completed" raise ValueError( self.message ) + class MetadataValidator( Validator ): """ Validator that checks for missing metadata """ + def __init__( self, message = None, check = "", skip = "" ): self.message = message self.check = check.split( "," ) self.skip = skip.split( "," ) + @classmethod def from_element( cls, param, elem ): return cls( message=elem.get( 'message', None ), check=elem.get( 'check', "" ), skip=elem.get( 'skip', "" ) ) + def validate( self, value, history=None ): if value: if not isinstance( value, model.DatasetInstance ): @@ -191,18 +254,22 @@ class MetadataValidator( Validator ): self.message = "Metadata missing, click the pencil icon in the history item to edit / save the metadata attributes" raise ValueError( self.message ) + class UnspecifiedBuildValidator( Validator ): """ Validator that checks for dbkey not equal to '?' """ + def __init__( self, message=None ): if message is None: self.message = "Unspecified genome build, click the pencil icon in the history item to set the genome build" else: self.message = message + @classmethod def from_element( cls, param, elem ): return cls( elem.get( 'message', None ) ) + def validate( self, value, history=None ): #if value is None, we cannot validate if value: @@ -212,36 +279,46 @@ class UnspecifiedBuildValidator( Validator ): if dbkey == '?': raise ValueError( self.message ) + class NoOptionsValidator( Validator ): """Validator that checks for empty select list""" + def __init__( self, message=None ): self.message = message + @classmethod def from_element( cls, param, elem ): return cls( elem.get( 'message', None ) ) + def validate( self, value, history=None ): if value is None: if self.message is None: self.message = "No options available for selection" raise ValueError( self.message ) + class EmptyTextfieldValidator( Validator ): """Validator that checks for empty text field""" + def __init__( self, message=None ): self.message = message + @classmethod def from_element( cls, param, elem ): return cls( elem.get( 'message', None ) ) + def validate( self, value, history=None ): if value == '': if self.message is None: self.message = "Field requires a value" raise ValueError( self.message ) + class MetadataInFileColumnValidator( Validator ): """ Validator that checks if the value for a dataset's metadata item exists in a file. """ + @classmethod def from_element( cls, param, elem ): filename = elem.get( "filename", None ) @@ -256,6 +333,7 @@ class MetadataInFileColumnValidator( Validator ): if line_startswith: line_startswith = line_startswith.strip() return cls( filename, metadata_name, metadata_column, message, line_startswith ) + def __init__( self, filename, metadata_name, metadata_column, message="Value for metadata not found.", line_startswith=None ): self.metadata_name = metadata_name self.message = message @@ -265,6 +343,7 @@ class MetadataInFileColumnValidator( Validator ): fields = line.split( '\t' ) if metadata_column < len( fields ): self.valid_values.append( fields[metadata_column].strip() ) + def validate( self, value, history = None ): if not value: return if hasattr( value, "metadata" ): @@ -272,10 +351,12 @@ class MetadataInFileColumnValidator( Validator ): return raise ValueError( self.message ) + class MetadataInDataTableColumnValidator( Validator ): """ Validator that checks if the value for a dataset's metadata item exists in a file. """ + @classmethod def from_element( cls, param, elem ): table_name = elem.get( "table_name", None ) @@ -323,38 +404,6 @@ class MetadataInDataTableColumnValidator( Validator ): return raise ValueError( self.message ) - -class GreaterThanZeroValidator( Validator ): - """ - Validator that ensures a number is greater than zero. - - >>> from galaxy.tools.parameters import ToolParameter - >>> p = ToolParameter.build( None, XML( ''' - ... - ... - ... - ... ''' ) ) - >>> t = p.validate( 1 ) - >>> t = p.validate( 0.5 ) - >>> t = p.validate( 0.0 ) - Traceback (most recent call last): - ... - ValueError: Value must be greater than zero - """ - - def __init__( self, message=None ): - self.message = message - - @classmethod - def from_element( cls, param, elem ): - return cls( elem.get( 'message', None ) ) - - def validate( self, value, history=None ): - if value <= 0: - if self.message is None: - self.message = "Value must be greater than zero" - raise ValueError( self.message ) - validator_types = dict( expression=ExpressionValidator, regex=RegexValidator, in_range=InRangeValidator, @@ -365,8 +414,7 @@ validator_types = dict( expression=ExpressionValidator, empty_field=EmptyTextfieldValidator, dataset_metadata_in_file=MetadataInFileColumnValidator, dataset_metadata_in_data_table=MetadataInDataTableColumnValidator, - dataset_ok_validator=DatasetOkValidator, - greater_than_zero=GreaterThanZeroValidator ) + dataset_ok_validator=DatasetOkValidator ) def get_suite(): """Get unittest suite for this module""" From 2a3ad8148b95dc964620e8c6f0caff43c2c1d561 Mon Sep 17 00:00:00 2001 From: Greg Von Kuster Date: Mon, 15 Jun 2015 13:21:24 -0400 Subject: [PATCH 03/20] Simplify the checks for setting strict_min and strict_max operators. --- lib/galaxy/tools/parameters/validation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/tools/parameters/validation.py b/lib/galaxy/tools/parameters/validation.py index 0bab4837be8..13647e3db22 100644 --- a/lib/galaxy/tools/parameters/validation.py +++ b/lib/galaxy/tools/parameters/validation.py @@ -149,9 +149,9 @@ class InRangeValidator( Validator ): if self.strict_min and self.strict_max: op1 = '>' op2 = '<' - if self.strict_min and not self.strict_max: + if self.strict_min: op1 = '>' - elif not self.strict_min and self.strict_max: + elif self.strict_max: op2 = '<' self.message = message or "Value must be %s %s and %s %s" % ( op1, self_min_str, op2, self_max_str ) From e8087f7b12d76aceeff38f0a2c70706e3ee676b7 Mon Sep 17 00:00:00 2001 From: Martin Cech Date: Mon, 15 Jun 2015 13:31:16 -0400 Subject: [PATCH 04/20] refactor TS javascript files to be separated from Galaxy JS thanks to Carl for helping me with this --- .../scripts/mvc/groups/group-detail-view.js | 2 +- .../scripts/mvc/groups/group-list-view.js | 8 ++++---- .../scripts/mvc/groups/group-listrow-view.js | 0 .../scripts/mvc/groups/group-model.js | 0 client/toolshed/scripts/test-file.js | 3 --- client/{galaxy => toolshed}/scripts/toolshed.groups.js | 6 +++--- lib/galaxy/webapps/tool_shed/controllers/groups.py | 2 +- static/scripts/mvc/groups/group-detail-view.js | 2 -- static/scripts/mvc/groups/group-groupdetail-view.js | 2 -- static/scripts/mvc/groups/group-grouprow-view.js | 2 -- static/scripts/mvc/groups/group-list-view.js | 2 -- static/scripts/mvc/groups/group.model.js | 2 -- static/scripts/toolshed.groups.js | 2 -- static/toolshed/maps/mvc/groups/group-detail-view.js.map | 1 + static/toolshed/maps/mvc/groups/group-list-view.js.map | 1 + static/toolshed/maps/mvc/groups/group-listrow-view.js.map | 1 + static/toolshed/maps/mvc/groups/group-model.js.map | 1 + static/toolshed/maps/test-file.js.map | 1 + static/toolshed/maps/toolshed.groups.js.map | 1 + static/toolshed/scripts/mvc/groups/group-detail-view.js | 2 ++ static/toolshed/scripts/mvc/groups/group-list-view.js | 2 ++ .../scripts/mvc/groups/group-listrow-view.js | 0 static/{ => toolshed}/scripts/mvc/groups/group-model.js | 0 static/toolshed/scripts/test-file.js | 2 ++ static/toolshed/scripts/toolshed.groups.js | 2 ++ templates/webapps/tool_shed/group/index.mako | 8 ++++++++ 26 files changed, 31 insertions(+), 24 deletions(-) rename client/{galaxy => toolshed}/scripts/mvc/groups/group-detail-view.js (99%) rename client/{galaxy => toolshed}/scripts/mvc/groups/group-list-view.js (96%) rename client/{galaxy => toolshed}/scripts/mvc/groups/group-listrow-view.js (100%) rename client/{galaxy => toolshed}/scripts/mvc/groups/group-model.js (100%) delete mode 100644 client/toolshed/scripts/test-file.js rename client/{galaxy => toolshed}/scripts/toolshed.groups.js (91%) delete mode 100644 static/scripts/mvc/groups/group-detail-view.js delete mode 100644 static/scripts/mvc/groups/group-groupdetail-view.js delete mode 100644 static/scripts/mvc/groups/group-grouprow-view.js delete mode 100644 static/scripts/mvc/groups/group-list-view.js delete mode 100644 static/scripts/mvc/groups/group.model.js delete mode 100644 static/scripts/toolshed.groups.js create mode 100644 static/toolshed/maps/mvc/groups/group-detail-view.js.map create mode 100644 static/toolshed/maps/mvc/groups/group-list-view.js.map create mode 100644 static/toolshed/maps/mvc/groups/group-listrow-view.js.map create mode 100644 static/toolshed/maps/mvc/groups/group-model.js.map create mode 100644 static/toolshed/maps/test-file.js.map create mode 100644 static/toolshed/maps/toolshed.groups.js.map create mode 100644 static/toolshed/scripts/mvc/groups/group-detail-view.js create mode 100644 static/toolshed/scripts/mvc/groups/group-list-view.js rename static/{ => toolshed}/scripts/mvc/groups/group-listrow-view.js (100%) rename static/{ => toolshed}/scripts/mvc/groups/group-model.js (100%) create mode 100644 static/toolshed/scripts/test-file.js create mode 100644 static/toolshed/scripts/toolshed.groups.js diff --git a/client/galaxy/scripts/mvc/groups/group-detail-view.js b/client/toolshed/scripts/mvc/groups/group-detail-view.js similarity index 99% rename from client/galaxy/scripts/mvc/groups/group-detail-view.js rename to client/toolshed/scripts/mvc/groups/group-detail-view.js index 062ae79274e..f00454ac6fa 100644 --- a/client/galaxy/scripts/mvc/groups/group-detail-view.js +++ b/client/toolshed/scripts/mvc/groups/group-detail-view.js @@ -1,6 +1,6 @@ define([ "libs/toastr", - "mvc/groups/group-model" + "group_model" ], function( mod_toastr, diff --git a/client/galaxy/scripts/mvc/groups/group-list-view.js b/client/toolshed/scripts/mvc/groups/group-list-view.js similarity index 96% rename from client/galaxy/scripts/mvc/groups/group-list-view.js rename to client/toolshed/scripts/mvc/groups/group-list-view.js index 3adeb0feefb..82b912c8b13 100644 --- a/client/galaxy/scripts/mvc/groups/group-list-view.js +++ b/client/toolshed/scripts/mvc/groups/group-list-view.js @@ -1,12 +1,12 @@ define([ "libs/toastr", - "mvc/groups/group-model", - "mvc/groups/group-listrow-view" + "group_model", + "group_row" ], function( mod_toastr, mod_group_model, - mod_group_listrow_view + mod_group_row ){ var GroupListView = Backbone.View.extend({ @@ -71,7 +71,7 @@ var GroupListView = Backbone.View.extend({ * @param {Group} model of the view that will be rendered */ renderOne: function( options ){ - var rowView = new mod_group_listrow_view.GroupListRowView( options ); + var rowView = new mod_group_row.GroupListRowView( options ); this.$el.find( '#group_list_body' ).append( rowView.el ); }, diff --git a/client/galaxy/scripts/mvc/groups/group-listrow-view.js b/client/toolshed/scripts/mvc/groups/group-listrow-view.js similarity index 100% rename from client/galaxy/scripts/mvc/groups/group-listrow-view.js rename to client/toolshed/scripts/mvc/groups/group-listrow-view.js diff --git a/client/galaxy/scripts/mvc/groups/group-model.js b/client/toolshed/scripts/mvc/groups/group-model.js similarity index 100% rename from client/galaxy/scripts/mvc/groups/group-model.js rename to client/toolshed/scripts/mvc/groups/group-model.js diff --git a/client/toolshed/scripts/test-file.js b/client/toolshed/scripts/test-file.js deleted file mode 100644 index 093dfad294e..00000000000 --- a/client/toolshed/scripts/test-file.js +++ /dev/null @@ -1,3 +0,0 @@ -define( [], function() { - return 'Remove this file'; -}); \ No newline at end of file diff --git a/client/galaxy/scripts/toolshed.groups.js b/client/toolshed/scripts/toolshed.groups.js similarity index 91% rename from client/galaxy/scripts/toolshed.groups.js rename to client/toolshed/scripts/toolshed.groups.js index 1785878ed51..4e02146a2fb 100644 --- a/client/galaxy/scripts/toolshed.groups.js +++ b/client/toolshed/scripts/toolshed.groups.js @@ -3,9 +3,9 @@ // MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM define([ - "mvc/groups/group-list-view", - "mvc/groups/group-detail-view", - "mvc/groups/group-model" + 'group_list', + 'group_detail', + 'group_model' ], function( mod_group_list, diff --git a/lib/galaxy/webapps/tool_shed/controllers/groups.py b/lib/galaxy/webapps/tool_shed/controllers/groups.py index 1e1e80f1351..3fac05dee17 100644 --- a/lib/galaxy/webapps/tool_shed/controllers/groups.py +++ b/lib/galaxy/webapps/tool_shed/controllers/groups.py @@ -14,7 +14,7 @@ class Group( BaseUIController ): def index( self, trans, **kwd ): # define app configuration for generic mako template app = { - 'jscript' : "toolshed.groups" + 'jscript' : "../toolshed/scripts/toolshed.groups" } return trans.fill_template( '/webapps/tool_shed/group/index.mako', config = { diff --git a/static/scripts/mvc/groups/group-detail-view.js b/static/scripts/mvc/groups/group-detail-view.js deleted file mode 100644 index fcee488d131..00000000000 --- a/static/scripts/mvc/groups/group-detail-view.js +++ /dev/null @@ -1,2 +0,0 @@ -define(["libs/toastr","mvc/groups/group-model"],function(a,b){var c=Backbone.View.extend({el:"#groups_element",options:{},app:null,initialize:function(a){this.options=_.extend(this.options,a),this.app=window.globalTS.groups,null!==this.app.collection?(this.model=this.app.collection.get(this.options.group_id),this.render()):this.fetchGroup()},fetchGroup:function(c){var d=this;this.options=_.extend(this.options,c),this.model=new b.Group({id:this.options.group_id}),this.model.fetch({success:function(a){console.log("received data: "),console.log(a),d.render()},error:function(b,c){a.error("undefined"!=typeof c.responseJSON?c.responseJSON.err_msg:"An error ocurred.")}})},render:function(){var a=this.templateRow();this.$el.html(a({group:this.model})),$("#center [data-toggle]").tooltip()},templateRow:function(){return _.template(["
",'

<%= group.get("name") %>

','

','A group of <%= group.get("members").length %> members with <%= group.get("repositories").length %> repositories and a total of <%= group.get("total_downloads") %> combined tool downloads.

',"

Members

",'',"","","","","","",'<% _.each(group.get("members"), function(member) { %>',"","","","","","<% }); %>","","
NameRepositoriesRegistered
","<%= member.username %>","",'<%= member.user_repos_count %>',"","<%= member.time_created %>","
","

Repositories

",'',"","","","","","","","","","",'<% _.each(group.get("repositories"), function(repo) { %>',"","","","","","","","","","<% }); %>","","
NameDescriptionDownloadsOwnerCreatedRatingVerified
",'<%= repo.name %>',"","<%= repo.description %>","","<%= repo.times_downloaded %>","","<%= repo.owner %>","","<%= repo.time_created %>","","<%= repo.ratings_mean %>","","<%= repo.approved %>","
","
"].join(""))}});return{GroupDetailView:c}}); -//# sourceMappingURL=../../../maps/mvc/groups/group-detail-view.js.map \ No newline at end of file diff --git a/static/scripts/mvc/groups/group-groupdetail-view.js b/static/scripts/mvc/groups/group-groupdetail-view.js deleted file mode 100644 index ac9d5f5c776..00000000000 --- a/static/scripts/mvc/groups/group-groupdetail-view.js +++ /dev/null @@ -1,2 +0,0 @@ -define([],function(){var a=Backbone.View.extend({events:{},initialize:function(a){this.render(a)},render:function(a){var b=this.templateRow();return this.setElement(b({group:a})),this.$el.show(),this},templateRow:function(){return _.template(["
TEST GROUP PAGE
"].join(""))}});return{GroupDetailView:a}}); -//# sourceMappingURL=../../../maps/mvc/groups/group-groupdetail-view.js.map \ No newline at end of file diff --git a/static/scripts/mvc/groups/group-grouprow-view.js b/static/scripts/mvc/groups/group-grouprow-view.js deleted file mode 100644 index 49178b680f1..00000000000 --- a/static/scripts/mvc/groups/group-grouprow-view.js +++ /dev/null @@ -1,2 +0,0 @@ -define([],function(){var a=Backbone.View.extend({events:{},initialize:function(a){this.render(a)},render:function(a){var b=this.templateRow();return this.setElement(b({group:a})),this.$el.show(),this},templateRow:function(){return _.template(['">','"><%= group.get("name") %>',"description",'<%= group.get("total_members") %>','<%= group.get("total_repos") %>',""].join(""))}});return{GroupRowView:a}}); -//# sourceMappingURL=../../../maps/mvc/groups/group-grouprow-view.js.map \ No newline at end of file diff --git a/static/scripts/mvc/groups/group-list-view.js b/static/scripts/mvc/groups/group-list-view.js deleted file mode 100644 index d14a196bd3f..00000000000 --- a/static/scripts/mvc/groups/group-list-view.js +++ /dev/null @@ -1,2 +0,0 @@ -define(["libs/toastr","mvc/groups/group-model","mvc/groups/group-listrow-view"],function(a,b,c){var d=Backbone.View.extend({el:"#groups_element",defaults:{},initialize:function(c){this.options=_.defaults(this.options||{},this.defaults,c);var d=this;window.globalTS.groups.collection=new b.Groups,window.globalTS.groups.collection.fetch({success:function(a){console.log("received data: "),console.log(a),d.render()},error:function(b,c){a.error("undefined"!=typeof c.responseJSON?c.responseJSON.err_msg:"An error ocurred.")}})},fetch:function(){},render:function(a){this.options=_.extend(this.options,a),$(".tooltip").hide();var b=this.templateGroupsList();this.$el.html(b({length:10,order:"asc"})),this.renderRows(window.globalTS.groups.collection.models),$("#center [data-toggle]").tooltip(),$("#center").css("overflow","auto")},renderRows:function(a){for(var b=0;b'),tmpl_array.push(""),tmpl_array.push('
'),tmpl_array.push("<% if(length === 0) { %>"),tmpl_array.push("
There are no groups yet.
"),tmpl_array.push("<% } else{ %>"),tmpl_array.push(''),tmpl_array.push(" "),tmpl_array.push(' '),tmpl_array.push(' '),tmpl_array.push(' '),tmpl_array.push(' '),tmpl_array.push(" "),tmpl_array.push(' '),tmpl_array.push(" "),tmpl_array.push("
name descriptionmembersrepositories
"),tmpl_array.push("<% }%>"),tmpl_array.push("
"),_.template(tmpl_array.join(""))}});return{GroupListView:d}}); -//# sourceMappingURL=../../../maps/mvc/groups/group-list-view.js.map \ No newline at end of file diff --git a/static/scripts/mvc/groups/group.model.js b/static/scripts/mvc/groups/group.model.js deleted file mode 100644 index b050bdad096..00000000000 --- a/static/scripts/mvc/groups/group.model.js +++ /dev/null @@ -1,2 +0,0 @@ -define([],function(){var a=Backbone.Model.extend({urlRoot:"/api/groups/"}),b=Backbone.Collection.extend({url:"/api/groups",model:a});return{Group:a,Groups:b}}); -//# sourceMappingURL=../../../maps/mvc/groups/group.model.js.map \ No newline at end of file diff --git a/static/scripts/toolshed.groups.js b/static/scripts/toolshed.groups.js deleted file mode 100644 index 4c0663b9afb..00000000000 --- a/static/scripts/toolshed.groups.js +++ /dev/null @@ -1,2 +0,0 @@ -define(["mvc/groups/group-list-view","mvc/groups/group-detail-view","mvc/groups/group-model"],function(a,b){var c=Backbone.Router.extend({routes:{"":"groups",":group_id":"group_page"}}),d=Backbone.View.extend({groupListView:null,groupDetailView:null,collection:null,initialize:function(){window.globalTS.groups=this,this.ts_router=new c,this.ts_router.on("route:groups",function(){window.globalTS.groups.groupListView=new a.GroupListView}),this.ts_router.on("route:group_page",function(a){window.globalTS.groups.groupDetailView=new b.GroupDetailView({group_id:a})}),Backbone.history.start({pushState:!1})}});return{ToolshedGroups:d}}); -//# sourceMappingURL=../maps/toolshed.groups.js.map \ No newline at end of file diff --git a/static/toolshed/maps/mvc/groups/group-detail-view.js.map b/static/toolshed/maps/mvc/groups/group-detail-view.js.map new file mode 100644 index 00000000000..9324e9d2023 --- /dev/null +++ b/static/toolshed/maps/mvc/groups/group-detail-view.js.map @@ -0,0 +1 @@ +{"version":3,"file":"group-detail-view.js","sources":["../../../src/mvc/groups/group-detail-view.js"],"names":["define","mod_toastr","mod_group_model","GroupDetailView","Backbone","View","extend","el","options","app","initialize","this","_","window","globalTS","groups","collection","model","get","group_id","render","fetchGroup","that","Group","id","fetch","success","console","log","error","response","responseJSON","err_msg","template","templateRow","$el","html","group","$","tooltip","join"],"mappings":"AAAAA,QACI,cACA,eAEJ,SACIC,EACAC,GAIJ,GAAIC,GAAkBC,SAASC,KAAKC,QAChCC,GAAI,kBACJC,WACAC,IAAK,KAELC,WAAa,SAAUF,GACnBG,KAAKH,QAAUI,EAAEN,OAAQK,KAAKH,QAASA,GACvCG,KAAKF,IAAMI,OAAOC,SAASC,OAEE,OAAxBJ,KAAKF,IAAIO,YACVL,KAAKM,MAAQN,KAAKF,IAAIO,WAAWE,IAAKP,KAAKH,QAAQW,UACnDR,KAAKS,UAELT,KAAKU,cAKbA,WAAY,SAAUb,GAClB,GAAIc,GAAOX,IACXA,MAAKH,QAAUI,EAAEN,OAAQK,KAAKH,QAASA,GACvCG,KAAKM,MAAQ,GAAIf,GAAgBqB,OAASC,GAAIb,KAAKH,QAAQW,WAC3DR,KAAKM,MAAMQ,OACTC,QAAS,SAAUT,GACjBU,QAAQC,IAAK,mBACbD,QAAQC,IAAKX,GACbK,EAAKF,UAEPS,MAAO,SAAUZ,EAAOa,GAElB7B,EAAW4B,MADyB,mBAA1BC,GAASC,aACDD,EAASC,aAAaC,QAEtB,yBAM9BZ,OAAQ,WACJ,GAAIa,GAAWtB,KAAKuB,aACpBvB,MAAKwB,IAAIC,KAAMH,GAAYI,MAAO1B,KAAKM,SACvCqB,EAAE,yBAAyBC,WAG/BL,YAAa,WACT,MAAOtB,GAAEqB,UACD,QACI,oCACA,mCACA,kMAEA,mBACA,6CACI,UACI,gBACA,wBACA,sBACJ,WACA,UACI,wDACA,OACI,OACI,yBACJ,QACA,OACI,gPACJ,QACA,OACI,6BACJ,QACJ,QACA,YACJ,WACJ,WAEA,wBACA,6CACI,UACI,gBACA,uBACA,qBACA,iBACA,mBACA,kBACA,oBACJ,WACA,UACI,2DACA,OACI,OACI,6KACJ,QACA,OACI,0BACJ,QACA,OACI,+BACJ,QACA,OACI,oBACJ,QACA,OACI,2BACJ,QACA,OACI,2BACJ,QACA,OACI,uBACJ,QACJ,QACA,YACJ,WACJ,WACJ,UACNO,KAAK,OAGf,QACIrC,gBAAiBA"} \ No newline at end of file diff --git a/static/toolshed/maps/mvc/groups/group-list-view.js.map b/static/toolshed/maps/mvc/groups/group-list-view.js.map new file mode 100644 index 00000000000..f440744e057 --- /dev/null +++ b/static/toolshed/maps/mvc/groups/group-list-view.js.map @@ -0,0 +1 @@ +{"version":3,"file":"group-list-view.js","sources":["../../../src/mvc/groups/group-list-view.js"],"names":["define","mod_toastr","mod_group_model","mod_group_row","GroupListView","Backbone","View","extend","el","defaults","initialize","options","this","_","that","window","globalTS","groups","collection","Groups","fetch","success","model","console","log","render","error","response","responseJSON","err_msg","$","hide","template","templateGroupsList","$el","html","length","order","renderRows","models","tooltip","css","groups_to_render","i","group","renderOne","rowView","GroupListRowView","find","append","tmpl_array","push","join"],"mappings":"AAAAA,QACI,cACA,cACA,aAED,SACCC,EACAC,EACAC,GAGJ,GAAIC,GAAgBC,SAASC,KAAKC,QAC9BC,GAAI,kBACJC,YAOAC,WAAa,SAAUC,GACnBC,KAAKD,QAAUE,EAAEJ,SAAUG,KAAKD,YAAeC,KAAKH,SAAUE,EAC9D,IAAIG,GAAOF,IACXG,QAAOC,SAASC,OAAOC,WAAa,GAAIhB,GAAgBiB,OACxDJ,OAAOC,SAASC,OAAOC,WAAWE,OAChCC,QAAS,SAAUC,GACjBC,QAAQC,IAAK,mBACbD,QAAQC,IAAKF,GACbR,EAAKW,UAEPC,MAAO,SAAUJ,EAAOK,GAElB1B,EAAWyB,MADyB,mBAA1BC,GAASC,aACDD,EAASC,aAAaC,QAEtB,yBAO9BT,MAAO,aAMPK,OAAQ,SAAWd,GACfC,KAAKD,QAAUE,EAAEN,OAAQK,KAAKD,QAASA,GACvCmB,EAAG,YAAaC,MAChB,IAAIC,GAAWpB,KAAKqB,oBACpBrB,MAAKsB,IAAIC,KAAMH,GAAYI,OAAQ,GAAIC,MAAO,SAC9CzB,KAAK0B,WAAYvB,OAAOC,SAASC,OAAOC,WAAWqB,QACnDT,EAAG,yBAA0BU,UAC7BV,EAAG,WAAYW,IAAK,WAAW,SAOnCH,WAAY,SAAUI,GAClB,IAAM,GAAIC,GAAI,EAAGA,EAAID,EAAiBN,OAAQO,IAAM,CAChD,GAAIC,GAAQF,EAAiBC,EAC7B/B,MAAKiC,WAAaD,MAAOA,MAQjCC,UAAW,SAAUlC,GACjB,GAAImC,GAAU,GAAI3C,GAAc4C,iBAAkBpC,EAClDC,MAAKsB,IAAIc,KAAM,oBAAqBC,OAAQH,EAAQtC,KAyCxDyB,mBAAoB,WAuBhB,MAtBAiB,eAEAA,WAAWC,KAAK,qBAChBD,WAAWC,KAAK,UAChBD,WAAWC,KAAK,mDAChBD,WAAWC,KAAK,4BAChBD,WAAWC,KAAK,uCAChBD,WAAWC,KAAK,iBAChBD,WAAWC,KAAK,8CAChBD,WAAWC,KAAK,cAChBD,WAAWC,KAAK,mMAChBD,WAAWC,KAAK,gDAChBD,WAAWC,KAAK,6CAChBD,WAAWC,KAAK,iDAChBD,WAAWC,KAAK,eAChBD,WAAWC,KAAK,mCAEhBD,WAAWC,KAAK,eAChBD,WAAWC,KAAK,YAChBD,WAAWC,KAAK,UAChBD,WAAWC,KAAK,UAETtC,EAAEmB,SAASkB,WAAWE,KAAK,OAK1C,QACIhD,cAAeA"} \ No newline at end of file diff --git a/static/toolshed/maps/mvc/groups/group-listrow-view.js.map b/static/toolshed/maps/mvc/groups/group-listrow-view.js.map new file mode 100644 index 00000000000..a3a50073eab --- /dev/null +++ b/static/toolshed/maps/mvc/groups/group-listrow-view.js.map @@ -0,0 +1 @@ +{"version":3,"file":"group-listrow-view.js","sources":["../../../src/mvc/groups/group-listrow-view.js"],"names":["define","GroupListRowView","Backbone","View","extend","events","initialize","options","this","render","group","tmpl","templateRow","setElement","$el","show","_","template","join"],"mappings":"AAAAA,UACA,WAGA,GAAIC,GAAmBC,SAASC,KAAKC,QACjCC,UAEAC,WAAa,SAAUC,GACnBC,KAAKC,OAAQF,EAAQG,QAGzBD,OAAQ,SAAUC,GACd,GAAIC,GAAOH,KAAKI,aAGhB,OAFAJ,MAAKK,WAAWF,GAAQD,MAAMA,KAC9BF,KAAKM,IAAIC,OACFP,MAGXI,YAAa,WACT,MAAOI,GAAEC,UACD,iDACA,iFACA,uBACA,6CACA,2CACA,SACNC,KAAK,OAKf,QACIjB,iBAAkBA"} \ No newline at end of file diff --git a/static/toolshed/maps/mvc/groups/group-model.js.map b/static/toolshed/maps/mvc/groups/group-model.js.map new file mode 100644 index 00000000000..7cf16222049 --- /dev/null +++ b/static/toolshed/maps/mvc/groups/group-model.js.map @@ -0,0 +1 @@ +{"version":3,"file":"group-model.js","sources":["../../../src/mvc/groups/group-model.js"],"names":["define","Group","Backbone","Model","extend","urlRoot","Groups","Collection","url","model"],"mappings":"AAAAA,UAAW,WAKP,GAAIC,GAAQC,SAASC,MAAMC,QACzBC,QAAS,gBAGPC,EAASJ,SAASK,WAAWH,QAC/BI,IAAK,cAELC,MAAOR,GAIb,QACIA,MAAOA,EACPK,OAAQA"} \ No newline at end of file diff --git a/static/toolshed/maps/test-file.js.map b/static/toolshed/maps/test-file.js.map new file mode 100644 index 00000000000..60e635db925 --- /dev/null +++ b/static/toolshed/maps/test-file.js.map @@ -0,0 +1 @@ +{"version":3,"file":"test-file.js","sources":["../src/test-file.js"],"names":["define"],"mappings":"AAAAA,UAAY,WACX,MAAO"} \ No newline at end of file diff --git a/static/toolshed/maps/toolshed.groups.js.map b/static/toolshed/maps/toolshed.groups.js.map new file mode 100644 index 00000000000..f8ba4759d22 --- /dev/null +++ b/static/toolshed/maps/toolshed.groups.js.map @@ -0,0 +1 @@ +{"version":3,"file":"toolshed.groups.js","sources":["../src/toolshed.groups.js"],"names":["define","mod_group_list","mod_group_detail","ToolshedRouter","Backbone","Router","extend","routes",":group_id","ToolshedGroups","View","groupListView","groupDetailView","collection","initialize","window","globalTS","groups","this","ts_router","on","GroupListView","group_id","GroupDetailView","history","start","pushState"],"mappings":"AAIAA,QACQ,aACA,eACA,eAEJ,SACIC,EACAC,GAMR,GAAIC,GAAiBC,SAASC,OAAOC,QACjCC,QACI,GAA4B,SAC5BC,YAA4B,gBAKhCC,EAAiBL,SAASM,KAAKJ,QAC/BK,cAAe,KACfC,gBAAiB,KACjBC,WAAY,KAEZC,WAAa,WACTC,OAAOC,SAASC,OAASC,KAEzBA,KAAKC,UAAY,GAAIhB,GACrBe,KAAKC,UAAUC,GAAI,eAAgB,WAC/BL,OAAOC,SAASC,OAAON,cAAgB,GAAIV,GAAeoB,gBAG9DH,KAAKC,UAAUC,GAAI,mBAAoB,SAAUE,GAC7CP,OAAOC,SAASC,OAAOL,gBAAkB,GAAIV,GAAiBqB,iBAAmBD,SAAUA,MAG/FlB,SAASoB,QAAQC,OAAOC,WAAW,MAI3C,QACIjB,eAAgBA"} \ No newline at end of file diff --git a/static/toolshed/scripts/mvc/groups/group-detail-view.js b/static/toolshed/scripts/mvc/groups/group-detail-view.js new file mode 100644 index 00000000000..a4ecf8189a1 --- /dev/null +++ b/static/toolshed/scripts/mvc/groups/group-detail-view.js @@ -0,0 +1,2 @@ +define(["libs/toastr","group_model"],function(a,b){var c=Backbone.View.extend({el:"#groups_element",options:{},app:null,initialize:function(a){this.options=_.extend(this.options,a),this.app=window.globalTS.groups,null!==this.app.collection?(this.model=this.app.collection.get(this.options.group_id),this.render()):this.fetchGroup()},fetchGroup:function(c){var d=this;this.options=_.extend(this.options,c),this.model=new b.Group({id:this.options.group_id}),this.model.fetch({success:function(a){console.log("received data: "),console.log(a),d.render()},error:function(b,c){a.error("undefined"!=typeof c.responseJSON?c.responseJSON.err_msg:"An error ocurred.")}})},render:function(){var a=this.templateRow();this.$el.html(a({group:this.model})),$("#center [data-toggle]").tooltip()},templateRow:function(){return _.template(["
",'

<%= group.get("name") %>

','

','A group of <%= group.get("members").length %> members with <%= group.get("repositories").length %> repositories and a total of <%= group.get("total_downloads") %> combined tool downloads.

',"

Members

",'',"","","","","","",'<% _.each(group.get("members"), function(member) { %>',"","","","","","<% }); %>","","
NameRepositoriesRegistered
","<%= member.username %>","",'<%= member.user_repos_count %>',"","<%= member.time_created %>","
","

Repositories

",'',"","","","","","","","","","",'<% _.each(group.get("repositories"), function(repo) { %>',"","","","","","","","","","<% }); %>","","
NameDescriptionDownloadsOwnerCreatedRatingVerified
",'<%= repo.name %>',"","<%= repo.description %>","","<%= repo.times_downloaded %>","","<%= repo.owner %>","","<%= repo.time_created %>","","<%= repo.ratings_mean %>","","<%= repo.approved %>","
","
"].join(""))}});return{GroupDetailView:c}}); +//# sourceMappingURL=../../../maps/mvc/groups/group-detail-view.js.map \ No newline at end of file diff --git a/static/toolshed/scripts/mvc/groups/group-list-view.js b/static/toolshed/scripts/mvc/groups/group-list-view.js new file mode 100644 index 00000000000..2d6b5f0b477 --- /dev/null +++ b/static/toolshed/scripts/mvc/groups/group-list-view.js @@ -0,0 +1,2 @@ +define(["libs/toastr","group_model","group_row"],function(a,b,c){var d=Backbone.View.extend({el:"#groups_element",defaults:{},initialize:function(c){this.options=_.defaults(this.options||{},this.defaults,c);var d=this;window.globalTS.groups.collection=new b.Groups,window.globalTS.groups.collection.fetch({success:function(a){console.log("received data: "),console.log(a),d.render()},error:function(b,c){a.error("undefined"!=typeof c.responseJSON?c.responseJSON.err_msg:"An error ocurred.")}})},fetch:function(){},render:function(a){this.options=_.extend(this.options,a),$(".tooltip").hide();var b=this.templateGroupsList();this.$el.html(b({length:10,order:"asc"})),this.renderRows(window.globalTS.groups.collection.models),$("#center [data-toggle]").tooltip(),$("#center").css("overflow","auto")},renderRows:function(a){for(var b=0;b'),tmpl_array.push(""),tmpl_array.push('
'),tmpl_array.push("<% if(length === 0) { %>"),tmpl_array.push("
There are no groups yet.
"),tmpl_array.push("<% } else{ %>"),tmpl_array.push(''),tmpl_array.push(" "),tmpl_array.push(' '),tmpl_array.push(' '),tmpl_array.push(' '),tmpl_array.push(' '),tmpl_array.push(" "),tmpl_array.push(' '),tmpl_array.push(" "),tmpl_array.push("
name descriptionmembersrepositories
"),tmpl_array.push("<% }%>"),tmpl_array.push("
"),_.template(tmpl_array.join(""))}});return{GroupListView:d}}); +//# sourceMappingURL=../../../maps/mvc/groups/group-list-view.js.map \ No newline at end of file diff --git a/static/scripts/mvc/groups/group-listrow-view.js b/static/toolshed/scripts/mvc/groups/group-listrow-view.js similarity index 100% rename from static/scripts/mvc/groups/group-listrow-view.js rename to static/toolshed/scripts/mvc/groups/group-listrow-view.js diff --git a/static/scripts/mvc/groups/group-model.js b/static/toolshed/scripts/mvc/groups/group-model.js similarity index 100% rename from static/scripts/mvc/groups/group-model.js rename to static/toolshed/scripts/mvc/groups/group-model.js diff --git a/static/toolshed/scripts/test-file.js b/static/toolshed/scripts/test-file.js new file mode 100644 index 00000000000..57532f0ce9d --- /dev/null +++ b/static/toolshed/scripts/test-file.js @@ -0,0 +1,2 @@ +define([],function(){return"Remove this file"}); +//# sourceMappingURL=../maps/test-file.js.map \ No newline at end of file diff --git a/static/toolshed/scripts/toolshed.groups.js b/static/toolshed/scripts/toolshed.groups.js new file mode 100644 index 00000000000..92f9e3f2f28 --- /dev/null +++ b/static/toolshed/scripts/toolshed.groups.js @@ -0,0 +1,2 @@ +define(["group_list","group_detail","group_model"],function(a,b){var c=Backbone.Router.extend({routes:{"":"groups",":group_id":"group_page"}}),d=Backbone.View.extend({groupListView:null,groupDetailView:null,collection:null,initialize:function(){window.globalTS.groups=this,this.ts_router=new c,this.ts_router.on("route:groups",function(){window.globalTS.groups.groupListView=new a.GroupListView}),this.ts_router.on("route:group_page",function(a){window.globalTS.groups.groupDetailView=new b.GroupDetailView({group_id:a})}),Backbone.history.start({pushState:!1})}});return{ToolshedGroups:d}}); +//# sourceMappingURL=../maps/toolshed.groups.js.map \ No newline at end of file diff --git a/templates/webapps/tool_shed/group/index.mako b/templates/webapps/tool_shed/group/index.mako index e070faec5ee..f72eedb6e72 100644 --- a/templates/webapps/tool_shed/group/index.mako +++ b/templates/webapps/tool_shed/group/index.mako @@ -41,6 +41,14 @@