Merge pull request #1821 from davebx/toolshed_decouple_api

Cherry-picked changes from pull request #1392.
This commit is contained in:
Martin Cech
2016-03-03 12:17:14 -05:00
13 changed files with 262 additions and 104 deletions
+17 -7
View File
@@ -288,8 +288,9 @@ class SelectField(BaseField):
<div><input type="checkbox" name="bar" value="3" id="bar|3"><label class="inline" for="bar|3">automatic</label></div>
<div><input type="checkbox" name="bar" value="4" id="bar|4" checked='checked'><label class="inline" for="bar|4">bazooty</label></div>
"""
def __init__( self, name, multiple=None, display=None, refresh_on_change=False, refresh_on_change_values=None, size=None ):
def __init__( self, name, multiple=None, display=None, refresh_on_change=False, refresh_on_change_values=None, size=None, field_id=None ):
self.name = name
self.field_id = field_id
self.multiple = multiple or False
self.size = size
self.options = list()
@@ -312,7 +313,11 @@ class SelectField(BaseField):
def add_option( self, text, value, selected=False ):
self.options.append( ( text, value, selected ) )
def get_html( self, prefix="", disabled=False ):
def get_html( self, prefix="", disabled=False, extra_attr=None ):
if extra_attr is not None:
self.extra_attributes = ' %s' % ' '.join( [ '%s="%s"' % ( k, escape( v ) ) for k, v in extra_attr.items() ] )
else:
self.extra_attributes = ''
if self.display == "checkboxes":
return self.get_html_checkboxes( prefix, disabled )
elif self.display == "radio":
@@ -335,8 +340,8 @@ class SelectField(BaseField):
selected_text = ""
if selected:
selected_text = " checked='checked'"
rval.append( '<div%s><input type="checkbox" name="%s%s" value="%s" id="%s"%s%s><label class="inline" for="%s">%s</label></div>'
% ( style, prefix, self.name, escaped_value, uniq_id, selected_text, self.get_disabled_str( disabled ), uniq_id, escape( text, quote=True ) ) )
rval.append( '<div%s><input type="checkbox" name="%s%s" value="%s" id="%s"%s%s%s><label class="inline" for="%s">%s</label></div>'
% ( style, prefix, self.name, escaped_value, uniq_id, selected_text, self.get_disabled_str( disabled ), self.extra_attributes, uniq_id, escape( text, quote=True ) ) )
ctr += 1
return unicodify( "\n".join( rval ) )
@@ -352,7 +357,7 @@ class SelectField(BaseField):
selected_text = ""
if selected:
selected_text = " checked='checked'"
rval.append( '<div%s><input type="radio" name="%s%s"%s value="%s" id="%s"%s%s><label class="inline" for="%s">%s</label></div>'
rval.append( '<div%s><input type="radio" name="%s%s"%s value="%s" id="%s"%s%s%s><label class="inline" for="%s">%s</label></div>'
% ( style,
prefix,
self.name,
@@ -361,6 +366,7 @@ class SelectField(BaseField):
uniq_id,
selected_text,
self.get_disabled_str( disabled ),
self.extra_attributes,
uniq_id,
text ) )
ctr += 1
@@ -388,8 +394,12 @@ class SelectField(BaseField):
rval.append( '<option value="%s"%s>%s</option>' % ( escape( unicodify( value ), quote=True ), selected_text, escape( unicodify( text ), quote=True ) ) )
if last_selected_value:
last_selected_value = ' last_selected_value="%s"' % escape( unicodify( last_selected_value ), quote=True )
rval.insert( 0, '<select name="%s%s"%s%s%s%s%s>'
% ( prefix, self.name, multiple, size, self.refresh_on_change_text, last_selected_value, self.get_disabled_str( disabled ) ) )
if self.field_id is not None:
id_string = ' id="%s"' % self.field_id
else:
id_string = ''
rval.insert( 0, '<select name="%s%s"%s%s%s%s%s%s%s>'
% ( prefix, self.name, multiple, size, self.refresh_on_change_text, last_selected_value, self.get_disabled_str( disabled ), id_string, self.extra_attributes ) )
rval.append( '</select>' )
return unicodify( "\n".join( rval ) )
+35 -7
View File
@@ -15,8 +15,11 @@ log = logging.getLogger( __name__ )
class CategoriesController( BaseAPIController ):
"""RESTful controller for interactions with categories in the Tool Shed."""
def __get_repository_count( self, trans, category_name ):
return self.app.repository_registry.viewable_repositories_and_suites_by_category.get( category_name, 0 )
def __get_value_mapper( self, trans ):
value_mapper = { 'id' : trans.security.encode_id }
value_mapper = { 'id': trans.security.encode_id }
return value_mapper
@expose_api
@@ -41,11 +44,11 @@ class CategoriesController( BaseAPIController ):
if not description:
# Default the description to the name.
description = name
if suc.get_category_by_name( trans.app, name ):
if suc.get_category_by_name( self.app, name ):
raise exceptions.Conflict( 'A category with that name already exists.' )
else:
# Create the category
category = trans.app.model.Category( name=name, description=description )
category = self.app.model.Category( name=name, description=description )
trans.sa_session.add( category )
trans.sa_session.flush()
category_dict = category.to_dict( view='element',
@@ -58,6 +61,30 @@ class CategoriesController( BaseAPIController ):
raise exceptions.RequestParameterMissingException( 'Missing required parameter "name".' )
return category_dict
@expose_api_anonymous_and_sessionless
def get_repositories( self, trans, category_id, **kwd ):
"""
GET /api/categories/{encoded_category_id}/repositories
Return information about the provided category and the repositories in that category.
:param id: the encoded id of the Category object
Example: GET localhost:9009/api/categories/f9cad7b01a472135/repositories
"""
category = suc.get_category( self.app, category_id )
if category is None:
category_dict = dict( message='Unable to locate category record for id %s.' % ( str( id ) ),
status='error' )
return category_dict
category_dict = category.to_dict( view='element',
value_mapper=self.__get_value_mapper( trans ) )
category_dict[ 'url' ] = web.url_for( controller='categories',
action='show',
id=trans.security.encode_id( category.id ) )
repositories = suc.get_repositories_by_category( self.app, category.id )
category_dict[ 'repositories' ] = repositories
return category_dict
@expose_api_anonymous_and_sessionless
def index( self, trans, deleted=False, **kwd ):
"""
@@ -72,14 +99,15 @@ class CategoriesController( BaseAPIController ):
deleted = util.asbool( deleted )
if deleted and not trans.user_is_admin():
raise exceptions.AdminRequiredException( 'Only administrators can query deleted categories.' )
for category in trans.sa_session.query( trans.app.model.Category ) \
.filter( trans.app.model.Category.table.c.deleted == deleted ) \
.order_by( trans.app.model.Category.table.c.name ):
for category in trans.sa_session.query( self.app.model.Category ) \
.filter( self.app.model.Category.table.c.deleted == deleted ) \
.order_by( self.app.model.Category.table.c.name ):
category_dict = category.to_dict( view='collection',
value_mapper=self.__get_value_mapper( trans ) )
category_dict[ 'url' ] = web.url_for( controller='categories',
action='show',
id=trans.security.encode_id( category.id ) )
category_dict[ 'repositories' ] = self.app.repository_registry.viewable_repositories_and_suites_by_category.get( category.name, 0 )
category_dicts.append( category_dict )
return category_dicts
@@ -93,7 +121,7 @@ class CategoriesController( BaseAPIController ):
Example: GET localhost:9009/api/categories/f9cad7b01a472135
"""
category = suc.get_category( trans.app, id )
category = suc.get_category( self.app, id )
if category is None:
category_dict = dict( message='Unable to locate category record for id %s.' % ( str( id ) ),
status='error' )
+106 -56
View File
@@ -73,7 +73,7 @@ class RepositoriesController( BaseAPIController ):
owner = payload.get( 'owner', '' )
if not owner:
raise HTTPBadRequest( detail="Missing required parameter 'owner'." )
repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
repository = suc.get_repository_by_name_and_owner( self.app, name, owner )
if repository is None:
error_message = 'Cannot locate repository with name %s and owner %s,' % ( str( name ), str( owner ) )
log.debug( error_message )
@@ -81,14 +81,14 @@ class RepositoriesController( BaseAPIController ):
response_dict[ 'message' ] = error_message
return response_dict
# Update the repository registry.
trans.app.repository_registry.add_entry( repository )
self.app.repository_registry.add_entry( repository )
response_dict[ 'status' ] = 'ok'
response_dict[ 'message' ] = 'Entries for repository %s owned by %s have been added to the Tool Shed repository registry.' \
% ( name, owner )
return response_dict
@web.expose_api_anonymous
def get_ordered_installable_revisions( self, trans, name, owner, **kwd ):
def get_ordered_installable_revisions( self, trans, **kwd ):
"""
GET /api/repositories/get_ordered_installable_revisions
@@ -98,23 +98,21 @@ class RepositoriesController( BaseAPIController ):
Returns the ordered list of changeset revision hash strings that are associated with installable revisions.
As in the changelog, the list is ordered oldest to newest.
"""
# Example URL: http://localhost:9009/api/repositories/get_installable_revisions?name=add_column&owner=test
if name and owner:
# Example URL: http://localhost:9009/api/repositories/get_ordered_installable_revisions?name=add_column&owner=test
name = kwd.get( 'name', None )
owner = kwd.get( 'owner', None )
tsr_id = kwd.get( 'tsr_id', None )
if None not in [ name, owner ]:
# Get the repository information.
repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
if repository is None:
error_message = "Error in the Tool Shed repositories API in get_ordered_installable_revisions: "
error_message += "cannot locate repository %s owned by %s." % ( str( name ), str( owner ) )
log.debug( error_message )
return []
repo = hg_util.get_repo_for_repository( trans.app, repository=repository, repo_path=None, create=False )
ordered_installable_revisions = suc.get_ordered_metadata_changeset_revisions( repository, repo, downloadable=True )
return ordered_installable_revisions
repository = suc.get_repository_by_name_and_owner( self.app, name, owner )
elif tsr_id is not None:
repository = suc.get_repository_in_tool_shed( self.app, tsr_id )
else:
error_message = "Error in the Tool Shed repositories API in get_ordered_installable_revisions: "
error_message += "invalid name %s or owner %s received." % ( str( name ), str( owner ) )
error_message += "invalid parameters received." % ( str( name ), str( owner ) )
log.debug( error_message )
return []
return repository.ordered_installable_revisions( self.app )
@web.expose_api_anonymous
def get_repository_revision_install_info( self, trans, name, owner, changeset_revision, **kwd ):
@@ -187,7 +185,7 @@ class RepositoriesController( BaseAPIController ):
# http://<xyz>/api/repositories/get_repository_revision_install_info?name=<n>&owner=<o>&changeset_revision=<cr>
if name and owner and changeset_revision:
# Get the repository information.
repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
repository = suc.get_repository_by_name_and_owner( self.app, name, owner )
if repository is None:
log.debug( 'Cannot locate repository %s owned by %s' % ( str( name ), str( owner ) ) )
return {}, {}, {}
@@ -198,15 +196,15 @@ class RepositoriesController( BaseAPIController ):
action='show',
id=encoded_repository_id )
# Get the repository_metadata information.
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans.app,
repository_metadata = suc.get_repository_metadata_by_changeset_revision( self.app,
encoded_repository_id,
changeset_revision )
if repository_metadata is None:
# The changeset_revision column in the repository_metadata table has been updated with a new
# value value, so find the changeset_revision to which we need to update.
repo = hg_util.get_repo_for_repository( trans.app, repository=repository, repo_path=None, create=False )
repo = hg_util.get_repo_for_repository( self.app, repository=repository, repo_path=None, create=False )
new_changeset_revision = suc.get_next_downloadable_changeset_revision( repository, repo, changeset_revision )
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans.app,
repository_metadata = suc.get_repository_metadata_by_changeset_revision( self.app,
encoded_repository_id,
new_changeset_revision )
changeset_revision = new_changeset_revision
@@ -226,7 +224,7 @@ class RepositoriesController( BaseAPIController ):
includes_tools_for_display_in_tool_panel, \
has_repository_dependencies, \
has_repository_dependencies_only_if_compiling_contained_td = \
repository_util.get_repo_info_dict( trans.app,
repository_util.get_repo_info_dict( self.app,
trans.user,
encoded_repository_id,
changeset_revision )
@@ -242,10 +240,30 @@ class RepositoriesController( BaseAPIController ):
log.debug( debug_msg )
return {}, {}, {}
@web.expose_api_anonymous
def get_installable_revisions( self, trans, **kwd ):
"""
GET /api/repositories/get_installable_revisions
:param tsr_id: the encoded toolshed ID of the repository
Returns a list of lists of changesets, in the format [ [ 0, fbb391dc803c ], [ 1, 9d9ec4d9c03e ], [ 2, 9b5b20673b89 ], [ 3, e8c99ce51292 ] ].
"""
# Example URL: http://localhost:9009/api/repositories/get_installable_revisions?tsr_id=9d37e53072ff9fa4
tsr_id = kwd.get( 'tsr_id', None )
if tsr_id is not None:
repository = suc.get_repository_in_tool_shed( self.app, tsr_id )
else:
error_message = "Error in the Tool Shed repositories API in get_ordered_installable_revisions: "
error_message += "missing or invalid parameter received."
log.debug( error_message )
return []
return repository.installable_revisions( self.app )
def __get_value_mapper( self, trans ):
value_mapper = { 'id' : trans.security.encode_id,
'repository_id' : trans.security.encode_id,
'user_id' : trans.security.encode_id }
value_mapper = { 'id': trans.security.encode_id,
'repository_id': trans.security.encode_id,
'user_id': trans.security.encode_id }
return value_mapper
@web.expose_api
@@ -283,7 +301,7 @@ class RepositoriesController( BaseAPIController ):
except tarfile.ReadError, e:
log.debug( 'Error opening capsule file %s: %s' % ( str( capsule_file_name ), str( e ) ) )
return {}
irm = capsule_manager.ImportRepositoryManager( trans.app,
irm = capsule_manager.ImportRepositoryManager( self.app,
trans.request.host,
trans.user,
trans.user_is_admin() )
@@ -386,16 +404,16 @@ class RepositoriesController( BaseAPIController ):
response = json.dumps( search_results )
return response
clause_list = [ and_( trans.app.model.Repository.table.c.deprecated == false(),
trans.app.model.Repository.table.c.deleted == deleted ) ]
clause_list = [ and_( self.app.model.Repository.table.c.deprecated == false(),
self.app.model.Repository.table.c.deleted == deleted ) ]
if owner is not None:
clause_list.append( and_( trans.app.model.User.table.c.username == owner,
trans.app.model.Repository.table.c.user_id == trans.app.model.User.table.c.id ) )
clause_list.append( and_( self.app.model.User.table.c.username == owner,
self.app.model.Repository.table.c.user_id == self.app.model.User.table.c.id ) )
if name is not None:
clause_list.append( trans.app.model.Repository.table.c.name == name )
for repository in trans.sa_session.query( trans.app.model.Repository ) \
clause_list.append( self.app.model.Repository.table.c.name == name )
for repository in trans.sa_session.query( self.app.model.Repository ) \
.filter( *clause_list ) \
.order_by( trans.app.model.Repository.table.c.name ):
.order_by( self.app.model.Repository.table.c.name ):
repository_dict = repository.to_dict( view='collection',
value_mapper=self.__get_value_mapper( trans ) )
repository_dict[ 'category_ids' ] = \
@@ -471,7 +489,7 @@ class RepositoriesController( BaseAPIController ):
owner = payload.get( 'owner', '' )
if not owner:
raise HTTPBadRequest( detail="Missing required parameter 'owner'." )
repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
repository = suc.get_repository_by_name_and_owner( self.app, name, owner )
if repository is None:
error_message = 'Cannot locate repository with name %s and owner %s,' % ( str( name ), str( owner ) )
log.debug( error_message )
@@ -479,7 +497,7 @@ class RepositoriesController( BaseAPIController ):
response_dict[ 'message' ] = error_message
return response_dict
# Update the repository registry.
trans.app.repository_registry.remove_entry( repository )
self.app.repository_registry.remove_entry( repository )
response_dict[ 'status' ] = 'ok'
response_dict[ 'message' ] = 'Entries for repository %s owned by %s have been removed from the Tool Shed repository registry.' \
% ( name, owner )
@@ -504,7 +522,7 @@ class RepositoriesController( BaseAPIController ):
my_writable = True
handled_repository_ids = []
repository_ids = []
rmm = repository_metadata_manager.RepositoryMetadataManager( trans.app, trans.user )
rmm = repository_metadata_manager.RepositoryMetadataManager( self.app, trans.user )
query = rmm.get_query_for_setting_metadata_on_repositories( my_writable=my_writable, order=False )
# Make sure repositories of type tool_dependency_definition are first in the list.
for repository in query:
@@ -546,7 +564,7 @@ class RepositoriesController( BaseAPIController ):
rmm.reset_all_metadata_on_repository_in_tool_shed()
rmm_invalid_file_tups = rmm.get_invalid_file_tups()
if rmm_invalid_file_tups:
message = tool_util.generate_message_for_invalid_tools( trans.app,
message = tool_util.generate_message_for_invalid_tools( self.app,
rmm_invalid_file_tups,
repository,
None,
@@ -563,7 +581,7 @@ class RepositoriesController( BaseAPIController ):
status = '%s : %s' % ( str( repository.name ), message )
results[ 'repository_status' ].append( status )
return results
rmm = repository_metadata_manager.RepositoryMetadataManager( app=trans.app,
rmm = repository_metadata_manager.RepositoryMetadataManager( app=self.app,
user=trans.user,
resetting_all_metadata_on_repository=True,
updating_installed_repository=False,
@@ -627,7 +645,7 @@ class RepositoriesController( BaseAPIController ):
results = dict( start_time=start_time,
repository_status=[] )
try:
rmm = repository_metadata_manager.RepositoryMetadataManager( app=trans.app,
rmm = repository_metadata_manager.RepositoryMetadataManager( app=self.app,
user=trans.user,
repository=repository,
resetting_all_metadata_on_repository=True,
@@ -636,7 +654,7 @@ class RepositoriesController( BaseAPIController ):
rmm.reset_all_metadata_on_repository_in_tool_shed()
rmm_invalid_file_tups = rmm.get_invalid_file_tups()
if rmm_invalid_file_tups:
message = tool_util.generate_message_for_invalid_tools( trans.app,
message = tool_util.generate_message_for_invalid_tools( self.app,
rmm_invalid_file_tups,
repository,
None,
@@ -656,7 +674,7 @@ class RepositoriesController( BaseAPIController ):
repository_id = payload.get( 'repository_id', None )
if repository_id is not None:
repository = suc.get_repository_in_tool_shed( trans.app, repository_id )
repository = suc.get_repository_in_tool_shed( self.app, repository_id )
start_time = strftime( "%Y-%m-%d %H:%M:%S" )
log.debug( "%s...resetting metadata on repository %s" % ( start_time, str( repository.name ) ) )
results = handle_repository( trans, start_time, repository )
@@ -685,7 +703,7 @@ class RepositoriesController( BaseAPIController ):
except Exception:
raise MalformedId( 'The given id is invalid.' )
repository = suc.get_repository_in_tool_shed( trans.app, id )
repository = suc.get_repository_in_tool_shed( self.app, id )
if repository is None:
raise ObjectNotFound( 'Unable to locate repository for the given id.' )
repository_dict = repository.to_dict( view='element',
@@ -695,6 +713,37 @@ class RepositoriesController( BaseAPIController ):
[ trans.security.encode_id( x.category.id ) for x in repository.categories ]
return repository_dict
@expose_api_anonymous_and_sessionless
def show_tools( self, trans, id, changeset, **kwd ):
repository_metadata = suc.get_repository_metadata_by_changeset_revision( self.app,
id,
changeset )
if repository_metadata is not None:
encoded_repository_metadata_id = trans.security.encode_id( repository_metadata.id )
repository_metadata_dict = repository_metadata.to_dict( view='collection',
value_mapper=self.__get_value_mapper( trans ) )
repository_metadata_dict[ 'url' ] = web.url_for( controller='repository_revisions',
action='show',
id=encoded_repository_metadata_id )
if 'tools' in repository_metadata.metadata:
repository_metadata_dict[ 'valid_tools' ] = repository_metadata.metadata[ 'tools' ]
# Get the repo_info_dict for installing the repository.
repo_info_dict, \
includes_tools, \
includes_tool_dependencies, \
includes_tools_for_display_in_tool_panel, \
has_repository_dependencies, \
has_repository_dependencies_only_if_compiling_contained_td = \
repository_util.get_repo_info_dict( self.app,
trans.user,
id,
changeset )
return repository_metadata_dict
else:
log.debug( "Unable to locate repository_metadata record for repository id %s and changeset_revision %s" %
( str( id ), str( changeset ) ) )
return {}
@expose_api_anonymous_and_sessionless
def metadata( self, trans, id, **kwd ):
"""
@@ -714,6 +763,7 @@ class RepositoriesController( BaseAPIController ):
trans.security.decode_id( id )
except Exception:
raise MalformedId( 'The given id is invalid.' )
recursive = util.asbool( kwd.get( 'recursive', 'True' ) )
all_metadata = {}
repository = suc.get_repository_in_tool_shed( self.app, id )
for changeset, changehash in repository.installable_revisions( self.app ):
@@ -722,15 +772,15 @@ class RepositoriesController( BaseAPIController ):
continue
metadata_dict = metadata.to_dict( value_mapper={ 'id': self.app.security.encode_id, 'repository_id': self.app.security.encode_id } )
metadata_dict[ 'repository' ] = repository.to_dict( value_mapper={ 'id': self.app.security.encode_id } )
if metadata.has_repository_dependencies:
if metadata.has_repository_dependencies and recursive:
metadata_dict[ 'repository_dependencies' ] = metadata_util.get_all_dependencies( self.app, metadata, processed_dependency_links=[] )
else:
metadata_dict[ 'repository_dependencies' ] = []
if metadata.includes_tool_dependencies:
if metadata.includes_tool_dependencies and recursive:
metadata_dict[ 'tool_dependencies' ] = repository.get_tool_dependencies( changehash )
else:
metadata_dict[ 'tool_dependencies' ] = {}
all_metadata[ '%s:%s' % ( changeset, changehash ) ] = metadata_dict
all_metadata[ '%s:%s' % ( int( changeset ), changehash ) ] = metadata_dict
return all_metadata
@expose_api
@@ -779,7 +829,7 @@ class RepositoriesController( BaseAPIController ):
category_ids=category_ids,
)
repo, message = repository_util.update_repository( app=trans.app, trans=trans, id=id, **update_kwds )
repo, message = repository_util.update_repository( app=self.app, trans=trans, id=id, **update_kwds )
if repo is None:
if "You are not the owner" in message:
raise InsufficientPermissionsException( message )
@@ -835,11 +885,11 @@ class RepositoriesController( BaseAPIController ):
if repo_type not in rt_util.types:
raise RequestParameterInvalidException( 'This repository type is not valid' )
invalid_message = repository_util.validate_repository_name( trans.app, name, trans.user )
invalid_message = repository_util.validate_repository_name( self.app, name, trans.user )
if invalid_message:
raise RequestParameterInvalidException( invalid_message )
repo, message = repository_util.create_repository( app=trans.app,
repo, message = repository_util.create_repository( app=self.app,
name=name,
type=repo_type,
description=synopsis,
@@ -871,24 +921,24 @@ class RepositoriesController( BaseAPIController ):
"""
# Example URL: http://localhost:9009/api/repositories/f9cad7b01a472135
rdah = attribute_handlers.RepositoryDependencyAttributeHandler( trans.app, unpopulate=False )
tdah = attribute_handlers.ToolDependencyAttributeHandler( trans.app, unpopulate=False )
rdah = attribute_handlers.RepositoryDependencyAttributeHandler( self.app, unpopulate=False )
tdah = attribute_handlers.ToolDependencyAttributeHandler( self.app, unpopulate=False )
repository = suc.get_repository_in_tool_shed( trans.app, id )
repository = suc.get_repository_in_tool_shed( self.app, id )
if not ( trans.user_is_admin() or
trans.app.security_agent.user_can_administer_repository( trans.user, repository ) or
trans.app.security_agent.can_push( trans.app, trans.user, repository ) ):
self.app.security_agent.user_can_administer_repository( trans.user, repository ) or
self.app.security_agent.can_push( self.app, trans.user, repository ) ):
trans.response.status = 400
return {
"err_msg": "You do not have permission to update this repository.",
}
repo_dir = repository.repo_path( trans.app )
repo = hg_util.get_repo_for_repository( trans.app, repository=None, repo_path=repo_dir, create=False )
repo_dir = repository.repo_path( self.app )
repo = hg_util.get_repo_for_repository( self.app, repository=None, repo_path=repo_dir, create=False )
upload_point = commit_util.get_upload_point( repository, **kwd )
tip = repository.tip( trans.app )
tip = repository.tip( self.app )
file_data = payload.get('file')
# Code stolen from gx's upload_common.py
@@ -938,12 +988,12 @@ class RepositoriesController( BaseAPIController ):
# Update the repository files for browsing.
hg_util.update_repository( repo )
# Get the new repository tip.
if tip == repository.tip( trans.app ):
if tip == repository.tip( self.app ):
trans.response.status = 400
message = 'No changes to repository.'
ok = False
else:
rmm = repository_metadata_manager.RepositoryMetadataManager( app=trans.app,
rmm = repository_metadata_manager.RepositoryMetadataManager( app=self.app,
user=trans.user,
repository=repository )
status, error_message = \
+11
View File
@@ -109,12 +109,18 @@ def app_factory( global_conf, **kwargs ):
name_prefix='category_',
path_prefix='/api',
parent_resources=dict( member_name='category', collection_name='categories' ) )
webapp.mapper.connect( 'repositories_in_category',
'/api/categories/{category_id}/repositories',
controller='categories',
action='get_repositories',
conditions=dict( method=[ "GET" ] ) )
webapp.mapper.resource( 'repository',
'repositories',
controller='repositories',
collection={ 'add_repository_registry_entry': 'POST',
'get_repository_revision_install_info': 'GET',
'get_ordered_installable_revisions': 'GET',
'get_installable_revisions': 'GET',
'remove_repository_registry_entry': 'POST',
'repository_ids_for_setting_metadata': 'GET',
'reset_metadata_on_repositories': 'POST',
@@ -152,6 +158,11 @@ def app_factory( global_conf, **kwargs ):
controller='repositories',
action='metadata',
conditions=dict( method=[ "GET" ] ) )
webapp.mapper.connect( 'repository_show_tools',
'/api/repositories/{id}/{changeset}/show_tools',
controller='repositories',
action='show_tools',
conditions=dict( method=[ "GET" ] ) )
webapp.mapper.connect( 'create_repository',
'/api/repositories',
controller='repositories',
@@ -1618,22 +1618,10 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ):
owner = kwd.get( 'owner', None )
changeset_revision = kwd.get( 'changeset_revision', None )
repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
# We aren't concerned with repositories of type tool_dependency_definition here if a
# repository_metadata record is not returned because repositories of this type will never
# have repository dependencies. However, if a readme file is uploaded, or some other change
# is made that does not create a new downloadable changeset revision but updates the existing
# one, we still want to be able to get repository dependencies.
repository_metadata = suc.get_current_repository_metadata_for_changeset_revision( trans.app,
repository,
changeset_revision )
if repository_metadata:
metadata = repository_metadata.metadata
if metadata:
toolshed_base_url = str( web.url_for( '/', qualified=True ) ).rstrip( '/' )
rb = relation_builder.RelationBuilder( trans.app, repository, repository_metadata, toolshed_base_url )
repository_dependencies = rb.get_repository_dependencies_for_changeset_revision()
if repository_dependencies:
return encoding_util.tool_shed_encode( repository_dependencies )
# get_repository_dependencies( self, app, changeset, toolshed_url )
dependencies = repository.get_repository_dependencies( trans.app, changeset_revision, web.url_for( '/', qualified=True ) )
if dependencies:
return encoding_util.tool_shed_encode( dependencies )
return ''
@web.expose
@@ -1724,13 +1712,9 @@ class RepositoryController( BaseUIController, ratings_util.ItemRatings ):
owner = kwd.get( 'owner', None )
changeset_revision = kwd.get( 'changeset_revision', None )
repository = suc.get_repository_by_name_and_owner( trans.app, name, owner )
for downloadable_revision in repository.downloadable_revisions:
if downloadable_revision.changeset_revision == changeset_revision:
break
metadata = downloadable_revision.metadata
tool_dependencies = metadata.get( 'tool_dependencies', '' )
if tool_dependencies:
return encoding_util.tool_shed_encode( tool_dependencies )
dependencies = repository.get_tool_dependencies( changeset_revision )
if dependencies is not None:
return encoding_util.tool_shed_encode( dependencies )
return ''
@web.expose
@@ -8,8 +8,8 @@ from galaxy.util.bunch import Bunch
from galaxy.util.hash_util import new_secure_hash
from galaxy.util.dictifiable import Dictifiable
import tool_shed.repository_types.util as rt_util
import tool_shed.util.shed_util_common as suc
from tool_shed.dependencies.repository import relation_builder
from tool_shed.util import shed_util_common as suc
from mercurial import hg
from mercurial import ui
@@ -253,14 +253,14 @@ class Repository( object, Dictifiable ):
def installable_revisions( self, app ):
return suc.get_metadata_revisions( self, hg.repository( ui.ui(), self.repo_path( app ) ), sort_revisions=True )
def ordered_installable_revisions( self, app ):
return suc.get_ordered_metadata_changeset_revisions( self, hg.repository( ui.ui(), self.repo_path( app ) ), downloadable=True )
def is_new( self, app ):
repo = hg.repository( ui.ui(), self.repo_path( app ) )
tip_ctx = repo.changectx( repo.changelog.tip() )
return tip_ctx.rev() < 0
def ordered_installable_revisions( self, app ):
return suc.get_ordered_metadata_changeset_revisions( self, hg.repository( ui.ui(), self.repo_path( app ) ), downloadable=True )
def repo_path( self, app ):
return app.hgweb_config_manager.get_entry( os.path.join( "repos", self.user.username, self.name ) )
@@ -201,7 +201,7 @@ Category.table = Table( "category", metadata,
Column( "create_time", DateTime, default=now ),
Column( "update_time", DateTime, default=now, onupdate=now ),
Column( "name", TrimmedString( 255 ), index=True, unique=True ),
Column( "description" , TEXT ),
Column( "description", TEXT ),
Column( "deleted", Boolean, index=True, default=False ) )
Tag.table = Table( "tag", metadata,
+1 -1
View File
@@ -341,7 +341,7 @@ def remove_protocol_from_tool_shed_url( tool_shed_url ):
return util.remove_protocol_from_url( tool_shed_url )
def tool_shed_get( app, base_url, pathspec=[], params={} ):
def tool_shed_get( app, base_url, pathspec=None, params=None ):
"""Make contact with the tool shed via the uri provided."""
registry = app.tool_shed_registry
# urllib2 auto-detects system proxies, when passed a Proxyhandler.
+5
View File
@@ -71,6 +71,11 @@ def get_latest_repository_metadata( app, decoded_repository_id, downloadable=Fal
changeset_revision )
def get_metadata_by_id( app, metadata_id ):
sa_session = app.model.context.current
return sa_session.query( app.model.RepositoryMetadata ).filter( app.model.RepositoryMetadata.table.c.id == metadata_id ).one()
def get_previous_metadata_changeset_revision( repository, repo, before_changeset_revision, downloadable=True ):
"""
Return the changeset_revision in the repository changelog that has associated metadata prior to
+37
View File
@@ -408,6 +408,43 @@ def handle_role_associations( app, role, repository, **kwd ):
return associations_dict
def check_for_updates( app, model, repository_id=None ):
message = ''
status = 'ok'
if repository_id is None:
success_count = 0
repository_names_not_updated = []
updated_count = 0
for repository in model.context.query( model.ToolShedRepository ) \
.filter( model.ToolShedRepository.table.c.deleted == false() ):
ok, updated = \
check_or_update_tool_shed_status_for_installed_repository( app, repository )
if ok:
success_count += 1
else:
repository_names_not_updated.append( '<b>%s</b>' % escape( str( repository.name ) ) )
if updated:
updated_count += 1
message = "Checked the status in the tool shed for %d repositories. " % success_count
message += "Updated the tool shed status for %d repositories. " % updated_count
if repository_names_not_updated:
message += "Unable to retrieve status from the tool shed for the following repositories:\n"
message += ", ".join( repository_names_not_updated )
else:
repository = suc.get_tool_shed_repository_by_id( app, repository_id )
ok, updated = \
check_or_update_tool_shed_status_for_installed_repository( app, repository )
if ok:
if updated:
message = "The tool shed status for repository <b>%s</b> has been updated." % escape( str( repository.name ) )
else:
message = "The status has not changed in the tool shed for repository <b>%s</b>." % escape( str( repository.name ) )
else:
message = "Unable to retrieve status from the tool shed for repository <b>%s</b>." % escape( str( repository.name ) )
status = 'error'
return message, status
def validate_repository_name( app, name, user ):
"""
Validate whether the given name qualifies as a new TS repo name.
+34 -1
View File
@@ -341,7 +341,9 @@ def get_ids_of_tool_shed_repositories_being_installed( app, as_string=False ):
return installing_repository_ids
def get_latest_downloadable_changeset_revision( app, repository, repo ):
def get_latest_downloadable_changeset_revision( app, repository, repo=None ):
if repo is None:
repo = hg_util.get_repo_for_repository( app, repository=repository, repo_path=None, create=False )
repository_tip = repository.tip( app )
repository_metadata = get_repository_metadata_by_changeset_revision( app, app.security.encode_id( repository.id ), repository_tip )
if repository_metadata and repository_metadata.downloadable:
@@ -365,6 +367,21 @@ def get_tool_dependency_definition_metadata_from_tool_shed( app, tool_shed_url,
return metadata
def get_metadata_changeset_revisions( repository, repo ):
"""
Return an unordered list of changeset_revisions and changeset numbers that are defined as installable.
"""
changeset_tups = []
for repository_metadata in repository.downloadable_revisions:
ctx = hg_util.get_changectx_for_changeset( repo, repository_metadata.changeset_revision )
if ctx:
rev = ctx.rev()
else:
rev = -1
changeset_tups.append( ( rev, repository_metadata.changeset_revision ) )
return sorted( changeset_tups )
def get_next_downloadable_changeset_revision( repository, repo, after_changeset_revision ):
"""
Return the installable changeset_revision in the repository changelog after the changeset to which
@@ -477,6 +494,22 @@ def get_repo_info_tuple_contents( repo_info_tuple ):
return description, repository_clone_url, changeset_revision, ctx_rev, repository_owner, repository_dependencies, tool_dependencies
def get_repositories_by_category( app, category_id ):
sa_session = app.model.context.current
resultset = sa_session.query( app.model.Category ).get( category_id )
repositories = []
default_value_mapper = { 'id': app.security.encode_id, 'user_id': app.security.encode_id }
for row in resultset.repositories:
repository_dict = row.repository.to_dict( value_mapper=default_value_mapper )
repository_dict[ 'metadata' ] = {}
for changeset, changehash in row.repository.installable_revisions( app ):
encoded_id = app.security.encode_id( row.repository.id )
metadata = get_repository_metadata_by_changeset_revision( app, encoded_id, changehash )
repository_dict[ 'metadata' ][ '%s:%s' % ( changeset, changehash ) ] = metadata.to_dict( value_mapper=default_value_mapper )
repositories.append( repository_dict )
return repositories
def get_repository_and_repository_dependencies_from_repo_info_dict( app, repo_info_dict ):
"""Return a tool_shed_repository or repository record defined by the information in the received repo_info_dict."""
repository_name = repo_info_dict.keys()[ 0 ]
+1 -1
View File
@@ -34,7 +34,7 @@ def build_tool_panel_section_select_field( app ):
options = []
for section_id, section_name in app.toolbox.get_sections():
options.append( ( section_name, section_id ) )
select_field = SelectField( name='tool_panel_section_id', display='radio' )
select_field = SelectField( name='tool_panel_section_id', field_id='tool_panel_section_select' )
for option_tup in options:
select_field.add_option( option_tup[ 0 ], option_tup[ 1 ] )
return select_field
@@ -108,7 +108,7 @@ class TestInstallingCircularDependencies( ShedTwillTestCase ):
self.display_installed_repository_manage_page( installed_filtering_repository )
self.deactivate_repository( installed_filtering_repository )
self.test_db_util.ga_refresh( installed_filtering_repository )
self.check_galaxy_repository_tool_panel_section( installed_filtering_repository, '' )
self.check_galaxy_repository_tool_panel_section( installed_filtering_repository, 'Get Data' )
strings_displayed = [ 'Missing repository', 'filtering', 'freebayes_0040', 'user1', "Galaxy's freebayes tool for test 0040" ]
self.display_installed_repository_manage_page( installed_freebayes_repository, strings_displayed=strings_displayed )
self.check_galaxy_repository_db_status( filtering_repository_name,
@@ -133,7 +133,7 @@ class TestInstallingCircularDependencies( ShedTwillTestCase ):
self.display_installed_repository_manage_page( installed_filtering_repository )
self.deactivate_repository( installed_freebayes_repository )
self.test_db_util.ga_refresh( installed_freebayes_repository )
self.check_galaxy_repository_tool_panel_section( installed_freebayes_repository, '' )
self.check_galaxy_repository_tool_panel_section( installed_freebayes_repository, 'Get Data' )
strings_displayed = [ 'Missing repository', 'freebayes', 'filtering_0040', 'user1', "Galaxy's filtering tool for test 0040" ]
self.display_installed_repository_manage_page( installed_filtering_repository, strings_displayed=strings_displayed )
self.check_galaxy_repository_db_status( 'freebayes_0040',
@@ -148,7 +148,7 @@ class TestInstallingCircularDependencies( ShedTwillTestCase ):
self.display_installed_repository_manage_page( installed_filtering_repository )
self.deactivate_repository( installed_filtering_repository )
self.test_db_util.ga_refresh( installed_filtering_repository )
self.check_galaxy_repository_tool_panel_section( installed_filtering_repository, '' )
self.check_galaxy_repository_tool_panel_section( installed_filtering_repository, 'Get Data' )
strings_displayed = [ 'Missing repository', 'filtering', 'freebayes_0040', 'user1', "Galaxy's freebayes tool for test 0040" ]
self.display_installed_repository_manage_page( installed_freebayes_repository, strings_displayed=strings_displayed )
self.check_galaxy_repository_db_status( filtering_repository_name,