Fixes for uploading a tool to the community space, and keep None from being displayed if there is no user_description.

This commit is contained in:
Greg Von Kuster
2010-05-12 09:18:05 -04:00
parent 01b583e0fe
commit cea2ff14ef
5 changed files with 132 additions and 107 deletions
@@ -28,8 +28,11 @@ class CommonController( BaseController ):
else:
# There must not be any categories associated with the tool
trans.app.security_agent.set_entity_category_associations( tools=[ tool ], categories=[] )
if params.get( 'description', False ):
tool.user_description = util.restore_text( params.get( 'description', '' ) )
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
@@ -236,7 +239,10 @@ def set_categories( trans, obj, category_ids, delete_existing_assocs=True ):
def get_tool( trans, id ):
return trans.sa_session.query( trans.model.Tool ).get( trans.app.security.decode_id( id ) )
def get_tools( trans ):
return trans.sa_session.query( trans.model.Tool ).order_by( trans.model.Tool.name )
# Return only the latest version of each tool
return trans.sa_session.query( trans.model.Tool ) \
.filter( trans.model.Tool.newer_version_id == None ) \
.order_by( trans.model.Tool.name )
def get_approved_tools( trans, category=None ):
# TODO: write this as a query using eagerload - will be much faster.
ids = []
@@ -26,112 +26,119 @@ class UploadController( BaseController ):
replace_version = None
uploaded_file = None
categories = get_categories( trans )
if not get_categories( trans ):
if not categories:
return trans.response.send_redirect( web.url_for( controller='tool',
action='browse_tools',
cntrller='tool',
message='No categories have been configured in this instance of the Galaxy Community. An administrator needs to create some via the Administrator control panel before anything can be uploaded',
status='error' ) )
elif params.file_data == '' and params.url.strip() == '':
message = 'No files were entered on the upload form.'
status = 'error'
elif params.file_data == '':
try:
uploaded_file = urllib2.urlopen( params.url.strip() )
except ( ValueError, urllib2.HTTPError ), e:
message = 'An error occurred trying to retrieve the URL entered on the upload form: %s' % e
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'
except urllib2.URLError, e:
message = 'An error occurred trying to retrieve the URL entered on the upload form: %s' % e.reason
status = 'error'
elif params.file_data not in ( '', None ):
uploaded_file = params.file_data.file
if params.upload_button and uploaded_file:
datatype = trans.app.datatypes_registry.get_datatype_by_extension( params.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:
elif file_data == '':
try:
# Initialize the tool object
meta = datatype.verify( uploaded_file )
meta.user = trans.user
meta.guid = trans.app.security.get_new_guid()
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 replace_id is None:
raise UploadError( 'A tool with the same ID already exists. If you are trying to update this tool to a new version, please use the upload form on the "Edit Tool" page. Otherwise, please choose a new ID.' )
elif existing:
replace_version = trans.sa_session.query( trans.app.model.Tool ).get( trans.security.decode_id( replace_id ) )
if replace_version.newer_version:
# If the user has picked an old version, switch to the newest version
replace_version = get_versions( trans, replace_version )[0]
if replace_version.tool_id != meta.id:
raise UploadError( 'The new tool id (%s) does not match the old tool id (%s). Check the tool XML file' % ( meta.id, replace_version.tool_id ) )
for old_version in get_versions( trans, replace_version ):
if old_version.version == meta.version:
raise UploadError( 'The new version (%s) matches an old version. Check your version in the tool XML file' % meta.version )
if old_version.is_new():
raise UploadError( 'There is an existing version of this tool which has not yet been submitted for approval, so either <a href="%s">submit or delete it</a> before uploading a new version.' % 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 tool which is waiting for administrative approval, so contact an administrator for help.' )
# 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 )
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
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 )
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' % e
status = 'error'
uploaded_file.close()
elif replace_id is not None:
replace_version = trans.sa_session.query( trans.app.model.Tool ).get( int( trans.app.security.decode_id( replace_id ) ) )
old_version = None
for old_version in get_versions( trans, 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:
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:
# TODO: tool should no longer be the default when we upload histories and workflows
upload_type = params.get( 'upload_type', 'tool' )
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()
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 replace_id is None:
raise UploadError( 'A tool with the same ID already exists. If you are trying to update this tool to a new version, please use the upload form on the "Edit Tool" page. Otherwise, please choose a new ID.' )
elif existing:
replace_version = trans.sa_session.query( trans.app.model.Tool ).get( trans.security.decode_id( replace_id ) )
if replace_version.newer_version:
# If the user has picked an old version, switch to the newest version
replace_version = get_versions( trans, replace_version )[0]
if replace_version.tool_id != meta.id:
raise UploadError( 'The new tool id (%s) does not match the old tool id (%s). Check the tool XML file' % ( meta.id, replace_version.tool_id ) )
for old_version in get_versions( trans, replace_version ):
if old_version.version == meta.version:
raise UploadError( 'The new version (%s) matches an old version. Check your version in the tool XML file' % meta.version )
if old_version.is_new():
raise UploadError( 'There is an existing version of this tool which has not yet been submitted for approval, so either <a href="%s">submit or delete it</a> before uploading a new version.' % 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 tool which is waiting for administrative approval, so contact an administrator for help.' )
# 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 )
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:
replace_version = trans.sa_session.query( trans.app.model.Tool ).get( int( trans.app.security.decode_id( replace_id ) ) )
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' ) )
for old_version in get_versions( trans, 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_upload_type = params.get( 'type', 'tool' )
selected_categories = [ trans.security.decode_id( id ) for id in category_ids ]
return trans.fill_template( '/webapps/community/upload/upload.mako',
@@ -120,11 +120,13 @@ class Tool( object ):
rval.version = root.attrib['version']
except KeyError, e:
raise DatatypeVerificationError( 'Tool XML file does not conform to the specification. Missing required &lt;tool&gt; tag attribute: %s' % e )
rval.description = None
rval.description = ''
desc_tag = root.find( 'description' )
if desc_tag is not None:
rval.description = desc_tag.text.strip()
rval.message = 'Tool: %s %s, Version: %s, ID: %s' % ( rval.name, rval.description or '', rval.version, rval.id )
if desc_tag:
description = desc_tag.text
if description:
rval.description = description.strip()
rval.message = 'Tool: %s %s, Version: %s, ID: %s' % ( str( rval.name ), str( rval.description ), str( rval.version ), str( rval.id ) )
return rval
else:
raise DatatypeVerificationError( 'Unable to find a properly formatted tool XML file' )
@@ -82,7 +82,11 @@ $().ready(function() {
</div>
<div class="form-row">
<label>Description:</label>
<div class="form-row-input"><textarea name="description" rows="5" cols="35">${tool.user_description}</textarea></div>
%if tool.user_description:
<div class="form-row-input"><textarea name="user_description" rows="5" cols="35">${tool.user_description}</textarea></div>
%else:
<div class="form-row-input"><textarea name="user_description" rows="5" cols="35"></textarea></div>
%endif
<div style="clear: both"></div>
</div>
<div class="form-row">
@@ -4,8 +4,12 @@
from galaxy.web.framework.helpers import time_ago
from urllib import quote_plus
menu_label = 'Edit information'
if cntrller in [ 'tool' ]:
can_edit = trans.app.security_agent.can_edit_item( trans.user, tool )
if can_edit:
menu_label = 'Edit information or submit for approval'
can_upload_new_version = trans.app.security_agent.can_upload_new_version( trans.user, tool, versions )
visible_versions = []
@@ -89,7 +93,7 @@
<a id="tool-${tool.id}-popup" class="popup-arrow" style="display: none;">&#9660;</a>
<div popupmenu="tool-${tool.id}-popup">
%if cntrller=='admin' or can_edit:
<a class="action-button" href="${h.url_for( controller='common', action='edit_tool', id=trans.app.security.encode_id( tool.id ), cntrller=cntrller )}">Edit information</a>
<a class="action-button" href="${h.url_for( controller='common', action='edit_tool', id=trans.app.security.encode_id( tool.id ), cntrller=cntrller )}">${menu_label}</a>
%endif
<a class="action-button" href="${h.url_for( controller='tool', action='download_tool', id=trans.app.security.encode_id( tool.id ) )}">Download tool</a>
%if cntrller=='admin' or trans.user==tool.user:
@@ -114,7 +118,9 @@
</div>
<div class="form-row">
<label>Description:</label>
${tool.user_description}
%if tool.user_description:
${tool.user_description}
%endif
<div style="clear: both"></div>
</div>
<div class="form-row">