From 94f34899522d201f5ad4ad98ab38692265e87dd3 Mon Sep 17 00:00:00 2001 From: Greg Von Kuster Date: Thu, 26 Aug 2010 10:55:47 -0400 Subject: [PATCH] Add support for all Galaxy form widget types to data library templates ( library templates now support SelectField, AddressField, CheckboxField, WorkflowField in addition to previously supported TextArea and TextField ). Create a new UsesFormDefinitionWidgets base controller class for use with all inheriting controllers that use Galaxy forms. Clean up some of the existing code by re-using mehtods in this new controller. Fix bugs related to new user address creation and editing existing user addresses: (1) form contents are now actually checked and if required, error messages are displayed (2) since there is only 1 "address" row in the UserAddress table, eliminate the address1 / address2 form field combination that was appened together for storage in the table ( ther eis now only 1 address line on all forms ). Fix functional tests to reflect above changes. --- lib/galaxy/web/base/controller.py | 53 +++- lib/galaxy/web/controllers/library_common.py | 66 ++-- lib/galaxy/web/controllers/requests_common.py | 14 +- lib/galaxy/web/controllers/user.py | 292 +++++++++--------- lib/galaxy/web/form_builder.py | 6 +- templates/library/common/common.mako | 100 ++++-- templates/library/common/folder_info.mako | 32 +- templates/library/common/ldda_edit_info.mako | 28 +- templates/library/common/ldda_info.mako | 32 +- .../library/common/library_dataset_info.mako | 32 +- templates/library/common/library_info.mako | 32 +- templates/library/common/new_folder.mako | 1 - templates/mobile/manage_library.mako | 6 +- templates/user/edit_address.mako | 89 +++++- templates/user/new_address.mako | 88 +++++- test/base/test_db_util.py | 7 + test/base/twilltestcase.py | 12 +- test/functional/test_forms_and_requests.py | 49 ++- 18 files changed, 644 insertions(+), 295 deletions(-) diff --git a/lib/galaxy/web/base/controller.py b/lib/galaxy/web/base/controller.py index cc1ab1cce57..7a522afbc89 100644 --- a/lib/galaxy/web/base/controller.py +++ b/lib/galaxy/web/base/controller.py @@ -8,6 +8,7 @@ from galaxy.web import error, form, url_for from galaxy.model.orm import * from galaxy.workflow.modules import * from galaxy.web.framework import simplejson +from galaxy.web.form_builder import AddressField, CheckboxField, SelectField, TextArea, TextField, WorkflowField from Cheetah.Template import Template @@ -290,7 +291,57 @@ class UsesHistory( SharableItemSecurity ): if not show_deleted: query = query.filter( trans.model.HistoryDatasetAssociation.deleted == False ) return query.all() - + +class UsesFormDefinitionWidgets: + """Mixin for controllers that use Galaxy form objects.""" + def widget_fields_have_contents( self, widgets ): + # Return True if any of the fields in widgets contain contents, widgets is a list of dictionaries that looks something like: + # [{'widget': , 'helptext': 'Field 0 help (Optional)', 'label': 'Field 0'}] + for i, field in enumerate( widgets ): + if ( isinstance( field[ 'widget' ], TextArea ) or isinstance( field[ 'widget' ], TextField ) ) and field[ 'widget' ].value: + return True + if isinstance( field[ 'widget' ], SelectField ) and field[ 'widget' ].options: + for option_label, option_value, selected in field['widget'].options: + if selected: + return True + if isinstance( field[ 'widget' ], CheckboxField ) and field[ 'widget' ].checked: + return True + if isinstance( field[ 'widget' ], WorkflowField ) and field[ 'widget' ].value not in [ 'none', 'None', None ]: + return True + if isinstance( field[ 'widget' ], AddressField ) and field[ 'widget' ].value not in [ 'none', 'None', None ]: + return True + return False + def clean_field_contents( self, widgets, **kwd ): + params = util.Params( kwd ) + field_contents = [] + for index in range( len( widgets ) ): + widget = widgets[ index ][ 'widget' ] + field_value = params.get( 'field_%i' % ( index ), '' ) + if isinstance( widget, CheckboxField ): + # CheckboxField values are lists if the checkbox is checked + field_value = str( widget.is_checked( field_value ) ).lower() + elif isinstance( widget, AddressField ): + # If the address was new, is has already been saved and widget.value is the new address.id + field_value = widget.value + field_contents.append( util.restore_text( field_value ) ) + return field_contents + def save_widget_field( self, trans, field_obj, index, **kwd ): + # Save a form_builder field object + # TODO: Add support for other field types ( e.g., WorkflowField ) + params = util.Params( kwd ) + if isinstance( field_obj, trans.model.UserAddress ): + field_obj.desc = util.restore_text( params.get( 'field_%i_short_desc' % index, '' ) ) + field_obj.name = util.restore_text( params.get( 'field_%i_name' % index, '' ) ) + field_obj.institution = util.restore_text( params.get( 'field_%i_institution' % index, '' ) ) + field_obj.address = util.restore_text( params.get( 'field_%i_address' % index, '' ) ) + field_obj.city = util.restore_text( params.get( 'field_%i_city' % index, '' ) ) + field_obj.state = util.restore_text( params.get( 'field_%i_state' % index, '' ) ) + field_obj.postal_code = util.restore_text( params.get( 'field_%i_postal_code' % index, '' ) ) + field_obj.country = util.restore_text( params.get( 'field_%i_country' % index, '' ) ) + field_obj.phone = util.restore_text( params.get( 'field_%i_phone' % index, '' ) ) + trans.sa_session.add( field_obj ) + trans.sa_session.flush() + class Sharable: """ Mixin for a controller that manages an item that can be shared. """ # Implemented methods. diff --git a/lib/galaxy/web/controllers/library_common.py b/lib/galaxy/web/controllers/library_common.py index da32c83b22d..e1d91f22955 100644 --- a/lib/galaxy/web/controllers/library_common.py +++ b/lib/galaxy/web/controllers/library_common.py @@ -6,7 +6,6 @@ from galaxy.security import RBACAgent from galaxy.util.json import to_json_string from galaxy.tools.actions import upload_common from galaxy.web.controllers.forms import get_all_forms -from galaxy.web.form_builder import SelectField, CheckboxField from galaxy.model.orm import * from galaxy.util.streamball import StreamBall import logging, tempfile, zipfile, tarfile, os, sys @@ -52,7 +51,7 @@ except OSError: pass os.rmdir( tmpd ) -class LibraryCommon( BaseController ): +class LibraryCommon( BaseController, UsesFormDefinitionWidgets ): @web.json def library_item_updates( self, trans, ids=None, states=None ): # Avoid caching @@ -160,9 +159,6 @@ class LibraryCommon( BaseController ): use_panels=use_panels, message=util.sanitize_text( message ), status='error' ) ) - # See if we have any associated templates - info_association, inherited = library.get_info_association() - widgets = library.get_template_widgets( trans ) if params.get( 'library_info_button', False ): # Deny modification if the user is not an admin and does not have the LIBRARY_MODIFY permission. if not ( is_admin or trans.app.security_agent.can_modify_library_item( current_user_roles, library ) ): @@ -201,11 +197,16 @@ class LibraryCommon( BaseController ): show_deleted=show_deleted, message=util.sanitize_text( message ), status='done' ) ) + # See if we have any associated templates + info_association, inherited = library.get_info_association() + widgets = library.get_template_widgets( trans ) + widget_fields_have_contents = self.widget_fields_have_contents( widgets ) return trans.fill_template( '/library/common/library_info.mako', cntrller=cntrller, use_panels=use_panels, library=library, widgets=widgets, + widget_fields_have_contents=widget_fields_have_contents, current_user_roles=current_user_roles, show_deleted=show_deleted, info_association=info_association, @@ -402,11 +403,6 @@ class LibraryCommon( BaseController ): show_deleted=show_deleted, message=util.sanitize_text( message ), status='error' ) ) - # See if we have any associated templates - widgets = [] - info_association, inherited = folder.get_info_association() - if info_association and ( not( inherited ) or info_association.inheritable ): - widgets = folder.get_template_widgets( trans ) if params.get( 'rename_folder_button', False ): # Deny modification if the user is not an admin and does not have the LIBRARY_MODIFY permission if not ( is_admin or trans.app.security_agent.can_modify_library_item( current_user_roles, folder ) ): @@ -439,12 +435,20 @@ class LibraryCommon( BaseController ): show_deleted=show_deleted, message=util.sanitize_text( message ), status='done' ) ) + # See if we have any associated templates + widgets = [] + widget_fields_have_contents = False + info_association, inherited = folder.get_info_association() + if info_association and ( not( inherited ) or info_association.inheritable ): + widgets = folder.get_template_widgets( trans ) + widget_fields_have_contents = self.widget_fields_have_contents( widgets ) return trans.fill_template( '/library/common/folder_info.mako', cntrller=cntrller, use_panels=use_panels, folder=folder, library_id=library_id, widgets=widgets, + widget_fields_have_contents=widget_fields_have_contents, current_user_roles=current_user_roles, show_deleted=show_deleted, info_association=info_association, @@ -677,9 +681,11 @@ class LibraryCommon( BaseController ): associated_lddas = [] # See if we have any associated templates widgets = [] + widget_fields_have_contents = False info_association, inherited = ldda.get_info_association() if info_association and ( not( inherited ) or info_association.inheritable ): widgets = ldda.get_template_widgets( trans ) + widget_fields_have_contents = self.widget_fields_have_contents( widgets ) return trans.fill_template( '/library/common/ldda_info.mako', cntrller=cntrller, use_panels=use_panels, @@ -689,6 +695,7 @@ class LibraryCommon( BaseController ): associated_lddas=associated_lddas, show_deleted=show_deleted, widgets=widgets, + widget_fields_have_contents=widget_fields_have_contents, current_user_roles=current_user_roles, info_association=info_association, inherited=inherited, @@ -1524,11 +1531,6 @@ class LibraryCommon( BaseController ): show_deleted=show_deleted, message=util.sanitize_text( message ), status='error' ) ) - # See if we have any associated templates - widgets = [] - info_association, inherited = library_dataset.library_dataset_dataset_association.get_info_association() - if info_association and ( not( inherited ) or info_association.inheritable ): - widgets = library_dataset.library_dataset_dataset_association.get_template_widgets( trans ) if params.get( 'edit_attributes_button', False ): # Deny access if the user is not an admin and does not have the LIBRARY_MODIFY permission. if not ( is_admin or trans.app.security_agent.can_modify_library_item( current_user_roles, library_dataset ) ): @@ -1553,6 +1555,13 @@ class LibraryCommon( BaseController ): trans.sa_session.flush() message = "Information updated for library dataset '%s'." % library_dataset.name status = 'done' + # See if we have any associated templates + widgets = [] + widget_fields_have_contents = False + info_association, inherited = library_dataset.library_dataset_dataset_association.get_info_association() + if info_association and ( not( inherited ) or info_association.inheritable ): + widgets = library_dataset.library_dataset_dataset_association.get_template_widgets( trans ) + widget_fields_have_contents = self.widget_fields_have_contents( widgets ) return trans.fill_template( '/library/common/library_dataset_info.mako', cntrller=cntrller, use_panels=use_panels, @@ -1562,6 +1571,7 @@ class LibraryCommon( BaseController ): info_association=info_association, inherited=inherited, widgets=widgets, + widget_fields_have_contents=widget_fields_have_contents, show_deleted=show_deleted, message=message, status=status ) @@ -2134,7 +2144,7 @@ class LibraryCommon( BaseController ): **kwd ) ) return trans.response.send_redirect( web.url_for( controller='forms', action='edit', **vars ) ) @web.expose - def edit_template_info( self, trans, cntrller, item_type, library_id, num_widgets, folder_id=None, ldda_id=None, **kwd ): + def edit_template_info( self, trans, cntrller, item_type, library_id, folder_id=None, ldda_id=None, **kwd ): # Edit the contents of the template fields without altering the template itself. params = util.Params( kwd ) show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) ) @@ -2156,10 +2166,28 @@ class LibraryCommon( BaseController ): show_deleted=show_deleted, message=util.sanitize_text( message ), status='error' ) ) + # We need the type of each template field widget + widgets = item.get_template_widgets( trans ) + # The list of widgets may include an AddressField which we need to save if it is new + for index, widget_dict in enumerate( widgets ): + widget = widget_dict[ 'widget' ] + if isinstance( widget, AddressField ): + value = util.restore_text( params.get( 'field_%i' % index, '' ) ) + if value == 'new': + if params.get( 'edit_info_button', False ): + # Save the new address + address = trans.app.model.UserAddress( user=trans.user ) + self.save_widget_field( trans, address, index, **kwd ) + widget.value = str( address.id ) + else: + # Form was submitted via refresh_on_change + widget.value = 'new' + elif value == unicode( 'none' ): + widget.value = '' + else: + widget.value = value # Save updated template field contents - field_contents = [] - for index in range( int( num_widgets ) ): - field_contents.append( util.restore_text( params.get( 'field_%i' % ( index ), '' ) ) ) + field_contents = self.clean_field_contents( widgets, **kwd ) if field_contents: # Since information templates are inherited, the template fields can be displayed on the information # page for a folder or ldda when it has no info_association object. If the user has added diff --git a/lib/galaxy/web/controllers/requests_common.py b/lib/galaxy/web/controllers/requests_common.py index 9c9d893b01c..ce66f008269 100644 --- a/lib/galaxy/web/controllers/requests_common.py +++ b/lib/galaxy/web/controllers/requests_common.py @@ -17,7 +17,7 @@ import csv log = logging.getLogger( __name__ ) -class RequestsCommon( BaseController ): +class RequestsCommon( BaseController, UsesFormDefinitionWidgets ): @web.json def sample_state_updates( self, trans, ids=None, states=None, cntrller=None ): @@ -207,17 +207,7 @@ class RequestsCommon( BaseController ): if value == 'new': # save this new address in the list of this user's addresses user_address = trans.app.model.UserAddress( user=user ) - user_address.desc = util.restore_text(params.get('field_%i_short_desc' % index, '')) - user_address.name = util.restore_text(params.get('field_%i_name' % index, '')) - user_address.institution = util.restore_text(params.get('field_%i_institution' % index, '')) - user_address.address = util.restore_text(params.get('field_%i_address1' % index, ''))+' '+util.restore_text(params.get('field_%i_address2' % index, '')) - user_address.city = util.restore_text(params.get('field_%i_city' % index, '')) - user_address.state = util.restore_text(params.get('field_%i_state' % index, '')) - user_address.postal_code = util.restore_text(params.get('field_%i_postal_code' % index, '')) - user_address.country = util.restore_text(params.get('field_%i_country' % index, '')) - user_address.phone = util.restore_text(params.get('field_%i_phone' % index, '')) - trans.sa_session.add( user_address ) - trans.sa_session.flush() + self.save_widget_field( trans, user_address, index, **kwd ) trans.sa_session.refresh( user ) values.append(int(user_address.id)) elif value == unicode('none'): diff --git a/lib/galaxy/web/controllers/user.py b/lib/galaxy/web/controllers/user.py index 72ec9553da8..8105d48f4df 100644 --- a/lib/galaxy/web/controllers/user.py +++ b/lib/galaxy/web/controllers/user.py @@ -26,7 +26,7 @@ require_login_creation_template = require_login_template % " If you don't alrea VALID_USERNAME_RE = re.compile( "^[a-z0-9\-]+$" ) -class User( BaseController ): +class User( BaseController, UsesFormDefinitionWidgets ): @web.expose def index( self, trans, webapp='galaxy', **kwd ): return trans.fill_template( '/user/index.mako', webapp=webapp ) @@ -263,17 +263,7 @@ class User( BaseController ): if value == 'new': # save this new address in the list of this user's addresses user_address = trans.app.model.UserAddress( user=user ) - user_address.desc = util.restore_text(params.get('field_%i_short_desc' % index, '')) - user_address.name = util.restore_text(params.get('field_%i_name' % index, '')) - user_address.institution = util.restore_text(params.get('field_%i_institution' % index, '')) - user_address.address = util.restore_text(params.get('field_%i_address1' % index, ''))+' '+util.restore_text(params.get('field_%i_address2' % index, '')) - user_address.city = util.restore_text(params.get('field_%i_city' % index, '')) - user_address.state = util.restore_text(params.get('field_%i_state' % index, '')) - user_address.postal_code = util.restore_text(params.get('field_%i_postal_code' % index, '')) - user_address.country = util.restore_text(params.get('field_%i_country' % index, '')) - user_address.phone = util.restore_text(params.get('field_%i_phone' % index, '')) - trans.sa_session.add( user_address ) - trans.sa_session.flush() + self.save_widget_field( trans, user_address, index, **kwd ) trans.sa_session.refresh( user ) values.append(int(user_address.id)) elif value == unicode('none'): @@ -673,8 +663,7 @@ class User( BaseController ): return trans.fill_template( 'user/permissions.mako' ) else: # User not logged in, history group must be only public - return trans.show_error_message( "You must be logged in to change your default permitted actions." ) - + return trans.show_error_message( "You must be logged in to change your default permitted actions." ) @web.expose @web.require_login( "to get most recently used tool" ) @web.json_pretty @@ -697,8 +686,7 @@ class User( BaseController ): "minsizehint" : tool.uihints.get( 'minwidth', -1 ), "description" : tool.description } - return tool_info - + return tool_info @web.expose def manage_addresses(self, trans, **kwd): if trans.user: @@ -726,123 +714,151 @@ class User( BaseController ): message = util.restore_text( params.get( 'message', '' ) ) status = params.get( 'status', 'done' ) admin_view = util.string_as_bool( params.get( 'admin_view', False ) ) - error = '' - user = trans.sa_session.query( trans.app.model.User ).get( int( params.get( 'user_id', None ) ) ) + user_id = params.get( 'user_id', False ) + if not user_id: + # User must be logged in to create a new address + return trans.show_error_message( "You must be logged in to create a new address." ) + user = trans.sa_session.query( trans.app.model.User ).get( int( user_id ) ) + short_desc = util.restore_text( params.get( 'short_desc', '' ) ) + name = util.restore_text( params.get( 'name', '' ) ) + institution = util.restore_text( params.get( 'institution', '' ) ) + address = util.restore_text( params.get( 'address', '' ) ) + city = util.restore_text( params.get( 'city', '' ) ) + state = util.restore_text( params.get( 'state', '' ) ) + postal_code = util.restore_text( params.get( 'postal_code', '' ) ) + country = util.restore_text( params.get( 'country', '' ) ) + phone = util.restore_text( params.get( 'phone', '' ) ) + ok = True if not trans.app.config.allow_user_creation and not trans.user_is_admin(): return trans.show_error_message( 'User registration is disabled. Please contact your Galaxy administrator for an account.' ) - if params.get( 'save_new_address_button', None ) == 'Save': - if not len( util.restore_text( params.get( 'short_desc', '' ) ) ): - error = 'Enter a short description for this address' - elif not len( util.restore_text( params.get( 'name', '' ) ) ): - error = 'Enter the full name' - elif not len( util.restore_text( params.get( 'institution', '' ) ) ): - error = 'Enter the institution associated with the user' - elif not len ( util.restore_text( params.get( 'address1', '' ) ) ): - error = 'Enter the address' - elif not len( util.restore_text( params.get( 'city', '' ) ) ): - error = 'Enter the city' - elif not len( util.restore_text( params.get( 'state', '' ) ) ): - error = 'Enter the state/province/region' - elif not len( util.restore_text( params.get( 'postal_code', '' ) ) ): - error = 'Enter the postal code' - elif not len( util.restore_text( params.get( 'country', '' ) ) ): - error = 'Enter the country' - else: - user_address = trans.app.model.UserAddress( user=user ) - user_address.desc = util.restore_text( params.get( 'short_desc', '' ) ) - user_address.name = util.restore_text( params.get( 'name', '' ) ) - user_address.institution = util.restore_text( params.get( 'institution', '' ) ) - user_address.address = util.restore_text( params.get( 'address1', '' ) )+' '+util.restore_text( params.get( 'address2', '' ) ) - user_address.city = util.restore_text( params.get( 'city', '' ) ) - user_address.state = util.restore_text( params.get( 'state', '' ) ) - user_address.postal_code = util.restore_text( params.get( 'postal_code', '' ) ) - user_address.country = util.restore_text( params.get( 'country', '' ) ) - user_address.phone = util.restore_text( params.get( 'phone', '' ) ) + if params.get( 'new_address_button', False ): + if not short_desc: + ok = False + message = 'Enter a short description for this address' + elif not name: + ok = False + message = 'Enter the name' + elif not institution: + ok = False + message = 'Enter the institution associated with the user' + elif not address: + ok = False + message = 'Enter the address' + elif not city: + ok = False + message = 'Enter the city' + elif not state: + ok = False + message = 'Enter the state/province/region' + elif not postal_code: + ok = False + message = 'Enter the postal code' + elif not country: + ok = False + message = 'Enter the country' + if ok: + user_address = trans.model.UserAddress( user=user, + desc=short_desc, + name=name, + institution=institution, + address=address, + city=city, + state=state, + postal_code=postal_code, + country=country, + phone=phone ) trans.sa_session.add( user_address ) trans.sa_session.flush() - message = 'Address %s has been added' % user_address.desc + message = 'Address (%s) has been added' % user_address.desc if admin_view: return trans.response.send_redirect( web.url_for( controller='user', action='show_info', admin_view=admin_view, user_id=user.id, message=message, - status='done') ) + status='done' ) ) return trans.response.send_redirect( web.url_for( controller='user', action='show_info', message=message, - status='done') ) - else: - # show the address form with the current values filled in - # create the widgets for each address field - widgets = [] - widgets.append(dict(label='Short description', - widget=TextField( 'short_desc', 40, '' ) ) ) - widgets.append(dict(label='Name', - widget=TextField( 'name', 40, '' ) ) ) - widgets.append(dict(label='Institution', - widget=TextField( 'institution', 40, '' ) ) ) - widgets.append(dict(label='Address Line 1', - widget=TextField( 'address1', 40, '' ) ) ) - widgets.append(dict(label='Address Line 2', - widget=TextField( 'address2', 40, '' ) ) ) - widgets.append(dict(label='City', - widget=TextField( 'city', 40, '' ) ) ) - widgets.append(dict(label='State', - widget=TextField( 'state', 40, '' ) ) ) - widgets.append(dict(label='Postal Code', - widget=TextField( 'postal_code', 40, '' ) ) ) - widgets.append(dict(label='Country', - widget=TextField( 'country', 40, '' ) ) ) - widgets.append(dict(label='Phone', - widget=TextField( 'phone', 40, '' ) ) ) - return trans.fill_template( 'user/new_address.mako', - user=user, - admin_view=admin_view, - widgets=widgets, - message=message, - status=status) + status='done' ) ) + # Display the address form with the current values filled in + return trans.fill_template( 'user/new_address.mako', + user=user, + admin_view=admin_view, + short_desc=short_desc, + name=name, + institution=institution, + address=address, + city=city, + state=state, + postal_code=postal_code, + country=country, + phone=phone, + message=message, + status=status ) @web.expose def edit_address( self, trans, **kwd ): params = util.Params( kwd ) - user_id = params.get( 'user_id', None ) - address_id = params.get( 'address_id', None ) message = util.restore_text( params.get( 'message', '' ) ) status = params.get( 'status', 'done' ) admin_view = util.string_as_bool( params.get( 'admin_view', False ) ) - error = '' + user_id = params.get( 'user_id', False ) + if not user_id: + # User must be logged in to create a new address + return trans.show_error_message( "You must be logged in to create a new address." ) user = trans.sa_session.query( trans.app.model.User ).get( int( user_id ) ) - user_address = trans.sa_session.query( trans.app.model.UserAddress ).get( int( address_id ) ) - if params.get( 'edit_address_button', None ) == 'Save changes': - if not len( util.restore_text( params.get( 'short_desc', '' ) ) ): - error = 'Enter a short description for this address' - elif not len( util.restore_text( params.get( 'name', '' ) ) ): - error = 'Enter the full name' - elif not len( util.restore_text( params.get( 'institution', '' ) ) ): - error = 'Enter the institution associated with the user' - elif not len ( util.restore_text( params.get( 'address1', '' ) ) ): - error = 'Enter the address' - elif not len( util.restore_text( params.get( 'city', '' ) ) ): - error = 'Enter the city' - elif not len( util.restore_text( params.get( 'state', '' ) ) ): - error = 'Enter the state/province/region' - elif not len( util.restore_text( params.get( 'postal_code', '' ) ) ): - error = 'Enter the postal code' - elif not len( util.restore_text( params.get( 'country', '' ) ) ): - error = 'Enter the country' - else: - user_address.desc = util.restore_text( params.get( 'short_desc', '' ) ) - user_address.name = util.restore_text( params.get( 'name', '' ) ) - user_address.institution = util.restore_text( params.get( 'institution', '' ) ) - user_address.address = util.restore_text( params.get( 'address1', '' ) )+' '+util.restore_text( params.get( 'address2', '' ) ) - user_address.city = util.restore_text( params.get( 'city', '' ) ) - user_address.state = util.restore_text( params.get( 'state', '' ) ) - user_address.postal_code = util.restore_text( params.get( 'postal_code', '' ) ) - user_address.country = util.restore_text( params.get( 'country', '' ) ) - user_address.phone = util.restore_text( params.get( 'phone', '' ) ) - trans.sa_session.add( user_address ) + address_id = params.get( 'address_id', None ) + if not address_id: + return trans.show_error_message( "No address_id received for editing." ) + address_obj = trans.sa_session.query( trans.app.model.UserAddress ).get( int( address_id ) ) + if params.get( 'edit_address_button', False ): + short_desc = util.restore_text( params.get( 'short_desc', '' ) ) + name = util.restore_text( params.get( 'name', '' ) ) + institution = util.restore_text( params.get( 'institution', '' ) ) + address = util.restore_text( params.get( 'address', '' ) ) + city = util.restore_text( params.get( 'city', '' ) ) + state = util.restore_text( params.get( 'state', '' ) ) + postal_code = util.restore_text( params.get( 'postal_code', '' ) ) + country = util.restore_text( params.get( 'country', '' ) ) + phone = util.restore_text( params.get( 'phone', '' ) ) + ok = True + if not short_desc: + ok = False + message = 'Enter a short description for this address' + elif not name: + ok = False + message = 'Enter the name' + elif not institution: + ok = False + message = 'Enter the institution associated with the user' + elif not address: + ok = False + message = 'Enter the address' + elif not city: + ok = False + message = 'Enter the city' + elif not state: + ok = False + message = 'Enter the state/province/region' + elif not postal_code: + ok = False + message = 'Enter the postal code' + elif not country: + ok = False + message = 'Enter the country' + if ok: + address_obj.desc = short_desc + address_obj.name = name + address_obj.institution = institution + address_obj.address = address + address_obj.city = city + address_obj.state = state + address_obj.postal_code = postal_code + address_obj.country = country + address_obj.phone = phone + trans.sa_session.add( address_obj ) trans.sa_session.flush() - message = 'Changes made to address %s are saved.' % user_address.desc + message = 'Address (%s) has been updated.' % address_obj.desc if admin_view: return trans.response.send_redirect( web.url_for( controller='user', action='show_info', @@ -853,38 +869,14 @@ class User( BaseController ): return trans.response.send_redirect( web.url_for( controller='user', action='show_info', message=message, - status='done') ) - else: - # show the address form with the current values filled in - # create the widgets for each address field - widgets = [] - widgets.append(dict(label='Short description', - widget=TextField( 'short_desc', 40, user_address.desc ) ) ) - widgets.append(dict(label='Name', - widget=TextField( 'name', 40, user_address.name ) ) ) - widgets.append(dict(label='Institution', - widget=TextField( 'institution', 40, user_address.institution ) ) ) - widgets.append(dict(label='Address Line 1', - widget=TextField( 'address1', 40, user_address.address ) ) ) - widgets.append(dict(label='Address Line 2', - widget=TextField( 'address2', 40, '' ) ) ) - widgets.append(dict(label='City', - widget=TextField( 'city', 40, user_address.city ) ) ) - widgets.append(dict(label='State', - widget=TextField( 'state', 40, user_address.state ) ) ) - widgets.append(dict(label='Postal Code', - widget=TextField( 'postal_code', 40, user_address.postal_code ) ) ) - widgets.append(dict(label='Country', - widget=TextField( 'country', 40, user_address.country ) ) ) - widgets.append(dict(label='Phone', - widget=TextField( 'phone', 40, user_address.phone ) ) ) - return trans.fill_template( 'user/edit_address.mako', - user=user, - address=user_address, - admin_view=admin_view, - widgets=widgets, - message=message, - status=status) + status='done' ) ) + # Display the address form with the current values filled in + return trans.fill_template( 'user/edit_address.mako', + user=user, + address_obj=address_obj, + admin_view=admin_view, + message=message, + status=status ) @web.expose def delete_address( self, trans, address_id=None, user_id=None, admin_view=False ): try: @@ -897,12 +889,13 @@ class User( BaseController ): message='Invalid address ID', status='error' ) ) user_address.deleted = True + trans.sa_session.add( user_address ) trans.sa_session.flush() return trans.response.send_redirect( web.url_for( controller='user', action='show_info', admin_view=admin_view, user_id=user_id, - message='Address %s deleted' % user_address.desc, + message='Address (%s) deleted' % user_address.desc, status='done') ) @web.expose def undelete_address( self, trans, address_id=None, user_id=None, admin_view=False ): @@ -921,9 +914,8 @@ class User( BaseController ): action='show_info', admin_view=admin_view, user_id=user_id, - message='Address %s undeleted' % user_address.desc, + message='Address (%s) undeleted' % user_address.desc, status='done') ) - @web.expose def set_user_pref_async( self, trans, pref_name, pref_value ): """ Set a user preference asynchronously. If user is not logged in, do nothing. """ @@ -931,13 +923,11 @@ class User( BaseController ): trans.log_action( trans.get_user(), "set_user_pref", "", { pref_name : pref_value } ) trans.user.preferences[pref_name] = pref_value trans.sa_session.flush() - @web.expose def log_user_action_async( self, trans, action, context, params ): """ Log a user action asynchronously. If user is not logged in, do nothing. """ if trans.user: trans.log_action( trans.get_user(), action, context, params ) - @web.expose @web.require_login() def dbkeys( self, trans, **kwds ): @@ -999,9 +989,7 @@ class User( BaseController ): user=user, dbkeys=dbkeys, message=message, - lines_skipped=lines_skipped ) - - + lines_skipped=lines_skipped ) @web.expose def api_keys( self, trans, **kwd ): params = util.Params( kwd ) diff --git a/lib/galaxy/web/form_builder.py b/lib/galaxy/web/form_builder.py index f9f837f3ffe..23726c1a719 100644 --- a/lib/galaxy/web/form_builder.py +++ b/lib/galaxy/web/form_builder.py @@ -384,8 +384,7 @@ class AddressField(BaseField): return [ ( "short_desc", "Short address description"), ( "name", "Name" ), ( "institution", "Institution" ), - ( "address1", "Address Line 1" ), - ( "address2", "Address Line 2" ), + ( "address", "Address" ), ( "city", "City" ), ( "state", "State/Province/Region" ), ( "postal_code", "Postal Code" ), @@ -437,8 +436,7 @@ class AddressField(BaseField): else: self.select_address.add_option('Add a new address', 'new') return self.select_address.get_html()+address_html - - + class WorkflowField(BaseField): def __init__(self, name, user=None, value=None, params=None): self.name = name diff --git a/templates/library/common/common.mako b/templates/library/common/common.mako index 171a11d974b..8f0e16d1435 100644 --- a/templates/library/common/common.mako +++ b/templates/library/common/common.mako @@ -1,5 +1,61 @@ -<%def name="render_template_info( cntrller, item_type, library_id, widgets, info_association, inherited, folder_id=None, ldda_id=None, editable=True )"> +<%def name="render_template_field( field )"> <% + from galaxy.web.form_builder import AddressField, CheckboxField, SelectField, TextArea, TextField, WorkflowField + + has_contents = False + value = '' + if isinstance( field[ 'widget' ], TextArea ) and field[ 'widget' ].value: + has_contents = True + label = field[ 'label' ] + value = '
%s
' % field[ 'widget' ].value + elif isinstance( field[ 'widget' ], TextField ) and field[ 'widget' ].value: + has_contents = True + label = field[ 'label' ] + value = field[ 'widget' ].value + elif isinstance( field[ 'widget' ], SelectField ) and field[ 'widget' ].options: + for option_label, option_value, selected in field['widget'].options: + if selected: + has_contents = True + label = field[ 'label' ] + value = option_value + elif isinstance( field[ 'widget' ], CheckboxField ) and field[ 'widget' ].checked: + has_contents = True + label = field[ 'label' ] + value = 'checked' + elif isinstance( field[ 'widget' ], WorkflowField ) and field[ 'widget' ].value not in [ 'none', 'None', None ]: + has_contents = True + label = field[ 'label' ] + widget = field[ 'widget' ] + workflow_user = widget.user + if workflow_user: + for workflow in workflow_user.stored_workflows: + if not workflow.deleted and str( widget.value ) == str( workflow.id ): + value = workflow.name + break + else: + # If we didn't find the selected workflow option above, we'll just print the value + value = field[ 'widget' ].value + elif isinstance( field[ 'widget' ], AddressField ) and field[ 'widget' ].value not in [ 'none', 'None', None ]: + has_contents = True + widget = field[ 'widget' ] + address = trans.sa_session.query( trans.model.UserAddress ).get( int( widget.value ) ) + label = address.desc + value = address.get_html() + %> + %if has_contents: +
+ + ${value} +
+ ${field[ 'helptext' ]} +
+
+
+ %endif + + +<%def name="render_template_fields( cntrller, item_type, library_id, widgets, widget_fields_have_contents, info_association, inherited, folder_id=None, ldda_id=None, editable=True )"> + <% if item_type == 'library': item = trans.sa_session.query( trans.app.model.Library ).get( trans.security.decode_id( library_id ) ) elif item_type == 'folder': @@ -41,7 +97,7 @@ %endif
-
+ %for i, field in enumerate( widgets ):
@@ -59,37 +115,17 @@

- %else: - <% contents = False %> - %for i, field in enumerate( widgets ): - %if field[ 'widget' ].value: - <% - contents = True - break - %> - %endif - %endfor - %if contents: -

-

-
Other information about ${item.name}
-
- %for i, field in enumerate( widgets ): - %if field[ 'widget' ].value: -
- -
${field[ 'widget' ].value}
-
- ${field[ 'helptext' ]} -
-
-
- %endif - %endfor -
+ %elif widget_fields_have_contents: +

+

+
Other information about ${item.name}
+
+ %for i, field in enumerate( widgets ): + ${render_template_field( field )} + %endfor
-

- %endif +

+

%endif %endif diff --git a/templates/library/common/folder_info.mako b/templates/library/common/folder_info.mako index 6cf21e064be..01638e5b5b6 100644 --- a/templates/library/common/folder_info.mako +++ b/templates/library/common/folder_info.mako @@ -1,6 +1,34 @@ <%inherit file="/base.mako"/> <%namespace file="/message.mako" import="render_msg" /> -<%namespace file="/library/common/common.mako" import="render_template_info" /> +<%namespace file="/library/common/common.mako" import="render_template_fields" /> + +<%def name="javascripts()"> + ${parent.javascripts()} + + <% from cgi import escape @@ -53,5 +81,5 @@

%if widgets: - ${render_template_info( cntrller=cntrller, item_type='folder', library_id=library_id, widgets=widgets, info_association=info_association, inherited=inherited, folder_id=trans.security.encode_id( folder.id ) )} + ${render_template_fields( cntrller=cntrller, item_type='folder', library_id=library_id, widgets=widgets, widget_fields_have_contents=widget_fields_have_contents, info_association=info_association, inherited=inherited, folder_id=trans.security.encode_id( folder.id ) )} %endif diff --git a/templates/library/common/ldda_edit_info.mako b/templates/library/common/ldda_edit_info.mako index 9d3acf08169..aaaad4b0b96 100644 --- a/templates/library/common/ldda_edit_info.mako +++ b/templates/library/common/ldda_edit_info.mako @@ -1,11 +1,35 @@ <%inherit file="/base.mako"/> <%namespace file="/message.mako" import="render_msg" /> -<%namespace file="/library/common/common.mako" import="render_template_info" /> +<%namespace file="/library/common/common.mako" import="render_template_fields" /> <% from galaxy import util %> <%def name="javascripts()"> ${parent.javascripts()} ${h.js("jquery.autocomplete", "autocomplete_tagging" )} + <%def name="stylesheets()"> @@ -155,5 +179,5 @@ %endif %if widgets: - ${render_template_info( cntrller=cntrller, item_type='ldda', library_id=library_id, widgets=widgets, info_association=info_association, inherited=inherited, folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), ldda_id=trans.security.encode_id( ldda.id ) )} + ${render_template_fields( cntrller=cntrller, item_type='ldda', library_id=library_id, widgets=widgets, widget_fields_have_contents=widget_fields_have_contents, info_association=info_association, inherited=inherited, folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), ldda_id=trans.security.encode_id( ldda.id ) )} %endif diff --git a/templates/library/common/ldda_info.mako b/templates/library/common/ldda_info.mako index 4c5985f80c9..07eeed2f865 100644 --- a/templates/library/common/ldda_info.mako +++ b/templates/library/common/ldda_info.mako @@ -1,6 +1,6 @@ <%inherit file="/base.mako"/> <%namespace file="/message.mako" import="render_msg" /> -<%namespace file="/library/common/common.mako" import="render_template_info" /> +<%namespace file="/library/common/common.mako" import="render_template_fields" /> <% from galaxy import util from galaxy.web.controllers.library_common import branch_deleted, get_containing_library_from_library_dataset @@ -23,6 +23,34 @@ can_modify = can_manage = False %> +<%def name="javascripts()"> + ${parent.javascripts()} + + + %if current_version: This is the latest version of this library dataset %else: @@ -134,7 +162,7 @@ %if widgets: - ${render_template_info( cntrller=cntrller, item_type='ldda', library_id=library_id, widgets=widgets, info_association=info_association, inherited=inherited, folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), ldda_id=trans.security.encode_id( ldda.id ), editable=False )} + ${render_template_fields( cntrller=cntrller, item_type='ldda', library_id=library_id, widgets=widgets, widget_fields_have_contents=widget_fields_have_contents, info_association=info_association, inherited=inherited, folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), ldda_id=trans.security.encode_id( ldda.id ), editable=False )} %endif %if trans.user_is_admin() and cntrller == 'library_admin': %if associated_hdas: diff --git a/templates/library/common/library_dataset_info.mako b/templates/library/common/library_dataset_info.mako index 82c50b499d3..3ef1b213e05 100644 --- a/templates/library/common/library_dataset_info.mako +++ b/templates/library/common/library_dataset_info.mako @@ -1,6 +1,34 @@ <%inherit file="/base.mako"/> <%namespace file="/message.mako" import="render_msg" /> -<%namespace file="/library/common/common.mako" import="render_template_info" /> +<%namespace file="/library/common/common.mako" import="render_template_fields" /> + +<%def name="javascripts()"> + ${parent.javascripts()} + + %if library_dataset == library_dataset.library_dataset_dataset_association.library_dataset: This is the latest version of this library dataset @@ -63,5 +91,5 @@ %if widgets: ## Templates are not currently supported for library_datasets, only the associated ldda. - ${render_template_info( cntrller, 'library_dataset', library_id, widgets, info_association=None, inherited=False, editable=False )} + ${render_template_fields( cntrller, 'library_dataset', library_id, widgets, widget_fields_have_contents, info_association=None, inherited=False, editable=False )} %endif diff --git a/templates/library/common/library_info.mako b/templates/library/common/library_info.mako index 2c08f0242fd..83b012f2550 100644 --- a/templates/library/common/library_info.mako +++ b/templates/library/common/library_info.mako @@ -1,6 +1,34 @@ <%inherit file="/base.mako"/> <%namespace file="/message.mako" import="render_msg" /> -<%namespace file="/library/common/common.mako" import="render_template_info" /> +<%namespace file="/library/common/common.mako" import="render_template_fields" /> + +<%def name="javascripts()"> + ${parent.javascripts()} + + <% from cgi import escape @@ -107,5 +135,5 @@ %if widgets: - ${render_template_info( cntrller=cntrller, item_type='library', library_id=trans.security.encode_id( library.id ), widgets=widgets, info_association=info_association, inherited=inherited, editable=not( library.deleted ) )} + ${render_template_fields( cntrller=cntrller, item_type='library', library_id=trans.security.encode_id( library.id ), widgets=widgets, widget_fields_have_contents=widget_fields_have_contents, info_association=info_association, inherited=inherited, editable=not( library.deleted ) )} %endif diff --git a/templates/library/common/new_folder.mako b/templates/library/common/new_folder.mako index abf4f94a863..e17b83ef819 100644 --- a/templates/library/common/new_folder.mako +++ b/templates/library/common/new_folder.mako @@ -1,6 +1,5 @@ <%inherit file="/base.mako"/> <%namespace file="/message.mako" import="render_msg" /> -<%namespace file="/library/common/common.mako" import="render_template_info" />