PageRenderTime 107ms CodeModel.GetById 61ms app.highlight 40ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/galaxy/web/controllers/request_type.py

https://bitbucket.org/cistrome/cistrome-harvard/
Python | 460 lines | 453 code | 4 blank | 3 comment | 15 complexity | 29b4384fb167dc029904ce694f4848c6 MD5 | raw file
  1from galaxy.web.base.controller import *
  2from galaxy.web.framework.helpers import time_ago, iff, grids
  3from galaxy.model.orm import *
  4from galaxy import model, util
  5from galaxy.web.form_builder import *
  6from galaxy.web.controllers.requests_common import invalid_id_redirect
  7import logging, os
  8
  9log = logging.getLogger( __name__ )
 10
 11class RequestTypeGrid( grids.Grid ):
 12    # Custom column types
 13    class NameColumn( grids.TextColumn ):
 14        def get_value(self, trans, grid, request_type):
 15            return request_type.name
 16    class DescriptionColumn( grids.TextColumn ):
 17        def get_value(self, trans, grid, request_type):
 18            return request_type.desc
 19    class RequestFormColumn( grids.TextColumn ):
 20        def get_value(self, trans, grid, request_type):
 21            return request_type.request_form.name
 22    class SampleFormColumn( grids.TextColumn ):
 23        def get_value(self, trans, grid, request_type):
 24            return request_type.sample_form.name
 25    class ExternalServiceColumn( grids.IntegerColumn ):
 26        def get_value(self, trans, grid, request_type):
 27            if request_type.external_services:
 28                return len( request_type.external_services )
 29            return 'No external service assigned'
 30    # Grid definition
 31    webapp = "galaxy"
 32    title = "Request Types"
 33    template = "admin/request_type/grid.mako"
 34    model_class = model.RequestType
 35    default_sort_key = "-create_time"
 36    num_rows_per_page = 50
 37    preserve_state = True
 38    use_paging = True
 39    default_filter = dict( deleted="False" )
 40    columns = [
 41        NameColumn( "Name", 
 42                    key="name",
 43                    link=( lambda item: iff( item.deleted, None, dict( operation="view_request_type", id=item.id ) ) ),
 44                    attach_popup=True,
 45                    filterable="advanced" ),
 46        DescriptionColumn( "Description",
 47                           key='desc',
 48                           filterable="advanced" ),
 49        RequestFormColumn( "Request Form", 
 50                           link=( lambda item: iff( item.deleted, None, dict( operation="view_form_definition", id=item.request_form.id ) ) ) ),
 51        SampleFormColumn( "Sample Form", 
 52                           link=( lambda item: iff( item.deleted, None, dict( operation="view_form_definition", id=item.sample_form.id ) ) ) ),
 53        ExternalServiceColumn( "External Services" ),
 54        grids.DeletedColumn( "Deleted", 
 55                             key="deleted", 
 56                             visible=False, 
 57                             filterable="advanced" )
 58    ]
 59    columns.append( grids.MulticolFilterColumn( "Search", 
 60                                                cols_to_filter=[ columns[0], columns[1] ], 
 61                                                key="free-text-search",
 62                                                visible=False,
 63                                                filterable="standard" ) )
 64    operations = [
 65        grids.GridOperation( "Edit request type", allow_multiple=False, condition=( lambda item: not item.deleted ) ),
 66        grids.GridOperation( "Edit permissions", allow_multiple=False, condition=( lambda item: not item.deleted ) ),
 67        grids.GridOperation( "Use run details template", allow_multiple=False, condition=( lambda item: not item.deleted and not item.run_details ) ),
 68        grids.GridOperation( "Delete", allow_multiple=True, condition=( lambda item: not item.deleted ) ),
 69        grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ) ),    
 70    ]
 71    global_actions = [
 72        grids.GridAction( "Create new request type", dict( controller='request_type', action='create_request_type' ) )
 73    ]
 74
 75class RequestType( BaseUIController, UsesFormDefinitions ):
 76    request_type_grid = RequestTypeGrid()
 77
 78    @web.expose
 79    @web.require_admin
 80    def browse_request_types( self, trans, **kwd ):
 81        if 'operation' in kwd:
 82            operation = kwd['operation'].lower()
 83            obj_id = kwd.get( 'id', None )
 84            if operation == "view_form_definition":
 85                return self.view_form_definition( trans, **kwd )
 86            elif operation == "view_request_type":
 87                return self.view_request_type( trans, **kwd )
 88            elif operation == "use run details template":
 89                return trans.response.send_redirect( web.url_for( controller='requests_admin',
 90                                                                  action='add_template',
 91                                                                  cntrller='requests_admin',
 92                                                                  item_type='request_type',
 93                                                                  form_type=trans.model.FormDefinition.types.RUN_DETAILS_TEMPLATE,
 94                                                                  request_type_id=obj_id ) )
 95            elif operation == "edit request type":
 96                return self.view_editable_request_type( trans, **kwd )
 97            elif operation == "delete":
 98                return self.delete_request_type( trans, **kwd )
 99            elif operation == "undelete":
100                return self.undelete_request_type( trans, **kwd )
101            elif operation == "edit permissions":
102                return self.request_type_permissions( trans, **kwd )
103            elif operation == "view_external_service":
104                return trans.response.send_redirect( web.url_for( controller='external_service',
105                                                                  action='view_external_service',
106                                                                  **kwd ) )
107        # Render the grid view
108        return self.request_type_grid( trans, **kwd )
109    @web.expose
110    @web.require_admin
111    def create_request_type( self, trans, **kwd ):
112        params = util.Params( kwd )
113        message = util.restore_text( params.get( 'message', ''  ) )
114        status = params.get( 'status', 'done' )
115        rt_info_widgets, rt_states_widgets = self.__get_populated_request_type_widgets( trans, **kwd )
116        external_service_select_fields_list = []
117        # get all the external services selected till now
118        external_services_list = self.__get_external_services( trans, **kwd )
119        for index, external_service in enumerate( external_services_list ): 
120            external_service_select_field = self.__build_external_service_select_field( trans, 
121                                                                                        'external_service_id_%i' % index, 
122                                                                                        external_service )
123            external_service_select_fields_list.append( external_service_select_field )
124        if params.get( 'add_state_button', False ):
125            # Append a new tuple to the set of states which will result in
126            # empty state name and description TextFields being displayed on
127            # the form.
128            rt_states_widgets.append( ( "", "" ) )
129        elif params.get( 'remove_state_button', False ):
130            index = int( params.get( 'remove_state_button', '' ).split( " " )[2] )
131            del rt_states_widgets[ index-1 ]
132        elif params.get( 'add_external_service_button', False ):
133            # create a new one
134            external_service_select_field = self.__build_external_service_select_field( trans, 
135                                                                                        'external_service_id_%i' % len( external_services_list ) )
136            external_service_select_fields_list.append( external_service_select_field )
137        elif params.get( 'create_request_type_button', False ):
138            self.__save_request_type( trans, action='create_request_type', **kwd )
139            message = 'The request type has been created.'
140            return trans.response.send_redirect( web.url_for( controller='request_type',
141                                                              action='browse_request_types',
142                                                              message=message,
143                                                              status=status ) )
144        # A request_type requires at least one possible sample state so that
145        # it can be used to create a sequencing request
146        if not len( rt_states_widgets ):
147            rt_states_widgets.append( ( "New", "First sample state" ) )
148        return trans.fill_template( '/admin/request_type/create_request_type.mako',
149                                    rt_info_widgets=rt_info_widgets,
150                                    rt_states_widgets=rt_states_widgets,
151                                    external_service_select_fields_list=external_service_select_fields_list,
152                                    message=message,
153                                    status=status )
154    def __get_external_services(self, trans, request_type=None, **kwd):
155        params = util.Params( kwd )
156        external_services_list = []
157        i = 0
158        while True:
159            if kwd.has_key( 'external_service_id_%i' % i ):
160                id = params.get( 'external_service_id_%i' % i, '' )
161                try:
162                    external_service = trans.sa_session.query( trans.model.ExternalService ).get( trans.security.decode_id( id ) )
163                except:
164                    return invalid_id_redirect( trans, 'request_type', id, 'external service', action='browse_request_types' )
165                external_services_list.append( external_service )
166                i += 1
167            else:
168                break
169        return external_services_list
170    @web.expose
171    @web.require_admin
172    def view_editable_request_type( self, trans, **kwd ):
173        params = util.Params( kwd )
174        message = util.restore_text( params.get( 'message', ''  ) )
175        status = params.get( 'status', 'done' )
176        request_type_id = params.get( 'id', None )
177        try:
178            request_type = trans.sa_session.query( trans.model.RequestType ).get( trans.security.decode_id( request_type_id ) )
179        except:
180            return invalid_id_redirect( trans, 'request_type', request_type_id, 'request type', action='browse_request_types' )
181        # See if we have any associated templates
182        widgets = request_type.get_template_widgets( trans )
183        widget_fields_have_contents = self.widget_fields_have_contents( widgets )
184        # get all the external services selected till now
185        external_service_select_fields_list = []
186        for index, external_service in enumerate( request_type.external_services ): 
187            external_service_select_field = self.__build_external_service_select_field( trans, 
188                                                                                        'external_service_id_%i' % index, 
189                                                                                        external_service )
190            external_service_select_fields_list.append( external_service_select_field )
191        return trans.fill_template( '/admin/request_type/edit_request_type.mako',
192                                    request_type=request_type,
193                                    widgets=widgets,
194                                    widget_fields_have_contents=widget_fields_have_contents,
195                                    external_service_select_fields_list=external_service_select_fields_list,
196                                    message=message,
197                                    status=status )
198    @web.expose
199    @web.require_admin
200    def edit_request_type( self, trans, **kwd ):
201        params = util.Params( kwd )
202        message = util.restore_text( params.get( 'message', ''  ) )
203        status = params.get( 'status', 'done' )
204        request_type_id = params.get( 'id', None )
205        try:
206            request_type = trans.sa_session.query( trans.model.RequestType ).get( trans.security.decode_id( request_type_id ) )
207        except:
208            return invalid_id_redirect( trans, 'request_type', request_type_id, 'request type', action='browse_request_types' )
209        # See if we have any associated templates
210        widgets = request_type.get_template_widgets( trans )
211        widget_fields_have_contents = self.widget_fields_have_contents( widgets )
212        # get all the external services selected till now
213        external_service_select_fields_list = []
214        external_services_list = self.__get_external_services( trans, request_type, **kwd )
215        if params.get( 'edit_request_type_button', False ):
216            request_type = self.__save_request_type( trans, action='edit_request_type', **kwd )
217            message = 'Changes made to request type (%s) have been saved' % request_type.name
218        elif params.get( 'add_external_service_button', False ):
219            external_services_list.append( None )
220        elif params.get( 'remove_external_service_button', False ):
221            index = int( kwd[ 'remove_external_service_button' ].split(' ')[3] ) - 1
222            del external_services_list[index]
223        #if external_services_list
224        for index, external_service in enumerate( external_services_list ): 
225            external_service_select_field = self.__build_external_service_select_field( trans, 
226                                                                                        'external_service_id_%i' % index, 
227                                                                                        external_service )
228            external_service_select_fields_list.append( external_service_select_field )
229        return trans.fill_template( '/admin/request_type/edit_request_type.mako',
230                                    request_type=request_type,
231                                    widgets=widgets,
232                                    widget_fields_have_contents=widget_fields_have_contents,
233                                    external_service_select_fields_list=external_service_select_fields_list,
234                                    message=message,
235                                    status=status )
236    def __save_request_type( self, trans, action, **kwd ):
237        # Here we save a newly created request_type or save changed
238        # attributes of an existing request_type.
239        params = util.Params( kwd )
240        request_type_id = params.get( 'id', None )
241        name = util.restore_text( params.get( 'name', ''  ) )
242        desc = util.restore_text( params.get( 'desc', '' ) )
243        request_form_id = params.get( 'request_form_id', 'none' )
244        sample_form_id = params.get( 'sample_form_id', 'none' )
245        external_service_id = params.get( 'external_service_id', 'none' )
246        # validate
247        if not name or request_form_id == 'none' or sample_form_id == 'none':
248            message = 'Enter the name, request form, sample form and at least one sample state associated with this request type.'
249            return trans.response.send_redirect( web.url_for( controller='request_type',
250                                                              action=action,
251                                                              message=message,
252                                                              status='error' ) )
253        try:
254            request_form = trans.sa_session.query( trans.model.FormDefinition ).get( trans.security.decode_id( request_form_id ) )
255        except:
256            return invalid_id_redirect( trans, 'request_type', request_type_id, 'form definition', action='browse_request_types' )
257        
258        try:
259            sample_form = trans.sa_session.query( trans.model.FormDefinition ).get( trans.security.decode_id( sample_form_id ) )
260        except:
261            return invalid_id_redirect( trans, 'request_type', request_type_id, 'form definition', action='browse_request_types' )
262        if request_type_id:
263            # We're saving changed attributes of an existing request_type.
264            request_type = trans.sa_session.query( trans.model.RequestType ).get( trans.security.decode_id( request_type_id ) )
265            request_type.name = name
266            request_type.desc = desc
267            request_type.request_form = request_form
268            request_type.sample_form = sample_form
269            for sample_state in request_type.states:
270                sample_state_id = trans.security.encode_id( sample_state.id )
271                name = util.restore_text( params.get( 'state_name_%s' % sample_state_id, '' ) )
272                desc = util.restore_text( params.get( 'state_desc_%s' % sample_state_id, '' ) )
273                sample_state.name = name
274                sample_state.desc = desc
275                trans.sa_session.add( sample_state )
276                trans.sa_session.flush()
277            trans.sa_session.add( request_type )
278            trans.sa_session.flush()
279        else:
280            # We're saving a newly created request_type
281            request_type = trans.model.RequestType( name=name,
282                                                    desc=desc,
283                                                    request_form=request_form,
284                                                    sample_form=sample_form ) 
285            trans.sa_session.add( request_type )
286            trans.sa_session.flush()
287            i = 0
288            while True:
289                if kwd.has_key( 'state_name_%i' % i ):
290                    name = util.restore_text( params.get( 'state_name_%i' % i, '' ) )
291                    desc = util.restore_text( params.get( 'state_desc_%i' % i, '' ) )
292                    sample_state = trans.model.SampleState( name, desc, request_type ) 
293                    trans.sa_session.add( sample_state )
294                    trans.sa_session.flush()
295                    i += 1
296                else:
297                    break
298        # delete existing associations
299        request_type.delete_external_service_associations( trans )
300        # save the external services associated with this request_type
301        external_services_list = self.__get_external_services( trans, **kwd )
302        for external_service in external_services_list:
303            request_type.add_external_service_association( trans, external_service )
304        return request_type
305    def __get_populated_request_type_widgets( self, trans, **kwd ):
306        request_form_definitions = self.get_all_forms( trans, 
307                                                        filter=dict( deleted=False ),
308                                                        form_type=trans.model.FormDefinition.types.REQUEST )
309        sample_form_definitions = self.get_all_forms( trans, 
310                                                      filter=dict( deleted=False ),
311                                                      form_type=trans.model.FormDefinition.types.SAMPLE )
312        if not request_form_definitions or not sample_form_definitions:
313            return [],[]
314        params = util.Params( kwd )
315        request_form_id = params.get( 'request_form_id', 'none' )
316        sample_form_id = params.get( 'sample_form_id', 'none' )
317        request_form_id_select_field = build_select_field( trans,
318                                                           objs=request_form_definitions,
319                                                           label_attr='name',
320                                                           select_field_name='request_form_id',
321                                                           selected_value=request_form_id,
322                                                           refresh_on_change=False )
323        sample_form_id_select_field = build_select_field( trans,
324                                                           objs=sample_form_definitions,
325                                                           label_attr='name',
326                                                           select_field_name='sample_form_id',
327                                                           selected_value=sample_form_id,
328                                                           refresh_on_change=False )
329        rt_info_widgets = [ dict( label='Name', 
330                                  widget=TextField( 'name', 40, util.restore_text( params.get( 'name', '' ) ) ) ),
331                            dict( label='Description', 
332                                  widget=TextField( 'desc', 40, util.restore_text( params.get( 'desc', '' ) ) ) ),
333                            dict( label='Request form',
334                                  widget=request_form_id_select_field ),
335                            dict( label='Sample form',
336                                  widget=sample_form_id_select_field ) ]
337        # Unsaved sample states being defined for this request type
338        rt_states = []
339        i=0
340        while True:
341            if kwd.has_key( 'state_name_%i' % i ):
342                rt_states.append( ( util.restore_text( params.get( 'state_name_%i' % i, ''  ) ), 
343                                    util.restore_text( params.get( 'state_desc_%i' % i, ''  ) ) ) )
344                i += 1
345            else:
346                break
347        return rt_info_widgets, rt_states
348                
349    @web.expose
350    @web.require_admin
351    def view_request_type( self, trans, **kwd ):
352        params = util.Params( kwd )
353        message = util.restore_text( params.get( 'message', ''  ) )
354        status = params.get( 'status', 'done' )
355        request_type_id = kwd.get( 'id', None )
356        try:
357            request_type = trans.sa_session.query( trans.model.RequestType ).get( trans.security.decode_id( request_type_id ) )
358        except:
359            return invalid_id_redirect( trans, 'request_type', request_type_id, 'request type', action='browse_request_types' )
360        # See if we have any associated templates
361        widgets = request_type.get_template_widgets( trans )
362        widget_fields_have_contents = self.widget_fields_have_contents( widgets )
363        return trans.fill_template( '/admin/request_type/view_request_type.mako', 
364                                    request_type=request_type,
365                                    widgets=widgets,
366                                    widget_fields_have_contents=widget_fields_have_contents,
367                                    message=message,
368                                    status=status )
369    @web.expose
370    @web.require_admin
371    def delete_request_type( self, trans, **kwd ):
372        request_type_id = kwd.get( 'id', '' )
373        request_type_id_list = util.listify( request_type_id )
374        for request_type_id in request_type_id_list:
375            try:
376                request_type = trans.sa_session.query( trans.model.RequestType ).get( trans.security.decode_id( request_type_id ) )
377            except:
378                return invalid_id_redirect( trans, 'request_type', request_type_id, 'request type', action='browse_request_types' )
379            request_type.deleted = True
380            trans.sa_session.add( request_type )
381            trans.sa_session.flush()
382        status = 'done'
383        message = '%i request types has been deleted' % len( request_type_id_list )
384        return trans.response.send_redirect( web.url_for( controller='request_type',
385                                                          action='browse_request_types',
386                                                          message=message,
387                                                          status='done' ) )
388    @web.expose
389    @web.require_admin
390    def undelete_request_type( self, trans, **kwd ):
391        request_type_id = kwd.get( 'id', '' )
392        request_type_id_list = util.listify( request_type_id )
393        for request_type_id in request_type_id_list:
394            try:
395                request_type = trans.sa_session.query( trans.model.RequestType ).get( trans.security.decode_id( request_type_id ) )
396            except:
397                return invalid_id_redirect( trans, 'request_type', request_type_id, 'request type', action='browse_request_types' )
398            request_type.deleted = False
399            trans.sa_session.add( request_type )
400            trans.sa_session.flush()
401        status = 'done'
402        message = '%i request types have been undeleted' % len( request_type_id_list )
403        return trans.response.send_redirect( web.url_for( controller='request_type',
404                                                          action='browse_request_types',
405                                                          message=message,
406                                                          status=status ) )
407    @web.expose
408    @web.require_admin
409    def request_type_permissions( self, trans, **kwd ):
410        params = util.Params( kwd )
411        message = util.restore_text( params.get( 'message', ''  ) )
412        status = params.get( 'status', 'done' )
413        request_type_id = kwd.get( 'id', '' )
414        try:
415            request_type = trans.sa_session.query( trans.model.RequestType ).get( trans.security.decode_id( request_type_id ) )
416        except:
417            return invalid_id_redirect( trans, 'request_type', request_type_id, 'request type', action='browse_request_types' )
418        roles = trans.sa_session.query( trans.model.Role ) \
419                                .filter( trans.model.Role.table.c.deleted==False ) \
420                                .order_by( trans.model.Role.table.c.name )
421        if params.get( 'update_roles_button', False ):
422            permissions = {}
423            for k, v in trans.model.RequestType.permitted_actions.items():
424                in_roles = [ trans.sa_session.query( trans.model.Role ).get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ]
425                permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles
426            trans.app.security_agent.set_request_type_permissions( request_type, permissions )
427            trans.sa_session.refresh( request_type )
428            message = "Permissions updated for request type '%s'" % request_type.name
429        return trans.fill_template( '/admin/request_type/request_type_permissions.mako',
430                                    request_type=request_type,
431                                    roles=roles,
432                                    status=status,
433                                    message=message )
434    @web.expose
435    @web.require_admin
436    def view_form_definition( self, trans, **kwd ):
437        form_definition_id = kwd.get( 'id', None )
438        try:
439            form_definition = trans.sa_session.query( trans.model.FormDefinition ).get( trans.security.decode_id( form_definition_id ) )
440        except:
441            return invalid_id_redirect( trans, 'request_type', form_definition_id, 'form definition', action='browse_request_types' )
442        return trans.fill_template( '/admin/forms/view_form_definition.mako',
443                                    form_definition=form_definition )
444
445    # ===== Methods for building SelectFields used on various admin_requests forms
446    def __build_external_service_select_field( self, trans, select_field_name, external_service=None ):
447        if external_service:
448            selected_value = trans.security.encode_id( external_service.id ) 
449        else:
450            selected_value = 'none'
451        all_external_services = trans.sa_session.query( trans.model.ExternalService ).filter( trans.model.ExternalService.table.c.deleted==False ).all()
452        for e in all_external_services:
453            external_service_type = e.get_external_service_type( trans )
454            e.label = '%s - %s' % ( e.name, external_service_type.name )
455        return build_select_field( trans,
456                                   objs=all_external_services,
457                                   label_attr='label',
458                                   select_field_name=select_field_name,
459                                   selected_value=selected_value,
460                                   refresh_on_change=False )