From 5dde45d61be4fb3ff9daf4956351cab0e1eb967f Mon Sep 17 00:00:00 2001 From: Greg Von Kuster Date: Thu, 2 Jun 2011 15:18:35 -0400 Subject: [PATCH] Eliminate all suport for tool / tool suite archives from the tool shed. Yikes! --- community_wsgi.ini.sample | 3 - lib/galaxy/web/base/controller.py | 10 - lib/galaxy/webapps/community/app.py | 11 +- lib/galaxy/webapps/community/buildapp.py | 13 +- lib/galaxy/webapps/community/config.py | 1 - .../webapps/community/controllers/admin.py | 308 +--------- .../webapps/community/controllers/common.py | 525 +----------------- .../community/controllers/repository.py | 4 +- .../webapps/community/controllers/tool.py | 214 ------- .../community/controllers/tool_upload.py | 183 ------ lib/galaxy/webapps/community/model/mapping.py | 109 +--- .../versions/0005_drop_tool_related_tables.py | 193 +++++++ .../webapps/community/security/__init__.py | 102 ---- .../migrate_tools_to_repositories.py | 6 +- templates/webapps/community/admin/center.mako | 20 - templates/webapps/community/admin/index.mako | 18 +- .../webapps/community/admin/reject_tool.mako | 70 --- templates/webapps/community/base_panels.mako | 6 +- .../webapps/community/common/rate_tool.mako | 212 ------- .../community/common/view_tool_history.mako | 92 --- templates/webapps/community/index.mako | 42 +- .../webapps/community/tool/edit_tool.mako | 192 ------- templates/webapps/community/tool/grid.mako | 1 - templates/webapps/community/tool/help.mako | 166 ------ .../webapps/community/tool/view_tool.mako | 247 -------- 25 files changed, 237 insertions(+), 2511 deletions(-) delete mode 100644 lib/galaxy/webapps/community/controllers/tool.py delete mode 100644 lib/galaxy/webapps/community/controllers/tool_upload.py create mode 100644 lib/galaxy/webapps/community/model/migrate/versions/0005_drop_tool_related_tables.py delete mode 100644 templates/webapps/community/admin/reject_tool.mako delete mode 100644 templates/webapps/community/common/rate_tool.mako delete mode 100644 templates/webapps/community/common/view_tool_history.mako delete mode 100644 templates/webapps/community/tool/edit_tool.mako delete mode 100644 templates/webapps/community/tool/grid.mako delete mode 100644 templates/webapps/community/tool/help.mako delete mode 100644 templates/webapps/community/tool/view_tool.mako diff --git a/community_wsgi.ini.sample b/community_wsgi.ini.sample index 9326a5551fa..9413337e108 100644 --- a/community_wsgi.ini.sample +++ b/community_wsgi.ini.sample @@ -12,9 +12,6 @@ threadpool_workers = 10 [app:main] -# Enable next-gen tool shed features -#enable_next_gen_tool_shed = True - # Specifies the factory for the universe WSGI application paste.app_factory = galaxy.webapps.community.buildapp:app_factory log_level = DEBUG diff --git a/lib/galaxy/web/base/controller.py b/lib/galaxy/web/base/controller.py index 186b07cbd46..166a0594a74 100644 --- a/lib/galaxy/web/base/controller.py +++ b/lib/galaxy/web/base/controller.py @@ -2026,16 +2026,6 @@ class Admin( object ): **kwd ) ) elif operation == "manage roles and groups": return self.manage_roles_and_groups_for_user( trans, **kwd ) - elif operation == "tools_by_user": - # This option is called via the ToolsColumn link in a grid subclass, - # so we need to add user_id to kwd since id in the subclass is tool.id, - # and update the current sort filter, using the grid subclass's default - # sort filter instead of this class's. - kwd[ 'user_id' ] = kwd[ 'id' ] - kwd[ 'sort' ] = 'name' - return trans.response.send_redirect( web.url_for( controller='admin', - action='browse_tools', - **kwd ) ) # Render the list view return self.user_list_grid( trans, **kwd ) @web.expose diff --git a/lib/galaxy/webapps/community/app.py b/lib/galaxy/webapps/community/app.py index 68cbf54fef0..9040b1778c6 100644 --- a/lib/galaxy/webapps/community/app.py +++ b/lib/galaxy/webapps/community/app.py @@ -11,14 +11,6 @@ class UniverseApplication( object ): self.config = config.Configuration( **kwargs ) self.config.check() config.configure_logging( self.config ) - if self.config.enable_next_gen_tool_shed: - # We don't need a datatypes_registry since we have no datatypes - pass - else: - import galaxy.webapps.community.datatypes - # Set up datatypes registry - self.datatypes_registry = galaxy.webapps.community.datatypes.Registry( self.config.root, self.config.datatypes_config ) - galaxy.model.set_datatypes_registry( self.datatypes_registry ) # Determine the database url if self.config.database_connection: db_url = self.config.database_connection @@ -29,8 +21,7 @@ class UniverseApplication( object ): create_or_verify_database( db_url, self.config.database_engine_options ) # Setup the database engine and ORM from galaxy.webapps.community.model import mapping - self.model = mapping.init( self.config.enable_next_gen_tool_shed, - self.config.file_path, + self.model = mapping.init( self.config.file_path, db_url, self.config.database_engine_options ) # Security helper diff --git a/lib/galaxy/webapps/community/buildapp.py b/lib/galaxy/webapps/community/buildapp.py index 8e6bca2d295..d7e145f847a 100644 --- a/lib/galaxy/webapps/community/buildapp.py +++ b/lib/galaxy/webapps/community/buildapp.py @@ -31,12 +31,6 @@ def add_controllers( webapp, app ): controller_dir = galaxy.webapps.community.controllers.__path__[0] for fname in os.listdir( controller_dir ): if not fname.startswith( "_" ) and fname.endswith( ".py" ): - if app.config.enable_next_gen_tool_shed and fname.startswith( 'tool_upload' ): - # The tool_upload controller is for the old version of the tool shed - continue - if not app.config.enable_next_gen_tool_shed and fname.startswith( 'upload' ): - # The upload controller is for the next gen tool shed - continue name = fname[:-3] module_name = "galaxy.webapps.community.controllers." + name module = __import__( module_name ) @@ -81,11 +75,8 @@ def app_factory( global_conf, **kwargs ): webapp = galaxy.web.framework.WebApplication( app, session_cookie='galaxycommunitysession' ) add_controllers( webapp, app ) webapp.add_route( '/:controller/:action', action='index' ) - if app.config.enable_next_gen_tool_shed: - webapp.add_route( '/:action', controller='repository', action='index' ) - webapp.add_route( '/repos/*path_info', controller='hg', action='handle_request', path_info='/' ) - else: - webapp.add_route( '/:action', controller='tool', action='index' ) + webapp.add_route( '/:action', controller='repository', action='index' ) + webapp.add_route( '/repos/*path_info', controller='hg', action='handle_request', path_info='/' ) webapp.finalize_config() # Wrap the webapp in some useful middleware if kwargs.get( 'middleware', True ): diff --git a/lib/galaxy/webapps/community/config.py b/lib/galaxy/webapps/community/config.py index bd059d2108d..d7fe6c5fc9e 100644 --- a/lib/galaxy/webapps/community/config.py +++ b/lib/galaxy/webapps/community/config.py @@ -47,7 +47,6 @@ class Configuration( object ): self.require_login = string_as_bool( kwargs.get( "require_login", "False" ) ) self.allow_user_creation = string_as_bool( kwargs.get( "allow_user_creation", "True" ) ) self.enable_openid = string_as_bool( kwargs.get( 'enable_openid', False ) ) - self.enable_next_gen_tool_shed = string_as_bool( kwargs.get( 'enable_next_gen_tool_shed', False ) ) self.template_path = resolve_path( kwargs.get( "template_path", "templates" ), self.root ) self.template_cache = resolve_path( kwargs.get( "template_cache_path", "database/compiled_templates/community" ), self.root ) self.admin_users = kwargs.get( "admin_users", "" ) diff --git a/lib/galaxy/webapps/community/controllers/admin.py b/lib/galaxy/webapps/community/controllers/admin.py index 069ae5ef15b..eae7e928780 100644 --- a/lib/galaxy/webapps/community/controllers/admin.py +++ b/lib/galaxy/webapps/community/controllers/admin.py @@ -2,14 +2,14 @@ from galaxy.web.base.controller import * from galaxy.webapps.community import model from galaxy.model.orm import * from galaxy.web.framework.helpers import time_ago, iff, grids -from common import ToolListGrid, CategoryListGrid, get_category, get_event, get_tool, get_versions -from repository import RepositoryListGrid, RepositoryCategoryListGrid +from common import get_category, get_repository +from repository import RepositoryListGrid, CategoryListGrid import logging log = logging.getLogger( __name__ ) class UserListGrid( grids.Grid ): # TODO: move this to an admin_common controller since it is virtually the same - # in the galaxy webapp. NOTE the additional ToolsColumn in this grid though... + # in the galaxy webapp. class UserLoginColumn( grids.TextColumn ): def get_value( self, trans, grid, user ): return user.email @@ -282,58 +282,6 @@ class GroupListGrid( grids.Grid ): preserve_state = False use_paging = True -class AdminToolListGrid( ToolListGrid ): - class StateColumn( grids.TextColumn ): - def get_value( self, trans, grid, tool ): - state = tool.state - if state == 'approved': - state_color = 'ok' - elif state == 'rejected': - state_color = 'error' - elif state == 'archived': - state_color = 'upload' - else: - state_color = state - return '
%s
' % ( state_color, state ) - class ToolStateColumn( grids.StateColumn ): - def filter( self, trans, user, query, column_filter ): - """Modify query to filter by state.""" - if column_filter == "All": - pass - elif column_filter in [ v for k, v in self.model_class.states.items() ]: - # Get all of the latest ToolEventAssociation ids - tea_ids = [ tea_id_tup[0] for tea_id_tup in trans.sa_session.query( func.max( model.ToolEventAssociation.table.c.id ) ) \ - .group_by( model.ToolEventAssociation.table.c.tool_id ) ] - # Get all of the Event ids associated with the latest ToolEventAssociation ids - event_ids = [ event_id_tup[0] for event_id_tup in trans.sa_session.query( model.ToolEventAssociation.table.c.event_id ) \ - .filter( model.ToolEventAssociation.table.c.id.in_( tea_ids ) ) ] - # Filter our query by state and event ids - return query.filter( and_( model.Event.table.c.state == column_filter, - model.Event.table.c.id.in_( event_ids ) ) ) - return query - - columns = [ col for col in ToolListGrid.columns ] - columns.append( - StateColumn( "Status", - model_class=model.Tool, - link=( lambda item: dict( operation="tools_by_state", id=item.id, webapp="community" ) ), - attach_popup=False ), - ) - columns.append( - # Columns that are valid for filtering but are not visible. - ToolStateColumn( "State", - key="state", - model_class=model.Tool, - visible=False, - filterable="advanced" ) - ) - operations = [ - grids.GridOperation( "Edit information", - condition=( lambda item: not item.deleted ), - allow_multiple=False, - url_args=dict( controller="common", action="edit_tool", cntrller="admin", webapp="community" ) ) - ] - class AdminCategoryListGrid( CategoryListGrid ): # Override standard filters standard_filters = [ @@ -374,72 +322,9 @@ class AdminController( BaseController, Admin ): role_list_grid = RoleListGrid() group_list_grid = GroupListGrid() manage_category_list_grid = ManageCategoryListGrid() - tool_category_list_grid = AdminCategoryListGrid() - tool_list_grid = AdminToolListGrid() repository_list_grid = RepositoryListGrid() - repository_category_list_grid = RepositoryCategoryListGrid() + category_list_grid = CategoryListGrid() - @web.expose - @web.require_admin - def browse_tools( self, trans, **kwd ): - # We add params to the keyword dict in this method in order to rename the param - # with an "f-" prefix, simulating filtering by clicking a search link. We have - # to take this approach because the "-" character is illegal in HTTP requests. - if 'operation' in kwd: - operation = kwd['operation'].lower() - if operation == "edit_tool": - return trans.response.send_redirect( web.url_for( controller='common', - action='edit_tool', - cntrller='admin', - **kwd ) ) - elif operation == "view_tool": - return trans.response.send_redirect( web.url_for( controller='common', - action='view_tool', - cntrller='admin', - **kwd ) ) - elif operation == 'tool_history': - return trans.response.send_redirect( web.url_for( controller='common', - cntrller='admin', - action='events', - **kwd ) ) - elif operation == "tools_by_user": - # Eliminate the current filters if any exist. - for k, v in kwd.items(): - if k.startswith( 'f-' ): - del kwd[ k ] - if 'user_id' in kwd: - user = get_user( trans, kwd[ 'user_id' ] ) - kwd[ 'f-email' ] = user.email - del kwd[ 'user_id' ] - else: - # The received id is the tool id, so we need to get the id of the user - # that uploaded the tool. - tool_id = kwd.get( 'id', None ) - tool = get_tool( trans, tool_id ) - kwd[ 'f-email' ] = tool.user.email - elif operation == "tools_by_state": - # Eliminate the current filters if any exist. - for k, v in kwd.items(): - if k.startswith( 'f-' ): - del kwd[ k ] - if 'state' in kwd: - # Called from the Admin menu - kwd[ 'f-state' ] = kwd[ 'state' ] - else: - # Called from the ToolStateColumn link - tool_id = kwd.get( 'id', None ) - tool = get_tool( trans, tool_id ) - kwd[ 'f-state' ] = tool.state - elif operation == "tools_by_category": - # Eliminate the current filters if any exist. - for k, v in kwd.items(): - if k.startswith( 'f-' ): - del kwd[ k ] - category_id = kwd.get( 'id', None ) - category = get_category( trans, category_id ) - kwd[ 'f-Category.name' ] = category.name - # Render the list view - return self.tool_list_grid( trans, **kwd ) @web.expose @web.require_admin def browse_repositories( self, trans, **kwd ): @@ -448,9 +333,9 @@ class AdminController( BaseController, Admin ): # to take this approach because the "-" character is illegal in HTTP requests. if 'operation' in kwd: operation = kwd['operation'].lower() - if operation == "view_repository": + if operation == "view_or_manage_repository": return trans.response.send_redirect( web.url_for( controller='repository', - action='view_repository', + action='browse_repositories', **kwd ) ) elif operation == "edit_repository": return trans.response.send_redirect( web.url_for( controller='repository', @@ -485,29 +370,16 @@ class AdminController( BaseController, Admin ): @web.require_admin def browse_categories( self, trans, **kwd ): if 'operation' in kwd: - operation = kwd['operation'].lower() - if trans.app.config.enable_next_gen_tool_shed: - if operation in [ "repositories_by_category", "repositories_by_user" ]: - # Eliminate the current filters if any exist. - for k, v in kwd.items(): - if k.startswith( 'f-' ): - del kwd[ k ] - return trans.response.send_redirect( web.url_for( controller='admin', - action='browse_repositories', - **kwd ) ) - else: - if operation in [ "tools_by_category", "tools_by_state", "tools_by_user" ]: - # Eliminate the current filters if any exist. - for k, v in kwd.items(): - if k.startswith( 'f-' ): - del kwd[ k ] - return trans.response.send_redirect( web.url_for( controller='admin', - action='browse_tools', - **kwd ) ) - if trans.app.config.enable_next_gen_tool_shed: - return self.repository_category_list_grid( trans, **kwd ) - else: - return self.tool_category_list_grid( trans, **kwd ) + operation = kwd[ 'operation' ].lower() + if operation in [ "repositories_by_category", "repositories_by_user" ]: + # Eliminate the current filters if any exist. + for k, v in kwd.items(): + if k.startswith( 'f-' ): + del kwd[ k ] + return trans.response.send_redirect( web.url_for( controller='admin', + action='browse_repositories', + **kwd ) ) + return self.category_list_grid( trans, **kwd ) @web.expose @web.require_admin def manage_categories( self, trans, **kwd ): @@ -573,140 +445,6 @@ class AdminController( BaseController, Admin ): status=status ) @web.expose @web.require_admin - def set_tool_state( self, trans, state, **kwd ): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - comments = util.restore_text( params.get( 'comments', '' ) ) - id = params.get( 'id', None ) - if not id: - message = "No tool id received for setting status" - status = 'error' - else: - tool = get_tool( trans, id ) - if state == trans.app.model.Tool.states.APPROVED: - # If we're approving a tool, all previously approved versions must be set to archived - for version in get_versions( tool ): - # TODO: get latest approved version instead of all versions - if version != tool and version.is_approved: - # Create an event with state ARCHIVED for the previously approved version of this tool - self.__create_tool_event( trans, - version, - trans.app.model.Tool.states.ARCHIVED ) - # Create an event with state APPROVED for this tool - self.__create_tool_event( trans, tool, state, comments ) - elif state == trans.app.model.Tool.states.REJECTED: - # If we're rejecting a tool, comments about why are necessary. - return trans.fill_template( '/webapps/community/admin/reject_tool.mako', - tool=tool, - cntrller='admin' ) - message = "State of tool '%s' is now %s" % ( tool.name, state ) - trans.response.send_redirect( web.url_for( controller='admin', - action='browse_tools', - message=message, - status=status ) ) - @web.expose - @web.require_admin - def reject_tool( self, trans, **kwd ): - params = util.Params( kwd ) - if params.get( 'cancel_reject_button', False ): - # Fix up the keyword dict to include params to view the current tool - # since that is the page from which we originated. - del kwd[ 'cancel_reject_button' ] - del kwd[ 'comments' ] - kwd[ 'webapp' ] = 'community' - kwd[ 'operation' ] = 'view_tool' - message = 'Tool rejection cancelled' - status = 'done' - return trans.response.send_redirect( web.url_for( controller='admin', - action='browse_tools', - message=message, - status=status, - **kwd ) ) - id = params.get( 'id', None ) - if not id: - return trans.response.send_redirect( web.url_for( controller=cntrller, - action='browse_tools', - message='No tool id received for rejecting', - status='error' ) ) - tool = get_tool( trans, id ) - if not trans.app.security_agent.can_approve_or_reject( trans.user, trans.user_is_admin(), 'admin', tool ): - return trans.response.send_redirect( web.url_for( controller='admin', - action='browse_tools', - message='You are not allowed to reject this tool', - status='error' ) ) - # Comments are required when rejecting a tool. - comments = util.restore_text( params.get( 'comments', '' ) ) - if not comments: - message = 'The reason for rejection is required when rejecting a tool.' - return trans.fill_template( '/webapps/community/admin/reject_tool.mako', - tool=tool, - cntrller='admin', - message=message, - status='error' ) - # Create an event with state REJECTED for this tool - self.__create_tool_event( trans, tool, trans.app.model.Tool.states.REJECTED, comments ) - message = 'The tool "%s" has been rejected.' % tool.name - return trans.response.send_redirect( web.url_for( controller='admin', - action='browse_tools', - operation='tools_by_state', - state='rejected', - message=message, - status='done' ) ) - def __create_tool_event( self, trans, tool, state, comments='' ): - event = trans.model.Event( state, comments ) - # Flush so we can get an id - trans.sa_session.add( event ) - trans.sa_session.flush() - tea = trans.model.ToolEventAssociation( tool, event ) - trans.sa_session.add( tea ) - trans.sa_session.flush() - @web.expose - @web.require_admin - def purge_tool( self, trans, **kwd ): - # This method completely removes a tool record and all associated foreign key rows - # from the database, so it must be used carefully. - # This method should only be called for a tool that has previously been deleted. - # Purging a deleted tool deletes all of the following from the database: - # - ToolCategoryAssociations - # - ToolEventAssociations and associated Events - # TODO: when we add tagging for tools, we'll have to purge them as well - params = util.Params( kwd ) - id = kwd.get( 'id', None ) - if not id: - message = "No tool ids received for purging" - trans.response.send_redirect( web.url_for( controller='admin', - action='browse_tools', - message=util.sanitize_text( message ), - status='error' ) ) - ids = util.listify( id ) - message = "Purged %d tools: " % len( ids ) - for tool_id in ids: - tool = get_tool( trans, tool_id ) - message += " %s " % tool.name - if not tool.deleted: - message = "Tool '%s' has not been deleted, so it cannot be purged." % tool.name - trans.response.send_redirect( web.url_for( controller='admin', - action='browse_tools', - message=util.sanitize_text( message ), - status='error' ) ) - # Delete ToolCategoryAssociations - for tca in tool.categories: - trans.sa_session.delete( tca ) - # Delete ToolEventAssociations and associated events - for tea in tool.events: - event = tea.event - trans.sa_session.delete( event ) - trans.sa_session.delete( tea ) - # Delete the tool - trans.sa_session.delete( tool ) - trans.sa_session.flush() - trans.response.send_redirect( web.url_for( controller='admin', - action='browse_tools', - message=util.sanitize_text( message ), - status='done' ) ) - @web.expose - @web.require_admin def edit_category( self, trans, **kwd ): params = util.Params( kwd ) message = util.restore_text( params.get( 'message', '' ) ) @@ -804,10 +542,7 @@ class AdminController( BaseController, Admin ): def purge_category( self, trans, **kwd ): # This method should only be called for a Category that has previously been deleted. # Purging a deleted Category deletes all of the following from the database: - # If trans.app.config.enable_next_gen_tool_shed: # - RepoitoryCategoryAssociations where category_id == Category.id - # Otherwise: - # - ToolCategoryAssociations where category_id == Category.id params = util.Params( kwd ) id = kwd.get( 'id', None ) if not id: @@ -826,14 +561,9 @@ class AdminController( BaseController, Admin ): action='manage_categories', message=util.sanitize_text( message ), status='error' ) ) - if trans.app.config.enable_next_gen_tool_shed: - # Delete RepositoryCategoryAssociations - for rca in category.repositories: - trans.sa_session.delete( rca ) - else: - # Delete ToolCategoryAssociations - for tca in category.tools: - trans.sa_session.delete( tca ) + # Delete RepositoryCategoryAssociations + for rca in category.repositories: + trans.sa_session.delete( rca ) trans.sa_session.flush() message += " %s " % category.name trans.response.send_redirect( web.url_for( controller='admin', diff --git a/lib/galaxy/webapps/community/controllers/common.py b/lib/galaxy/webapps/community/controllers/common.py index 8691531b63d..a9cd26b59a5 100644 --- a/lib/galaxy/webapps/community/controllers/common.py +++ b/lib/galaxy/webapps/community/controllers/common.py @@ -34,508 +34,8 @@ class ItemRatings( UsesItemRatings ): trans.sa_session.flush() return item_rating -class ToolListGrid( grids.Grid ): - class NameColumn( grids.TextColumn ): - def get_value( self, trans, grid, tool ): - return tool.name - class TypeColumn( grids.BooleanColumn ): - def get_value( self, trans, grid, tool ): - if tool.is_suite: - return 'Suite' - return 'Tool' - class VersionColumn( grids.TextColumn ): - def get_value( self, trans, grid, tool ): - return tool.version - class DescriptionColumn( grids.TextColumn ): - def get_value( self, trans, grid, tool ): - return tool.description - class CategoryColumn( grids.TextColumn ): - def get_value( self, trans, grid, tool ): - rval = '' - return rval - class ToolCategoryColumn( grids.GridColumn ): - def filter( self, trans, user, query, column_filter ): - """Modify query to filter by category.""" - if column_filter == "All": - pass - return query.filter( model.Category.name == column_filter ) - class UserColumn( grids.TextColumn ): - def get_value( self, trans, grid, tool ): - if tool.user: - return tool.user.username - return 'no user' - class EmailColumn( grids.TextColumn ): - def filter( self, trans, user, query, column_filter ): - if column_filter == 'All': - return query - return query.filter( and_( model.Tool.table.c.user_id == model.User.table.c.id, - model.User.table.c.email == column_filter ) ) - # Grid definition - title = "Tools" - model_class = model.Tool - template='/webapps/community/tool/grid.mako' - default_sort_key = "name" - columns = [ - NameColumn( "Name", - key="Tool.name", - link=( lambda item: dict( operation="view_tool", id=item.id, webapp="community" ) ), - attach_popup=False ), - DescriptionColumn( "Description", - key="description", - attach_popup=False ), - VersionColumn( "Version", - key="version", - attach_popup=False, - filterable="advanced" ), - CategoryColumn( "Category", - model_class=model.Category, - key="Category.name", - attach_popup=False ), - UserColumn( "Uploaded By", - model_class=model.User, - link=( lambda item: dict( operation="tools_by_user", id=item.id, webapp="community" ) ), - attach_popup=False, - key="username" ), - TypeColumn( "Type", - key="suite", - attach_popup=False ), - grids.CommunityRatingColumn( "Average Rating", - key="rating" ), - # Columns that are valid for filtering but are not visible. - EmailColumn( "Email", - model_class=model.User, - key="email", - visible=False ), - ToolCategoryColumn( "Category", - model_class=model.Category, - key="Category.name", - visible=False ) - ] - columns.append( grids.MulticolFilterColumn( "Search tool name, description, version", - cols_to_filter=[ columns[0], columns[1], columns[2] ], - key="free-text-search", - visible=False, - filterable="standard" ) ) - operations = [] - standard_filters = [] - default_filter = {} - num_rows_per_page = 50 - preserve_state = False - use_paging = True - def build_initial_query( self, trans, **kwd ): - return trans.sa_session.query( self.model_class ) \ - .join( model.User.table ) \ - .join( model.ToolEventAssociation.table ) \ - .join( model.Event.table ) \ - .outerjoin( model.ToolCategoryAssociation.table ) \ - .outerjoin( model.Category.table ) - -class CategoryListGrid( grids.Grid ): - class NameColumn( grids.TextColumn ): - def get_value( self, trans, grid, category ): - return category.name - class DescriptionColumn( grids.TextColumn ): - def get_value( self, trans, grid, category ): - return category.description - class ToolsColumn( grids.TextColumn ): - def get_value( self, trans, grid, category ): - if category.tools: - viewable_tools = 0 - for tca in category.tools: - viewable_tools += 1 - return viewable_tools - return 0 - - # Grid definition - webapp = "community" - title = "Categories" - model_class = model.Category - template='/webapps/community/category/grid.mako' - default_sort_key = "name" - columns = [ - NameColumn( "Name", - key="name", - link=( lambda item: dict( operation="tools_by_category", id=item.id, webapp="community" ) ), - attach_popup=False, - filterable="advanced" ), - DescriptionColumn( "Description", - key="description", - attach_popup=False, - filterable="advanced" ), - # Columns that are valid for filtering but are not visible. - grids.DeletedColumn( "Deleted", - key="deleted", - visible=False, - filterable="advanced" ), - ToolsColumn( "Tools", - model_class=model.Tool, - attach_popup=False ) - ] - columns.append( grids.MulticolFilterColumn( "Search category name, description", - cols_to_filter=[ columns[0], columns[1] ], - key="free-text-search", - visible=False, - filterable="standard" ) ) - - # Override these - global_actions = [] - operations = [] - standard_filters = [] - num_rows_per_page = 50 - preserve_state = False - use_paging = True - -class CommonController( BaseController, ItemRatings ): - @web.expose - def edit_tool( self, trans, cntrller, **kwd ): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - id = params.get( 'id', None ) - if not id: - return trans.response.send_redirect( web.url_for( controller=cntrller, - action='browse_tools', - cntrller=cntrller, - message='Select a tool to edit', - status='error' ) ) - tool = get_tool( trans, id ) - can_edit = trans.app.security_agent.can_edit( trans.user, trans.user_is_admin(), cntrller, tool ) - if not can_edit: - return trans.response.send_redirect( web.url_for( controller=cntrller, - action='browse_tools', - cntrller=cntrller, - message='You are not allowed to edit this tool', - status='error' ) ) - if params.get( 'edit_tool_button', False ): - if params.get( 'in_categories', False ): - in_categories = [ trans.sa_session.query( trans.app.model.Category ).get( x ) for x in util.listify( params.in_categories ) ] - trans.app.security_agent.set_entity_category_associations( tools=[ tool ], categories=in_categories ) - else: - # There must not be any categories associated with the tool - trans.app.security_agent.set_entity_category_associations( tools=[ tool ], categories=[] ) - user_description = util.restore_text( params.get( 'user_description', '' ) ) - if user_description: - tool.user_description = user_description - else: - tool.user_description = '' - trans.sa_session.add( tool ) - trans.sa_session.flush() - message = "Tool '%s' description and category associations have been saved" % tool.name - return trans.response.send_redirect( web.url_for( controller='common', - action='edit_tool', - cntrller=cntrller, - id=id, - message=message, - status='done' ) ) - elif params.get( 'approval_button', False ): - user_description = util.restore_text( params.get( 'user_description', '' ) ) - if user_description: - tool.user_description = user_description - if params.get( 'in_categories', False ): - in_categories = [ trans.sa_session.query( trans.app.model.Category ).get( x ) for x in util.listify( params.in_categories ) ] - trans.app.security_agent.set_entity_category_associations( tools=[ tool ], categories=in_categories ) - else: - # There must not be any categories associated with the tool - trans.app.security_agent.set_entity_category_associations( tools=[ tool ], categories=[] ) - trans.sa_session.add( tool ) - trans.sa_session.flush() - # Move the state from NEW to WAITING - event = trans.app.model.Event( state=trans.app.model.Tool.states.WAITING ) - tea = trans.app.model.ToolEventAssociation( tool, event ) - trans.sa_session.add_all( ( event, tea ) ) - trans.sa_session.flush() - message = "Tool '%s' has been submitted for approval and can no longer be modified" % ( tool.name ) - return trans.response.send_redirect( web.url_for( controller='common', - action='view_tool', - cntrller=cntrller, - id=id, - message=message, - status='done' ) ) - else: - # The user_description field is required when submitting for approval - message = 'A user description is required prior to approval.' - status = 'error' - in_categories = [] - out_categories = [] - for category in get_categories( trans ): - if category in [ x.category for x in tool.categories ]: - in_categories.append( ( category.id, category.name ) ) - else: - out_categories.append( ( category.id, category.name ) ) - if tool.is_rejected: - # Include the comments regarding the reason for rejection - reason_for_rejection = tool.latest_event.comment - else: - reason_for_rejection = '' - can_approve_or_reject = trans.app.security_agent.can_approve_or_reject( trans.user, trans.user_is_admin(), cntrller, tool ) - can_delete = trans.app.security_agent.can_delete( trans.user, trans.user_is_admin(), cntrller, tool ) - can_download = trans.app.security_agent.can_download( trans.user, trans.user_is_admin(), cntrller, tool ) - can_purge = trans.app.security_agent.can_purge( trans.user, trans.user_is_admin(), cntrller ) - can_upload_new_version = trans.app.security_agent.can_upload_new_version( trans.user, tool ) - can_view = trans.app.security_agent.can_view( trans.user, trans.user_is_admin(), cntrller, tool ) - return trans.fill_template( '/webapps/community/tool/edit_tool.mako', - cntrller=cntrller, - tool=tool, - id=id, - in_categories=in_categories, - out_categories=out_categories, - can_approve_or_reject=can_approve_or_reject, - can_delete=can_delete, - can_download=can_download, - can_edit=can_edit, - can_purge=can_purge, - can_upload_new_version=can_upload_new_version, - can_view=can_view, - reason_for_rejection=reason_for_rejection, - message=message, - status=status ) - @web.expose - def view_tool( self, trans, cntrller, **kwd ): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - id = params.get( 'id', None ) - if not id: - return trans.response.send_redirect( web.url_for( controller=cntrller, - action='browse_tools', - cntrller=cntrller, - message='Select a tool to view', - status='error' ) ) - tool = get_tool( trans, id ) - can_view = trans.app.security_agent.can_view( trans.user, trans.user_is_admin(), cntrller, tool ) - if not can_view: - return trans.response.send_redirect( web.url_for( controller=cntrller, - action='browse_tools', - cntrller=cntrller, - message='You are not allowed to view this tool', - status='error' ) ) - avg_rating, num_ratings = self.get_ave_item_rating_data( trans.sa_session, tool, webapp_model=trans.model ) - can_approve_or_reject = trans.app.security_agent.can_approve_or_reject( trans.user, trans.user_is_admin(), cntrller, tool ) - can_delete = trans.app.security_agent.can_delete( trans.user, trans.user_is_admin(), cntrller, tool ) - can_download = trans.app.security_agent.can_download( trans.user, trans.user_is_admin(), cntrller, tool ) - can_edit = trans.app.security_agent.can_edit( trans.user, trans.user_is_admin(), cntrller, tool ) - can_purge = trans.app.security_agent.can_purge( trans.user, trans.user_is_admin(), cntrller ) - can_rate = trans.app.security_agent.can_rate( trans.user, trans.user_is_admin(), cntrller, tool ) - can_upload_new_version = trans.app.security_agent.can_upload_new_version( trans.user, tool ) - categories = [ tca.category for tca in tool.categories ] - display_reviews = util.string_as_bool( params.get( 'display_reviews', False ) ) - tool_file_contents = tarfile.open( tool.file_name, 'r' ).getnames() - tra = self.get_user_item_rating( trans.sa_session, trans.user, tool, webapp_model=trans.model ) - visible_versions = trans.app.security_agent.get_visible_versions( trans.user, trans.user_is_admin(), cntrller, tool ) - if tool.is_rejected: - # Include the comments regarding the reason for rejection - reason_for_rejection = tool.latest_event.comment - else: - reason_for_rejection = '' - return trans.fill_template( '/webapps/community/tool/view_tool.mako', - avg_rating=avg_rating, - categories=categories, - can_approve_or_reject=can_approve_or_reject, - can_delete=can_delete, - can_download=can_download, - can_edit=can_edit, - can_purge=can_purge, - can_rate=can_rate, - can_upload_new_version=can_upload_new_version, - can_view=can_view, - cntrller=cntrller, - display_reviews=display_reviews, - num_ratings=num_ratings, - reason_for_rejection=reason_for_rejection, - tool=tool, - tool_file_contents=tool_file_contents, - tra=tra, - visible_versions=visible_versions, - message=message, - status=status ) - @web.expose - def delete_tool( self, trans, cntrller, **kwd ): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - id = params.get( 'id', None ) - if not id: - message='Select a tool to delete' - status='error' - else: - tool = get_tool( trans, id ) - if not trans.app.security_agent.can_delete( trans.user, trans.user_is_admin(), cntrller, tool ): - return trans.response.send_redirect( web.url_for( controller=cntrller, - action='browse_tools', - cntrller=cntrller, - message='You are not allowed to delete this tool', - status='error' ) ) - # Create a new event - event = trans.model.Event( state=trans.model.Tool.states.DELETED ) - # Flush so we can get an event id - trans.sa_session.add( event ) - trans.sa_session.flush() - # Associate the tool with the event - tea = trans.model.ToolEventAssociation( tool=tool, event=event ) - # Delete the tool, keeping state for categories, events and versions - tool.deleted = True - trans.sa_session.add_all( ( tool, tea ) ) - trans.sa_session.flush() - # TODO: What if the tool has versions, should they all be deleted? - message = "Tool '%s' version %s has been marked deleted" % ( tool.name, tool.version ) - status = 'done' - return trans.response.send_redirect( web.url_for( controller=cntrller, - action='browse_tools', - cntrller=cntrller, - message=message, - status=status ) ) - @web.expose - def download_tool( self, trans, cntrller, **kwd ): - params = util.Params( kwd ) - id = params.get( 'id', None ) - if not id: - return trans.response.send_redirect( web.url_for( controller='tool', - action='browse_tools', - cntrller=cntrller, - message='Select a tool to download', - status='error' ) ) - tool = get_tool( trans, id ) - if not trans.app.security_agent.can_download( trans.user, trans.user_is_admin(), cntrller, tool ): - return trans.response.send_redirect( web.url_for( controller=cntrller, - action='browse_tools', - cntrller=cntrller, - message='You are not allowed to download this tool', - status='error' ) ) - trans.response.set_content_type( tool.mimetype ) - trans.response.headers['Content-Length'] = int( os.stat( tool.file_name ).st_size ) - trans.response.headers['Content-Disposition'] = 'attachment; filename=%s' % tool.download_file_name - return open( tool.file_name ) - @web.expose - def upload_new_tool_version( self, trans, cntrller, **kwd ): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - id = params.get( 'id', None ) - if not id: - return trans.response.send_redirect( web.url_for( controller=cntrller, - action='browse_tools', - cntrller=cntrller, - message='Select a tool to upload a new version', - status='error' ) ) - tool = get_tool( trans, id ) - if not trans.app.security_agent.can_upload_new_version( trans.user, tool ): - return trans.response.send_redirect( web.url_for( controller=cntrller, - action='browse_tools', - cntrller=cntrller, - message='You are not allowed to upload a new version of this tool', - status='error' ) ) - return trans.response.send_redirect( web.url_for( controller='tool_upload', - action='upload', - message=message, - status=status, - replace_id=id ) ) - @web.expose - @web.require_login( "view tool history" ) - def view_tool_history( self, trans, cntrller, **kwd ): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - id = params.get( 'id', None ) - if not id: - return trans.response.send_redirect( web.url_for( controller=cntrller, - action='browse_tools', - cntrller=cntrller, - message='Select a tool to view its history', - status='error' ) ) - tool = get_tool( trans, id ) - can_view = trans.app.security_agent.can_view( trans.user, trans.user_is_admin(), cntrller, tool ) - if not can_view: - return trans.response.send_redirect( web.url_for( controller=cntrller, - action='browse_tools', - cntrller=cntrller, - message="You are not allowed to view this tool's history", - status='error' ) ) - can_approve_or_reject = trans.app.security_agent.can_approve_or_reject( trans.user, trans.user_is_admin(), cntrller, tool ) - can_edit = trans.app.security_agent.can_edit( trans.user, trans.user_is_admin(), cntrller, tool ) - can_delete = trans.app.security_agent.can_delete( trans.user, trans.user_is_admin(), cntrller, tool ) - can_download = trans.app.security_agent.can_download( trans.user, trans.user_is_admin(), cntrller, tool ) - events = [ tea.event for tea in tool.events ] - events = [ ( event.state, time_ago( event.update_time ), event.comment ) for event in events ] - return trans.fill_template( '/webapps/community/common/view_tool_history.mako', - cntrller=cntrller, - events=events, - tool=tool, - can_approve_or_reject=can_approve_or_reject, - can_edit=can_edit, - can_delete=can_delete, - can_download=can_download, - can_view=can_view, - message=message, - status=status ) - @web.expose - @web.require_login( "rate tools" ) - def rate_tool( self, trans, cntrller, **kwd ): - """ Rate a tool and return updated rating data. """ - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - id = params.get( 'id', None ) - if not id: - return trans.response.send_redirect( web.url_for( controller=cntrller, - action='browse_tools', - cntrller=cntrller, - message='Select a tool to rate', - status='error' ) ) - tool = get_tool( trans, id ) - can_rate = trans.app.security_agent.can_rate( trans.user, trans.user_is_admin(), cntrller, tool ) - if not can_rate: - return trans.response.send_redirect( web.url_for( controller=cntrller, - action='browse_tools', - cntrller=cntrller, - message="You are not allowed to rate this tool", - status='error' ) ) - if params.get( 'rate_button', False ): - rating = int( params.get( 'rating', '0' ) ) - comment = util.restore_text( params.get( 'comment', '' ) ) - rating = self.rate_item( trans, trans.user, tool, rating, comment ) - avg_rating, num_ratings = self.get_ave_item_rating_data( trans.sa_session, tool, webapp_model=trans.model ) - can_approve_or_reject = trans.app.security_agent.can_approve_or_reject( trans.user, trans.user_is_admin(), cntrller, tool ) - can_edit = trans.app.security_agent.can_edit( trans.user, trans.user_is_admin(), cntrller, tool ) - can_delete = trans.app.security_agent.can_delete( trans.user, trans.user_is_admin(), cntrller, tool ) - can_download = trans.app.security_agent.can_download( trans.user, trans.user_is_admin(), cntrller, tool ) - display_reviews = util.string_as_bool( params.get( 'display_reviews', False ) ) - tra = self.get_user_item_rating( trans.sa_session, trans.user, tool, webapp_model=trans.model ) - return trans.fill_template( '/webapps/community/common/rate_tool.mako', - cntrller=cntrller, - tool=tool, - avg_rating=avg_rating, - can_approve_or_reject=can_approve_or_reject, - can_edit=can_edit, - can_delete=can_delete, - can_download=can_download, - can_rate=can_rate, - display_reviews=display_reviews, - num_ratings=num_ratings, - tra=tra, - message=message, - status=status ) - ## ---- Utility methods ------------------------------------------------------- -def get_versions( item ): - """Get all versions of item""" - versions = [ item ] - this_item = item - while item.newer_version: - versions.insert( 0, item.newer_version ) - item = item.newer_version - item = this_item - while item.older_version: - versions.append( item.older_version[ 0 ] ) - item = item.older_version[ 0 ] - return versions def get_categories( trans ): """Get all categories from the database""" return trans.sa_session.query( trans.model.Category ) \ @@ -544,28 +44,6 @@ def get_categories( trans ): def get_category( trans, id ): """Get a category from the database""" return trans.sa_session.query( trans.model.Category ).get( trans.security.decode_id( id ) ) -def get_tool( trans, id ): - """Get a tool from the database""" - return trans.sa_session.query( trans.model.Tool ).get( trans.security.decode_id( id ) ) -def get_latest_versions_of_tools( trans ): - """Get only the latest version of each tool from the database""" - return trans.sa_session.query( trans.model.Tool ) \ - .filter( trans.model.Tool.table.c.newer_version_id == None ) \ - .order_by( trans.model.Tool.table.c.name ) -def get_latest_versions_of_tools_by_state( trans, state ): - """Get only the latest version of each tool whose state is the received state from the database""" - tools = [] - for tool in trans.sa_session.query( trans.model.Tool ) \ - .order_by( trans.model.Tool.table.c.name ): - if tool.state == state: - tools.append( tool ) - return tools -def get_event( trans, id ): - """Get an event from the databse""" - return trans.sa_session.query( trans.model.Event ).get( trans.security.decode_id( id ) ) -def get_user( trans, id ): - """Get a user from the database""" - return trans.sa_session.query( trans.model.User ).get( trans.security.decode_id( id ) ) def get_repository( trans, id ): """Get a repository from the database via id""" return trans.sa_session.query( trans.model.Repository ).get( trans.security.decode_id( id ) ) @@ -577,3 +55,6 @@ def get_repository_tip( repository ): tip_changeset = repository.changelog.tip() tip_ctx = repository.changectx( tip_changeset ) return "%s:%s" % ( str( tip_ctx.rev() ), tip_ctx.parents()[0] ) +def get_user( trans, id ): + """Get a user from the database""" + return trans.sa_session.query( trans.model.User ).get( trans.security.decode_id( id ) ) diff --git a/lib/galaxy/webapps/community/controllers/repository.py b/lib/galaxy/webapps/community/controllers/repository.py index 01417921369..b180187adac 100644 --- a/lib/galaxy/webapps/community/controllers/repository.py +++ b/lib/galaxy/webapps/community/controllers/repository.py @@ -15,7 +15,7 @@ log = logging.getLogger( __name__ ) VALID_REPOSITORYNAME_RE = re.compile( "^[a-z0-9\_]+$" ) -class RepositoryCategoryListGrid( grids.Grid ): +class CategoryListGrid( grids.Grid ): # TODO rename this class to be categoryListGrid when we eliminate all the tools stuff. class NameColumn( grids.TextColumn ): def get_value( self, trans, grid, category ): @@ -166,7 +166,7 @@ class RepositoryListGrid( grids.Grid ): class RepositoryController( BaseController, ItemRatings ): repository_list_grid = RepositoryListGrid() - category_list_grid = RepositoryCategoryListGrid() + category_list_grid = CategoryListGrid() @web.expose def index( self, trans, **kwd ): diff --git a/lib/galaxy/webapps/community/controllers/tool.py b/lib/galaxy/webapps/community/controllers/tool.py deleted file mode 100644 index 4efc9c2e03a..00000000000 --- a/lib/galaxy/webapps/community/controllers/tool.py +++ /dev/null @@ -1,214 +0,0 @@ -import os, logging, urllib, tarfile - -from galaxy.web.base.controller import * -from galaxy.webapps.community import model -from galaxy.web.framework.helpers import time_ago, iff, grids -from galaxy.model.orm import * -# TODO: the following is bad because it imports the common controller. -from common import * - -log = logging.getLogger( __name__ ) - -class StateColumn( grids.StateColumn ): - def get_value( self, trans, grid, tool ): - state = tool.state - if state == trans.model.Tool.states.APPROVED: - state_color = 'ok' - elif state == trans.model.Tool.states.REJECTED: - state_color = 'error' - elif state == trans.model.Tool.states.ARCHIVED: - state_color = 'upload' - else: - state_color = state - return '
%s
' % ( state_color, state ) - -class ToolStateColumn( grids.StateColumn ): - 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 [ v for k, v in self.model_class.states.items() ]: - # Get all of the latest Events associated with the current version of each tool - latest_event_id_for_current_versions_of_tools = [ tool.latest_event.id for tool in get_latest_versions_of_tools_by_state( trans, column_filter ) ] - # Filter query by the latest state for the current version of each tool - return query.filter( and_( model.Event.table.c.state == column_filter, - model.Event.table.c.id.in_( latest_event_id_for_current_versions_of_tools ) ) ) - return query - -class ApprovedToolListGrid( ToolListGrid ): - columns = [ col for col in ToolListGrid.columns ] - columns.append( - StateColumn( "Status", - link=( lambda item: dict( operation="tools_by_state", id=item.id, webapp="community" ) ), - visible=False, - attach_popup=False ) - ) - columns.append( - ToolStateColumn( "State", - key="state", - visible=False, - filterable="advanced" ) - ) - -class MyToolsListGrid( ApprovedToolListGrid ): - columns = [ col for col in ToolListGrid.columns ] - columns.append( - StateColumn( "Status", - link=( lambda item: dict( operation="tools_by_state", id=item.id, webapp="community" ) ), - visible=True, - attach_popup=False ) - ) - columns.append( - ToolStateColumn( "State", - key="state", - visible=False, - filterable="advanced" ) - ) - -class ToolCategoryListGrid( CategoryListGrid ): - """ - Replaces the tools column in the Category grid with a similar column, - but displaying the number of APPROVED tools in the category. - """ - class ToolsColumn( grids.TextColumn ): - def get_value( self, trans, grid, category ): - if category.tools: - viewable_tools = 0 - for tca in category.tools: - tool = tca.tool - if tool.is_approved: - viewable_tools += 1 - return viewable_tools - return 0 - - columns = [] - for col in CategoryListGrid.columns: - if not isinstance( col, CategoryListGrid.ToolsColumn ): - columns.append( col ) - columns.append( - ToolsColumn( "Tools", - model_class=model.Tool, - attach_popup=False ) - ) - -class ToolController( BaseController ): - - tool_list_grid = ApprovedToolListGrid() - my_tools_list_grid = MyToolsListGrid() - category_list_grid = ToolCategoryListGrid() - - @web.expose - def index( self, trans, **kwd ): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - return trans.fill_template( '/webapps/community/index.mako', message=message, status=status ) - @web.expose - def browse_categories( self, trans, **kwd ): - if 'operation' in kwd: - operation = kwd['operation'].lower() - if operation in [ "tools_by_category", "tools_by_state", "tools_by_user" ]: - # Eliminate the current filters if any exist. - for k, v in kwd.items(): - if k.startswith( 'f-' ): - del kwd[ k ] - return trans.response.send_redirect( web.url_for( controller='tool', - action='browse_tools', - cntrller='tool', - **kwd ) ) - # Render the list view - return self.category_list_grid( trans, **kwd ) - @web.expose - def browse_tools( self, trans, **kwd ): - # We add params to the keyword dict in this method in order to rename the param - # with an "f-" prefix, simulating filtering by clicking a search link. We have - # to take this approach because the "-" character is illegal in HTTP requests. - if 'operation' not in kwd: - # We may have been redirected here after performing an action. If we were - # redirected from the tool controller, we have to add the default tools_by_category - # operation to kwd so only tools we should see are displayed. This implies that - # all redirectes from the tool controller added the cntrller value to kwd when - # redirecting. - cntrller = kwd.get( 'cntrller', None ) - if cntrller == 'tool': - kwd[ 'operation' ] = 'approved_tools' - if 'operation' in kwd: - operation = kwd['operation'].lower() - if operation == "view_tool": - return trans.response.send_redirect( web.url_for( controller='common', - action='view_tool', - cntrller='tool', - **kwd ) ) - elif operation == "edit_tool": - return trans.response.send_redirect( web.url_for( controller='common', - action='edit_tool', - cntrller='tool', - **kwd ) ) - elif operation == "download tool": - return trans.response.send_redirect( web.url_for( controller='common', - action='download_tool', - cntrller='tool', - **kwd ) ) - elif operation == "tools_by_user": - # Eliminate the current filters if any exist. - for k, v in kwd.items(): - if k.startswith( 'f-' ): - del kwd[ k ] - if 'user_id' in kwd: - user = get_user( trans, kwd[ 'user_id' ] ) - kwd[ 'f-email' ] = user.email - del kwd[ 'user_id' ] - else: - # The received id is the tool id, so we need to get the id of the user - # that uploaded the tool. - tool_id = kwd.get( 'id', None ) - tool = get_tool( trans, tool_id ) - kwd[ 'f-email' ] = tool.user.email - elif operation == "my_tools": - # Eliminate the current filters if any exist. - for k, v in kwd.items(): - if k.startswith( 'f-' ): - del kwd[ k ] - kwd[ 'f-email' ] = trans.user.email - return self.my_tools_list_grid( trans, **kwd ) - elif operation == "approved_tools": - # Eliminate the current filters if any exist. - for k, v in kwd.items(): - if k.startswith( 'f-' ): - del kwd[ k ] - # Make sure only the latest version of a tool whose state is APPROVED are displayed. - kwd[ 'f-state' ] = trans.model.Tool.states.APPROVED - return self.tool_list_grid( trans, **kwd ) - elif operation == "tools_by_category": - # Eliminate the current filters if any exist. - for k, v in kwd.items(): - if k.startswith( 'f-' ): - del kwd[ k ] - category_id = kwd.get( 'id', None ) - category = get_category( trans, category_id ) - kwd[ 'f-Category.name' ] = category.name - # Make sure only the latest version of a tool whose state is APPROVED are displayed. - kwd[ 'f-state' ] = trans.model.Tool.states.APPROVED - # Render the list view - return self.tool_list_grid( trans, **kwd ) - @web.expose - def view_tool_file( self, trans, **kwd ): - params = util.Params( kwd ) - id = params.get( 'id', None ) - if not id: - return trans.response.send_redirect( web.url_for( controller='tool', - action='browse_tools', - cntrller='tool', - message='Select a tool to download', - status='error' ) ) - tool = get_tool( trans, id ) - tool_file_name = urllib.unquote_plus( kwd['file_name'] ) - tool_file = tarfile.open( tool.file_name ).extractfile( tool_file_name ) - trans.response.set_content_type( 'text/plain' ) - return tool_file - @web.expose - def help( self, trans, **kwd ): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - return trans.fill_template( '/webapps/community/tool/help.mako', message=message, status=status, **kwd ) diff --git a/lib/galaxy/webapps/community/controllers/tool_upload.py b/lib/galaxy/webapps/community/controllers/tool_upload.py deleted file mode 100644 index 0c4c45e7cab..00000000000 --- a/lib/galaxy/webapps/community/controllers/tool_upload.py +++ /dev/null @@ -1,183 +0,0 @@ -import sys, os, shutil, logging, urllib2 -from galaxy.web.base.controller import * -from galaxy.web.framework.helpers import time_ago, iff, grids -from galaxy.model.orm import * -from galaxy.web.form_builder import SelectField, build_select_field -from galaxy.webapps.community import datatypes -from common import get_categories, get_category, get_versions - -log = logging.getLogger( __name__ ) - -# States for passing messages -SUCCESS, INFO, WARNING, ERROR = "done", "info", "warning", "error" - -class UploadError( Exception ): - pass - -class ToolUploadController( BaseController ): - - @web.expose - @web.require_login( 'upload', use_panels=True, webapp='community' ) - def upload( self, trans, **kwd ): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - category_ids = util.listify( params.get( 'category_id', '' ) ) - replace_id = params.get( 'replace_id', None ) - if replace_id: - replace_version = trans.sa_session.query( trans.app.model.Tool ).get( trans.security.decode_id( replace_id ) ) - upload_type = replace_version.type - else: - replace_version = None - upload_type = params.get( 'upload_type', 'tool' ) - uploaded_file = None - categories = get_categories( trans ) - if not categories: - message = 'No categories have been configured in this instance of the Galaxy Tool Shed. ' + \ - 'An administrator needs to create some via the Administrator control panel before anything can be uploaded', - status = 'error' - return trans.response.send_redirect( web.url_for( controller='tool', - action='browse_tools', - cntrller='tool', - message=message, - status=status ) ) - if params.get( 'upload_button', False ): - url_paste = params.get( 'url', '' ).strip() - file_data = params.get( 'file_data', '' ) - if file_data == '' and url_paste == '': - message = 'No files were entered on the upload form.' - status = 'error' - elif file_data == '': - try: - uploaded_file = urllib2.urlopen( url_paste ) - except ( ValueError, urllib2.HTTPError ), e: - message = 'An error occurred trying to retrieve the URL entered on the upload form: %s' % str( e ) - status = 'error' - except urllib2.URLError, e: - message = 'An error occurred trying to retrieve the URL entered on the upload form: %s' % e.reason - status = 'error' - elif file_data not in ( '', None ): - uploaded_file = file_data.file - if uploaded_file: - datatype = trans.app.datatypes_registry.get_datatype_by_extension( upload_type ) - if datatype is None: - message = 'An unknown file type was selected. This should not be possible, please report the error.' - status = 'error' - else: - try: - # Initialize the tool object - meta = datatype.verify( uploaded_file ) - meta.user = trans.user - meta.guid = trans.app.security.get_new_guid() - meta.suite = upload_type == 'toolsuite' - obj = datatype.create_model_object( meta ) - trans.sa_session.add( obj ) - if isinstance( obj, trans.app.model.Tool ): - existing = trans.sa_session.query( trans.app.model.Tool ) \ - .filter_by( tool_id = meta.id ) \ - .first() - if existing and not replace_id: - raise UploadError( 'A %s with the same Id already exists. If you are trying to update this %s to a new version, use the upload form on the "Edit Tool" page. Otherwise, change the Id in the %s config.' % \ - ( obj.label, obj.label, obj.label ) ) - elif replace_id and not existing: - raise UploadError( 'The new %s id (%s) does not match the old %s id (%s). Check the %s config files.' % \ - ( obj.label, str( meta.id ), obj.label, str( replace_version.tool_id ), obj.label ) ) - elif existing and replace_id: - if replace_version.newer_version: - # If the user has picked an old version, switch to the newest version - replace_version = get_versions( replace_version )[0] - if replace_version.tool_id != meta.id: - raise UploadError( 'The new %s id (%s) does not match the old %s id (%s). Check the %s config files.' % \ - ( obj.label, str( meta.id ), obj.label, str( replace_version.tool_id ), obj.label ) ) - for old_version in get_versions( replace_version ): - if old_version.version == meta.version: - raise UploadError( 'The new version (%s) matches an old version. Check your version in the %s config file.' % \ - ( str( meta.version ), obj.label ) ) - if old_version.is_new: - raise UploadError( 'There is an existing version of this %s which has not yet been submitted for approval, so either submit it or delete it before uploading a new version.' % \ - ( obj.label, - url_for( controller='common', - action='view_tool', - cntrller='tool', - id=trans.security.encode_id( old_version.id ) ) ) ) - if old_version.is_waiting: - raise UploadError( 'There is an existing version of this %s which is waiting for administrative approval, so contact an administrator for help.' % \ - obj.label ) - # Defer setting the id since the newer version id doesn't exist until the new Tool object is flushed - if category_ids: - for category_id in category_ids: - category = trans.app.model.Category.get( trans.security.decode_id( category_id ) ) - # Initialize the tool category - tca = trans.app.model.ToolCategoryAssociation( obj, category ) - trans.sa_session.add( tca ) - # Initialize the tool event - event = trans.app.model.Event( state=trans.app.model.Tool.states.NEW ) - # Flush to get an event id - trans.sa_session.add( event ) - trans.sa_session.flush() - tea = trans.app.model.ToolEventAssociation( obj, event ) - trans.sa_session.add( tea ) - if replace_version and replace_id: - replace_version.newer_version_id = obj.id - trans.sa_session.add( replace_version ) - # TODO: should the state be changed to archived? We'll leave it alone for now - # because if the newer version is deleted, we'll need to add logic to reset the - # the older version back to it's previous state ( possible approved ). - comment = "Replaced by new version %s" % obj.version - event = trans.app.model.Event( state=replace_version.state, comment=comment ) - # Flush to get an event id - trans.sa_session.add( event ) - trans.sa_session.flush() - tea = trans.app.model.ToolEventAssociation( replace_version, event ) - trans.sa_session.flush() - try: - os.link( uploaded_file.name, obj.file_name ) - except OSError: - shutil.copy( uploaded_file.name, obj.file_name ) - # We're setting cntrller to 'tool' since that is the only controller from which we can upload - # TODO: this will need tweaking when we can upload histories or workflows - return trans.response.send_redirect( web.url_for( controller='common', - action='edit_tool', - cntrller='tool', - id=trans.app.security.encode_id( obj.id ), - message='Uploaded %s' % meta.message, - status='done' ) ) - except ( datatypes.DatatypeVerificationError, UploadError ), e: - message = str( e ) - status = 'error' - uploaded_file.close() - elif replace_id is not None: - old_version = None - for old_version in get_versions( replace_version ): - if old_version.is_new: - message = 'There is an existing version of this tool which has not been submitted for approval, so either submit or delete it before uploading a new version.' - break - if old_version.is_waiting: - message = 'There is an existing version of this tool which is waiting for administrative approval, so contact an administrator for help.' - break - else: - old_version = None - if old_version is not None: - return trans.response.send_redirect( web.url_for( controller='common', - action='view_tool', - cntrller='tool', - id=trans.app.security.encode_id( old_version.id ), - message=message, - status='error' ) ) - selected_categories = [ trans.security.decode_id( id ) for id in category_ids ] - datatype_extensions = trans.app.datatypes_registry.get_datatype_extensions() - upload_type_select_list = build_select_field( trans, - objs=datatype_extensions, - label_attr='self', - select_field_name='upload_type', - initial_value=upload_type, - selected_value=upload_type, - refresh_on_change=True ) - return trans.fill_template( '/webapps/community/upload/upload.mako', - message=message, - status=status, - selected_upload_type=upload_type, - upload_type_select_list=upload_type_select_list, - replace_id=replace_id, - selected_categories=selected_categories, - categories=get_categories( trans ) ) diff --git a/lib/galaxy/webapps/community/model/mapping.py b/lib/galaxy/webapps/community/model/mapping.py index 355a620955b..9fb1aed0048 100644 --- a/lib/galaxy/webapps/community/model/mapping.py +++ b/lib/galaxy/webapps/community/model/mapping.py @@ -122,22 +122,6 @@ RepositoryCategoryAssociation.table = Table( "repository_category_association", Column( "repository_id", Integer, ForeignKey( "repository.id" ), index=True ), Column( "category_id", Integer, ForeignKey( "category.id" ), index=True ) ) -Tool.table = Table( "tool", metadata, - Column( "id", Integer, primary_key=True ), - Column( "guid", TrimmedString( 255 ), index=True, unique=True ), - Column( "tool_id", TrimmedString( 255 ), index=True ), - Column( "create_time", DateTime, default=now ), - Column( "update_time", DateTime, default=now, onupdate=now ), - Column( "newer_version_id", Integer, ForeignKey( "tool.id" ), nullable=True ), - Column( "name", TrimmedString( 255 ), index=True ), - Column( "description" , TEXT ), - Column( "user_description" , TEXT ), - Column( "version", TrimmedString( 255 ) ), - Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ), - Column( "external_filename" , TEXT ), - Column( "deleted", Boolean, index=True, default=False ), - Column( "suite", Boolean, default=False, index=True ) ) - Category.table = Table( "category", metadata, Column( "id", Integer, primary_key=True ), Column( "create_time", DateTime, default=now ), @@ -146,32 +130,6 @@ Category.table = Table( "category", metadata, Column( "description" , TEXT ), Column( "deleted", Boolean, index=True, default=False ) ) -ToolCategoryAssociation.table = Table( "tool_category_association", metadata, - Column( "id", Integer, primary_key=True ), - Column( "tool_id", Integer, ForeignKey( "tool.id" ), index=True ), - Column( "category_id", Integer, ForeignKey( "category.id" ), index=True ) ) - -Event.table = Table( 'event', metadata, - Column( "id", Integer, primary_key=True ), - Column( "create_time", DateTime, default=now ), - Column( "update_time", DateTime, default=now, onupdate=now ), - Column( "state", TrimmedString( 255 ), index=True ), - Column( "comment", TEXT ) ) - -ToolEventAssociation.table = Table( "tool_event_association", metadata, - Column( "id", Integer, primary_key=True ), - Column( "tool_id", Integer, ForeignKey( "tool.id" ), index=True ), - Column( "event_id", Integer, ForeignKey( "event.id" ), index=True ) ) - -ToolRatingAssociation.table = Table( "tool_rating_association", metadata, - Column( "id", Integer, primary_key=True ), - Column( "create_time", DateTime, default=now ), - Column( "update_time", DateTime, default=now, onupdate=now ), - Column( "tool_id", Integer, ForeignKey( "tool.id" ), index=True ), - Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ), - Column( "rating", Integer, index=True ), - Column( "comment", TEXT ) ) - Tag.table = Table( "tag", metadata, Column( "id", Integer, primary_key=True ), Column( "type", Integer ), @@ -179,27 +137,10 @@ Tag.table = Table( "tag", metadata, Column( "name", TrimmedString(255) ), UniqueConstraint( "name" ) ) -ToolTagAssociation.table = Table( "tool_tag_association", metadata, - Column( "id", Integer, primary_key=True ), - Column( "tool_id", Integer, ForeignKey( "tool.id" ), index=True ), - Column( "tag_id", Integer, ForeignKey( "tag.id" ), index=True ), - Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ), - Column( "user_tname", TrimmedString(255), index=True), - Column( "value", TrimmedString(255), index=True), - Column( "user_value", TrimmedString(255), index=True) ) - -ToolAnnotationAssociation.table = Table( "tool_annotation_association", metadata, - Column( "id", Integer, primary_key=True ), - Column( "tool_id", Integer, ForeignKey( "tool.id" ), index=True ), - Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ), - Column( "annotation", TEXT, index=True) ) - # With the tables defined we can define the mappers and setup the # relationships between the model objects. assign_mapper( context, User, User.table, - properties=dict( tools=relation( Tool, primaryjoin=( Tool.table.c.user_id == User.table.c.id ), order_by=( Tool.table.c.name ) ), - active_tools=relation( Tool, primaryjoin=( ( Tool.table.c.user_id == User.table.c.id ) & ( not_( Tool.table.c.deleted ) ) ), order_by=( Tool.table.c.name ) ), - active_repositories=relation( Repository, primaryjoin=( ( Repository.table.c.user_id == User.table.c.id ) & ( not_( Repository.table.c.deleted ) ) ), order_by=( Repository.table.c.name ) ), + properties=dict( active_repositories=relation( Repository, primaryjoin=( ( Repository.table.c.user_id == User.table.c.id ) & ( not_( Repository.table.c.deleted ) ) ), order_by=( Repository.table.c.name ) ), galaxy_sessions=relation( GalaxySession, order_by=desc( GalaxySession.table.c.update_time ) ) ) ) assign_mapper( context, Group, Group.table, @@ -233,49 +174,8 @@ assign_mapper( context, GalaxySession, GalaxySession.table, assign_mapper( context, Tag, Tag.table, properties=dict( children=relation(Tag, backref=backref( 'parent', remote_side=[Tag.table.c.id] ) ) ) ) -assign_mapper( context, ToolTagAssociation, ToolTagAssociation.table, - properties=dict( tag=relation(Tag, backref="tagged_tools"), user=relation( User ) ) ) - -assign_mapper( context, ToolAnnotationAssociation, ToolAnnotationAssociation.table, - properties=dict( tool=relation( Tool ), user=relation( User ) ) ) - -assign_mapper( context, Tool, Tool.table, - properties = dict( - categories=relation( ToolCategoryAssociation ), - events=relation( ToolEventAssociation, secondary=Event.table, - primaryjoin=( Tool.table.c.id==ToolEventAssociation.table.c.tool_id ), - secondaryjoin=( ToolEventAssociation.table.c.event_id==Event.table.c.id ), - order_by=desc( Event.table.c.update_time ), - viewonly=True, - uselist=True ), - ratings=relation( ToolRatingAssociation, order_by=desc( ToolRatingAssociation.table.c.update_time ), backref="tools" ), - user=relation( User.mapper ), - older_version=relation( - Tool, - primaryjoin=( Tool.table.c.newer_version_id == Tool.table.c.id ), - backref=backref( "newer_version", primaryjoin=( Tool.table.c.newer_version_id == Tool.table.c.id ), remote_side=[Tool.table.c.id] ) ) - ) ) - - -assign_mapper( context, ToolCategoryAssociation, ToolCategoryAssociation.table, - properties=dict( - category=relation( Category ), - tool=relation( Tool ) ) ) - -assign_mapper( context, ToolRatingAssociation, ToolRatingAssociation.table, - properties=dict( tool=relation( Tool ), user=relation( User ) ) ) - -assign_mapper( context, Event, Event.table, - properties=None ) - -assign_mapper( context, ToolEventAssociation, ToolEventAssociation.table, - properties=dict( - tool=relation( Tool ), - event=relation( Event ) ) ) - assign_mapper( context, Category, Category.table, - properties=dict( tools=relation( ToolCategoryAssociation ), - repositories=relation( RepositoryCategoryAssociation ) ) ) + properties=dict( repositories=relation( RepositoryCategoryAssociation ) ) ) assign_mapper( context, Repository, Repository.table, properties = dict( @@ -309,11 +209,8 @@ def load_egg_for_url( url ): # Let this go, it could possibly work with db's we don't support log.error( "database_connection contains an unknown SQLAlchemy database dialect: %s" % dialect ) -def init( enable_next_gen_tool_shed, file_path, url, engine_options={}, create_tables=False ): +def init( file_path, url, engine_options={}, create_tables=False ): """Connect mappings to the database""" - if not enable_next_gen_tool_shed: - # Connect tool archive location to the file path - Tool.file_path = file_path # Load the appropriate db module load_egg_for_url( url ) # Create the database engine diff --git a/lib/galaxy/webapps/community/model/migrate/versions/0005_drop_tool_related_tables.py b/lib/galaxy/webapps/community/model/migrate/versions/0005_drop_tool_related_tables.py new file mode 100644 index 00000000000..e15738c9f83 --- /dev/null +++ b/lib/galaxy/webapps/community/model/migrate/versions/0005_drop_tool_related_tables.py @@ -0,0 +1,193 @@ +""" +Drops the tool, tool_category_association, event, tool_event_association, tool_rating_association, +tool_tag_association and tool_annotation_association tables since they are no longer used in the +next-gen tool shed. +""" +from sqlalchemy import * +from sqlalchemy.orm import * +from sqlalchemy.exc import * +from migrate import * +from migrate.changeset import * + +import datetime +now = datetime.datetime.utcnow + +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 ) + +# Need our custom types, but don't import anything else from model +from galaxy.model.custom_types import * + +metadata = MetaData( migrate_engine ) +db_session = scoped_session( sessionmaker( bind=migrate_engine, autoflush=False, autocommit=True ) ) + +def upgrade(): + print __doc__ + # Load existing tables + metadata.reflect() + # Load and then drop the tool_category_association table + try: + ToolCategoryAssociation_table = Table( "tool_category_association", metadata, autoload=True ) + except NoSuchTableError: + log.debug( "Failed loading table tool_category_association" ) + try: + ToolCategoryAssociation_table.drop() + except Exception, e: + log.debug( "Dropping tool_category_association table failed: %s" % str( e ) ) + # Load and then drop the tool_event_association table + try: + ToolEventAssociation_table = Table( "tool_event_association", metadata, autoload=True ) + except NoSuchTableError: + log.debug( "Failed loading table tool_event_association" ) + try: + ToolEventAssociation_table.drop() + except Exception, e: + log.debug( "Dropping tool_event_association table failed: %s" % str( e ) ) + # Load and then drop the tool_rating_association table + try: + ToolRatingAssociation_table = Table( "tool_rating_association", metadata, autoload=True ) + except NoSuchTableError: + log.debug( "Failed loading table tool_rating_association" ) + try: + ToolRatingAssociation_table.drop() + except Exception, e: + log.debug( "Dropping tool_rating_association table failed: %s" % str( e ) ) + # Load and then drop the tool_tag_association table + try: + ToolTagAssociation_table = Table( "tool_tag_association", metadata, autoload=True ) + except NoSuchTableError: + log.debug( "Failed loading table tool_tag_association" ) + try: + ToolTagAssociation_table.drop() + except Exception, e: + log.debug( "Dropping tool_tag_association table failed: %s" % str( e ) ) + # Load and then drop the tool_annotation_association table + try: + ToolAnnotationAssociation_table = Table( "tool_annotation_association", metadata, autoload=True ) + except NoSuchTableError: + log.debug( "Failed loading table tool_annotation_association" ) + try: + ToolAnnotationAssociation_table.drop() + except Exception, e: + log.debug( "Dropping tool_annotation_association table failed: %s" % str( e ) ) + # Load and then drop the event table + try: + Event_table = Table( "event", metadata, autoload=True ) + except NoSuchTableError: + log.debug( "Failed loading table event" ) + try: + Event_table.drop() + except Exception, e: + log.debug( "Dropping event table failed: %s" % str( e ) ) + # Load and then drop the tool table + try: + Tool_table = Table( "tool", metadata, autoload=True ) + except NoSuchTableError: + log.debug( "Failed loading table tool" ) + try: + Tool_table.drop() + except Exception, e: + log.debug( "Dropping tool table failed: %s" % str( e ) ) +def downgrade(): + # Load existing tables + metadata.reflect() + # We've lost all of our data, so downgrading is useless. However, we'll + # at least re-create the dropped tables. + Event_table = Table( 'event', metadata, + Column( "id", Integer, primary_key=True ), + Column( "create_time", DateTime, default=now ), + Column( "update_time", DateTime, default=now, onupdate=now ), + Column( "state", TrimmedString( 255 ), index=True ), + Column( "comment", TEXT ) ) + + Tool_table = Table( "tool", metadata, + Column( "id", Integer, primary_key=True ), + Column( "guid", TrimmedString( 255 ), index=True, unique=True ), + Column( "tool_id", TrimmedString( 255 ), index=True ), + Column( "create_time", DateTime, default=now ), + Column( "update_time", DateTime, default=now, onupdate=now ), + Column( "newer_version_id", Integer, ForeignKey( "tool.id" ), nullable=True ), + Column( "name", TrimmedString( 255 ), index=True ), + Column( "description" , TEXT ), + Column( "user_description" , TEXT ), + Column( "version", TrimmedString( 255 ) ), + Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ), + Column( "external_filename" , TEXT ), + Column( "deleted", Boolean, index=True, default=False ), + Column( "suite", Boolean, default=False, index=True ) ) + + ToolCategoryAssociation_table = Table( "tool_category_association", metadata, + Column( "id", Integer, primary_key=True ), + Column( "tool_id", Integer, ForeignKey( "tool.id" ), index=True ), + Column( "category_id", Integer, ForeignKey( "category.id" ), index=True ) ) + + ToolEventAssociation_table = Table( "tool_event_association", metadata, + Column( "id", Integer, primary_key=True ), + Column( "tool_id", Integer, ForeignKey( "tool.id" ), index=True ), + Column( "event_id", Integer, ForeignKey( "event.id" ), index=True ) ) + + ToolRatingAssociation_table = Table( "tool_rating_association", metadata, + Column( "id", Integer, primary_key=True ), + Column( "create_time", DateTime, default=now ), + Column( "update_time", DateTime, default=now, onupdate=now ), + Column( "tool_id", Integer, ForeignKey( "tool.id" ), index=True ), + Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ), + Column( "rating", Integer, index=True ), + Column( "comment", TEXT ) ) + + ToolTagAssociation_table = Table( "tool_tag_association", metadata, + Column( "id", Integer, primary_key=True ), + Column( "tool_id", Integer, ForeignKey( "tool.id" ), index=True ), + Column( "tag_id", Integer, ForeignKey( "tag.id" ), index=True ), + Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ), + Column( "user_tname", TrimmedString(255), index=True), + Column( "value", TrimmedString(255), index=True), + Column( "user_value", TrimmedString(255), index=True) ) + + ToolAnnotationAssociation_table = Table( "tool_annotation_association", metadata, + Column( "id", Integer, primary_key=True ), + Column( "tool_id", Integer, ForeignKey( "tool.id" ), index=True ), + Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ), + Column( "annotation", TEXT, index=True) ) + + # Create the event table + try: + Event_table.create() + except Exception, e: + log.debug( "Creating event table failed: %s" % str( e ) ) + # Create the tool table + try: + Tool_table.create() + except Exception, e: + log.debug( "Creating tool table failed: %s" % str( e ) ) + # Create the tool_category_association table + try: + ToolCategoryAssociation_table.create() + except Exception, e: + log.debug( "Creating tool_category_association table failed: %s" % str( e ) ) + # Create the tool_event_association table + try: + ToolEventAssociation_table.create() + except Exception, e: + log.debug( "Creating tool_event_association table failed: %s" % str( e ) ) + # Create the tool_rating_association table + try: + ToolRatingAssociation_table.create() + except Exception, e: + log.debug( "Creating tool_rating_association table failed: %s" % str( e ) ) + # Create the tool_tag_association table + try: + ToolTagAssociation_table.create() + except Exception, e: + log.debug( "Creating tool_tag_association table failed: %s" % str( e ) ) + # Create the tool_annotation_association table + try: + ToolAnnotationAssociation_table.create() + except Exception, e: + log.debug( "Creating tool_annotation_association table failed: %s" % str( e ) ) diff --git a/lib/galaxy/webapps/community/security/__init__.py b/lib/galaxy/webapps/community/security/__init__.py index 82a67289f2e..2dffe949587 100644 --- a/lib/galaxy/webapps/community/security/__init__.py +++ b/lib/galaxy/webapps/community/security/__init__.py @@ -6,7 +6,6 @@ from datetime import datetime, timedelta from galaxy.util.bunch import Bunch from galaxy.util import listify from galaxy.model.orm import * -from galaxy.webapps.community.controllers.common import get_versions log = logging.getLogger(__name__) @@ -77,8 +76,6 @@ class CommunityRBACAgent( RBACAgent ): elif 'role' in kwd: if 'group' in kwd: return self.associate_group_role( kwd['group'], kwd['role'] ) - elif 'tool' in kwd: - return self.associate_tool_category( kwd['tool'], kwd['category'] ) elif 'repository' in kwd: return self.associate_repository_category( kwd[ 'repository' ], kwd[ 'category' ] ) raise 'No valid method of associating provided components: %s' % kwd @@ -97,11 +94,6 @@ class CommunityRBACAgent( RBACAgent ): self.sa_session.add( assoc ) self.sa_session.flush() return assoc - def associate_tool_category( self, tool, category ): - assoc = self.model.ToolCategoryAssociation( tool, category ) - self.sa_session.add( assoc ) - self.sa_session.flush() - return assoc def associate_repository_category( self, repository, category ): assoc = self.model.RepositoryCategoryAssociation( repository, category ) self.sa_session.add( assoc ) @@ -162,77 +154,6 @@ class CommunityRBACAgent( RBACAgent ): self.associate_components( user=user, role=role ) for group in groups: self.associate_components( user=user, group=group ) - def set_entity_category_associations( self, tools=[], categories=[], delete_existing_assocs=True ): - for tool in tools: - if delete_existing_assocs: - for a in tool.categories: - self.sa_session.delete( a ) - self.sa_session.flush() - self.sa_session.refresh( tool ) - for category in categories: - self.associate_components( tool=tool, category=category ) - def can_rate( self, user, user_is_admin, cntrller, item ): - # The current user can rate and review the item if they are an admin or if - # they did not upload the item and the item is approved or archived. - if user and user_is_admin and cntrller == 'admin': - return True - if cntrller in [ 'tool' ] and ( item.is_approved or item.is_archived ) and user != item.user: - return True - return False - def can_approve_or_reject( self, user, user_is_admin, cntrller, item ): - # The current user can approve or reject the item if the user - # is an admin, and the item's state is WAITING. - return user and user_is_admin and cntrller=='admin' and item.is_waiting - def can_delete( self, user, user_is_admin, cntrller, item ): - # The current user can delete the item if they are an admin or if they uploaded the - # item and in either case the item's state is not DELETED. - if user and user_is_admin and cntrller == 'admin': - can_delete = not item.is_deleted - elif cntrller in [ 'tool' ]: - can_delete = user==item.user and not item.is_deleted - else: - can_delete = False - return can_delete - def can_download( self, user, user_is_admin, cntrller, item ): - # The current user can download the item if they are an admin or if the - # item's state is not one of: NEW, WAITING. - if user and user_is_admin and cntrller == 'admin': - return True - elif cntrller in [ 'tool' ]: - can_download = not( item.is_new or item.is_waiting ) - else: - can_download = False - return can_download - def can_edit( self, user, user_is_admin, cntrller, item ): - # The current user can edit the item if they are an admin or if they uploaded the item - # and the item's state is one of: NEW, REJECTED. - if user and user_is_admin and cntrller == 'admin': - return True - if cntrller in [ 'tool' ]: - return user and user==item.user and ( item.is_new or item.is_rejected ) - return False - def can_purge( self, user, user_is_admin, cntrller ): - # The current user can purge the item if they are an admin. - return user and user_is_admin and cntrller == 'admin' - def can_upload_new_version( self, user, item ): - # The current user can upload a new version as long as the item's state is not NEW or WAITING. - if not user: - return False - versions = get_versions( item ) - state_ok = True - for version in versions: - if version.is_new or version.is_waiting: - state_ok = False - break - return state_ok - def can_view( self, user, user_is_admin, cntrller, item ): - # The current user can view the item if they are an admin or if they uploaded the item - # or if the item's state is APPROVED. - if user and user_is_admin and cntrller == 'admin': - return True - if cntrller in [ 'tool' ] and item.is_approved or item.is_archived or item.is_deleted: - return True - return user and user==item.user def can_push( self, user, repository ): # TODO: handle this via the mercurial api. if not user: @@ -246,29 +167,6 @@ class CommunityRBACAgent( RBACAgent ): allowed = config.get( "web", option ) return user.username in allowed return False - def get_all_action_permissions( self, user, user_is_admin, cntrller, item ): - """Get all permitted actions on item for the current user""" - can_edit = self.can_edit( cntrller, user, user_is_admin, item ) - can_view = self.can_view( cntrller, user, user_is_admin, item ) - can_upload_new_version = self.can_upload_new_version( user, item ) - visible_versions = self.get_visible_versions( user, user_is_admin, cntrller, item ) - can_approve_or_reject = self.can_approve_or_reject( user, user_is_admin, cntrller, item ) - can_delete = self.can_delete( user, user_is_admin, cntrller, item ) - return can_edit, can_view, can_upload_new_version, can_delete, visible_versions, can_approve_or_reject - def get_visible_versions( self, user, user_is_admin, cntrller, item ): - # All previous versions of item can be displayed if the current user is an admin - # or they uploaded item. Otherwise, only versions whose state is APPROVED or - # ARCHIVED will be displayed. - if user and user_is_admin and cntrller == 'admin': - visible_versions = get_versions( item ) - elif cntrller in [ 'tool' ]: - visible_versions = [] - for version in get_versions( item ): - if version.is_approved or version.is_archived or version.user == user: - visible_versions.append( version ) - else: - visible_versions = [] - return visible_versions def get_permitted_actions( filter=None ): '''Utility method to return a subset of RBACAgent's permitted actions''' diff --git a/scripts/tool_shed/migrate_tools_to_repositories.py b/scripts/tool_shed/migrate_tools_to_repositories.py index 2948adf08fa..cd1a97246c5 100644 --- a/scripts/tool_shed/migrate_tools_to_repositories.py +++ b/scripts/tool_shed/migrate_tools_to_repositories.py @@ -8,6 +8,8 @@ associated with them, and migrates old tool shed stuff to new tool shed stuff. ====== CRITICAL ======= +0. This script must be run on a repo updated to changeset: 5621:4618be57481b + 1. Before running this script, make sure the following config setting is set in community_wsgi.ini # Enable next-gen tool shed features @@ -16,10 +18,6 @@ enable_next_gen_tool_shed = True 2. This script requires the Galaxy instance to use Postgres for database storage. To run this script, use "sh migrate_tools_to_repositories.sh" from this directory - -TODO: This script currently creates hg repos under the name of the user running the script. When -we get the hgweb stuff working, see if we can correct this, creating repos under the user name of the -user that uploaded the tool archive. ''' import sys, os, subprocess, ConfigParser, shutil, tarfile, tempfile diff --git a/templates/webapps/community/admin/center.mako b/templates/webapps/community/admin/center.mako index 7528846287b..4726edffada 100644 --- a/templates/webapps/community/admin/center.mako +++ b/templates/webapps/community/admin/center.mako @@ -6,26 +6,6 @@

The menu on the left provides the following features