diff --git a/lib/galaxy/model/__init__.py b/lib/galaxy/model/__init__.py
index eb32ab656ab..fd38e7214c7 100644
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -14,6 +14,7 @@ import galaxy.datatypes.registry
from galaxy.datatypes.metadata import MetadataCollection
from galaxy.security import RBACAgent, get_permitted_actions
from galaxy.util.hash_util import *
+from galaxy.web.form_builder import *
import logging
log = logging.getLogger( __name__ )
@@ -686,10 +687,23 @@ class Library( object ):
self.name = name or "Unnamed library"
self.description = description
self.root_folder = root_folder
- def get_info_association( self, restrict=False ):
+ def get_info_association( self, restrict=False, inherited=False ):
if self.info_association:
- return self.info_association[0]
- return None
+ return self.info_association[0], inherited
+ return None, inherited
+ def get_template_widgets( self, trans, get_contents=True ):
+ # See if we have any associated templates - the returned value for
+ # inherited is not applicable at the library level
+ info_association, inherited = self.get_info_association()
+ if info_association:
+ template = info_association.template
+ if get_contents:
+ # See if we have any field contents
+ info = info_association.info
+ if info:
+ return template.get_widgets( trans.user, contents=info.content )
+ return template.get_widgets( trans.user )
+ return []
class LibraryFolder( object ):
def __init__( self, name=None, description=None, item_count=0, order_id=None ):
@@ -708,19 +722,35 @@ class LibraryFolder( object ):
folder.parent_id = self.id
folder.order_id = self.item_count
self.item_count += 1
- def get_info_association( self, restrict=False ):
+ def get_info_association( self, restrict=False, inherited=False ):
# If restrict is True, we will return this folder's info_association, not inheriting.
# If restrict is False, we'll return the next available info_association in the
- # inheritable hierarchy
+ # inheritable hierarchy. True is also returned if the info_association was inherited,
+ # and False if not. This enables us to eliminate displaying the any contents of the inherited
+ # template.
if self.info_association:
- return self.info_association[0]
+ return self.info_association[0], inherited
if restrict:
- return None
+ return None, inherited
if self.parent:
- return self.parent.get_info_association()
+ return self.parent.get_info_association( inherited=True )
if self.library_root:
- return self.library_root[0].get_info_association()
- return None
+ return self.library_root[0].get_info_association( inherited=True )
+ return None, inherited
+ def get_template_widgets( self, trans, get_contents=True ):
+ # See if we have any associated templates
+ info_association, inherited = self.get_info_association()
+ if info_association:
+ template = info_association.template
+ # See if we have any field contents, but only if the info_association was
+ # not inherited ( we do not want to display the inherited contents ).
+ if not inherited and get_contents:
+ info = info_association.info
+ if info:
+ return template.get_widgets( trans.user, info.content )
+ else:
+ return template.get_widgets( trans.user )
+ return []
@property
def active_library_datasets( self ):
# This needs to be a list
@@ -839,15 +869,31 @@ class LibraryDatasetDatasetAssociation( DatasetInstance ):
return ldda
def clear_associated_files( self, metadata_safe = False, purge = False ):
return
- def get_info_association( self, restrict=False ):
+ def get_info_association( self, restrict=False, inherited=False ):
# If restrict is True, we will return this ldda's info_association whether it
# exists or not. If restrict is False, we'll return the next available info_association
- # in the inheritable hierarchy
+ # in the inheritable hierarchy. True is also returned if the info_association was inherited,
+ # and False if not. This enables us to eliminate displaying the any contents of the inherited
+ # template.
if self.info_association:
- return self.info_association[0]
+ return self.info_association[0], inherited
if restrict:
- return None
- return self.library_dataset.folder.get_info_association()
+ return None, inherited
+ return self.library_dataset.folder.get_info_association( inherited=True )
+ def get_template_widgets( self, trans, get_contents=True ):
+ # See if we have any associated templates
+ info_association, inherited = self.get_info_association()
+ if info_association:
+ template = info_association.template
+ # See if we have any field contents, but only if the info_association was
+ # not inherited ( we do not want to display the inherited contents ).
+ if not inherited and get_contents:
+ info = info_association.info
+ if info:
+ return template.get_widgets( trans.user, info.content )
+ else:
+ return template.get_widgets( trans.user )
+ return []
class LibraryInfoAssociation( object ):
def __init__( self, library, form_definition, info ):
@@ -1030,6 +1076,62 @@ class FormDefinition( object ):
if f['layout'] == str(layout_index):
fields_dict[i] = f
return fields_dict
+ def get_widgets( self, user, contents=[], **kwd ):
+ '''
+ Return the list of widgets that comprise a form definition,
+ including field contents if any.
+ '''
+ params = util.Params( kwd )
+ widgets = []
+ for index, field in enumerate( self.fields ):
+ field_name = 'field_%i' % index
+ # determine the value of the field
+ if field_name in kwd:
+ # the user had already filled out this field and the same form is re-rendered
+ # due to some reason like required fields have been left out.
+ if field[ 'type' ] == 'CheckboxField':
+ value = CheckboxField.is_checked( util.restore_text( params.get( field_name, False ) ) )
+ else:
+ value = util.restore_text( params.get( field_name, '' ) )
+ elif contents:
+ # this field has a saved value
+ value = str( contents[ index ] )
+ else:
+ # if none of the above, then leave the field empty
+ if field[ 'type' ] == 'CheckboxField':
+ # Since we do not have contents, set checkbox value to False
+ value = False
+ else:
+ # Set other field types to empty string
+ value = ''
+ # create the field widget
+ field_widget = eval( field[ 'type' ] )( field_name )
+ if field[ 'type' ] == 'TextField':
+ field_widget.set_size( 40 )
+ field_widget.value = value
+ elif field[ 'type' ] == 'TextArea':
+ field_widget.set_size( 3, 40 )
+ field_widget.value = value
+ elif field['type'] == 'AddressField':
+ field_widget.user = user
+ field_widget.value = value
+ field_widget.params = params
+ elif field[ 'type' ] == 'SelectField':
+ for option in field[ 'selectlist' ]:
+ if option == value:
+ field_widget.add_option( option, option, selected=True )
+ else:
+ field_widget.add_option( option, option )
+ elif field[ 'type' ] == 'CheckboxField':
+ field_widget.checked = value
+ if field[ 'required' ] == 'required':
+ req = 'Required'
+ else:
+ req = 'Optional'
+ widgets.append( dict( label=field[ 'label' ],
+ widget=field_widget,
+ helptext='%s (%s)' % ( field[ 'helptext' ], req ) ) )
+ return widgets
class FormDefinitionCurrent( object ):
def __init__(self, form_definition=None):
diff --git a/lib/galaxy/web/controllers/admin.py b/lib/galaxy/web/controllers/admin.py
index 1153ad010e7..8bce1a53ff7 100644
--- a/lib/galaxy/web/controllers/admin.py
+++ b/lib/galaxy/web/controllers/admin.py
@@ -3,7 +3,6 @@ from datetime import datetime, timedelta
from galaxy import util, datatypes
from galaxy.web.base.controller import *
from galaxy.model.orm import *
-from galaxy.web.controllers.forms import get_all_forms, get_form_widgets
from galaxy.web.framework.helpers import time_ago, iff, grids
import logging
log = logging.getLogger( __name__ )
@@ -242,7 +241,7 @@ class Admin( BaseController ):
# whose DatasetPermissions is associated with the Role
# [ ( LibraryDatasetDatasetAssociation [ action, action ] ) ]
library_dataset_actions = {}
- for dp in role.actions:
+ for dp in role.dataset_actions:
for ldda in trans.app.model.LibraryDatasetDatasetAssociation \
.filter( trans.app.model.LibraryDatasetDatasetAssociation.dataset_id==dp.dataset_id ) \
.all():
diff --git a/lib/galaxy/web/controllers/dataset.py b/lib/galaxy/web/controllers/dataset.py
index fed4e83a28e..4189a258ebe 100644
--- a/lib/galaxy/web/controllers/dataset.py
+++ b/lib/galaxy/web/controllers/dataset.py
@@ -36,6 +36,9 @@ ${stdout}
job info:
${info}
-----------------------------------------------------------------------------
+job traceback:
+${traceback}
+-----------------------------------------------------------------------------
(This is an automated message).
"""
@@ -76,6 +79,7 @@ class DatasetInterface( BaseController ):
tool_id=job.tool_id,
stderr=job.stderr,
stdout=job.stdout,
+ traceback=job.traceback,
info=job.info ) )
frm = to_address
# Check email a bit
diff --git a/lib/galaxy/web/controllers/forms.py b/lib/galaxy/web/controllers/forms.py
index 84cac8a8a5f..24eb34146e0 100644
--- a/lib/galaxy/web/controllers/forms.py
+++ b/lib/galaxy/web/controllers/forms.py
@@ -500,10 +500,6 @@ def get_all_forms( trans, all_versions=False, filter=None, form_type='All' ):
Return all the latest forms from the form_definition_current table
if all_versions is set to True. Otherwise return all the versions
of all the forms from the form_definition table.
-
- TODO: when we add the concept of a form_definition_type ( e.g.,
- 'request_header', 'request_sample', 'library_template' ), filter
- the query if received filter is not None.
'''
if all_versions:
return trans.app.model.FormDefinition.query().all()
@@ -515,64 +511,3 @@ def get_all_forms( trans, all_versions=False, filter=None, form_type='All' ):
return [ fdc.latest_form for fdc in fdc_list ]
else:
return [ fdc.latest_form for fdc in fdc_list if fdc.latest_form.type == form_type ]
-
-
-
-def get_form_widgets( trans, form, contents=[], user=None, **kwd ):
- '''
- Return the list of widgets that comprise a form definition,
- including field contents if any.
- '''
- params = util.Params( kwd )
- if not user:
- user = trans.user
- widgets = []
- for index, field in enumerate( form.fields ):
- field_name = 'field_%i' % index
- # determine the value of the field
- if field_name in kwd:
- # the user had already filled out this field and the same form is re-rendered
- # due to some reason like required fields have been left out.
- if field[ 'type' ] == 'CheckboxField':
- value = CheckboxField.is_checked( util.restore_text( params.get( field_name, False ) ) )
- else:
- value = util.restore_text( params.get( field_name, '' ) )
- elif contents:
- # this field has a saved value
- value = str(contents[ index ])
- else:
- # if none of the above, then leave the field empty
- if field[ 'type' ] == 'CheckboxField':
- # Since we do not have contents, set checkbox value to False
- value = False
- else:
- # Set other field types to empty string
- value = ''
- # create the field widget
- field_widget = eval( field[ 'type' ] )( field_name )
- if field[ 'type' ] == 'TextField':
- field_widget.set_size( 40 )
- field_widget.value = value
- elif field[ 'type' ] == 'TextArea':
- field_widget.set_size( 3, 40 )
- field_widget.value = value
- elif field['type'] == 'AddressField':
- field_widget.user = user
- field_widget.value = value
- field_widget.params = params
- elif field[ 'type' ] == 'SelectField':
- for option in field[ 'selectlist' ]:
- if option == value:
- field_widget.add_option( option, option, selected=True )
- else:
- field_widget.add_option( option, option )
- elif field[ 'type' ] == 'CheckboxField':
- field_widget.checked = value
- if field[ 'required' ] == 'required':
- req = 'Required'
- else:
- req = 'Optional'
- widgets.append( dict( label=field[ 'label' ],
- widget=field_widget,
- helptext='%s (%s)' % ( field[ 'helptext' ], req ) ) )
- return widgets
diff --git a/lib/galaxy/web/controllers/library.py b/lib/galaxy/web/controllers/library.py
index dbc2b2eaf5b..f748e380c2f 100644
--- a/lib/galaxy/web/controllers/library.py
+++ b/lib/galaxy/web/controllers/library.py
@@ -3,7 +3,7 @@ from galaxy.model.orm import *
from galaxy.datatypes import sniff
from galaxy import util
from galaxy.util.odict import odict
-from galaxy.web.controllers.forms import get_all_forms, get_form_widgets
+from galaxy.web.controllers.forms import get_all_forms
from galaxy.util.streamball import StreamBall
import logging, tempfile, zipfile, tarfile, os, sys
@@ -149,16 +149,7 @@ class Library( BaseController ):
messagetype='error' ) )
if action == 'information':
# See if we have any associated templates
- if library.info_association:
- template = library.info_association[0].template
- # See if we have any field contents
- info = library.info_association[0].info
- if info:
- widgets = get_form_widgets( trans, template, info.content )
- else:
- widgets = get_form_widgets( trans, template )
- else:
- widgets = []
+ widgets = library.get_template_widgets( trans )
if params.get( 'rename_library_button', False ):
old_name = library.name
new_name = util.restore_text( params.name )
@@ -479,17 +470,7 @@ class Library( BaseController ):
msg=util.sanitize_text( msg ),
messagetype='error' ) )
# See if we have any associated templates
- info_association = ldda.get_info_association()
- if info_association:
- template = info_association.template
- # See if we have any field contents
- info = info_association.info
- if info:
- widgets = get_form_widgets( trans, template, info.content )
- else:
- widgets = get_form_widgets( trans, template )
- else:
- widgets = []
+ widgets = ldda.get_template_widgets( trans )
if action == 'permissions':
if params.get( 'update_roles_button', False ):
# The user clicked the Save button on the 'Associate With Roles' form
@@ -782,6 +763,8 @@ class Library( BaseController ):
msg=util.sanitize_text( msg ),
messagetype='error' ) )
if not id or replace_dataset:
+ # See if we have any inherited templates, but do not inherit contents.
+ widgets = folder.get_template_widgets( trans, get_contents=False )
upload_option = params.get( 'upload_option', 'upload_file' )
# No dataset(s) specified, so display the upload form. Send list of data formats to the form
# so the "extension" select list can be populated dynamically
@@ -806,6 +789,7 @@ class Library( BaseController ):
last_used_build=last_used_build,
roles=roles,
history=history,
+ widgets=widgets,
msg=msg,
messagetype=messagetype,
replace_dataset=replace_dataset )
@@ -968,17 +952,7 @@ class Library( BaseController ):
messagetype=messagetype )
elif action == 'information':
# See if we have any associated templates
- info_association = folder.get_info_association()
- if info_association:
- template = info_association.template
- # See if we have any field contents
- info = info_association.info
- if info:
- widgets = get_form_widgets( trans, template, info.content )
- else:
- widgets = get_form_widgets( trans, template )
- else:
- widgets = []
+ widgets = folder.get_template_widgets( trans )
if params.get( 'rename_folder_button', False ):
if trans.app.security_agent.can_modify_library_item( user, roles, folder ):
old_name = folder.name
diff --git a/lib/galaxy/web/controllers/library_admin.py b/lib/galaxy/web/controllers/library_admin.py
index db725f4f3a2..31dd842fb39 100644
--- a/lib/galaxy/web/controllers/library_admin.py
+++ b/lib/galaxy/web/controllers/library_admin.py
@@ -2,7 +2,7 @@ import sys
from galaxy import util
from galaxy.web.base.controller import *
from galaxy.model.orm import *
-from galaxy.web.controllers.forms import get_all_forms, get_form_widgets
+from galaxy.web.controllers.forms import get_all_forms
# Older py compatibility
try:
set()
@@ -96,17 +96,7 @@ class LibraryAdmin( BaseController ):
return trans.fill_template( '/admin/library/new_library.mako', msg=msg, messagetype=messagetype )
elif action == 'information':
# See if we have any associated templates
- info_association = library.get_info_association()
- if info_association:
- template = info_association.template
- # See if we have any field contents
- info = info_association.info
- if info:
- widgets = get_form_widgets( trans, template, info.content )
- else:
- widgets = get_form_widgets( trans, template )
- else:
- widgets = []
+ widgets = library.get_template_widgets( trans )
if params.get( 'rename_library_button', False ):
old_name = library.name
new_name = util.restore_text( params.name )
@@ -293,17 +283,7 @@ class LibraryAdmin( BaseController ):
messagetype=messagetype )
elif action == 'information':
# See if we have any associated templates
- info_association = folder.get_info_association()
- if info_association:
- template = info_association.template
- # See if we have any field contents
- info = info_association.info
- if info:
- widgets = get_form_widgets( trans, template, info.content )
- else:
- widgets = get_form_widgets( trans, template )
- else:
- widgets = []
+ widgets = folder.get_template_widgets( trans )
if params.get( 'rename_folder_button', False ):
old_name = folder.name
new_name = util.restore_text( params.name )
@@ -478,13 +458,8 @@ class LibraryAdmin( BaseController ):
msg=util.sanitize_text( msg ),
messagetype=messagetype ) )
elif not id or replace_dataset:
- # See if we have any associated templates
- info_association = folder.get_info_association()
- if info_association:
- template = info_association.template
- widgets = get_form_widgets( trans, template )
- else:
- widgets = []
+ # See if we have any inherited templates, but do not inherit contents.
+ widgets = folder.get_template_widgets( trans, get_contents=False )
upload_option = params.get( 'upload_option', 'upload_file' )
# No dataset(s) specified, so display the upload form. Send list of data formats to the form
# so the "extension" select list can be populated dynamically
@@ -536,17 +511,7 @@ class LibraryAdmin( BaseController ):
msg=util.sanitize_text( msg ),
messagetype='error' ) )
# See if we have any associated templates
- info_association = ldda.get_info_association()
- if info_association:
- template = info_association.template
- # See if we have any field contents
- info = info_association.info
- if info:
- widgets = get_form_widgets( trans, template, info.content )
- else:
- widgets = get_form_widgets( trans, template )
- else:
- widgets = []
+ widgets = ldda.get_template_widgets( trans )
if action == 'permissions':
if params.get( 'update_roles_button', False ):
permissions = {}
@@ -1019,8 +984,9 @@ class LibraryAdmin( BaseController ):
# Since information templates are inherited, the template fields can be displayed on the information
# page for a folder or library dataset when it has no info_association object. If the user has added
# field contents on an inherited template via a parent's info_association, we'll need to create a new
- # form_values and info_association for the current object.
- info_association = library_item.get_info_association( restrict=True )
+ # form_values and info_association for the current object. The value for the returned inherited variable
+ # is not applicable at this level.
+ info_association, inherited = library_item.get_info_association( restrict=True )
if info_association:
template = info_association.template
info = info_association.info
@@ -1031,7 +997,7 @@ class LibraryAdmin( BaseController ):
form_values.flush()
else:
# Inherit the next available info_association so we can get the template
- info_association = library_item.get_info_association()
+ info_association, inherited = library_item.get_info_association()
template = info_association.template
# Create a new FormValues object
form_values = trans.app.model.FormValues( template, field_contents )
diff --git a/lib/galaxy/web/controllers/library_dataset.py b/lib/galaxy/web/controllers/library_dataset.py
index 281d11a6311..60e1caa157c 100644
--- a/lib/galaxy/web/controllers/library_dataset.py
+++ b/lib/galaxy/web/controllers/library_dataset.py
@@ -205,7 +205,7 @@ class UploadLibraryDataset( BaseController ):
template_field_contents = []
template = None
folder = trans.app.model.LibraryFolder.get( folder_id )
- info_association = folder.get_info_association()
+ info_association, inherited = folder.get_info_association()
if info_association:
template = info_association.template
for field_index in range( len( template.fields ) ):
diff --git a/lib/galaxy/web/controllers/requests.py b/lib/galaxy/web/controllers/requests.py
index bb4c9ff0510..3102d6e9dd7 100644
--- a/lib/galaxy/web/controllers/requests.py
+++ b/lib/galaxy/web/controllers/requests.py
@@ -9,7 +9,6 @@ import logging, tempfile, zipfile, tarfile, os, sys
from galaxy.web.form_builder import *
from datetime import datetime, timedelta
from cgi import escape, FieldStorage
-from galaxy.web.controllers.forms import get_form_widgets
log = logging.getLogger( __name__ )
@@ -480,7 +479,7 @@ class Requests( BaseController ):
libraries[ library ] = hidden_folder_ids
libui = self.__library_ui(libraries, **kwd)
widgets = widgets + libui
- widgets = widgets + get_form_widgets(trans, request_type.request_form, contents=[], **kwd)
+ widgets = widgets + request_type.request_form.get_widgets( user, **kwd )
return trans.fill_template( '/requests/new_request.mako',
select_request_type=select_request_type,
request_type=request_type,
@@ -722,7 +721,7 @@ class Requests( BaseController ):
libraries[ library ] = hidden_folder_ids
libui = self.__library_ui(libraries, request, **kwd)
widgets = widgets + libui
- widgets = widgets + get_form_widgets(trans, request.type.request_form, request.values.content, **kwd)
+ widgets = widgets + request.type.request_form.get_widgets( user, request.values.content, **kwd )
return trans.fill_template( '/requests/edit_request.mako',
select_request_type=select_request_type,
request_type=request.type,
diff --git a/lib/galaxy/web/controllers/requests_admin.py b/lib/galaxy/web/controllers/requests_admin.py
index 37285bbf338..fccbeacea0d 100644
--- a/lib/galaxy/web/controllers/requests_admin.py
+++ b/lib/galaxy/web/controllers/requests_admin.py
@@ -7,7 +7,6 @@ from galaxy.util.streamball import StreamBall
import logging, tempfile, zipfile, tarfile, os, sys
from galaxy.web.form_builder import *
from datetime import datetime, timedelta
-from galaxy.web.controllers.forms import get_form_widgets
from galaxy.web.controllers.forms import get_all_forms
log = logging.getLogger( __name__ )
@@ -178,7 +177,7 @@ class Requests( BaseController ):
# libraries selectbox
libui = self.__library_ui(trans, request.user, request, **kwd)
widgets = widgets + libui
- widgets = widgets + get_form_widgets(trans, request.type.request_form, request.values.content, request.user, **kwd)
+ widgets = widgets + request.type.request_form.get_widgets( request.user, request.values.content, **kwd )
return trans.fill_template( '/admin/requests/edit_request.mako',
select_request_type=select_request_type,
request_type=request.type,
@@ -687,7 +686,7 @@ class Requests( BaseController ):
# libraries selectbox
libui = self.__library_ui(trans, user, **kwd)
widgets = widgets + libui
- widgets = widgets + get_form_widgets(trans, request_type.request_form, contents=[], user=user, **kwd)
+ widgets = widgets + request_type.request_form.get_widgets( user, **kwd )
return trans.fill_template( '/admin/requests/new_request.mako',
select_request_type=select_request_type,
request_type=request_type,
diff --git a/templates/admin/library/browse_library.mako b/templates/admin/library/browse_library.mako
index 441e5ab58cb..2aaee5e06c3 100644
--- a/templates/admin/library/browse_library.mako
+++ b/templates/admin/library/browse_library.mako
@@ -85,48 +85,48 @@
else:
current_version = False
%>
-