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

https://bitbucket.org/cistrome/cistrome-harvard/ · Python · 460 lines · 428 code · 7 blank · 25 comment · 58 complexity · 29b4384fb167dc029904ce694f4848c6 MD5 · raw file

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