from galaxy.web.base.controller import * from galaxy.model.orm import * from galaxy.datatypes import sniff from galaxy import model, util import logging, os, sys from galaxy.web.form_builder import * from galaxy.tools.parameters.basic import parameter_types from elementtree.ElementTree import XML, Element from galaxy.util.odict import odict import copy from galaxy.web.framework.helpers import time_ago, iff, grids log = logging.getLogger( __name__ ) class FormsGrid( grids.Grid ): # Custom column types class NameColumn( grids.TextColumn ): def get_value(self, trans, grid, form): return form.latest_form.name class DescriptionColumn( grids.TextColumn ): def get_value(self, trans, grid, form): return form.latest_form.desc class TypeColumn( grids.TextColumn ): def get_value(self, trans, grid, form): return form.latest_form.type # Grid definition title = "Forms" template = "admin/forms/grid.mako" model_class = model.FormDefinitionCurrent default_sort_key = "-create_time" num_rows_per_page = 50 preserve_state = True use_paging = True default_filter = dict( deleted="False" ) columns = [ NameColumn( "Name", key="name", model_class=model.FormDefinition, link=( lambda item: iff( item.deleted, None, dict( operation="view", id=item.id ) ) ), attach_popup=True, filterable="advanced" ), DescriptionColumn( "Description", key='desc', model_class=model.FormDefinition, filterable="advanced" ), TypeColumn( "Type" ), grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" ) ] columns.append( grids.MulticolFilterColumn( "Search", cols_to_filter=[ columns[0], columns[1] ], key="free-text-search", visible=False, filterable="standard" ) ) operations = [ grids.GridOperation( "Edit", allow_multiple=False, condition=( lambda item: not item.deleted ) ), grids.GridOperation( "Delete", allow_multiple=True, condition=( lambda item: not item.deleted ) ), grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ) ), ] global_actions = [ grids.GridAction( "Create new form", dict( controller='forms', action='create_form' ) ) ] class Forms( BaseController ): # Empty form field empty_field = { 'label': '', 'helptext': '', 'visible': True, 'required': False, 'type': BaseField.form_field_types()[0], 'selectlist': [], 'layout': 'none', 'default': '' } forms_grid = FormsGrid() @web.expose @web.require_admin def manage( self, trans, **kwd ): if 'operation' in kwd: operation = kwd['operation'].lower() if not kwd.get( 'id', None ): return trans.response.send_redirect( web.url_for( controller='forms', action='manage', status='error', message="Invalid form ID") ) if operation == "view": return self.__view( trans, **kwd ) elif operation == "delete": return self.__delete( trans, **kwd ) elif operation == "undelete": return self.__undelete( trans, **kwd ) elif operation == "edit": return self.edit( trans, **kwd ) return self.forms_grid( trans, **kwd ) def __view(self, trans, **kwd): try: fdc = trans.sa_session.query( trans.app.model.FormDefinitionCurrent )\ .get( trans.security.decode_id(kwd['id']) ) except: return trans.response.send_redirect( web.url_for( controller='forms', action='manage', message='Invalid form', status='error' ) ) return trans.fill_template( '/admin/forms/show_form_read_only.mako', form_definition=fdc.latest_form ) def __form_types_widget(self, trans, selected='none'): form_type_selectbox = SelectField( 'form_type_selectbox' ) if selected == 'none': form_type_selectbox.add_option('Select one', 'none', selected=True) else: form_type_selectbox.add_option('Select one', 'none') fd_types = trans.app.model.FormDefinition.types.items() fd_types.sort() for ft in fd_types: if selected == ft[1]: form_type_selectbox.add_option(ft[1], ft[1], selected=True) else: form_type_selectbox.add_option(ft[1], ft[1]) return form_type_selectbox @web.expose @web.require_admin def create_form( self, trans, **kwd ): params = util.Params( kwd ) message = util.restore_text( params.get( 'message', '' ) ) status = params.get( 'status', 'done' ) self.__imported_from_file = False if params.get( 'create_form_button', False ): fd, message = self.__save_form( trans, fdc_id=None, **kwd ) if not fd: return trans.response.send_redirect( web.url_for( controller='forms', action='create_form', message=message, status='error', name=util.restore_text( params.get( 'name', '' ) ), description=util.restore_text( params.get( 'description', '' ) ) )) self.__get_saved_form( fd ) if self.__imported_from_file: return trans.response.send_redirect( web.url_for( controller='forms', action='edit', id=trans.security.encode_id(fd.current.id)) ) else: return trans.response.send_redirect( web.url_for( controller='forms', action='edit', id=trans.security.encode_id(fd.current.id), add_field_button='Add field', name=fd.name, description=fd.desc, form_type_selectbox=fd.type ) ) inputs = [ ( 'Name', TextField( 'name', 40, util.restore_text( params.get( 'name', '' ) ) ) ), ( 'Description', TextField( 'description', 40, util.restore_text( params.get( 'description', '' ) ) ) ), ( 'Type', self.__form_types_widget(trans, selected=params.get( 'form_type', 'none' )) ), ( 'Import from csv file (Optional)', FileField( 'file_data', 40, '' ) ) ] return trans.fill_template( '/admin/forms/create_form.mako', inputs=inputs, message=message, status=status ) def __delete( self, trans, **kwd ): id_list = util.listify( kwd['id'] ) delete_failed = [] for id in id_list: try: fdc = trans.sa_session.query( trans.app.model.FormDefinitionCurrent ).get( trans.security.decode_id(id) ) except: return trans.response.send_redirect( web.url_for( controller='forms', action='manage', message='Invalid form', status='error' ) ) fdc.deleted = True trans.sa_session.add( fdc ) trans.sa_session.flush() return trans.response.send_redirect( web.url_for( controller='forms', action='manage', message='%i forms have been deleted.' % len(id_list), status='done') ) def __undelete( self, trans, **kwd ): id_list = util.listify( kwd['id'] ) delete_failed = [] for id in id_list: try: fdc = trans.sa_session.query( trans.app.model.FormDefinitionCurrent ).get( trans.security.decode_id(id) ) except: return trans.response.send_redirect( web.url_for( controller='forms', action='manage', message='Invalid form', status='error' ) ) fdc.deleted = False trans.sa_session.add( fdc ) trans.sa_session.flush() return trans.response.send_redirect( web.url_for( controller='forms', action='manage', message='%i forms have been undeleted.' % len(id_list), status='done') ) @web.expose def edit( self, trans, response_redirect=None, **kwd ): ''' This callback method is for handling form editing. The value of response_redirect should be an URL that is defined by the caller. This allows for redirecting as desired when the form changes have been saved. For an example of how this works, see the edit_template() method in the library_common controller. ''' params = util.Params( kwd ) message = util.restore_text( params.get( 'message', '' ) ) status = params.get( 'status', 'done' ) try: fdc = trans.sa_session.query( trans.app.model.FormDefinitionCurrent ).get( trans.security.decode_id(kwd['id']) ) except: return trans.response.send_redirect( web.url_for( controller='forms', action='manage', message='Invalid form', status='error' ) ) fd = fdc.latest_form # # Save changes # if params.get( 'save_changes_button', False ): fd_new, message = self.__save_form( trans, fdc_id=fd.form_definition_current.id, **kwd ) # if validation error encountered while saving the form, show the # unsaved form, with the error message if not fd_new: current_form = self.__get_form( trans, **kwd ) return self.__show( trans=trans, form=fd, current_form=current_form, message=message, status='error', response_redirect=response_redirect, **kwd ) # everything went fine. form saved successfully. Show the saved form or redirect # to response_redirect if appropriate. if response_redirect: return trans.response.send_redirect( response_redirect ) fd = fd_new current_form = self.__get_saved_form( fd ) message = "The form '%s' has been updated with the changes." % fd.name return self.__show( trans=trans, form=fd, current_form=current_form, message=message, status=status, response_redirect=response_redirect, **kwd ) # # Add a layout grid # elif params.get( 'add_layout_grid', False ): current_form = self.__get_form( trans, **kwd ) current_form['layout'].append('') # show the form again return self.__show( trans=trans, form=fd, current_form=current_form, message=message, status=status, response_redirect=response_redirect, **kwd ) # # Delete a layout grid # elif params.get( 'remove_layout_grid_button', False ): current_form = self.__get_form( trans, **kwd ) index = int( kwd[ 'remove_layout_grid_button' ].split( ' ' )[2] ) - 1 del current_form['layout'][index] return self.__show( trans=trans, form=fd, current_form=current_form, message=message, status=status, response_redirect=response_redirect, **kwd ) # # Add a field # elif params.get( 'add_field_button', False ): current_form = self.__get_form( trans, **kwd ) current_form['fields'].append( self.empty_field ) # show the form again with one empty field return self.__show( trans=trans, form=fd, current_form=current_form, message=message, status=status, response_redirect=response_redirect, **kwd ) # # Delete a field # elif params.get( 'remove_button', False ): current_form = self.__get_form( trans, **kwd ) # find the index of the field to be removed from the remove button label index = int( kwd[ 'remove_button' ].split( ' ' )[2] ) - 1 del current_form['fields'][index] return self.__show( trans=trans, form=fd, current_form=current_form, message=message, status=status, response_redirect=response_redirect, **kwd ) # # Add SelectField option # elif 'Add' in kwd.values(): return self.__add_selectbox_option(trans, fd, message, status, response_redirect=response_redirect, **kwd) # # Remove SelectField option # elif 'Remove' in kwd.values(): return self.__remove_selectbox_option(trans, fd, message, status, response_redirect=response_redirect, **kwd) # # Refresh page # elif params.get( 'refresh', False ): current_form = self.__get_form( trans, **kwd ) return self.__show( trans=trans, form=fd, current_form=current_form, message=message, status=status, response_redirect=response_redirect, **kwd ) # # Show the form for editing # else: current_form = self.__get_saved_form( fd ) return self.__show( trans=trans, form=fd, current_form=current_form, message=message, status=status, response_redirect=response_redirect, **kwd ) def __add_selectbox_option( self, trans, fd, message, status, response_redirect=None, **kwd ): ''' This method adds a selectbox option. The kwd dict searched for the field index which needs to be removed ''' current_form = self.__get_form( trans, **kwd ) index = -1 for k, v in kwd.items(): if v == 'Add': # extract the field index from the # button name of format: 'addoption_' index = int(k.split('_')[1]) break if index == -1: # something wrong happened return self.__show( trans=trans, form=fd, current_form=current_form, message='Error in adding selectfield option', status='error', response_redirect=response_redirect, **kwd ) # add an empty option current_form[ 'fields' ][ index ][ 'selectlist' ].append( '' ) return self.__show( trans=trans, form=fd, current_form=current_form, message=message, status=status, response_redirect=response_redirect, **kwd ) def __remove_selectbox_option( self, trans, fd, message, status, response_redirect=None, **kwd ): ''' This method removes a selectbox option. The kwd dict searched for the field index and option index which needs to be removed ''' current_form = self.__get_form( trans, **kwd ) option = -1 for k, v in kwd.items(): if v == 'Remove': # extract the field & option indices from the # button name of format: 'removeoption__