commit/galaxy-central: greg: Add the ability for a tool shed admin to delete / undelete repositories. Fix the display for TextArea fields in the tool shed. Fix a bug in the Advanced search gid feature - the Advanced search box will now correctly close even if the grid's default_filter dictionary is not empty. Add the ability to not render the Advanced search box on a grid by passing a flag value to the render method.
1 new changeset in galaxy-central: http://bitbucket.org/galaxy/galaxy-central/changeset/c2d266a4a8f8/ changeset: c2d266a4a8f8 user: greg date: 2011-06-30 18:13:20 summary: Add the ability for a tool shed admin to delete / undelete repositories. Fix the display for TextArea fields in the tool shed. Fix a bug in the Advanced search gid feature - the Advanced search box will now correctly close even if the grid's default_filter dictionary is not empty. Add the ability to not render the Advanced search box on a grid by passing a flag value to the render method. affected #: 10 files (2.9 KB) --- a/lib/galaxy/web/framework/helpers/grids.py Thu Jun 30 11:45:24 2011 -0400 +++ b/lib/galaxy/web/framework/helpers/grids.py Thu Jun 30 12:13:20 2011 -0400 @@ -626,6 +626,13 @@ args = { self.key: val } accepted_filters.append( GridColumnFilter( label, args) ) return accepted_filters + def filter( self, trans, user, query, column_filter ): + """Modify query to filter self.model_class by state.""" + if column_filter == "All": + pass + elif column_filter in [ "True", "False" ]: + query = query.filter( self.model_class.deleted == column_filter ) + return query class StateColumn( GridColumn ): """ --- a/lib/galaxy/webapps/community/controllers/admin.py Thu Jun 30 11:45:24 2011 -0400 +++ b/lib/galaxy/webapps/community/controllers/admin.py Thu Jun 30 12:13:20 2011 -0400 @@ -2,6 +2,7 @@ from galaxy.webapps.community import model from galaxy.model.orm import * from galaxy.web.framework.helpers import time_ago, iff, grids +from galaxy.util import inflector from common import get_category, get_repository from repository import RepositoryListGrid, CategoryListGrid import logging @@ -282,39 +283,30 @@ preserve_state = False use_paging = True -class AdminCategoryListGrid( CategoryListGrid ): - # Override standard filters - standard_filters = [ - grids.GridColumnFilter( "Active", args=dict( deleted=False ) ), - grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ), - grids.GridColumnFilter( "All", args=dict( deleted='All' ) ) - ] - class ManageCategoryListGrid( CategoryListGrid ): columns = [ col for col in CategoryListGrid.columns ] # Override the NameColumn to include an Edit link columns[ 0 ] = CategoryListGrid.NameColumn( "Name", - key="name", + key="Category.name", link=( lambda item: dict( operation="Edit", id=item.id, webapp="community" ) ), model_class=model.Category, - attach_popup=False, - filterable="advanced" ) + attach_popup=False ) global_actions = [ grids.GridAction( "Add new category", dict( controller='admin', action='manage_categories', operation='create', webapp="community" ) ) ] - operations = [ grids.GridOperation( "Delete", - condition=( lambda item: not item.deleted ), - allow_multiple=True, - url_args=dict( webapp="community", action="mark_category_deleted" ) ), - grids.GridOperation( "Undelete", - condition=( lambda item: item.deleted ), - allow_multiple=True, - url_args=dict( webapp="community", action="undelete_category" ) ), - grids.GridOperation( "Purge", - condition=( lambda item: item.deleted ), - allow_multiple=True, - url_args=dict( webapp="community", action="purge_category" ) ) ] + +class AdminRepositoryListGrid( RepositoryListGrid ): + operations = [ operation for operation in RepositoryListGrid.operations ] + operations.append( grids.GridOperation( "Delete", + allow_multiple=True, + condition=( lambda item: not item.deleted ), + async_compatible=False ) ) + operations.append( grids.GridOperation( "Undelete", + allow_multiple=True, + condition=( lambda item: item.deleted ), + async_compatible=False ) ) + standard_filters = [] class AdminController( BaseController, Admin ): @@ -322,7 +314,7 @@ role_list_grid = RoleListGrid() group_list_grid = GroupListGrid() manage_category_list_grid = ManageCategoryListGrid() - repository_list_grid = RepositoryListGrid() + repository_list_grid = AdminRepositoryListGrid() @web.expose @web.require_admin @@ -363,10 +355,81 @@ category_id = kwd.get( 'id', None ) category = get_category( trans, category_id ) kwd[ 'f-Category.name' ] = category.name + elif operation == "receive email alerts": + if kwd[ 'id' ]: + return trans.response.send_redirect( web.url_for( controller='repository', + action='set_email_alerts', + **kwd ) ) + else: + del kwd[ 'operation' ] + elif operation == 'delete': + return self.mark_repository_deleted( trans, **kwd ) + elif operation == "undelete": + return self.undelete_repository( trans, **kwd ) # Render the list view return self.repository_list_grid( trans, **kwd ) @web.expose @web.require_admin + def mark_repository_deleted( self, trans, **kwd ): + params = util.Params( kwd ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) + id = kwd.get( 'id', None ) + if id: + ids = util.listify( id ) + count = 0 + deleted_repositories = "" + for repository_id in ids: + repository = get_repository( trans, repository_id ) + if not repository.deleted: + repository.deleted = True + trans.sa_session.add( repository ) + trans.sa_session.flush() + count += 1 + deleted_repositories += " %s " % repository.name + if count: + message = "Deleted %d %s: %s" % ( count, inflector.cond_plural( len( ids ), "repository" ), deleted_repositories ) + else: + message = "All selected repositories were already marked deleted." + else: + message = "No repository ids received for deleting." + status = 'error' + trans.response.send_redirect( web.url_for( controller='admin', + action='browse_repositories', + message=util.sanitize_text( message ), + status=status ) ) + @web.expose + @web.require_admin + def undelete_repository( self, trans, **kwd ): + params = util.Params( kwd ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) + id = kwd.get( 'id', None ) + if id: + ids = util.listify( id ) + count = 0 + undeleted_repositories = "" + for repository_id in ids: + repository = get_repository( trans, repository_id ) + if repository.deleted: + repository.deleted = False + trans.sa_session.add( repository ) + trans.sa_session.flush() + count += 1 + undeleted_repositories += " %s" % repository.name + if count: + message = "Undeleted %d %s: %s" % ( count, inflector.cond_plural( count, "repository" ), undeleted_repositories ) + else: + message = "No selected repositories were marked deleted, so they could not be undeleted." + else: + message = "No repository ids received for undeleting." + status = 'error' + trans.response.send_redirect( web.url_for( controller='admin', + action='browse_repositories', + message=util.sanitize_text( message ), + status='done' ) ) + @web.expose + @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. @@ -476,22 +539,25 @@ @web.expose @web.require_admin def mark_category_deleted( self, trans, **kwd ): + # TODO: We should probably eliminate the Category.deleted column since it really makes no + # sense to mark a category as deleted (category names and descriptions can be changed instead). + # If we do this, and the following 2 methods can be eliminated. params = util.Params( kwd ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) id = kwd.get( 'id', None ) - if not id: - message = "No category ids received for deleting" - trans.response.send_redirect( web.url_for( controller='admin', - action='manage_categories', - message=message, - status='error' ) ) - ids = util.listify( id ) - message = "Deleted %d categories: " % len( ids ) - for category_id in ids: - category = get_category( trans, category_id ) - category.deleted = True - trans.sa_session.add( category ) - trans.sa_session.flush() - message += " %s " % category.name + if id: + ids = util.listify( id ) + message = "Deleted %d categories: " % len( ids ) + for category_id in ids: + category = get_category( trans, category_id ) + category.deleted = True + trans.sa_session.add( category ) + trans.sa_session.flush() + message += " %s " % category.name + else: + message = "No category ids received for deleting." + status = 'error' trans.response.send_redirect( web.url_for( controller='admin', action='manage_categories', message=util.sanitize_text( message ), @@ -500,30 +566,25 @@ @web.require_admin def undelete_category( self, trans, **kwd ): params = util.Params( kwd ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) id = kwd.get( 'id', None ) - if not id: - message = "No category ids received for undeleting" - trans.response.send_redirect( web.url_for( controller='admin', - action='manage_categories', - message=message, - status='error' ) ) - ids = util.listify( id ) - count = 0 - undeleted_categories = "" - for category_id in ids: - category = get_category( trans, category_id ) - if not category.deleted: - message = "Category '%s' has not been deleted, so it cannot be undeleted." % category.name - trans.response.send_redirect( web.url_for( controller='admin', - action='manage_categories', - message=util.sanitize_text( message ), - status='error' ) ) - category.deleted = False - trans.sa_session.add( category ) - trans.sa_session.flush() - count += 1 - undeleted_categories += " %s" % category.name - message = "Undeleted %d categories: %s" % ( count, undeleted_categories ) + if id: + ids = util.listify( id ) + count = 0 + undeleted_categories = "" + for category_id in ids: + category = get_category( trans, category_id ) + if category.deleted: + category.deleted = False + trans.sa_session.add( category ) + trans.sa_session.flush() + count += 1 + undeleted_categories += " %s" % category.name + message = "Undeleted %d categories: %s" % ( count, undeleted_categories ) + else: + message = "No category ids received for undeleting." + status = 'error' trans.response.send_redirect( web.url_for( controller='admin', action='manage_categories', message=util.sanitize_text( message ), @@ -535,28 +596,26 @@ # Purging a deleted Category deletes all of the following from the database: # - RepoitoryCategoryAssociations where category_id == Category.id params = util.Params( kwd ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) id = kwd.get( 'id', None ) - if not id: - message = "No category ids received for purging" - trans.response.send_redirect( web.url_for( controller='admin', - action='manage_categories', - message=util.sanitize_text( message ), - status='error' ) ) - ids = util.listify( id ) - message = "Purged %d categories: " % len( ids ) - for category_id in ids: - category = get_category( trans, category_id ) - if not category.deleted: - message = "Category '%s' has not been deleted, so it cannot be purged." % category.name - trans.response.send_redirect( web.url_for( controller='admin', - action='manage_categories', - message=util.sanitize_text( message ), - status='error' ) ) - # Delete RepositoryCategoryAssociations - for rca in category.repositories: - trans.sa_session.delete( rca ) - trans.sa_session.flush() - message += " %s " % category.name + if id: + ids = util.listify( id ) + count = 0 + purged_categories = "" + message = "Purged %d categories: " % len( ids ) + for category_id in ids: + category = get_category( trans, category_id ) + if category.deleted: + # Delete RepositoryCategoryAssociations + for rca in category.repositories: + trans.sa_session.delete( rca ) + trans.sa_session.flush() + purged_categories += " %s " % category.name + message = "Purged %d categories: %s" % ( count, purged_categories ) + else: + message = "No category ids received for purging." + status = 'error' trans.response.send_redirect( web.url_for( controller='admin', action='manage_categories', message=util.sanitize_text( message ), --- a/lib/galaxy/webapps/community/controllers/repository.py Thu Jun 30 11:45:24 2011 -0400 +++ b/lib/galaxy/webapps/community/controllers/repository.py Thu Jun 30 12:13:20 2011 -0400 @@ -50,25 +50,19 @@ default_sort_key = "name" columns = [ NameColumn( "Name", - key="name", + key="Category.name", link=( lambda item: dict( operation="repositories_by_category", id=item.id, webapp="community" ) ), - attach_popup=False, - filterable="advanced" ), + attach_popup=False ), DescriptionColumn( "Description", - key="description", - attach_popup=False, - filterable="advanced" ), + key="Category.description", + attach_popup=False ), # Columns that are valid for filtering but are not visible. - grids.DeletedColumn( "Deleted", - key="deleted", - visible=False, - filterable="advanced" ), RepositoriesColumn( "Repositories", model_class=model.Repository, attach_popup=False ) ] - # Override these + default_filter = {} global_actions = [] operations = [] standard_filters = [] @@ -102,7 +96,7 @@ def filter( self, trans, user, query, column_filter ): """Modify query to filter by category.""" if column_filter == "All": - pass + return query return query.filter( model.Category.name == column_filter ) class UserColumn( grids.TextColumn ): def get_value( self, trans, grid, repository ): @@ -127,7 +121,7 @@ default_sort_key = "name" columns = [ NameColumn( "Name", - key="Repository.name", + key="name", link=( lambda item: dict( operation="view_or_manage_repository", id=item.id, webapp="community" ) ), attach_popup=False ), DescriptionColumn( "Description", @@ -143,20 +137,22 @@ model_class=model.User, link=( lambda item: dict( operation="repositories_by_user", id=item.id, webapp="community" ) ), attach_popup=False, - key="username" ), - grids.CommunityRatingColumn( "Average Rating", - key="rating" ), - EmailAlertsColumn( "Alert", - attach_popup=False ), + key="User.username" ), + grids.CommunityRatingColumn( "Average Rating", key="rating" ), + EmailAlertsColumn( "Alert", attach_popup=False ), # Columns that are valid for filtering but are not visible. EmailColumn( "Email", model_class=model.User, - key="email", + key="User.email", visible=False ), RepositoryCategoryColumn( "Category", model_class=model.Category, key="Category.name", - visible=False ) + visible=False ), + grids.DeletedColumn( "Deleted", + key="deleted", + visible=False, + filterable="advanced" ) ] columns.append( grids.MulticolFilterColumn( "Search repository name, description", cols_to_filter=[ columns[0], columns[1] ], @@ -168,7 +164,7 @@ condition=( lambda item: not item.deleted ), async_compatible=False ) ] standard_filters = [] - default_filter = {} + default_filter = dict( deleted="False" ) num_rows_per_page = 50 preserve_state = False use_paging = True --- a/templates/grid_common.mako Thu Jun 30 11:45:24 2011 -0400 +++ b/templates/grid_common.mako Thu Jun 30 12:13:20 2011 -0400 @@ -102,7 +102,7 @@ </%def> ## Print grid search/filtering UI. -<%def name="render_grid_filters( grid )"> +<%def name="render_grid_filters( grid, render_advanced_search=True )"> ## Standard search. <div id="standard-search"><table> @@ -124,11 +124,12 @@ ## Only show advanced search if there are filterable columns. <% show_advanced_search_link = False - for column in grid.columns: - if column.filterable == "advanced": - show_advanced_search_link = True - break - endif + if render_advanced_search: + for column in grid.columns: + if column.filterable == "advanced": + show_advanced_search_link = True + break + endif %> %if show_advanced_search_link: <% args = { "advanced-search" : True } %> @@ -170,7 +171,7 @@ %if column.key in cur_filter_dict and column.key in default_filter_dict and \ cur_filter_dict[column.key] != default_filter_dict[column.key]: <script type="text/javascript"> - $('#advanced-search').css("display", "block"); + $('#advanced-search').css("display", "none"); </script> %endif --- a/templates/webapps/community/category/grid.mako Thu Jun 30 11:45:24 2011 -0400 +++ b/templates/webapps/community/category/grid.mako Thu Jun 30 12:13:20 2011 -0400 @@ -25,7 +25,7 @@ %endif </ul> %endif - ${render_grid_filters( repo_grid )} + ${render_grid_filters( repo_grid, render_advanced_search=False )} </div></%def> --- a/templates/webapps/community/repository/create_repository.mako Thu Jun 30 11:45:24 2011 -0400 +++ b/templates/webapps/community/repository/create_repository.mako Thu Jun 30 12:13:20 2011 -0400 @@ -31,7 +31,7 @@ <div class="form-row"><label>Detailed description:</label> %if long_description: - <textarea name="long_description" rows="3" cols="80">${long_description}</textarea> + <pre><textarea name="long_description" rows="3" cols="80">${long_description}</textarea></pre> %else: <textarea name="long_description" rows="3" cols="80"></textarea> %endif --- a/templates/webapps/community/repository/manage_repository.mako Thu Jun 30 11:45:24 2011 -0400 +++ b/templates/webapps/community/repository/manage_repository.mako Thu Jun 30 12:13:20 2011 -0400 @@ -112,7 +112,7 @@ <div class="form-row"><label>Detailed description:</label> %if long_description: - <textarea name="long_description" rows="3" cols="80">${long_description}</textarea> + <pre><textarea name="long_description" rows="3" cols="80">${long_description}</textarea></pre> %else: <textarea name="long_description" rows="3" cols="80"></textarea> %endif @@ -247,7 +247,7 @@ %><tr><td>${render_star_rating( name, review.rating, disabled=True )}</td> - <td>${review.comment}</td> + <td><pre>${review.comment}</pre></td><td>${time_ago( review.update_time )}</td><td>${review.user.username}</td></tr> --- a/templates/webapps/community/repository/rate_repository.mako Thu Jun 30 11:45:24 2011 -0400 +++ b/templates/webapps/community/repository/rate_repository.mako Thu Jun 30 12:13:20 2011 -0400 @@ -142,9 +142,13 @@ <div class="form-row"><label>Review:</label> %if rra and rra.comment: - <div class="form-row-input"><textarea name="comment" rows="5" cols="35">${rra.comment}</textarea></div> + <div class="form-row-input"> + <pre><textarea name="comment" rows="5" cols="80">${rra.comment}</textarea></pre> + </div> %else: - <div class="form-row-input"><textarea name="comment" rows="5" cols="35"></textarea></div> + <div class="form-row-input"> + <textarea name="comment" rows="5" cols="80"></textarea> + </div> %endif <div style="clear: both"></div></div> @@ -179,7 +183,7 @@ %><tr><td>${render_star_rating( name, review.rating, disabled=True )}</td> - <td>${review.comment}</td> + <td><pre>${review.comment}</pre></td><td>${time_ago( review.update_time )}</td><td>${review.user.username}</td></tr> --- a/templates/webapps/community/repository/upload.mako Thu Jun 30 11:45:24 2011 -0400 +++ b/templates/webapps/community/repository/upload.mako Thu Jun 30 12:13:20 2011 -0400 @@ -125,7 +125,7 @@ <label>Change set commit message:</label><div class="form-row-input"> %if commit_message: - <textarea name="commit_message" rows="3" cols="35">${commit_message}</textarea> + <pre><textarea name="commit_message" rows="3" cols="35">${commit_message}</textarea></pre> %else: <textarea name="commit_message" rows="3" cols="35"></textarea> %endif --- a/templates/webapps/community/repository/view_repository.mako Thu Jun 30 11:45:24 2011 -0400 +++ b/templates/webapps/community/repository/view_repository.mako Thu Jun 30 12:13:20 2011 -0400 @@ -113,7 +113,7 @@ %if repository.long_description: <div class="form-row"><label>Detailed description:</label> - ${repository.long_description} + <pre>${repository.long_description}</pre><div style="clear: both"></div></div> %endif @@ -206,7 +206,7 @@ %><tr><td>${render_star_rating( name, review.rating, disabled=True )}</td> - <td>${review.comment}</td> + <td><pre>${review.comment}</pre></td><td>${time_ago( review.update_time )}</td><td>${review.user.username}</td></tr> 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.
participants (1)
-
Bitbucket