# HG changeset patch -- Bitbucket.org # Project galaxy-dist # URL http://bitbucket.org/galaxy/galaxy-dist/overview # User rc # Date 1277909210 14400 # Node ID c1172bae7b0fc41e4bd52bfe73c130309c2387fe # Parent 9289b4d7fa4d1d1b630c044dfbc102cf870f62e3 lims: requests/request_admin controller refactor A new controller called requests_common now handles all common tasks like create/edit/delete requests & samples. The requests controller has only the grid definition and requests_admin controller has the request_type code and the sequencer data transfer code. Also fixed a form importer bug in forms.py --- /dev/null +++ b/templates/requests/common/sample_events.mako @@ -0,0 +1,65 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + +<%def name="title()">Events for Sample ${sample.name}</%def> + +<h2>Events for Sample "${sample.name}"</h2> +<ul class="manage-table-actions"> + <li> + <a class="action-button" href="${h.url_for( controller=cntrller, action='list', operation='show', id=trans.security.encode_id(sample.request.id) )}"> + <span>Browse this request</span></a> + </li> +</ul> +<h3>User: ${sample.request.user.email}</h3> + +%if message: + ${render_msg( message, status )} +%endif + +<div class="toolForm"> + <table class="grid"> + <thead> + <tr> + <th>State</th> + <th>Description</th> + <th>Last Update</th> + <th>Comments</th> + </tr> + </thead> + <tbody> + %for state, desc, updated, comments in events_list: + <tr class="libraryRow libraryOrFolderRow" id="libraryRow"> + <td><b><a>${state}</a></b></td> + <td><a>${desc}</a></td> + <td><a>${updated}</a></td> + <td><a>${comments}</a></td> + </tr> + %endfor + </tbody> + </table> +</div> +%if cntrller == 'requests_admin' and trans.user_is_admin(): + <div class="toolForm"> + <div class="toolFormTitle">Change current state</div> + <div class="toolFormBody"> + <form name="event" action="${h.url_for( controller='requests_admin', action='save_state', new=True, sample_id=sample.id)}" method="post" > + %for w in widgets: + <div class="form-row"> + <label> + ${w[0]} + </label> + ${w[1].get_html()} + %if w[0] == 'Comments': + <div class="toolParamHelp" style="clear: both;"> + Optional + </div> + %endif + </div> + %endfor + <div class="form-row"> + <input type="submit" name="add_event_button" value="Save"/> + </div> + </form> + </div> + </div> +%endif --- a/test/functional/test_forms_and_requests.py +++ b/test/functional/test_forms_and_requests.py @@ -189,7 +189,7 @@ class TestFormsAndRequests( TwillTestCas # Make sure the request_type is not accessible by regular_user2 since regular_user2 does not have Role1. self.logout() self.login( email=regular_user2.email ) - self.visit_url( '%s/requests/new?create=True&select_request_type=%i' % (self.url, request_type.id) ) + self.visit_url( '%s/requests_common/new?cntrller=requests&select_request_type=True' % self.url ) try: self.check_page_for_string( 'There are no request types created for a new request.' ) raise AssertionError, 'The request_type %s is accessible by %s when it should be restricted' % ( request_type.name, regular_user2.email ) @@ -304,12 +304,12 @@ class TestFormsAndRequests( TwillTestCas self.logout() self.login( email='test@bx.psu.edu' ) self.check_request_admin_grid(state=request_one.states.SUBMITTED, request_name=request_one.name) - self.visit_url( "%s/requests_admin/list?sort=-create_time&operation=show_request&id=%s" \ + self.visit_url( "%s/requests_admin/list?operation=show&id=%s" \ % ( self.url, self.security.encode_id( request_one.id ) )) self.check_page_for_string( 'Sequencing Request "%s"' % request_one.name ) # set bar codes for the samples bar_codes = [ '1234567890', '0987654321' ] - self.add_bar_codes( request_one.id, request_one.name, bar_codes ) + self.add_bar_codes( request_one.id, request_one.name, bar_codes, request_one.samples ) # change the states of all the samples of this request for sample in request_one.samples: self.change_sample_state( sample.name, sample.id, request_type.states[1].id, request_type.states[1].name ) @@ -328,11 +328,12 @@ class TestFormsAndRequests( TwillTestCas self.login( email='test@bx.psu.edu' ) request_name = "RequestTwo" # simulate request creation - url_str = '%s/requests_admin/new?create=True&create_request_button=Save&select_request_type=%i&select_user=%i&name=%s&library_id=%i&folder_id=%i&refresh=True&field_2=%s&field_0=%s&field_1=%i' \ - % ( self.url, request_type.id, regular_user.id, request_name, library_one.id, library_one.root_folder.id, "field_2_value", 'option1', user_address.id ) + url_str = '%s/requests_common/new?cntrller=requests_admin&create_request_button=Save&select_request_type=%i&select_user=%i&name=%s&refresh=True&field_2=%s&field_0=%s&field_1=%i' \ + % ( self.url, request_type.id, regular_user.id, request_name, "field_2_value", 'option1', user_address.id ) + print url_str self.home() self.visit_url( url_str ) - self.check_page_for_string( "The new request named %s has been created" % request_name ) + self.check_page_for_string( "The new request named <b>%s</b> has been created" % request_name ) global request_two request_two = sa_session.query( galaxy.model.Request ) \ .filter( and_( galaxy.model.Request.table.c.name==request_name, @@ -370,44 +371,44 @@ class TestFormsAndRequests( TwillTestCas # check if the request's state is now set to 'submitted' assert request_two.state is not request_two.states.REJECTED, "The state of the request '%s' should be set to '%s'" \ % ( request_two.name, request_two.states.REJECTED ) - def test_055_reset_data_for_later_test_runs( self ): - """Reseting data to enable later test runs to pass""" - # Logged in as admin_user - # remove the request_type permissions - rt_actions = sa_session.query( galaxy.model.RequestTypePermissions ) \ - .filter(and_(galaxy.model.RequestTypePermissions.table.c.request_type_id==request_type.id) ) \ - .order_by( desc( galaxy.model.RequestTypePermissions.table.c.create_time ) ) \ - .all() - for a in rt_actions: - sa_session.delete( a ) - sa_session.flush() - ################## - # Purge all libraries - ################## - for library in [ library_one ]: - self.delete_library_item( 'library_admin', - self.security.encode_id( library.id ), - self.security.encode_id( library.id ), - library.name, - item_type='library' ) - self.purge_library( self.security.encode_id( library.id ), library.name ) - ################## - # Eliminate all non-private roles - ################## - for role in [ role_one, role_two ]: - self.mark_role_deleted( self.security.encode_id( role.id ), role.name ) - self.purge_role( self.security.encode_id( role.id ), role.name ) - # Manually delete the role from the database - sa_session.refresh( role ) - sa_session.delete( role ) - sa_session.flush() - ################## - # Eliminate all groups - ################## - for group in [ group_one ]: - self.mark_group_deleted( self.security.encode_id( group.id ), group.name ) - self.purge_group( self.security.encode_id( group.id ), group.name ) - # Manually delete the group from the database - refresh( group ) - sa_session.delete( group ) - sa_session.flush() +# def test_055_reset_data_for_later_test_runs( self ): +# """Reseting data to enable later test runs to pass""" +# # Logged in as admin_user +# # remove the request_type permissions +# rt_actions = sa_session.query( galaxy.model.RequestTypePermissions ) \ +# .filter(and_(galaxy.model.RequestTypePermissions.table.c.request_type_id==request_type.id) ) \ +# .order_by( desc( galaxy.model.RequestTypePermissions.table.c.create_time ) ) \ +# .all() +# for a in rt_actions: +# sa_session.delete( a ) +# sa_session.flush() +# ################## +# # Purge all libraries +# ################## +# for library in [ library_one ]: +# self.delete_library_item( 'library_admin', +# self.security.encode_id( library.id ), +# self.security.encode_id( library.id ), +# library.name, +# item_type='library' ) +# self.purge_library( self.security.encode_id( library.id ), library.name ) +# ################## +# # Eliminate all non-private roles +# ################## +# for role in [ role_one, role_two ]: +# self.mark_role_deleted( self.security.encode_id( role.id ), role.name ) +# self.purge_role( self.security.encode_id( role.id ), role.name ) +# # Manually delete the role from the database +# sa_session.refresh( role ) +# sa_session.delete( role ) +# sa_session.flush() +# ################## +# # Eliminate all groups +# ################## +# for group in [ group_one ]: +# self.mark_group_deleted( self.security.encode_id( group.id ), group.name ) +# self.purge_group( self.security.encode_id( group.id ), group.name ) +# # Manually delete the group from the database +# refresh( group ) +# sa_session.delete( group ) +# sa_session.flush() --- a/templates/admin/requests/show_request.mako +++ /dev/null @@ -1,528 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> -<%namespace file="/requests/sample_state.mako" import="render_sample_state" /> -<%namespace file="/requests/sample_datasets.mako" import="render_sample_datasets" /> - -%if message: - ${render_msg( message, status )} -%endif - -<script type="text/javascript"> -$( function() { - $( "select[refresh_on_change='true']").change( function() { - var refresh = false; - var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' ) - if ( refresh_on_change_values ) { - refresh_on_change_values = refresh_on_change_values.value.split( ',' ); - var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' ); - for( i= 0; i < refresh_on_change_values.length; i++ ) { - if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){ - refresh = true; - break; - } - } - } - else { - refresh = true; - } - if ( refresh ){ - $( "#show_request" ).submit(); - } - }); -}); -</script> - - -<script type="text/javascript"> -$(document).ready(function(){ - //hide the all of the element with class msg_body - $(".msg_body").hide(); - //toggle the componenet with class msg_body - $(".msg_head").click(function(){ - $(this).next(".msg_body").slideToggle(450); - }); -}); -</script> - -<script type="text/javascript"> - // Looks for changes in sample states using an async request. Keeps - // calling itself (via setTimeout) until all samples are in a terminal - // state. - var updater = function ( sample_states ) { - // Check if there are any items left to track - var empty = true; - for ( i in sample_states ) { - empty = false; - break; - } - if ( ! empty ) { - setTimeout( function() { updater_callback( sample_states ) }, 1000 ); - } - }; - var updater_callback = function ( sample_states ) { - // Build request data - var ids = [] - var states = [] - $.each( sample_states, function ( id, state ) { - ids.push( id ); - states.push( state ); - }); - // Make ajax call - $.ajax( { - type: "POST", - url: "${h.url_for( controller='requests_admin', action='sample_state_updates' )}", - dataType: "json", - data: { ids: ids.join( "," ), states: states.join( "," ) }, - success : function ( data ) { - $.each( data, function( id, val ) { - // Replace HTML - var cell1 = $("#sampleState-" + id); - cell1.html( val.html_state ); - var cell2 = $("#sampleDatasets-" + id); - cell2.html( val.html_datasets ); - sample_states[ parseInt(id) ] = val.state; - }); - updater( sample_states ); - }, - error: function() { - // Just retry, like the old method, should try to be smarter - updater( sample_states ); - } - }); - }; -</script> - -<style type="text/css"> -.msg_head { - padding: 0px 0px; - cursor: pointer; -} -</style> - -<script type="text/javascript"> - function stopRKey(evt) { - var evt = (evt) ? evt : ((event) ? event : null); - var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null); - if ((evt.keyCode == 13) && (node.type=="text")) {return false;} - } - document.onkeypress = stopRKey -</script> - -%if request.submitted(): - <% samples_not_ready = request.sequence_run_ready() %> - %if samples_not_ready: - ${render_msg( "Select a target library and folder for all the samples before starting the sequence run", "warning" )} - %endif -%endif - -%if request.rejected(): - ${render_msg( "Reason for rejection: "+request.last_comment(), "warning" )} -%endif - -<div class="grid-header"> - <h2>Sequencing Request "${request.name}"</h2> -</div> - -<ul class="manage-table-actions"> - - %if request.unsubmitted() and request.samples: - <li> - <a class="action-button" confirm="More samples cannot be added to this request once it is submitted. Click OK to submit." href="${h.url_for( controller='requests_admin', action='list', operation='Submit', id=trans.security.encode_id(request.id) )}"> - <span>Submit request</span></a> - </li> - %endif - %if request.submitted(): - <li> - <a class="action-button" href="${h.url_for( controller='requests_admin', action='list', operation='Reject', id=trans.security.encode_id(request.id))}"> - <span>Reject request</span></a> - </li> - %endif - <li> - <a class="action-button" href="${h.url_for( controller='requests_admin', action='list', operation='events', id=trans.security.encode_id(request.id) )}"> - <span>History</span></a> - </li> - - -</ul> - -<%def name="show_basic_info_form( sample_index, sample, info )"> - <td> - <input type="text" name=sample_${sample_index}_name value="${info['name']}" size="10"/> - <div class="toolParamHelp" style="clear: both;"> - <i>${' (required)' }</i> - </div> - </td> - %if sample: - %if sample.request.unsubmitted(): - <td></td> - %else: - <td><input type="text" name=sample_${sample_index}_barcode value="${info['barcode']}" size="10"/></td> - %endif - %else: - <td></td> - %endif - %if sample: - %if sample.request.unsubmitted(): - <td>Unsubmitted</td> - %else: - <td><a href="${h.url_for( controller='requests_admin', action='show_events', sample_id=sample.id)}">${sample.current_state().name}</a></td> - %endif - %else: - <td></td> - %endif - <td>${info['lib_widget'].get_html()}</td> - <td>${info['folder_widget'].get_html()}</td> - %if request.submitted() or request.complete(): - %if sample: - <td><a href="${h.url_for( controller='requests_admin', action='show_datatx_page', sample_id=trans.security.encode_id(sample.id) )}">${len(sample.dataset_files)}</a></td> - %else: - <td><a href="${h.url_for( controller='requests_admin', action='show_datatx_page', sample_id=trans.security.encode_id(sample.id) )}">Add</a></td> - %endif - %endif -</%def> - -## This function displays the "Basic Information" grid -<%def name="render_basic_info_grid()"> - <h4>Sample Information</h4> - <table class="grid"> - <thead> - <tr> - <th>Name</th> - <th>Barcode</th> - <th>State</th> - <th>Data Library</th> - <th>Folder</th> - %if request.submitted() or request.complete(): - <th>Dataset(s) Transferred</th> - %endif - <th></th> - </tr> - <thead> - <tbody> - <% - trans.sa_session.refresh( request ) - %> - %for sample_index, info in enumerate(current_samples): - <% - if sample_index in range(len(request.samples)): - sample = request.samples[sample_index] - else: - sample = None - %> - %if edit_mode == 'True': - <tr> - ${show_basic_info_form( sample_index, sample, info )} - </tr> - %else: - <tr> - %if sample_index in range(len(request.samples)): - <td>${info['name']}</td> - <td>${info['barcode']}</td> - %if sample.request.unsubmitted(): - <td>Unsubmitted</td> - %else: - <td id="sampleState-${sample.id}">${render_sample_state( sample )}</td> - %endif - -## <td> -## %if sample: -## %if sample.request.unsubmitted(): -## Unsubmitted -## %else: -## <a href="${h.url_for( controller='requests_admin', action='show_events', sample_id=sample.id)}">${sample.current_state().name}</a> -## %endif -## %endif -## </td> - %if info['library']: - <td><a href="${h.url_for( controller='library_common', action='browse_library', cntrller='library', id=trans.security.encode_id( info['library'].id ) )}">${info['library'].name}</a></td> - %else: - <td></td> - %endif - %if info['folder']: - <td>${info['folder'].name}</td> - %else: - <td></td> - %endif - %if request.submitted() or request.complete(): - <td id="sampleDatasets-${sample.id}"> - ${render_sample_datasets( sample )} -## <a href="${h.url_for( controller='requests_admin', action='show_datatx_page', sample_id=trans.security.encode_id(sample.id) )}">${len(sample.dataset_files)}</a> - </td> - %endif - - - %else: - ${show_basic_info_form( sample_index, sample, info )} - %endif - %if request.unsubmitted() or request.rejected(): - <td> - %if sample: - %if sample.request.unsubmitted(): - <a class="action-button" href="${h.url_for( controller='requests_admin', action='delete_sample', request_id=request.id, sample_id=sample_index )}"> - <img src="${h.url_for('/static/images/delete_icon.png')}" /> - <span></span></a> - %endif - %endif - </td> - %endif - </tr> - %endif - %endfor - </tbody> - </table> -</%def> - -<%def name="render_sample_form( index, sample_name, sample_values, fields_dict )"> - <td> - ${sample_name} - </td> - %for field_index, field in fields_dict.items(): - <td> - %if field['type'] == 'TextField': - <input type="text" name="sample_${index}_field_${field_index}" value="${sample_values[field_index]}" size="7"/> - %elif field['type'] == 'SelectField': - <select name="sample_${index}_field_${field_index}" last_selected_value="2"> - %for option_index, option in enumerate(field['selectlist']): - %if option == sample_values[field_index]: - <option value="${option}" selected>${option}</option> - %else: - <option value="${option}">${option}</option> - %endif - %endfor - </select> - %elif field['type'] == 'WorkflowField': - <select name="sample_${index}_field_${field_index}"> - %if str(sample_values[field_index]) == 'none': - <option value="none" selected>Select one</option> - %else: - <option value="none">Select one</option> - %endif - %for option_index, option in enumerate(request.user.stored_workflows): - %if not option.deleted: - %if str(option.id) == str(sample_values[field_index]): - <option value="${option.id}" selected>${option.name}</option> - %else: - <option value="${option.id}">${option.name}</option> - %endif - %endif - %endfor - </select> - %elif field['type'] == 'CheckboxField': - <input type="checkbox" name="sample_${index}_field_${field_index}" value="Yes"/> - %endif - <div class="toolParamHelp" style="clear: both;"> - <i>${'('+field['required']+')' }</i> - </div> - </td> - %endfor -</%def> - -<%def name="render_sample( index, sample_name, sample_values, fields_dict )"> - <td> - ${sample_name} - </td> - %for field_index, field in fields_dict.items(): - <td> - %if sample_values[field_index]: - %if field['type'] == 'WorkflowField': - %if str(sample_values[field_index]) != 'none': - <% workflow = trans.sa_session.query( trans.app.model.StoredWorkflow ).get( int(sample_values[field_index]) ) %> - <a href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${workflow.name}</a> - %endif - %else: - ${sample_values[field_index]} - %endif - %else: - <i>None</i> - %endif - </td> - %endfor -</%def> - -<div class="toolForm"> - <div class="form-row"> - <div class="msg_list"> - <h4 class="msg_head"><u>Request Information</u></h4> - <div class="msg_body"> - %for index, rd in enumerate(request_details): - <div class="form-row"> - <label>${rd['label']}</label> - %if not rd['value']: - <i>None</i> - %else: - %if rd['label'] == 'State': - <a href="${h.url_for( controller='requests_admin', action='list', operation='events', id=trans.security.encode_id(request.id) )}">${rd['value']}</a> - %else: - ${rd['value']} - %endif - %endif - </div> - <div style="clear: both"></div> - %endfor - <div class="form-row"> - <ul class="manage-table-actions"> - <li> - <a class="action-button" href="${h.url_for( controller='requests_admin', action='list', operation='Edit', id=trans.security.encode_id(request.id))}"> - <span>Edit request details</span></a> - </li> - </ul> - </div> - </div> - </div> - </div> -</div> - -<br/> - - -<%def name="render_grid( grid_index, grid_name, fields_dict )"> - <br/> - <div class="msg_list"> - %if grid_name: - <h4 class="msg_head"><u>${grid_name}</u></h4> - %else: - <h4>Grid ${grid_index}</h4> - %endif - %if edit_mode == 'False' or len(current_samples) <= len(request.samples): - <div class="msg_body"> - %else: - <div class="msg_body2"> - %endif - <table class="grid"> - <thead> - <tr> - <th>Name</th> - %for index, field in fields_dict.items(): - <th> - ${field['label']} - <div class="toolParamHelp" style="clear: both;"> - <i>${field['helptext']}</i> - </div> - </th> - %endfor - <th></th> - </tr> - <thead> - <tbody> - <% - trans.sa_session.refresh( request ) - %> - %for sample_index, sample in enumerate(current_samples): - %if edit_mode == 'True': - <tr> - ${render_sample_form( sample_index, sample['name'], sample['field_values'], fields_dict)} - </tr> - %else: - <tr> - %if sample_index in range(len(request.samples)): - ${render_sample( sample_index, sample['name'], sample['field_values'], fields_dict )} - %else: - ${render_sample_form( sample_index, sample['name'], sample['field_values'], fields_dict)} - %endif - </tr> - %endif - %endfor - </tbody> - </table> - </div> - </div> -</%def> - -<div class="toolForm"> - ##<div class="toolFormTitle">Samples (${len(request.samples)})</div> - <form id="show_request" name="show_request" action="${h.url_for( controller='requests_admin', action='show_request', edit_mode=edit_mode )}" enctype="multipart/form-data" method="post" > - <div class="form-row"> - %if current_samples: - ## first render the basic info grid - ${render_basic_info_grid()} - ## then render the other grid(s) - <% trans.sa_session.refresh( request.type.sample_form ) %> - %for grid_index, grid_name in enumerate(request.type.sample_form.layout): - ${render_grid( grid_index, grid_name, request.type.sample_form.fields_of_grid( grid_index ) )} - <br/> - %endfor - %else: - <label>There are no samples.</label> - %endif - </div> - %if request.samples and request.submitted(): - <script type="text/javascript"> - // Updater - updater({${ ",".join( [ '"%s" : "%s"' % ( s.id, s.current_state().name ) for s in request.samples ] ) }}); - </script> - %endif - - %if edit_mode == 'False': - <table class="grid"> - <tbody> - <tr> - <div class="form-row"> - - %if request.unsubmitted(): - <td> - %if current_samples: - <label>Copy </label> - <input type="integer" name="num_sample_to_copy" value="1" size="3"/> - <label>sample(s) from sample</label> - ${sample_copy.get_html()} - %endif - <input type="submit" name="add_sample_button" value="Add New"/> - </td> - %endif - <td> - %if len(current_samples) and len(current_samples) <= len(request.samples): - <input type="submit" name="edit_samples_button" value="Edit samples"/> - %endif - </td> - </div> - </tr> - </tbody> - </table> - %endif - %if request.samples or current_samples: - <div class="form-row"> - <div style="float: left; width: 250px; margin-right: 10px;"> - <input type="hidden" name="refresh" value="true" size="40"/> - </div> - <div style="clear: both"></div> - </div> - %if edit_mode == 'True': - <div class="form-row"> - <input type="submit" name="save_samples_button" value="Save"/> - <input type="submit" name="cancel_changes_button" value="Cancel"/> - </div> - %elif request.unsubmitted(): - <div class="form-row"> - <input type="submit" name="save_samples_button" value="Save"/> - </div> - %endif - - %endif - <input type="hidden" name="request_id" value="${request.id}" /> - </form> -</div> - -<br/> - -%if request.unsubmitted(): -<div class="toolForm"> - <form id="show_request" name="show_request" action="${h.url_for( controller='requests_admin', action='show_request', edit_mode=edit_mode )}" enctype="multipart/form-data" method="post" > - <div class="form-row"> - <div class="msg_list"> - <h4 class="msg_head"><u>Import samples from csv file</u></h4> - <div class="msg_body"> - <input type="file" name="file_data" /> - <input type="submit" name="import_samples_button" value="Import samples"/> - <br/> - <div class="toolParamHelp" style="clear: both;"> - The csv file must be in the following format:<br/> - SampleName,DataLibrary,DataLibraryFolder,FieldValue1,FieldValue2... - </div> - </div> - </div> - </div> - <input type="hidden" name="request_id" value="${request.id}" /> - </form> -</div> -%endif - --- a/templates/admin/samples/events.mako +++ /dev/null @@ -1,63 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - -<%def name="title()">Events for Sample ${sample.name}</%def> - -<h2>Events for Sample "${sample.name}"</h2> -<ul class="manage-table-actions"> - <li> - <a class="action-button" href="${h.url_for( controller='requests_admin', action='list', operation='show_request', id=trans.security.encode_id(sample.request.id) )}"> - <span>Browse this request</span></a> - </li> -</ul> -<h3>User: ${sample.request.user.email}</h3> - -%if message: - ${render_msg( message, status )} -%endif - -<div class="toolForm"> - <table class="grid"> - <thead> - <tr> - <th>State</th> - <th>Description</th> - <th>Last Update</th> - <th>Comments</th> - </tr> - </thead> - <tbody> - %for state, desc, updated, comments in events_list: - <tr class="libraryRow libraryOrFolderRow" id="libraryRow"> - <td><b><a>${state}</a></b></td> - <td><a>${desc}</a></td> - <td><a>${updated}</a></td> - <td><a>${comments}</a></td> - </tr> - %endfor - </tbody> - </table> -</div> -<div class="toolForm"> - <div class="toolFormTitle">Change current state</div> - <div class="toolFormBody"> - <form name="event" action="${h.url_for( controller='requests_admin', action='save_state', new=True, sample_id=sample.id)}" method="post" > - %for w in widgets: - <div class="form-row"> - <label> - ${w[0]} - </label> - ${w[1].get_html()} - %if w[0] == 'Comments': - <div class="toolParamHelp" style="clear: both;"> - Optional - </div> - %endif - </div> - %endfor - <div class="form-row"> - <input type="submit" name="add_event_button" value="Save"/> - </div> - </form> - </div> -</div> --- a/scripts/galaxy_messaging/server/data_transfer.py +++ b/scripts/galaxy_messaging/server/data_transfer.py @@ -194,7 +194,7 @@ class DataTransfer(object): Update the data transfer status for this dataset in the database ''' try: - log.debug('Setting status "%s" for dataset "%s"' % ( status, str(dataset_index) ) ) + log.debug('Setting status "%s" for dataset "%s" of sample "%s"' % ( status, str(dataset_index), str(self.sample_id) ) ) df = from_json_string(self.galaxydb.get_sample_dataset_files(self.sample_id)) if dataset_index == 'All': for dataset in self.dataset_files: --- a/scripts/galaxy_messaging/server/galaxydb_interface.py +++ b/scripts/galaxy_messaging/server/galaxydb_interface.py @@ -28,7 +28,7 @@ class GalaxyDbInterface(object): def __init__(self, dbstr): self.dbstr = dbstr self.db_engine = create_engine(self.dbstr) -# self.db_engine.echo = True + self.db_engine.echo = True self.metadata = MetaData(self.db_engine) self.session = sessionmaker(bind=self.db_engine) self.event_table = Table('sample_event', self.metadata, autoload=True ) --- a/templates/requests/sample_state.mako +++ /dev/null @@ -1,5 +0,0 @@ -<%def name="render_sample_state( sample )"> - <a href="${h.url_for( controller='requests_admin', action='show_events', sample_id=sample.id)}">${sample.current_state().name}</a> -</%def> - -${render_sample_state( sample )} --- a/templates/admin/requests/dataset.mako +++ b/templates/admin/requests/dataset.mako @@ -11,7 +11,7 @@ <ul class="manage-table-actions"><li> - <a class="action-button" href="${h.url_for( controller='requests_admin', action='show_datatx_page', sample_id=trans.security.encode_id(sample.id) )}"> + <a class="action-button" href="${h.url_for( controller='requests_common', action='show_datatx_page', cntrller='requests_admin', sample_id=trans.security.encode_id(sample.id) )}"><span>Dataset transfer page</span></a></li></ul> --- a/templates/admin/samples/bar_codes.mako +++ /dev/null @@ -1,46 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - - -%if message: - ${render_msg( message, status )} -%endif - - -<h2>Bar codes for Samples of Request "${request.name}"</h2> -<h3>User: ${user.email}</h3> - -<ul class="manage-table-actions"> - <li> - <a class="action-button" href="${h.url_for( controller='requests_admin', action='list', operation='show_request', id=trans.security.encode_id(request.id) )}"> - <span>Browse this request</span></a> - </li> -</ul> - -<div class="toolForm"> - <form name="bar_codes" action="${h.url_for( controller='requests_admin', action='save_bar_codes', request_id=request.id)}" method="post" > - <table class="grid"> - <thead> - <tr> - <th>Name</th> - <th>Description</th> - <th>Bar code</th> - </tr> - </thead> - <tbody> - %for index, sample in enumerate(samples_list): - <tr class="libraryRow libraryOrFolderRow" id="libraryRow"> - <td><b><a>${sample.name}</a></b></td> - <td><a>${sample.desc}</a></td> - <td> - ${widgets[index].get_html()} - </td> - </tr> - %endfor - </tbody> - </table> - <div class="form-row"> - <input type="submit" name="save_bar_codes" value="Save"/> - </div> - </form> -</div> --- a/templates/requests/edit_request.mako +++ /dev/null @@ -1,84 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - -%if message: - ${render_msg( message, status )} -%endif - -<script type="text/javascript"> -$( function() { - $( "select[refresh_on_change='true']").change( function() { - var refresh = false; - var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' ) - if ( refresh_on_change_values ) { - refresh_on_change_values = refresh_on_change_values.value.split( ',' ); - var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' ); - for( i= 0; i < refresh_on_change_values.length; i++ ) { - if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){ - refresh = true; - break; - } - } - } - else { - refresh = true; - } - if ( refresh ){ - $( "#edit_request" ).submit(); - } - }); -}); -</script> - -<br/> -<br/> -<ul class="manage-table-actions"> - <li> - <a class="action-button" href="${h.url_for( controller='requests', action='list')}"> - <span>Browse requests</span></a> - </li> -</ul> - -<div class="toolForm"> - <div class="toolFormTitle">Edit request "${request.name}"</div> - %if len(select_request_type.options) == 1: - There are no request types created for a new request. - %else: - <div class="toolFormBody"> - <form name="edit_request" id="edit_request" action="${h.url_for( controller='requests', action='edit', request_id=request.id)}" method="post" > - <div class="form-row"> - <label> - Select Request Type: - </label> - ${select_request_type.get_html()} - </div> - - %if select_request_type.get_selected() != ('Select one', 'none'): - %for i, field in enumerate(widgets): - <div class="form-row"> - <label>${field['label']}</label> - ${field['widget'].get_html()} - %if field['label'] == 'Data library' and new_library: - ${new_library.get_html()} - %endif - <div class="toolParamHelp" style="clear: both;"> - ${field['helptext']} - </div> - <div style="clear: both"></div> - </div> - %endfor - <div class="form-row"> - <div style="float: left; width: 250px; margin-right: 10px;"> - <input type="hidden" name="refresh" value="true" size="40"/> - </div> - <div style="clear: both"></div> - </div> - <div class="form-row"> - <input type="submit" name="save_changes_request_button" value="Save changes"/> - ##<input type="submit" name="edit_samples_button" value="Edit samples"/> - </div> - %endif - </form> - </div> -</div> -%endif --- a/templates/requests/new_request.mako +++ /dev/null @@ -1,94 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - -%if message: - ${render_msg( message, status )} -%endif - -<script type="text/javascript"> -$( function() { - $( "select[refresh_on_change='true']").change( function() { - var refresh = false; - var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' ) - if ( refresh_on_change_values ) { - refresh_on_change_values = refresh_on_change_values.value.split( ',' ); - var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' ); - for( i= 0; i < refresh_on_change_values.length; i++ ) { - if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){ - refresh = true; - break; - } - } - } - else { - refresh = true; - } - if ( refresh ){ - $( "#new_request" ).submit(); - } - }); -}); -</script> - -<%def name="javascripts()"> - ${parent.javascripts()} - ${h.js("jquery.autocomplete", "autocomplete_tagging" )} -</%def> - -<%def name="stylesheets()"> - ${parent.stylesheets()} - ${h.css( "autocomplete_tagging" )} -</%def> - -<br/> -<br/> -<ul class="manage-table-actions"> - <li> - <a class="action-button" href="${h.url_for( controller='requests', action='list')}"> - <span>Browse requests</span></a> - </li> -</ul> - -<div class="toolForm"> - <div class="toolFormTitle">Add a new request</div> - %if len(select_request_type.options) == 1: - There are no request types created for a new request. - %else: - <div class="toolFormBody"> - <form name="new_request" id="new_request" action="${h.url_for( controller='requests', action='new', create=True )}" method="post" > - <div class="form-row"> - <label> - Select Request Type: - </label> - ${select_request_type.get_html()} - </div> - - %if select_request_type.get_selected() != ('Select one', 'none'): - %for i, field in enumerate(widgets): - <div class="form-row"> - <label>${field['label']}</label> - ${field['widget'].get_html()} - ##%if field['label'] == 'Data library' and new_library: - ## ${new_library.get_html()} - ##%endif - <div class="toolParamHelp" style="clear: both;"> - ${field['helptext']} - </div> - <div style="clear: both"></div> - </div> - %endfor - <div class="form-row"> - <div style="float: left; width: 250px; margin-right: 10px;"> - <input type="hidden" name="refresh" value="true" size="40"/> - </div> - <div style="clear: both"></div> - </div> - <div class="form-row"> - <input type="submit" name="create_request_button" value="Save"/> - <input type="submit" name="create_request_samples_button" value="Add samples"/> - </div> - %endif - </form> - </div> -</div> -%endif --- /dev/null +++ b/templates/requests/common/index.mako @@ -0,0 +1,16 @@ +<%inherit file="/webapps/galaxy/base_panels.mako"/> + +<%def name="init()"> +<% + self.has_left_panel=False + self.has_right_panel=False + self.active_view="requests" + self.message_box_visible=False +%> +</%def> + +<%def name="center_panel()"> + + <iframe name="galaxy_main" id="galaxy_main" frameborder="0" style="position: absolute; width: 100%; height: 100%;" src="${h.url_for( controller="requests", action="list" )}"></iframe> + +</%def> --- a/templates/sample/index.mako +++ /dev/null @@ -1,16 +0,0 @@ -<%inherit file="/webapps/galaxy/base_panels.mako"/> - -<%def name="init()"> -<% - self.has_left_panel=False - self.has_right_panel=False - self.active_view="requests" - -%> -</%def> - -<%def name="center_panel()"> - - <iframe name="galaxy_main" id="galaxy_main" frameborder="0" style="position: absolute; width: 100%; height: 100%;" src="${h.url_for( controller="sample", action="list", request_id=request_id )}"></iframe> - -</%def> --- a/templates/requests/show_request.mako +++ /dev/null @@ -1,430 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - - -%if message: - ${render_msg( message, status )} -%endif - -<script type="text/javascript"> -$( function() { - $( "select[refresh_on_change='true']").change( function() { - var refresh = false; - var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' ) - if ( refresh_on_change_values ) { - refresh_on_change_values = refresh_on_change_values.value.split( ',' ); - var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' ); - for( i= 0; i < refresh_on_change_values.length; i++ ) { - if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){ - refresh = true; - break; - } - } - } - else { - refresh = true; - } - if ( refresh ){ - $( "#show_request" ).submit(); - } - }); -}); -</script> - - -<script type="text/javascript"> -$(document).ready(function(){ - //hide the all of the element with class msg_body - $(".msg_body").hide(); - //toggle the componenet with class msg_body - $(".msg_head").click(function(){ - $(this).next(".msg_body").slideToggle(450); - }); -}); -</script> -<style type="text/css"> -.msg_head { - padding: 0px 0px; - cursor: pointer; -} - -} -</style> - -%if request.rejected(): - ${render_msg( "Reason for rejection: "+request.last_comment(), "warning" )} -%endif - -<div class="grid-header"> - <h2>Sequencing Request "${request.name}"</h2> -</div> - -<ul class="manage-table-actions"> - %if request.unsubmitted() and request.samples: - <li> - <a class="action-button" confirm="More samples cannot be added to this request once it is submitted. Click OK to submit." href="${h.url_for( controller='requests', action='list', operation='Submit', id=trans.security.encode_id(request.id) )}"> - <span>Submit request</span></a> - </li> - %endif - <li> - <a class="action-button" href="${h.url_for( controller='requests', action='list', operation='events', id=trans.security.encode_id(request.id) )}"> - <span>History</span></a> - </li> - <li> - <a class="action-button" href="${h.url_for( controller='requests', action='list')}"> - <span>Browse requests</span></a> - </li> -</ul> - -<%def name="show_basic_info_form( sample_index, sample, info )"> - <td> - <input type="text" name=sample_${sample_index}_name value="${info['name']}" size="10"/> - <div class="toolParamHelp" style="clear: both;"> - <i>${' (required)' }</i> - </div> - </td> - %if sample: - %if sample.request.unsubmitted(): - <td></td> - %else: - <td><input type="text" name=sample_${sample_index}_barcode value="${info['barcode']}" size="10"/></td> - %endif - %else: - <td></td> - %endif - %if sample: - %if not sample.current_state(): - <td>Unsubmitted</td> - %else: - <td><a href="${h.url_for( controller='requests_admin', action='show_events', sample_id=sample.id)}">${sample.current_state().name}</a></td> - %endif - %else: - <td></td> - %endif - <td>${info['lib_widget'].get_html()}</td> - <td>${info['folder_widget'].get_html()}</td> - %if request.submitted() or request.complete(): - %if sample: - <td><a href="${h.url_for( controller='requests_admin', action='show_datatx_page', sample_id=trans.security.encode_id(sample.id) )}">${len(sample.dataset_files)}</a></td> - %else: - <td><a href="${h.url_for( controller='requests_admin', action='show_datatx_page', sample_id=trans.security.encode_id(sample.id) )}">Add</a></td> - %endif - %endif -</%def> - -## This function displays the "Basic Information" grid -<%def name="render_basic_info_grid()"> - <h4>Sample Information</h4> - <table class="grid"> - <thead> - <tr> - <th>Name</th> - <th>Barcode</th> - <th>State</th> - <th>Data Library</th> - <th>Folder</th> - %if request.submitted() or request.complete(): - <th>Dataset(s) Transferred</th> - %endif - <th></th> - </tr> - <thead> - <tbody> - <% - trans.sa_session.refresh( request ) - %> - %for sample_index, info in enumerate(current_samples): - <% - if sample_index in range(len(request.samples)): - sample = request.samples[sample_index] - else: - sample = None - %> - %if edit_mode == 'True': - <tr> - ${show_basic_info_form( sample_index, sample, info )} - </tr> - %else: - <tr> - %if sample_index in range(len(request.samples)): - <td>${info['name']}</td> - <td>${info['barcode']}</td> - <td> - %if sample.current_state(): - <a href="${h.url_for( controller='requests', action='show_events', sample_id=sample.id)}">${sample.current_state().name}</a> - %else: - Unsubmitted - %endif - </td> - %if info['library']: - <td><a href="${h.url_for( controller='library_common', action='browse_library', cntrller='library', id=trans.security.encode_id( info['library'].id ) )}">${info['library'].name}</a></td> - %else: - <td></td> - %endif - %if info['folder']: - <td>${info['folder'].name}</td> - %else: - <td></td> - %endif - %if request.submitted() or request.complete(): - <td> - <a href="${h.url_for( controller='requests', action='show_datatx_page', sample_id=trans.security.encode_id(sample.id) )}">${len(sample.dataset_files)}</a> - </td> - %endif - - - %else: - ${show_basic_info_form( sample_index, sample, info )} - %endif - %if request.unsubmitted() or request.rejected(): - <td> - %if sample: - %if sample.request.unsubmitted(): - <a class="action-button" href="${h.url_for( controller='requests_admin', action='delete_sample', request_id=request.id, sample_id=sample_index )}"> - <img src="${h.url_for('/static/images/delete_icon.png')}" /> - <span></span></a> - %endif - %endif - </td> - %endif - </tr> - %endif - %endfor - </tbody> - </table> -</%def> - -<%def name="render_sample_form( index, sample_name, sample_values, fields_dict )"> - <td> - ${sample_name} - </td> - %for field_index, field in fields_dict.items(): - <td> - %if field['type'] == 'TextField': - <input type="text" name="sample_${index}_field_${field_index}" value="${sample_values[field_index]}" size="7"/> - %elif field['type'] == 'SelectField': - <select name="sample_${index}_field_${field_index}" last_selected_value="2"> - %for option_index, option in enumerate(field['selectlist']): - %if option == sample_values[field_index]: - <option value="${option}" selected>${option}</option> - %else: - <option value="${option}">${option}</option> - %endif - %endfor - </select> - %elif field['type'] == 'WorkflowField': - <select name="sample_${index}_field_${field_index}"> - %if str(sample_values[field_index]) == 'none': - <option value="none" selected>Select one</option> - %else: - <option value="none">Select one</option> - %endif - %for option_index, option in enumerate(request.user.stored_workflows): - %if not option.deleted: - %if str(option.id) == str(sample_values[field_index]): - <option value="${option.id}" selected>${option.name}</option> - %else: - <option value="${option.id}">${option.name}</option> - %endif - %endif - %endfor - </select> - %elif field['type'] == 'CheckboxField': - <input type="checkbox" name="sample_${index}_field_${field_index}" value="Yes"/> - %endif - <div class="toolParamHelp" style="clear: both;"> - <i>${'('+field['required']+')' }</i> - </div> - </td> - %endfor -</%def> - -<%def name="render_sample( index, sample_name, sample_values, fields_dict )"> - <td> - ${sample_name} - </td> - %for field_index, field in fields_dict.items(): - <td> - %if sample_values[field_index]: - %if field['type'] == 'WorkflowField': - %if str(sample_values[field_index]) != 'none': - <% workflow = trans.sa_session.query( trans.app.model.StoredWorkflow ).get( int(sample_values[field_index]) ) %> - <a href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${workflow.name}</a> - %endif - %else: - ${sample_values[field_index]} - %endif - %else: - <i>None</i> - %endif - - </td> - %endfor -</%def> - -<%def name="render_grid( grid_index, grid_name, fields_dict )"> - <br/> - <div class="msg_list"> - %if grid_name: - <h4 class="msg_head"><u>${grid_name}</u></h4> - %else: - <h4>Grid ${grid_index}</h4> - %endif - %if edit_mode == 'False' or len(current_samples) <= len(request.samples): - <div class="msg_body"> - %else: - <div class="msg_body2"> - %endif - <table class="grid"> - <thead> - <tr> - <th>Name</th> - %for index, field in fields_dict.items(): - <th> - ${field['label']} - <div class="toolParamHelp" style="clear: both;"> - <i>${field['helptext']}</i> - </div> - </th> - %endfor - <th></th> - </tr> - <thead> - <tbody> - <% - trans.sa_session.refresh( request ) - %> - %for sample_index, sample in enumerate(current_samples): - %if edit_mode == 'True': - <tr> - ${render_sample_form( sample_index, sample['name'], sample['field_values'], fields_dict)} - </tr> - %else: - <tr> - %if sample_index in range(len(request.samples)): - ${render_sample( sample_index, sample['name'], sample['field_values'], fields_dict )} - %else: - ${render_sample_form( sample_index, sample['name'], sample['field_values'], fields_dict)} - %endif - </tr> - %endif - %endfor - </tbody> - </table> - </div> - </div> -</%def> - -<div class="toolForm"> - <form id="request_details" name="request_details" > - <div class="form-row"> - <div class="msg_list"> - <h4 class="msg_head"><u>Request Information</u></h4> - <div class="msg_body"> - %for index, rd in enumerate(request_details): - <div class="form-row"> - <label>${rd['label']}</label> - %if not rd['value']: - <i>None</i> - %else: - %if rd['label'] == 'State': - <a href="${h.url_for( controller='requests_admin', action='list', operation='events', id=trans.security.encode_id(request.id) )}">${rd['value']}</a> - %else: - ${rd['value']} - %endif - %endif - </div> - <div style="clear: both"></div> - %endfor - <div class="form-row"> - <ul class="manage-table-actions"> - <li> - <a class="action-button" href="${h.url_for( controller='requests_admin', action='list', operation='Edit', id=trans.security.encode_id(request.id))}"> - <span>Edit request details</span></a> - </li> - </ul> - </div> - </div> - </div> - </div> - </form> - <form id="show_request" name="show_request" action="${h.url_for( controller='requests', action='show_request', edit_mode=edit_mode )}" enctype="multipart/form-data" method="post" > - <div class="form-row"> - %if current_samples: - ## first render the basic info grid - ${render_basic_info_grid()} - ## then render the other grid(s) - <% trans.sa_session.refresh( request.type.sample_form ) %> - %for grid_index, grid_name in enumerate(request.type.sample_form.layout): - ${render_grid( grid_index, grid_name, request.type.sample_form.fields_of_grid( grid_index ) )} - <br/> - %endfor - %else: - <label>There are no samples.</label> - %endif - </div> - %if request.unsubmitted() and edit_mode == 'False': - <table class="grid"> - <tbody> - <tr> - <div class="form-row"> - <td> - %if current_samples: - <label>Copy </label> - <input type="integer" name="num_sample_to_copy" value="1" size="3"/> - <label>sample(s) from sample</label> - ${sample_copy.get_html()} - %endif - <input type="submit" name="add_sample_button" value="Add New"/> - </td> - <td> - %if len(current_samples) and len(current_samples) <= len(request.samples): - <input type="submit" name="edit_samples_button" value="Edit samples"/> - %endif - </td> - </div> - </tr> - </tbody> - </table> - %endif - %if request.unsubmitted() and (request.samples or current_samples): - <div class="form-row"> - <div style="float: left; width: 250px; margin-right: 10px;"> - <input type="hidden" name="refresh" value="true" size="40"/> - </div> - <div style="clear: both"></div> - </div> - <div class="form-row"> - <input type="submit" name="save_samples_button" value="Save"/> - %if edit_mode == 'True': - <input type="submit" name="cancel_changes_button" value="Cancel"/> - %endif - </div> - %endif - <input type="hidden" name="request_id" value="${request.id}" /> - </form> -</div> - - -<br/> -%if request.unsubmitted(): -<div class="toolForm"> - <form id="show_request" name="show_request" action="${h.url_for( controller='requests', action='show_request', edit_mode=edit_mode )}" enctype="multipart/form-data" method="post" > - <div class="form-row"> - <div class="msg_list"> - <h4 class="msg_head"><u>Import samples from csv file</u></h4> - <div class="msg_body"> - <input type="file" name="file_data" /> - <input type="submit" name="import_samples_button" value="Import samples"/> - <br/> - <div class="toolParamHelp" style="clear: both;"> - The csv file must be in the following format:<br/> - SampleName,DataLibrary,DataLibraryFolder,FieldValue1,FieldValue2... - </div> - </div> - </div> - </div> - <input type="hidden" name="request_id" value="${request.id}" /> - </form> -</div> -%endif --- /dev/null +++ b/templates/requests/common/new_request.mako @@ -0,0 +1,91 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + +%if message: + ${render_msg( message, status )} +%endif + +<script type="text/javascript"> +$( function() { + $( "select[refresh_on_change='true']").change( function() { + var refresh = false; + var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' ) + if ( refresh_on_change_values ) { + refresh_on_change_values = refresh_on_change_values.value.split( ',' ); + var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' ); + for( i= 0; i < refresh_on_change_values.length; i++ ) { + if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){ + refresh = true; + break; + } + } + } + else { + refresh = true; + } + if ( refresh ){ + $( "#new_request" ).submit(); + } + }); +}); +</script> + +<%def name="javascripts()"> + ${parent.javascripts()} + ${h.js("jquery.autocomplete", "autocomplete_tagging" )} +</%def> + +<%def name="stylesheets()"> + ${parent.stylesheets()} + ${h.css( "autocomplete_tagging" )} +</%def> + +<br/> +<br/> +<ul class="manage-table-actions"> + <li> + <a class="action-button" href="${h.url_for( controller=cntrller, cntrller=cntrller, action='list')}"> + <span>Browse requests</span></a> + </li> +</ul> + +<div class="toolForm"> + <div class="toolFormTitle">Add a new request</div> + %if len(select_request_type.options) == 1: + There are no request types created for a new request. + %else: + <div class="toolFormBody"> + <form name="new_request" id="new_request" action="${h.url_for( controller='requests_common', action='new', cntrller=cntrller)}" method="post" > + <div class="form-row"> + <label> + Select request type + </label> + ${select_request_type.get_html()} + </div> + + %if select_request_type.get_selected() != ('Select one', 'none'): + %for i, field in enumerate(widgets): + <div class="form-row"> + <label>${field['label']}</label> + ${field['widget'].get_html()} + <div class="toolParamHelp" style="clear: both;"> + ${field['helptext']} + </div> + <div style="clear: both"></div> + </div> + %endfor + <div class="form-row"> + <input type="submit" name="create_request_button" value="Save"/> + <input type="submit" name="create_request_samples_button" value="Add samples"/> + </div> + %endif + <div class="form-row"> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="hidden" name="refresh" value="true" size="40"/> + </div> + <div style="clear: both"></div> + </div> + </form> + </div> +</div> +%endif --- a/templates/admin/requests/get_data.mako +++ /dev/null @@ -1,227 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - - -%if message: - ${render_msg( message, status )} -%endif - -<script type="text/javascript"> -$(document).ready(function(){ - //hide the all of the element with class msg_body - $(".msg_body").hide(); - //toggle the componenet with class msg_body - $(".msg_head").click(function(){ - $(this).next(".msg_body").slideToggle(450); - }); -}); - - - - -</script> - -<script type="text/javascript"> - function display_file_details(sample_id, folder_path) - { - var w = document.get_data.files_list.selectedIndex; - var selected_value = document.get_data.files_list.options[w].value; - var cell = $("#file_details"); - if(selected_value.charAt(selected_value.length-1) != '/') - { - // Make ajax call - $.ajax( { - type: "POST", - url: "${h.url_for( controller='requests_admin', action='get_file_details' )}", - dataType: "json", - data: { id: sample_id, folder_path: document.get_data.folder_path.value+selected_value }, - success : function ( data ) { - cell.html( '<label>'+data+'</label>' ) - } - }); - } - else - { - cell.html( '' ) - } - - - } -</script> - -<script type="text/javascript"> - function open_folder1(sample_id, folder_path) - { - var w = document.get_data.files_list.selectedIndex; - var selected_value = document.get_data.files_list.options[w].value; - var cell = $("#file_details"); - if(selected_value.charAt(selected_value.length-1) == '/') - { - document.get_data.folder_path.value = document.get_data.folder_path.value+selected_value - // Make ajax call - $.ajax( { - type: "POST", - url: "${h.url_for( controller='requests_admin', action='open_folder' )}", - dataType: "json", - data: { id: sample_id, folder_path: document.get_data.folder_path.value }, - success : function ( data ) { - document.get_data.files_list.options.length = 0 - for(i=0; i<data.length; i++) - { - var newOpt = new Option(data[i], data[i]); - document.get_data.files_list.options[i] = newOpt; - } - //cell.html( '<label>'+data+'</label>' ) - - } - }); - } - else - { - cell.html( '' ) - } - } -</script> - - -<style type="text/css"> -.msg_head { - padding: 0px 0px; - cursor: pointer; -} - -} -</style> - - -<h2>Data transfer from Sequencer</h2> -<h3>Sample "${sample.name}" of Request "${sample.request.name}"</h3> -<br/> -<br/> - -<ul class="manage-table-actions"> - %if sample.request.submitted() and sample.inprogress_dataset_files(): - <li> - <a class="action-button" href="${h.url_for( controller='requests_admin', action='show_datatx_page', sample_id=trans.security.encode_id(sample.id) )}"> - <span>Refresh this page</span></a> - </li> - %endif - <li> - <a class="action-button" href="${h.url_for( controller='requests_admin', action='manage_request_types', operation='view', id=trans.security.encode_id(sample.request.type.id) )}"> - <span>Sequencer information</span></a> - </li> - <li> - <a class="action-button" href="${h.url_for( controller='library_common', action='browse_library', cntrller='library_admin', id=trans.security.encode_id( sample.library.id ) )}"> - <span>${sample.library.name} Data Library</span></a> - </li> - <li> - <a class="action-button" href="${h.url_for( controller='requests_admin', action='list', operation='show_request', id=trans.security.encode_id(sample.request.id) )}"> - <span>Browse this request</span></a> - </li> -</ul> - -<div class="toolForm"> - %if len(dataset_files): -## <form name="get_data" action="${h.url_for( controller='requests_admin', action='get_data', sample_id=sample.id)}" method="post" > - <div class="form-row"> - <h4>Sample Dataset(s)</h4> - %if sample.untransferred_dataset_files(): - <div class="form-row"> - <ul class="manage-table-actions"> - <li> - <a class="action-button" href="${h.url_for( controller='requests_admin', action='get_data', start_transfer_button=True, sample_id=sample.id )}"> - <span>Start transfer</span></a> - </li> - </ul> - </div> - %endif - <div class="form-row"> - <table class="grid"> - <thead> - <tr> - <th>Dataset File</th> - <th>Transfer Status</th> - <th></th> - </tr> - <thead> - <tbody> - %for dataset_index, dataset_file in enumerate(dataset_files): - ${sample_dataset_files( dataset_index, dataset_file['name'], dataset_file['status'] )} - %endfor - </tbody> - </table> - </div> - </div> - -## </form> -##</div> - - -<br/> -<br/> -%endif - -##<div class="toolForm"> - <form name="get_data" id="get_data" action="${h.url_for( controller='requests_admin', action='get_data', sample_id=sample.id)}" method="post" > - <div class="form-row"> - ##<div class="toolFormTitle">Select files for transfer</div> - <h4>Select files for transfer</h4> - <div style="width: 60%;"> - <div class="form-row"> - <label>Folder path on the sequencer:</label> - <input type="text" name="folder_path" value="${folder_path}" size="100"/> - <input type="submit" name="browse_button" value="List contents"/> - ##<input type="submit" name="open_folder" value="Open folder"/> - <input type="submit" name="folder_up" value="Up"/> - </div> - <div class="form-row"> - <select name="files_list" id="files_list" style="max-width: 98%; width: 98%; height: 150px; font-size: 100%;" ondblclick="open_folder1(${sample.id}, '${folder_path}')" onChange="display_file_details(${sample.id}, '${folder_path}')" multiple> - %for index, f in enumerate(files): - <option value="${f}">${f}</option> - %endfor - </select> - <br/> - <div id="file_details" class="toolParamHelp" style="clear: both;"> - - </div> - </div> - <div class="form-row"> - <div class="toolParamHelp" style="clear: both;"> - After selecting dataset(s), be sure to click on the <b>Start transfer</b> button. - Once the transfer is complete the dataset(s) will show up on this page. - </div> - <input type="submit" name="select_files_button" value="Select"/> - </div> - </div> - </div> - </form> -</div> - -<%def name="sample_dataset_files( dataset_index, dataset_name, status )"> - <tr> - <td> - <label class="msg_head"><a href="${h.url_for( controller='requests_admin', action='dataset_details', sample_id=trans.security.encode_id(sample.id), dataset_index=dataset_index )}">${dataset_name}</a></label> -## <div class="msg_head"><u>${dataset_file.split('/')[-1]}</u></div> -## <div class="msg_body"> -## ${dataset_file} -## </div> - </td> - <td> - %if status not in [sample.transfer_status.NOT_STARTED, sample.transfer_status.COMPLETE]: - <i>${status}</i> - %else: - ${status} - %endif - </td> - ##<td></td> - %if status == sample.transfer_status.NOT_STARTED: - <td> - <a class="action-button" href="${h.url_for( controller='requests_admin', action='get_data', sample_id=sample.id, remove_dataset_button=True, dataset_index=dataset_index )}"> - <img src="${h.url_for('/static/images/delete_icon.png')}" /> - <span></span></a> - </td> - %else: - <td></td> - %endif - </tr> -</%def> --- a/templates/admin/requests/add_states.mako +++ /dev/null @@ -1,26 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - -%if message: - ${render_msg( message, status )} -%endif - -<div class="toolForm"> - <div class="toolFormTitle">Create ${num_states} states for the '${request_type_name}' request type</div> - <form name="new_form_fields" action="${h.url_for( controller='requests_admin', action='request_type', name=request_type_name, description=desc, num_states=num_states, request_form_id=request_form_id, sample_form_id=sample_form_id)}" method="post" > - <div class="toolFormBody"> - %for element_count in range( num_states ): - <div class="form-row"> - <label>${1+element_count}) State name:</label> - <input type="text" name="state_name_${element_count}" value="" size="40"/> - <label>State help text (optional):</label> - <input type="text" name="state_desc_${element_count}" value="" size="40"/> - </div> - <div style="clear: both"></div> - %endfor - </div> - <div class="form-row"> - <input type="submit" name="save_request_type" value="Save"/> - </div> - </form> -</div> --- /dev/null +++ b/templates/requests/common/edit_request.mako @@ -0,0 +1,84 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + +%if message: + ${render_msg( message, status )} +%endif + +<script type="text/javascript"> +$( function() { + $( "select[refresh_on_change='true']").change( function() { + var refresh = false; + var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' ) + if ( refresh_on_change_values ) { + refresh_on_change_values = refresh_on_change_values.value.split( ',' ); + var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' ); + for( i= 0; i < refresh_on_change_values.length; i++ ) { + if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){ + refresh = true; + break; + } + } + } + else { + refresh = true; + } + if ( refresh ){ + $( "#edit_request" ).submit(); + } + }); +}); +</script> + +<br/> +<br/> +<ul class="manage-table-actions"> + <li> + <a class="action-button" href="${h.url_for( controller=cntrller, cntrller=cntrller, action='list')}"> + <span>Browse requests</span></a> + </li> +</ul> + +<div class="toolForm"> + <div class="toolFormTitle">Edit request "${request.name}"</div> + %if len(select_request_type.options) == 1: + There are no request types created for a new request. + %else: + <div class="toolFormBody"> + <form name="edit_request" id="edit_request" action="${h.url_for( controller='requests_common', cntrller=cntrller, action='edit', id=trans.security.encode_id(request.id))}" method="post" > + <div class="form-row"> + <label> + Select Request Type: + </label> + ${select_request_type.get_html()} + </div> + + %if select_request_type.get_selected() != ('Select one', 'none'): + %for i, field in enumerate(widgets): + <div class="form-row"> + <label>${field['label']}</label> + ${field['widget'].get_html()} + %if field['label'] == 'Data library' and new_library: + ${new_library.get_html()} + %endif + <div class="toolParamHelp" style="clear: both;"> + ${field['helptext']} + </div> + <div style="clear: both"></div> + </div> + %endfor + <div class="form-row"> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="hidden" name="refresh" value="true" size="40"/> + </div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <input type="submit" name="save_changes_request_button" value="Save changes"/> + ##<input type="submit" name="edit_samples_button" value="Edit samples"/> + </div> + %endif + </form> + </div> +</div> +%endif --- a/lib/galaxy/web/controllers/requests.py +++ b/lib/galaxy/web/controllers/requests.py @@ -84,7 +84,7 @@ class RequestsGrid( grids.Grid ): NameColumn( "Name", key="name", model_class=model.Request, - link=( lambda item: iff( item.deleted, None, dict( operation="show_request", id=item.id ) ) ), + link=( lambda item: iff( item.deleted, None, dict( operation="show", id=item.id ) ) ), attach_popup=True, filterable="advanced" ), DescriptionColumn( "Description", @@ -92,7 +92,7 @@ class RequestsGrid( grids.Grid ): model_class=model.Request, filterable="advanced" ), SamplesColumn( "Sample(s)", - link=( lambda item: iff( item.deleted, None, dict( operation="show_request", id=item.id ) ) ), ), + link=( lambda item: iff( item.deleted, None, dict( operation="show", id=item.id ) ) ), ), TypeColumn( "Type" ), grids.GridColumn( "Last Updated", key="update_time", format=time_ago ), grids.DeletedColumn( "Deleted", @@ -120,7 +120,8 @@ class RequestsGrid( grids.Grid ): ] global_actions = [ - grids.GridAction( "Create new request", dict( controller='requests', + grids.GridAction( "Create new request", dict( controller='requests_common', + cntrller='requests', action='new', select_request_type='True' ) ) ] @@ -149,18 +150,36 @@ class Requests( BaseController ): action='list', status='error', message="Invalid request ID") ) - if operation == "show_request": - return self.__show_request( trans, **kwd ) + if operation == "show": + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests', + action='show', + **kwd ) ) elif operation == "submit": - return self.__submit_request( trans, **kwd ) + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests', + action='submit', + **kwd ) ) elif operation == "delete": - return self.__delete_request( trans, **kwd ) + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests', + action='delete', + **kwd ) ) elif operation == "undelete": - return self.__undelete_request( trans, **kwd ) + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests', + action='undelete', + **kwd ) ) elif operation == "edit": - return self.__edit_request( trans, **kwd ) + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests', + action='edit', + show=True, **kwd ) ) elif operation == "events": - return self.__request_events( trans, **kwd ) + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests', + action='events', + **kwd ) ) # if there are one or more requests that has been rejected by the admin # recently, then show a message as a reminder to the user rlist = trans.sa_session.query( trans.app.model.Request ) \ @@ -176,915 +195,4 @@ class Requests( BaseController ): % rejected # Render the list view return self.request_grid( trans, **kwd ) - def __request_events(self, trans, **kwd): - try: - request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) ) - except: - message = "Invalid request ID" - log.warn( message ) - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - status='error', - message=message, - **kwd) ) - events_list = [] - all_events = request.events - for event in all_events: - events_list.append((event.state, time_ago(event.update_time), event.comment)) - return trans.fill_template( '/requests/events.mako', - events_list=events_list, request=request) - def request_details(self, trans, id): - ''' - Shows the request details - ''' - request = trans.sa_session.query( trans.app.model.Request ).get( id ) - # list of widgets to be rendered on the request form - request_details = [] - # main details - request_details.append(dict(label='Description', - value=request.desc, - helptext='')) - request_details.append(dict(label='Type', - value=request.type.name, - helptext='')) - - request_details.append(dict(label='State', - value=request.state(), - helptext='')) - request_details.append(dict(label='Date created', - value=request.create_time, - helptext='')) - # form fields - for index, field in enumerate(request.type.request_form.fields): - if field['required']: - req = 'Required' - else: - req = 'Optional' - if field['type'] == 'AddressField': - if request.values.content[index]: - request_details.append(dict(label=field['label'], - value=trans.sa_session.query( trans.app.model.UserAddress ).get( int( request.values.content[index] ) ).get_html(), - helptext=field['helptext']+' ('+req+')')) - else: - request_details.append(dict(label=field['label'], - value=None, - helptext=field['helptext']+' ('+req+')')) - - else: - request_details.append(dict(label=field['label'], - value=request.values.content[index], - helptext=field['helptext']+' ('+req+')')) - if request.notify: - notify = 'Yes' - else: - notify = 'No' - request_details.append(dict(label='Send email notification once the sequencing request is complete', - value=notify, - helptext='')) - return request_details - def __show_request(self, trans, **kwd): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - add_sample = params.get('add_sample', False) - try: - request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) ) - except: - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - status='error', - message="Invalid request ID") ) - # get all data libraries accessible to this user - libraries = request.user.accessible_libraries( trans, [ trans.app.security_agent.permitted_actions.LIBRARY_ADD ] ) - current_samples = [] - for i, s in enumerate(request.samples): - lib_widget, folder_widget = self.__library_widgets(trans, request.user, i, libraries, s, **kwd) - current_samples.append(dict(name=s.name, - barcode=s.bar_code, - library=s.library, - folder=s.folder, - dataset_files=s.dataset_files, - field_values=s.values.content, - lib_widget=lib_widget, - folder_widget=folder_widget)) - if add_sample: - lib_widget, folder_widget = self.__library_widgets(trans, request.user, - len(current_samples)+1, - libraries, None, **kwd) - current_samples.append(dict(name='Sample_%i' % (len(current_samples)+1), - barcode='', - library=None, - folder=None, - dataset_files=[], - field_values=['' for field in request.type.sample_form.fields], - lib_widget=lib_widget, - folder_widget=folder_widget)) - return trans.fill_template( '/requests/show_request.mako', - request=request, - request_details=self.request_details(trans, request.id), - current_samples=current_samples, - sample_copy=self.__copy_sample(current_samples), - details='hide', edit_mode=util.restore_text( params.get( 'edit_mode', 'False' ) ), - message=message, status=status ) - def __library_widgets(self, trans, user, sample_index, libraries, sample=None, lib_id=None, folder_id=None, **kwd): - ''' - This method creates the data library & folder selectbox for creating & - editing samples. First we get a list of all the libraries accessible to - the current user and display it in a selectbox. If the user has selected an - existing library then display all the accessible sub folders of the selected - data library. - ''' - params = util.Params( kwd ) - # data library selectbox - if not lib_id: - lib_id = params.get( "sample_%i_library_id" % sample_index, 'none' ) - selected_lib = None - if sample and lib_id == 'none': - if sample.library: - lib_id = str(sample.library.id) - selected_lib = sample.library - # create data library selectbox with refresh on change enabled - lib_id_list = ['new'] + [str(lib.id) for lib in libraries.keys()] - lib_widget = SelectField( "sample_%i_library_id" % sample_index, - refresh_on_change=True, - refresh_on_change_values=lib_id_list ) - # fill up the options in the Library selectbox - # first option 'none' is the value for "Select one" option - if lib_id == 'none': - lib_widget.add_option('Select one', 'none', selected=True) - else: - lib_widget.add_option('Select one', 'none') - # all the libraries available to the selected user - for lib, hidden_folder_ids in libraries.items(): - if str(lib.id) == str(lib_id): - lib_widget.add_option(lib.name, lib.id, selected=True) - selected_lib, selected_hidden_folder_ids = lib, hidden_folder_ids.split(',') - else: - lib_widget.add_option(lib.name, lib.id) - lib_widget.refresh_on_change_values.append(lib.id) - # create the folder selectbox - folder_widget = SelectField( "sample_%i_folder_id" % sample_index ) - # when editing a request, either the user has already selected a subfolder or not - if sample: - if sample.folder: - current_fid = sample.folder.id - else: - # when a folder not yet associated with the request then the - # the current folder is set to the root_folder of the - # parent data library if present. - if sample.library: - current_fid = sample.library.root_folder.id - else: - current_fid = params.get( "sample_%i_folder_id" % sample_index, 'none' ) - else: - if folder_id: - current_fid = folder_id - else: - current_fid = 'none' - # first option - if lib_id == 'none': - folder_widget.add_option('Select one', 'none', selected=True) - else: - folder_widget.add_option('Select one', 'none') - if selected_lib: - # get all show-able folders for the selected library - showable_folders = trans.app.security_agent.get_showable_folders( user, user.all_roles(), - selected_lib, - [ trans.app.security_agent.permitted_actions.LIBRARY_ADD ], - selected_hidden_folder_ids ) - for f in showable_folders: - if str(f.id) == str(current_fid): - folder_widget.add_option(f.name, f.id, selected=True) - else: - folder_widget.add_option(f.name, f.id) - return lib_widget, folder_widget - def __update_samples(self, trans, request, **kwd): - ''' - This method retrieves all the user entered sample information and - returns an list of all the samples and their field values - ''' - params = util.Params( kwd ) - details = params.get( 'details', 'hide' ) - edit_mode = params.get( 'edit_mode', 'False' ) - # get all data libraries accessible to this user - libraries = request.user.accessible_libraries( trans, [ trans.app.security_agent.permitted_actions.LIBRARY_ADD ] ) - - current_samples = [] - for i, s in enumerate(request.samples): - lib_widget, folder_widget = self.__library_widgets(trans, request.user, i, libraries, s, **kwd) - current_samples.append(dict(name=s.name, - barcode=s.bar_code, - library=s.library, - folder=s.folder, - field_values=s.values.content, - lib_widget=lib_widget, - folder_widget=folder_widget)) - if edit_mode == 'False': - sample_index = len(request.samples) - else: - sample_index = 0 - while True: - lib_id = None - folder_id = None - if params.get( 'sample_%i_name' % sample_index, '' ): - # data library - try: - library = trans.sa_session.query( trans.app.model.Library ).get( int( params.get( 'sample_%i_library_id' % sample_index, None ) ) ) - lib_id = library.id - except: - library = None - # folder - try: - folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get( int( params.get( 'sample_%i_folder_id' % sample_index, None ) ) ) - folder_id = folder.id - except: - if library: - folder = library.root_folder - else: - folder = None - sample_info = dict( name=util.restore_text( params.get( 'sample_%i_name' % sample_index, '' ) ), - barcode=util.restore_text( params.get( 'sample_%i_barcode' % sample_index, '' ) ), - library=library, - folder=folder) - sample_info['field_values'] = [] - for field_index in range(len(request.type.sample_form.fields)): - sample_info['field_values'].append(util.restore_text( params.get( 'sample_%i_field_%i' % (sample_index, field_index), '' ) )) - if edit_mode == 'False': - sample_info['lib_widget'], sample_info['folder_widget'] = self.__library_widgets(trans, - request.user, - sample_index, - libraries, - None, lib_id, folder_id, **kwd) - current_samples.append(sample_info) - else: - sample_info['lib_widget'], sample_info['folder_widget'] = self.__library_widgets(trans, - request.user, - sample_index, - libraries, - request.samples[sample_index], - **kwd) - current_samples[sample_index] = sample_info - sample_index = sample_index + 1 - else: - break - return current_samples, details, edit_mode, libraries - def __copy_sample(self, current_samples): - copy_list = SelectField('copy_sample') - copy_list.add_option('None', -1, selected=True) - for i, s in enumerate(current_samples): - copy_list.add_option(s['name'], i) - return copy_list - def __import_samples(self, trans, request, current_samples, details, libraries, **kwd): - ''' - This method reads the samples csv file and imports all the samples - The format of the csv file is: - SampleName,DataLibrary,DataLibraryFolder,Field1,Field2.... - ''' - try: - params = util.Params( kwd ) - edit_mode = params.get( 'edit_mode', 'False' ) - file_obj = params.get('file_data', '') - reader = csv.reader(file_obj.file) - for row in reader: - lib_id = None - folder_id = None - lib = trans.sa_session.query( trans.app.model.Library ) \ - .filter( and_( trans.app.model.Library.table.c.name==row[1], \ - trans.app.model.Library.table.c.deleted==False ) )\ - .first() - if lib: - folder = trans.sa_session.query( trans.app.model.LibraryFolder ) \ - .filter( and_( trans.app.model.LibraryFolder.table.c.name==row[2], \ - trans.app.model.LibraryFolder.table.c.deleted==False ) )\ - .first() - if folder: - lib_id = lib.id - folder_id = folder.id - lib_widget, folder_widget = self.__library_widgets(trans, request.user, len(current_samples), - libraries, None, lib_id, folder_id, **kwd) - current_samples.append(dict(name=row[0], - barcode='', - library=None, - folder=None, - lib_widget=lib_widget, - folder_widget=folder_widget, - field_values=row[3:])) - return trans.fill_template( '/admin/requests/show_request.mako', - request=request, - request_details=self.request_details(trans, request.id), - current_samples=current_samples, - sample_copy=self.__copy_sample(current_samples), - details=details, - edit_mode=edit_mode) - except: - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - operation='show_request', - id=trans.security.encode_id(request.id), - status='error', - message='Error in importing samples file' )) - - @web.expose - @web.require_login( "create/submit sequencing requests" ) - def show_request(self, trans, **kwd): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - try: - request = trans.sa_session.query( trans.app.model.Request ).get( int( params.get( 'request_id', None ) ) ) - except: - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - status='error', - message="Invalid request ID", - **kwd) ) - # get the user entered sample details - current_samples, details, edit_mode, libraries = self.__update_samples( trans, request, **kwd ) - if params.get('import_samples_button', False) == 'Import samples': - return self.__import_samples(trans, request, current_samples, details, libraries, **kwd) - elif params.get('add_sample_button', False) == 'Add New': - # add an empty or filled sample - # if the user has selected a sample no. to copy then copy the contents - # of the src sample to the new sample else an empty sample - src_sample_index = int(params.get( 'copy_sample', -1 )) - # get the number of new copies of the src sample - num_sample_to_copy = int(params.get( 'num_sample_to_copy', 1 )) - if src_sample_index == -1: - for ns in range(num_sample_to_copy): - # empty sample - lib_widget, folder_widget = self.__library_widgets(trans, request.user, - len(current_samples), - libraries, None, **kwd) - current_samples.append(dict(name='Sample_%i' % (len(current_samples)+1), - barcode='', - library=None, - folder=None, - field_values=['' for field in request.type.sample_form.fields], - lib_widget=lib_widget, - folder_widget=folder_widget)) - else: - src_library_id = current_samples[src_sample_index]['lib_widget'].get_selected()[1] - src_folder_id = current_samples[src_sample_index]['folder_widget'].get_selected()[1] - for ns in range(num_sample_to_copy): - lib_widget, folder_widget = self.__library_widgets(trans, request.user, - len(current_samples), - libraries, sample=None, - lib_id=src_library_id, - folder_id=src_folder_id, - **kwd) - current_samples.append(dict(name=current_samples[src_sample_index]['name']+'_%i' % (len(current_samples)+1), - barcode='', - library_id='none', - folder_id='none', - field_values=[val for val in current_samples[src_sample_index]['field_values']], - lib_widget=lib_widget, - folder_widget=folder_widget)) - return trans.fill_template( '/requests/show_request.mako', - request=request, - request_details=self.request_details(trans, request.id), - current_samples=current_samples, - sample_copy=self.__copy_sample(current_samples), - details=details, - edit_mode=edit_mode) - elif params.get('save_samples_button', False) == 'Save': - # check for duplicate sample names - message = '' - for index in range(len(current_samples)-len(request.samples)): - sample_index = index + len(request.samples) - sample_name = current_samples[sample_index]['name'] - if not sample_name.strip(): - message = 'Please enter the name of sample number %i' % sample_index - break - count = 0 - for i in range(len(current_samples)): - if sample_name == current_samples[i]['name']: - count = count + 1 - if count > 1: - message = "This request has <b>%i</b> samples with the name <b>%s</b>.\nSamples belonging to a request must have unique names." % (count, sample_name) - break - if message: - return trans.fill_template( '/requests/show_request.mako', - request=request, - request_details=self.request_details(trans, request.id), - current_samples = current_samples, - sample_copy=self.__copy_sample(current_samples), - details=details, edit_mode=edit_mode, - status='error', message=message) - # save all the new/unsaved samples entered by the user - if edit_mode == 'False': - for index in range(len(current_samples)-len(request.samples)): - sample_index = len(request.samples) - form_values = trans.app.model.FormValues(request.type.sample_form, - current_samples[sample_index]['field_values']) - trans.sa_session.add( form_values ) - trans.sa_session.flush() - s = trans.app.model.Sample(current_samples[sample_index]['name'], '', - request, form_values, - current_samples[sample_index]['barcode'], - current_samples[sample_index]['library'], - current_samples[sample_index]['folder'], - dataset_files=[]) - trans.sa_session.add( s ) - trans.sa_session.flush() - else: - status = 'done' - message = 'Changes made to the sample(s) are saved. ' - for sample_index in range(len(current_samples)): - sample = request.samples[sample_index] - sample.name = current_samples[sample_index]['name'] - sample.library = current_samples[sample_index]['library'] - sample.folder = current_samples[sample_index]['folder'] - if request.submitted(): - bc_message = self.__validate_barcode(trans, sample, current_samples[sample_index]['barcode']) - if bc_message: - status = 'error' - message += bc_message - else: - sample.bar_code = current_samples[sample_index]['barcode'] - trans.sa_session.add( sample ) - trans.sa_session.flush() - form_values = trans.sa_session.query( trans.app.model.FormValues ).get( sample.values.id ) - form_values.content = current_samples[sample_index]['field_values'] - trans.sa_session.add( form_values ) - trans.sa_session.flush() - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - operation='show_request', - id=trans.security.encode_id(request.id), - status=status, - message=message )) - elif params.get('edit_samples_button', False) == 'Edit samples': - edit_mode = 'True' - return trans.fill_template( '/requests/show_request.mako', - request=request, - request_details=self.request_details(trans, request.id), - current_samples=current_samples, - sample_copy=self.__copy_sample(current_samples), - details=details, libraries=libraries, - edit_mode=edit_mode) - elif params.get('cancel_changes_button', False) == 'Cancel': - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - operation='show_request', - id=trans.security.encode_id(request.id)) ) - else: - return trans.fill_template( '/requests/show_request.mako', - request=request, - request_details=self.request_details(trans, request.id), - current_samples=current_samples, - sample_copy=self.__copy_sample(current_samples), - details=details, libraries=libraries, - edit_mode=edit_mode, status=status, message=message) - - - @web.expose - @web.require_login( "create/submit sequencing requests" ) - def delete_sample(self, trans, **kwd): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - request = trans.sa_session.query( trans.app.model.Request ).get( int( params.get( 'request_id', 0 ) ) ) - current_samples, details, edit_mode = self.__update_samples( request, **kwd ) - sample_index = int(params.get('sample_id', 0)) - sample_name = current_samples[sample_index]['name'] - s = request.has_sample(sample_name) - if s: - trans.sa_session.delete( s.values ) - trans.sa_session.delete( s ) - trans.sa_session.flush() - del current_samples[sample_index] - return trans.fill_template( '/requests/show_request.mako', - request=request, - request_details=self.request_details(trans, request.id), - current_samples = current_samples, - sample_copy=self.__copy_sample(current_samples), - details=details, - edit_mode=edit_mode) - def __select_request_type(self, trans, rtid): - requesttype_list = trans.user.accessible_request_types(trans) - rt_ids = ['none'] - for rt in requesttype_list: - if not rt.deleted: - rt_ids.append(str(rt.id)) - select_reqtype = SelectField('select_request_type', - refresh_on_change=True, - refresh_on_change_values=rt_ids[1:]) - if rtid == 'none': - select_reqtype.add_option('Select one', 'none', selected=True) - else: - select_reqtype.add_option('Select one', 'none') - for rt in requesttype_list: - if not rt.deleted: - if rtid == rt.id: - select_reqtype.add_option(rt.name, rt.id, selected=True) - else: - select_reqtype.add_option(rt.name, rt.id) - return select_reqtype - @web.expose - @web.require_login( "create/submit sequencing requests" ) - def new(self, trans, **kwd): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - if params.get('select_request_type', False) == 'True': - return trans.fill_template( '/requests/new_request.mako', - select_request_type=self.__select_request_type(trans, 'none'), - widgets=[], - message=message, - status=status) - elif params.get('create', False) == 'True': - if params.get('create_request_button', False) == 'Save' \ - or params.get('create_request_samples_button', False) == 'Add samples': - request_type = trans.sa_session.query( trans.app.model.RequestType ).get( int( params.select_request_type ) ) - if not util.restore_text(params.get('name', '')): - message = 'Please enter the <b>Name</b> of the request' - kwd['create'] = 'True' - kwd['status'] = 'error' - kwd['message'] = message - kwd['create_request_button'] = None - kwd['create_request_samples_button'] = None - return trans.response.send_redirect( web.url_for( controller='requests', - action='new', - **kwd) ) - request = self.__save_request(trans, None, **kwd) - message = 'The new request named <b>%s</b> has been created' % request.name - if params.get('create_request_button', False) == 'Save': - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - message=message , - status='done') ) - elif params.get('create_request_samples_button', False) == 'Add samples': - new_kwd = {} - new_kwd['id'] = trans.security.encode_id(request.id) - new_kwd['operation'] = 'show_request' - new_kwd['add_sample'] = True - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - message=message , - status='done', - **new_kwd) ) - else: - return self.__show_request_form(trans, **kwd) - elif params.get('refresh', False) == 'true': - return self.__show_request_form(trans, **kwd) - def __show_request_form(self, trans, **kwd): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - try: - request_type = trans.sa_session.query( trans.app.model.RequestType ).get( int( params.select_request_type ) ) - except: - return trans.fill_template( '/requests/new_request.mako', - select_request_type=self.__select_request_type(trans, 'none'), - widgets=[], - message=message, - status=status) - form_values = None - select_request_type = self.__select_request_type(trans, request_type.id) - # list of widgets to be rendered on the request form - widgets = [] - widgets.append(dict(label='Name of the Experiment', - widget=TextField('name', 40, - util.restore_text( params.get( 'name', '' ) )), - helptext='(Required)')) - widgets.append(dict(label='Description', - widget=TextField('desc', 40, - util.restore_text( params.get( 'desc', '' ) )), - helptext='(Optional)')) - widgets = widgets + request_type.request_form.get_widgets( trans.user, **kwd ) - widgets.append(dict(label='Send email notification once the sequencing request is complete', - widget=CheckboxField('email_notify', False), - helptext='')) - return trans.fill_template( '/requests/new_request.mako', - select_request_type=select_request_type, - request_type=request_type, - widgets=widgets, - message=message, - status=status) - def __validate(self, trans, request): - ''' - Validates the request entered by the user - ''' - empty_fields = [] - # check rest of the fields of the form - for index, field in enumerate(request.type.request_form.fields): - if field['required'] == 'required' and request.values.content[index] in ['', None]: - empty_fields.append(field['label']) - if empty_fields: - message = 'Fill the following fields of the request <b>%s</b> before submitting<br/>' % request.name - for ef in empty_fields: - message = message + '<b>' +ef + '</b><br/>' - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - operation='edit', - status = 'error', - message=message, - id=trans.security.encode_id(request.id) )) - # now check the required fields of all the samples of this request - for s in request.samples: - for index, field in enumerate(request.type.sample_form.fields): - if field['required'] == 'required' and s.values.content[index] in ['', None]: - empty_fields.append((s.name, field['label'])) - if empty_fields: - message = 'Fill the following fields of the request <b>%s</b> before submitting<br/>' % request.name - for sname, ef in empty_fields: - message = message + '<b>%s</b> field of sample <b>%s</b><br/>' % (ef, sname) - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - operation='show_request', - status = 'error', - message=message, - id=trans.security.encode_id(request.id) )) - def __save_request(self, trans, request=None, **kwd): - ''' - This method saves a new request if request_id is None. - ''' - params = util.Params( kwd ) - request_type = trans.sa_session.query( trans.app.model.RequestType ).get( int( params.select_request_type ) ) - name = util.restore_text(params.get('name', '')) - desc = util.restore_text(params.get('desc', '')) - notify = CheckboxField.is_checked( params.get('email_notify', '') ) - # library - try: - library = trans.sa_session.query( trans.app.model.Library ).get( int( params.get( 'library_id', None ) ) ) - except: - library = None - try: - folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get( int( params.get( 'folder_id', None ) ) ) - except: - if library: - folder = library.root_folder - else: - folder = None - # fields - values = [] - for index, field in enumerate(request_type.request_form.fields): - if field['type'] == 'AddressField': - value = util.restore_text(params.get('field_%i' % index, '')) - if value == 'new': - # save this new address in the list of this user's addresses - user_address = trans.app.model.UserAddress( user=trans.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() - trans.sa_session.refresh( trans.user ) - values.append(int(user_address.id)) - elif value == unicode('none'): - values.append('') - else: - values.append(int(value)) - elif field['type'] == 'CheckboxField': - values.append(CheckboxField.is_checked( params.get('field_%i' % index, '') )) - else: - values.append(util.restore_text(params.get('field_%i' % index, ''))) - form_values = trans.app.model.FormValues(request_type.request_form, values) - trans.sa_session.add( form_values ) - trans.sa_session.flush() - if not request: - request = trans.app.model.Request(name, desc, request_type, - trans.user, form_values, notify) - trans.sa_session.add( request ) - trans.sa_session.flush() - trans.sa_session.refresh( request ) - # create an event with state 'New' for this new request - comments = "Request created." - event = trans.app.model.RequestEvent(request, request.states.NEW, comments) - trans.sa_session.add( event ) - trans.sa_session.flush() - else: - request.name = name - request.desc = desc - request.type = request_type - request.user = trans.user - request.values = form_values - request.notify = notify - trans.sa_session.add( request ) - trans.sa_session.flush() - return request - @web.expose - @web.require_login( "create/submit sequencing requests" ) - def edit(self, trans, **kwd): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - try: - request = trans.sa_session.query( trans.app.model.Request ).get( int( params.get( 'request_id', None ) ) ) - except: - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - status='error', - message="Invalid request ID", - **kwd) ) - if params.get('show', False) == 'True': - return self.__edit_request(trans, id=trans.security.encode_id(request.id), **kwd) - elif params.get('save_changes_request_button', False) == 'Save changes' \ - or params.get('edit_samples_button', False) == 'Edit samples': - request_type = trans.sa_session.query( trans.app.model.RequestType ).get( int( params.select_request_type ) ) - if not util.restore_text(params.get('name', '')): - message = 'Please enter the <b>Name</b> of the request' - kwd['status'] = 'error' - kwd['message'] = message - kwd['show'] = 'True' - return trans.response.send_redirect( web.url_for( controller='requests', - action='edit', - **kwd) ) - request = self.__save_request(trans, request, **kwd) - message = 'The changes made to the request named %s has been saved' % request.name - if params.get('save_changes_request_button', False) == 'Save changes': - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - message=message , - status='done') ) - elif params.get('edit_samples_button', False) == 'Edit samples': - new_kwd = {} - new_kwd['request_id'] = request.id - new_kwd['edit_samples_button'] = 'Edit samples' - return trans.response.send_redirect( web.url_for( controller='requests', - action='show_request', - message=message , - status='done', - **new_kwd) ) - elif params.get('refresh', False) == 'true': - return self.__edit_request(trans, id=trans.security.encode_id(request.id), **kwd) - - def __edit_request(self, trans, **kwd): - try: - request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) ) - except: - message = "Invalid request ID" - log.warn( message ) - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - status='error', - message=message) ) - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - select_request_type = self.__select_request_type(trans, request.type.id) - # list of widgets to be rendered on the request form - widgets = [] - if util.restore_text( params.get( 'name', '' ) ): - name = util.restore_text( params.get( 'name', '' ) ) - else: - name = request.name - widgets.append(dict(label='Name', - widget=TextField('name', 40, name), - helptext='(Required)')) - if util.restore_text( params.get( 'desc', '' ) ): - desc = util.restore_text( params.get( 'desc', '' ) ) - else: - desc = request.desc - widgets.append(dict(label='Description', - widget=TextField('desc', 40, desc), - helptext='(Optional)')) - widgets = widgets + request.type.request_form.get_widgets( trans.user, request.values.content, **kwd ) - widgets.append(dict(label='Send email notification once the sequencing request is complete', - widget=CheckboxField('email_notify', request.notify), - helptext='')) - return trans.fill_template( '/requests/edit_request.mako', - select_request_type=select_request_type, - request_type=request.type, - request=request, - widgets=widgets, - message=message, - status=status) - return self.__show_request_form(trans) - def __delete_request(self, trans, **kwd): - id_list = util.listify( kwd['id'] ) - delete_failed = [] - for id in id_list: - try: - request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(id) ) - except: - message = "Invalid request ID" - log.warn( message ) - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - status='error', - message=message, - **kwd) ) - # a request cannot be deleted once its submitted - if not request.new(): - delete_failed.append(request.name) - else: - request.deleted = True - trans.sa_session.add( request ) - # delete all the samples belonging to this request - for s in request.samples: - s.deleted = True - trans.sa_session.add( s ) - trans.sa_session.flush() - if not len(delete_failed): - message = '%i request(s) has been deleted.' % len(id_list) - status = 'done' - else: - message = '%i request(s) has been deleted. %i request %s could not be deleted as they have been submitted.' % (len(id_list)-len(delete_failed), - len(delete_failed), str(delete_failed)) - status = 'warning' - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - status=status, - message=message) ) - def __undelete_request(self, trans, **kwd): - id_list = util.listify( kwd['id'] ) - for id in id_list: - try: - request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(id) ) - except: - message = "Invalid request ID" - log.warn( message ) - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - status='error', - message=message, - **kwd) ) - request.deleted = False - trans.sa_session.add( request ) - # undelete all the samples belonging to this request - for s in request.samples: - s.deleted = False - trans.sa_session.add( s ) - trans.sa_session.flush() - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - status='done', - message='%i request(s) has been undeleted.' % len(id_list) ) ) - def __submit_request(self, trans, **kwd): - try: - request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) ) - except: - message = "Invalid request ID" - log.warn( message ) - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - status='error', - message=message, - **kwd) ) - # check if all the required request and its sample fields have been filled - self.__validate(trans, request) - # change the request state to 'Submitted' - comments = "Sequencing request is in progress." - event = trans.app.model.RequestEvent(request, request.states.SUBMITTED, comments) - trans.sa_session.add( event ) - trans.sa_session.flush() - # get the new state - new_state = request.type.states[0] - for s in request.samples: - event = trans.app.model.SampleEvent(s, new_state, 'Samples submitted to the system') - trans.sa_session.add( event ) - trans.sa_session.flush() - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - id=trans.security.encode_id(request.id), - status='done', - message='The request <b>%s</b> has been submitted.' % request.name - ) ) - @web.expose - @web.require_login( "create/submit sequencing requests" ) - def show_events(self, trans, **kwd): - params = util.Params( kwd ) - try: - sample_id = int(params.get('sample_id', False)) - sample = trans.sa_session.query( trans.app.model.Sample ).get( sample_id ) - except: - message = "Invalid sample ID" - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - status='error', - message=message, - **kwd) ) - events_list = [] - all_events = sample.events - for event in all_events: - events_list.append((event.state.name, event.state.desc, time_ago(event.update_time), event.comment)) - return trans.fill_template( '/sample/sample_events.mako', - events_list=events_list, - sample_name=sample.name, - request=sample.request) - # - # Data transfer from sequencer - # - @web.expose - @web.require_login( "create/submit sequencing requests" ) - def show_datatx_page( self, trans, **kwd ): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - try: - sample = trans.sa_session.query( trans.app.model.Sample ).get( trans.security.decode_id( kwd['sample_id'] ) ) - except: - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - status='error', - message="Invalid sample ID", - **kwd) ) - return trans.fill_template( '/requests/show_data.mako', - sample=sample, dataset_files=sample.dataset_files ) + --- a/lib/galaxy/web/controllers/forms.py +++ b/lib/galaxy/web/controllers/forms.py @@ -474,8 +474,7 @@ class Forms( BaseController ): return trans.response.send_redirect( web.url_for( controller='forms', action='new', status='error', - message='Error in importing <b>%s</b> file' % csv_file, - **kwd)) + message='Error in importing <b>%s</b> file' % csv_file.file)) self.__imported_from_file = True return fields, list(layouts) def __validate_form(self, **kwd): --- a/templates/admin/requests/edit_request.mako +++ /dev/null @@ -1,88 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - -%if message: - ${render_msg( message, status )} -%endif - -<script type="text/javascript"> -$( function() { - $( "select[refresh_on_change='true']").change( function() { - var refresh = false; - var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' ) - if ( refresh_on_change_values ) { - refresh_on_change_values = refresh_on_change_values.value.split( ',' ); - var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' ); - for( i= 0; i < refresh_on_change_values.length; i++ ) { - if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){ - refresh = true; - break; - } - } - } - else { - refresh = true; - } - if ( refresh ){ - $( "#edit_request" ).submit(); - } - }); -}); -</script> - -<br/> -<br/> -<ul class="manage-table-actions"> - <li> - <a class="action-button" href="${h.url_for( controller='requests_admin', action='list', operation='show_request', id=trans.security.encode_id(request.id) )}"> - <span>Browse this request</span></a> - </li> - <li> - <a class="action-button" href="${h.url_for( controller='requests_admin', action='list')}"> - <span>Browse requests</span></a> - </li> -</ul> - -<div class="toolForm"> - <div class="toolFormTitle">Edit request "${request.name}" from ${request.user.email}</div> - %if len(select_request_type.options) == 1: - There are no request types created for a new request. - %else: - <div class="toolFormBody"> - <form name="edit_request" id="edit_request" action="${h.url_for( controller='requests_admin', action='edit', request_id=request.id)}" method="post" > - <div class="form-row"> - <label> - Select Request Type: - </label> - ${select_request_type.get_html()} - </div> - - %if select_request_type.get_selected() != ('Select one', 'none'): - %for i, field in enumerate(widgets): - <div class="form-row"> - <label>${field['label']}</label> - ${field['widget'].get_html()} - %if field['label'] == 'Library' and new_library: - ${new_library.get_html()} - %endif - <div class="toolParamHelp" style="clear: both;"> - ${field['helptext']} - </div> - <div style="clear: both"></div> - </div> - %endfor - <div class="form-row"> - <div style="float: left; width: 250px; margin-right: 10px;"> - <input type="hidden" name="refresh" value="true" size="40"/> - </div> - <div style="clear: both"></div> - </div> - <div class="form-row"> - <input type="submit" name="save_changes_request_button" value="Save changes"/> - ##<input type="submit" name="edit_samples_button" value="Edit samples"/> - </div> - %endif - </form> - </div> -</div> -%endif --- a/templates/requests/sample_datasets.mako +++ /dev/null @@ -1,7 +0,0 @@ -<%def name="render_sample_datasets( sample )"> - <a href="${h.url_for(controller='requests_admin', action='show_datatx_page', sample_id=trans.security.encode_id(sample.id))}">${sample.transferred_dataset_files()}/${len(sample.dataset_files)}</a> -</%def> - - - -${render_sample_datasets( sample )} --- /dev/null +++ b/templates/requests/common/events.mako @@ -0,0 +1,39 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + +<h2>History of Sequencing Request "${request.name}"</h2> +<ul class="manage-table-actions"> + <li> + <a class="action-button" href="${h.url_for( controller=cntrller, action='list', operation='show_request', id=trans.security.encode_id(request.id) )}"> + <span>Browse this request</span></a> + </li> + <li> + <a class="action-button" href="${h.url_for( controller=cntrller, action='list')}"> + <span>Browse all requests</span></a> + </li> +</ul> + +%if message: + ${render_msg( message, status )} +%endif + +<div class="toolForm"> + <table class="grid"> + <thead> + <tr> + <th>State</th> + <th>Last Update</th> + <th>Comments</th> + </tr> + </thead> + <tbody> + %for state, updated, comments in events_list: + <tr class="libraryRow libraryOrFolderRow" id="libraryRow"> + <td><b><a>${state}</a></b></td> + <td><a>${updated}</a></td> + <td><a>${comments}</a></td> + </tr> + %endfor + </tbody> + </table> +</div> --- /dev/null +++ b/templates/requests/common/show_request.mako @@ -0,0 +1,547 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> +<%namespace file="/requests/common/sample_state.mako" import="render_sample_state" /> +<%namespace file="/requests/common/sample_datasets.mako" import="render_sample_datasets" /> + + + +<script type="text/javascript"> +$( function() { + $( "select[refresh_on_change='true']").change( function() { + var refresh = false; + var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' ) + if ( refresh_on_change_values ) { + refresh_on_change_values = refresh_on_change_values.value.split( ',' ); + var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' ); + for( i= 0; i < refresh_on_change_values.length; i++ ) { + if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){ + refresh = true; + break; + } + } + } + else { + refresh = true; + } + if ( refresh ){ + $( "#show_request" ).submit(); + } + }); +}); +</script> + + +<script type="text/javascript"> +$(document).ready(function(){ + //hide the all of the element with class msg_body + $(".msg_body").hide(); + //toggle the componenet with class msg_body + $(".msg_head").click(function(){ + $(this).next(".msg_body").slideToggle(450); + }); +}); +</script> + +<script type="text/javascript"> + // Looks for changes in sample states using an async request. Keeps + // calling itself (via setTimeout) until all samples are in a terminal + // state. + var updater = function ( sample_states ) { + // Check if there are any items left to track + var empty = true; + for ( i in sample_states ) { + empty = false; + break; + } + if ( ! empty ) { + setTimeout( function() { updater_callback( sample_states ) }, 1000 ); + } + }; + var updater_callback = function ( sample_states ) { + // Build request data + var ids = [] + var states = [] + $.each( sample_states, function ( id, state ) { + ids.push( id ); + states.push( state ); + }); + // Make ajax call + $.ajax( { + type: "POST", + url: "${h.url_for( controller='requests_common', action='sample_state_updates' )}", + dataType: "json", + data: { ids: ids.join( "," ), states: states.join( "," ) }, + success : function ( data ) { + $.each( data, function( id, val, cntrller ) { + // Replace HTML + var cell1 = $("#sampleState-" + id); + cell1.html( val.html_state ); + var cell2 = $("#sampleDatasets-" + id); + cell2.html( val.html_datasets ); + sample_states[ parseInt(id) ] = val.state; + }); + updater( sample_states ); + }, + error: function() { + // Just retry, like the old method, should try to be smarter + updater( sample_states ); + } + }); + }; +</script> + +<style type="text/css"> +.msg_head { + padding: 0px 0px; + cursor: pointer; +} +</style> + +<script type="text/javascript"> + function stopRKey(evt) { + var evt = (evt) ? evt : ((event) ? event : null); + var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null); + if ((evt.keyCode == 13) && (node.type=="text")) {return false;} + } + document.onkeypress = stopRKey +</script> + +%if request.submitted(): + <% samples_not_ready = request.sequence_run_ready() %> + %if samples_not_ready: + ${render_msg( "Select a target library and folder for all the samples before starting the sequence run", "warning" )} + %endif +%endif + +%if request.rejected(): + ${render_msg( "Reason for rejection: "+request.last_comment(), "warning" )} +%endif + +<div class="grid-header"> + <h2>Sequencing Request "${request.name}"</h2> +</div> + +<ul class="manage-table-actions"> + + %if request.unsubmitted() and request.samples: + <li> + <a class="action-button" confirm="More samples cannot be added to this request once it is submitted. Click OK to submit." href="${h.url_for( controller=cntrller, action='list', operation='Submit', id=trans.security.encode_id(request.id) )}"> + <span>Submit request</span></a> + </li> + %endif + %if cntrller == 'requests_admin' and trans.user_is_admin(): + %if request.submitted(): + <li> + <a class="action-button" href="${h.url_for( controller=cntrller, action='list', operation='reject', id=trans.security.encode_id(request.id))}"> + <span>Reject request</span></a> + </li> + %endif + %endif + <li> + <a class="action-button" href="${h.url_for( controller=cntrller, action='list', operation='events', id=trans.security.encode_id(request.id) )}"> + <span>History</span></a> + </li> + <li> + <a class="action-button" href="${h.url_for( controller=cntrller, action='list')}"> + <span>Browse requests</span></a> + </li> + +</ul> + + +%if message: + ${render_msg( message, status )} +%endif + + + + +<div class="toolForm"> + <div class="form-row"> + <div class="msg_list"> + <h4 class="msg_head"><u>Request Information</u></h4> + <div class="msg_body"> + %for index, rd in enumerate(request_details): + <div class="form-row"> + <label>${rd['label']}</label> + %if not rd['value']: + <i>None</i> + %else: + %if rd['label'] == 'State': + <a href="${h.url_for( controller=cntrller, action='list', operation='events', id=trans.security.encode_id(request.id) )}">${rd['value']}</a> + %else: + ${rd['value']} + %endif + %endif + </div> + <div style="clear: both"></div> + %endfor + <div class="form-row"> + <ul class="manage-table-actions"> + <li> + <a class="action-button" href="${h.url_for( controller='requests_admin', action='list', operation='Edit', id=trans.security.encode_id(request.id))}"> + <span>Edit request details</span></a> + </li> + </ul> + </div> + </div> + </div> + </div> +</div> + +<br/> + +<div class="toolForm"> + <form id="show_request" name="show_request" action="${h.url_for( controller='requests_common', cntrller=cntrller, action='request_page', edit_mode=edit_mode )}" method="post" > + <div class="form-row"> + %if current_samples: + ## first render the basic info grid + ${render_basic_info_grid()} + ## then render the other grid(s) + <% trans.sa_session.refresh( request.type.sample_form ) %> + %for grid_index, grid_name in enumerate(request.type.sample_form.layout): + ${render_grid( grid_index, grid_name, request.type.sample_form.fields_of_grid( grid_index ) )} + <br/> + %endfor + %else: + <label>There are no samples.</label> + %endif + </div> + %if request.samples and request.submitted(): + <script type="text/javascript"> + // Updater + updater({${ ",".join( [ '"%s" : "%s"' % ( s.id, s.current_state().name ) for s in request.samples ] ) }}); + </script> + %endif + + %if edit_mode == 'False': + <table class="grid"> + <tbody> + <tr> + <div class="form-row"> + + %if request.unsubmitted(): + <td> + %if current_samples: + <label>Copy </label> + <input type="integer" name="num_sample_to_copy" value="1" size="3"/> + <label>sample(s) from sample</label> + ${sample_copy.get_html()} + %endif + <input type="submit" name="add_sample_button" value="Add New"/> + </td> + %endif + <td> + %if len(current_samples) and len(current_samples) <= len(request.samples): + <input type="submit" name="edit_samples_button" value="Edit samples"/> + %endif + </td> + </div> + </tr> + </tbody> + </table> + %endif + %if request.samples or current_samples: + <div class="form-row"> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="hidden" name="refresh" value="true" size="40"/> + </div> + <div style="clear: both"></div> + </div> + %if edit_mode == 'True': + <div class="form-row"> + <input type="submit" name="save_samples_button" value="Save"/> + <input type="submit" name="cancel_changes_button" value="Cancel"/> + </div> + %elif request.unsubmitted(): + <div class="form-row"> + <input type="submit" name="save_samples_button" value="Save"/> + </div> + %endif + + %endif + <input type="hidden" name="id" value="${trans.security.encode_id(request.id)}" /> + </form> +</div> + +<br/> + +%if request.unsubmitted(): +<div class="toolForm"> + <form id="import" name="import" action="${h.url_for( controller='requests_common', action='request_page', edit_mode=edit_mode, request_id=trans.security.encode_id(request.id) )}" enctype="multipart/form-data" method="post" > + <div class="form-row"> + <div class="msg_list"> + <h4 class="msg_head"><u>Import samples from csv file</u></h4> + <div class="msg_body"> + <input type="file" name="file_data" /> + <input type="submit" name="import_samples_button" value="Import samples"/> + <br/> + <div class="toolParamHelp" style="clear: both;"> + The csv file must be in the following format:<br/> + SampleName,DataLibrary,DataLibraryFolder,FieldValue1,FieldValue2... + </div> + </div> + </div> + </div> +## <input type="hidden" name="request_id" value="${request.id}" /> + </form> +</div> +%endif + +<%def name="render_grid( grid_index, grid_name, fields_dict )"> + <br/> + <div class="msg_list"> + %if grid_name: + <h4 class="msg_head"><u>${grid_name}</u></h4> + %else: + <h4>Grid ${grid_index}</h4> + %endif + %if edit_mode == 'False' or len(current_samples) <= len(request.samples): + <div class="msg_body"> + %else: + <div class="msg_body2"> + %endif + <table class="grid"> + <thead> + <tr> + <th>Name</th> + %for index, field in fields_dict.items(): + <th> + ${field['label']} + <div class="toolParamHelp" style="clear: both;"> + <i>${field['helptext']}</i> + </div> + </th> + %endfor + <th></th> + </tr> + <thead> + <tbody> + <% + trans.sa_session.refresh( request ) + %> + %for sample_index, sample in enumerate(current_samples): + %if edit_mode == 'True': + <tr> + ${render_sample_form( sample_index, sample['name'], sample['field_values'], fields_dict)} + </tr> + %else: + <tr> + %if sample_index in range(len(request.samples)): + ${render_sample( sample_index, sample['name'], sample['field_values'], fields_dict )} + %else: + ${render_sample_form( sample_index, sample['name'], sample['field_values'], fields_dict)} + %endif + </tr> + %endif + %endfor + </tbody> + </table> + </div> + </div> +</%def> + +## This function displays the "Basic Information" grid +<%def name="render_basic_info_grid()"> + <h4>Sample Information</h4> + <table class="grid"> + <thead> + <tr> + <th>Name</th> + <th>Barcode</th> + <th>State</th> + <th>Data Library</th> + <th>Folder</th> + %if request.submitted() or request.complete(): + <th>Dataset(s) Transferred</th> + %endif + <th></th> + </tr> + <thead> + <tbody> + <% + trans.sa_session.refresh( request ) + %> + %for sample_index, info in enumerate(current_samples): + <% + if sample_index in range(len(request.samples)): + sample = request.samples[sample_index] + else: + sample = None + %> + %if edit_mode == 'True': + <tr> + ${show_basic_info_form( sample_index, sample, info )} + </tr> + %else: + <tr> + %if sample_index in range(len(request.samples)): + <td>${info['name']}</td> + <td>${info['barcode']}</td> + %if sample.request.unsubmitted(): + <td>Unsubmitted</td> + %else: + <td id="sampleState-${sample.id}">${render_sample_state( cntrller, sample )}</td> + %endif + %if info['library']: + <td><a href="${h.url_for( controller='library_common', action='browse_library', cntrller='library', id=trans.security.encode_id( info['library'].id ) )}">${info['library'].name}</a></td> + %else: + <td></td> + %endif + %if info['folder']: + <td>${info['folder'].name}</td> + %else: + <td></td> + %endif + %if request.submitted() or request.complete(): + <td id="sampleDatasets-${sample.id}"> + ${render_sample_datasets( cntrller, sample )} + </td> + %endif + + + %else: + ${show_basic_info_form( sample_index, sample, info )} + %endif + %if request.unsubmitted() or request.rejected(): + <td> + %if sample: + %if sample.request.unsubmitted(): + <a class="action-button" href="${h.url_for( controller='requests_common', cntrller=cntrller, action='delete_sample', request_id=request.id, sample_id=sample_index )}"> + <img src="${h.url_for('/static/images/delete_icon.png')}" /> + <span></span></a> + %endif + %endif + </td> + %endif + </tr> + %endif + %endfor + </tbody> + </table> +</%def> + +<%def name="show_basic_info_form( sample_index, sample, info )"> + <td> + <input type="text" name=sample_${sample_index}_name value="${info['name']}" size="10"/> + <div class="toolParamHelp" style="clear: both;"> + <i>${' (required)' }</i> + </div> + </td> + %if cntrller == 'requests': + %if sample: + %if sample.request.unsubmitted(): + <td></td> + %else: + <td><input type="text" name=sample_${sample_index}_barcode value="${info['barcode']}" size="10"/></td> + %endif + %else: + <td></td> + %endif + %elif cntrller == 'requests_admin': + %if sample: + %if sample.request.unsubmitted(): + <td></td> + %else: + <td><input type="text" name=sample_${sample_index}_barcode value="${info['barcode']}" size="10"/></td> + %endif + %else: + <td></td> + %endif + %endif + %if sample: + %if sample.request.unsubmitted(): + <td>Unsubmitted</td> + %else: + <td><a href="${h.url_for( controller='requests_admin', action='sample_events', sample_id=sample.id)}">${sample.current_state().name}</a></td> + %endif + %else: + <td></td> + %endif + <td>${info['lib_widget'].get_html()}</td> + <td>${info['folder_widget'].get_html()}</td> + %if request.submitted() or request.complete(): + %if sample: + <td><a href="${h.url_for( controller='requests_admin', action='show_datatx_page', sample_id=trans.security.encode_id(sample.id) )}">${len(sample.dataset_files)}</a></td> + %else: + <td><a href="${h.url_for( controller='requests_admin', action='show_datatx_page', sample_id=trans.security.encode_id(sample.id) )}">Add</a></td> + %endif + %endif +</%def> + +<%def name="render_sample( index, sample_name, sample_values, fields_dict )"> + <td> + ${sample_name} + </td> + %for field_index, field in fields_dict.items(): + <td> + %if sample_values[field_index]: + %if field['type'] == 'WorkflowField': + %if str(sample_values[field_index]) != 'none': + <% workflow = trans.sa_session.query( trans.app.model.StoredWorkflow ).get( int(sample_values[field_index]) ) %> + <a href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${workflow.name}</a> + %endif + %else: + ${sample_values[field_index]} + %endif + %else: + <i>None</i> + %endif + </td> + %endfor +</%def> + +<%def name="render_sample_form( index, sample_name, sample_values, fields_dict )"> + <td> + ${sample_name} + </td> + %for field_index, field in fields_dict.items(): + <td> + %if field['type'] == 'TextField': + <input type="text" name="sample_${index}_field_${field_index}" value="${sample_values[field_index]}" size="7"/> + %elif field['type'] == 'SelectField': + <select name="sample_${index}_field_${field_index}" last_selected_value="2"> + %for option_index, option in enumerate(field['selectlist']): + %if option == sample_values[field_index]: + <option value="${option}" selected>${option}</option> + %else: + <option value="${option}">${option}</option> + %endif + %endfor + </select> + %elif field['type'] == 'WorkflowField': + <select name="sample_${index}_field_${field_index}"> + %if str(sample_values[field_index]) == 'none': + <option value="none" selected>Select one</option> + %else: + <option value="none">Select one</option> + %endif + %for option_index, option in enumerate(request.user.stored_workflows): + %if not option.deleted: + %if str(option.id) == str(sample_values[field_index]): + <option value="${option.id}" selected>${option.name}</option> + %else: + <option value="${option.id}">${option.name}</option> + %endif + %endif + %endfor + </select> + %elif field['type'] == 'CheckboxField': + <input type="checkbox" name="sample_${index}_field_${field_index}" value="Yes"/> + %endif + <div class="toolParamHelp" style="clear: both;"> + <i>${'('+field['required']+')' }</i> + </div> + </td> + %endfor +</%def> + + + + + + + + + + --- a/templates/admin/requests/new_request.mako +++ /dev/null @@ -1,94 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - -%if message: - ${render_msg( message, status )} -%endif - -<script type="text/javascript"> -$( function() { - $( "select[refresh_on_change='true']").change( function() { - var refresh = false; - var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' ) - if ( refresh_on_change_values ) { - refresh_on_change_values = refresh_on_change_values.value.split( ',' ); - var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' ); - for( i= 0; i < refresh_on_change_values.length; i++ ) { - if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){ - refresh = true; - break; - } - } - } - else { - refresh = true; - } - if ( refresh ){ - $( "#new_request" ).submit(); - } - }); -}); -</script> - -<%def name="javascripts()"> - ${parent.javascripts()} - ${h.js("jquery.autocomplete", "autocomplete_tagging" )} -</%def> - -<%def name="stylesheets()"> - ${parent.stylesheets()} - ${h.css( "autocomplete_tagging" )} -</%def> - -<br/> -<br/> -<ul class="manage-table-actions"> - <li> - <a class="action-button" href="${h.url_for( controller='requests_admin', action='list')}"> - <span>Browse requests</span></a> - </li> -</ul> - -<div class="toolForm"> - <div class="toolFormTitle">Add a new request</div> - %if len(select_request_type.options) == 1: - There are no request types created for a new request. - %else: - <div class="toolFormBody"> - <form name="new_request" id="new_request" action="${h.url_for( controller='requests_admin', action='new', create=True )}" method="post" > - <div class="form-row"> - <label> - Select Request Type - </label> - ${select_request_type.get_html()} - </div> - - %if select_request_type.get_selected() != ('Select one', 'none'): - %for i, field in enumerate(widgets): - <div class="form-row"> - <label>${field['label']}</label> - ${field['widget'].get_html()} - %if field['label'] == 'Library' and new_library: - ${new_library.get_html()} - %endif - <div class="toolParamHelp" style="clear: both;"> - ${field['helptext']} - </div> - <div style="clear: both"></div> - </div> - %endfor - <div class="form-row"> - <div style="float: left; width: 250px; margin-right: 10px;"> - <input type="hidden" name="refresh" value="true" size="40"/> - </div> - <div style="clear: both"></div> - </div> - <div class="form-row"> - <input type="submit" name="create_request_button" value="Save"/> - <input type="submit" name="create_request_samples_button" value="Add samples"/> - </div> - %endif - </form> - </div> -</div> -%endif --- a/templates/sample/sample_events.mako +++ /dev/null @@ -1,45 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - -<%def name="title()">Events for Sample ${sample_name}</%def> - - -<h2>Events for Sample "${sample_name}"</h2> - -<ul class="manage-table-actions"> - <li> - <a class="action-button" href="${h.url_for( controller='requests', action='list', operation='show_request', id=trans.security.encode_id(request.id) )}"> - <span>Browse this request</span></a> - </li> - <li> - <a class="action-button" href="${h.url_for( controller='requests', action='list')}"> - <span>Browse requests</span></a> - </li> -</ul> - -%if message: - ${render_msg( message, status )} -%endif - -<div class="toolForm"> - <table class="grid"> - <thead> - <tr> - <th>State</th> - <th>Description</th> - <th>Updated</th> - <th>Comments</th> - </tr> - </thead> - <tbody> - %for state, desc, updated, comments in events_list: - <tr class="libraryRow libraryOrFolderRow" id="libraryRow"> - <td><b><a>${state}</a></b></td> - <td><a>${desc}</a></td> - <td><a>${updated}</a></td> - <td><a>${comments}</a></td> - </tr> - %endfor - </tbody> - </table> -</div> --- /dev/null +++ b/templates/requests/common/sample_datasets.mako @@ -0,0 +1,7 @@ +<%def name="render_sample_datasets( cntrller, sample )"> + <a href="${h.url_for(controller='requests_common', cntrller=cntrller, action='show_datatx_page', sample_id=trans.security.encode_id(sample.id))}">${sample.transferred_dataset_files()}/${len(sample.dataset_files)}</a> +</%def> + + + +${render_sample_datasets( cntrller, sample )} --- a/test/base/twilltestcase.py +++ b/test/base/twilltestcase.py @@ -1485,14 +1485,13 @@ class TwillTestCase( unittest.TestCase ) url ="%s&%s=%s" % ( url, key, role_ids_str ) self.home() self.visit_url( "%s/%s" % ( self.url, url ) ) - print url check_str = "Permissions updated for request type '%s'" % request_type_name self.check_page_for_string( check_str ) self.home() def create_request( self, request_type_id, name, desc, fields ): self.home() - self.visit_url( "%s/requests/new?create=True&select_request_type=%i" % ( self.url, - request_type_id ) ) + self.visit_url( "%s/requests_common/new?select_request_type=%i&refresh=true&cntrller=requests" % ( self.url, + request_type_id ) ) self.check_page_for_string( 'Add a new request' ) tc.fv( "1", "name", name ) tc.fv( "1", "desc", desc ) @@ -1514,21 +1513,20 @@ class TwillTestCase( unittest.TestCase ) self.check_page_for_string( new_desc ) def add_samples( self, request_id, request_name, samples ): self.home() - url = "%s/requests/list?sort=-create_time&operation=show_request&id=%s" % ( self.url, self.security.encode_id( request_id ) ) + url = "%s/requests/list?operation=show&id=%s" % ( self.url, self.security.encode_id( request_id ) ) self.visit_url( url ) self.check_page_for_string( 'Sequencing Request "%s"' % request_name ) self.check_page_for_string( 'There are no samples.' ) # this redundant stmt below is add so that the second form in # the page gets selected - tc.fv( "3", "request_id", request_id ) + url = ["%s/requests_common/request_page?cntrller=requests&edit_mode=False&id=%s" % ( self.url, self.security.encode_id( request_id ) )] for sample_index, sample in enumerate(samples): - tc.submit( "add_sample_button" ) - self.check_page_for_string( 'Sequencing Request "%s"' % request_name ) sample_name, fields = sample - tc.fv( "3", "sample_%i_name" % sample_index, sample_name ) + url.append("sample_%i_name=%s" % (sample_index, sample_name.replace(' ', '+'))) for field_index, field_value in enumerate(fields): - tc.fv( "3", "sample_%i_field_%i" % ( sample_index, field_index ), field_value ) - tc.submit( "save_samples_button" ) + url.append("sample_%i_field_%i=%s" % ( sample_index, field_index , field_value.replace(' ', '+') )) + url.append("save_samples_button=Save") + self.visit_url('&'.join(url)) for sample_name, fields in samples: self.check_page_for_string( sample_name ) self.check_page_for_string( 'Unsubmitted' ) @@ -1549,19 +1547,24 @@ class TwillTestCase( unittest.TestCase ) tc.fv( "1", "comment", comment ) tc.submit( "reject_button" ) self.check_page_for_string( 'Request <b>%s</b> has been rejected.' % request_name ) - self.visit_url( "%s/requests/list?sort=-create_time&operation=show_request&id=%s" % ( self.url, self.security.encode_id( request_id ) )) + self.visit_url( "%s/requests/list?&operation=show&id=%s" % ( self.url, self.security.encode_id( request_id ) )) self.check_page_for_string( comment ) - def add_bar_codes( self, request_id, request_name, bar_codes ): + def add_bar_codes( self, request_id, request_name, bar_codes, samples ): self.home() - self.visit_url( "%s/requests_admin/bar_codes?request_id=%i" % (self.url, request_id) ) - self.check_page_for_string( 'Bar codes for Samples of Request "%s"' % request_name ) + url = "%s/requests/list?operation=show&id=%s" % ( self.url, self.security.encode_id( request_id ) ) + self.visit_url( url ) + self.check_page_for_string( 'Sequencing Request "%s"' % request_name ) + url = ["%s/requests_common/request_page?save_samples_button=Save&cntrller=requests&edit_mode=True&id=%s" % ( self.url, self.security.encode_id( request_id ) )] for index, bar_code in enumerate(bar_codes): - tc.fv( "1", "sample_%i_bar_code" % index, bar_code ) - tc.submit( "save_bar_codes" ) - self.check_page_for_string( 'Bar codes have been saved for this request' ) + url.append("sample_%i_barcode=%s" % (index, bar_code )) + url.append("sample_%i_name=%s" % (index, samples[index].name.replace(' ', '+') )) + self.visit_url('&'.join(url)) + self.check_page_for_string( 'Changes made to the sample(s) are saved.' ) + for index, bar_code in enumerate(bar_codes): + self.check_page_for_string( bar_code ) def change_sample_state( self, sample_name, sample_id, new_state_id, new_state_name, comment='' ): self.home() - self.visit_url( "%s/requests_admin/show_events?sample_id=%i" % (self.url, sample_id) ) + self.visit_url( "%s/requests_common/sample_events?cntrller=requests_admin&sample_id=%i" % (self.url, sample_id) ) self.check_page_for_string( 'Events for Sample "%s"' % sample_name ) tc.fv( "1", "select_state", str(new_state_id) ) tc.fv( "1", "comment", comment ) --- a/templates/requests/show_data.mako +++ /dev/null @@ -1,86 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - - -%if message: - ${render_msg( message, status )} -%endif - -<script type="text/javascript"> -$(document).ready(function(){ - //hide the all of the element with class msg_body - $(".msg_body").hide(); - //toggle the componenet with class msg_body - $(".msg_head").click(function(){ - $(this).next(".msg_body").slideToggle(450); - }); -}); -</script> -<style type="text/css"> -.msg_head { - padding: 0px 0px; - cursor: pointer; -} - -} -</style> - - -<h2>Data transfer from Sequencer</h2> -<h3>Sample "${sample.name}" of Request "${sample.request.name}"</h3> - -<ul class="manage-table-actions"> - %if sample.request.submitted() and sample.inprogress_dataset_files(): - <li> - <a class="action-button" href="${h.url_for( controller='requests', action='show_datatx_page', sample_id=trans.security.encode_id(sample.id) )}"> - <span>Refresh this page</span></a> - </li> - %endif - %if sample.library: - <li> - <a class="action-button" href="${h.url_for( controller='library_common', action='browse_library', cntrller='library', id=trans.security.encode_id( sample.library.id ) )}"> - <span>${sample.library.name} Data Library</span></a> - </li> - %endif - <li> - <a class="action-button" href="${h.url_for( controller='requests', action='list', operation='show_request', id=trans.security.encode_id(sample.request.id) )}"> - <span>Browse this request</span></a> - </li> -</ul> - -<div class="toolForm"> - <form name="get_data" action="${h.url_for( controller='requests_admin', action='get_data', sample_id=sample.id)}" method="post" > - <div class="form-row"> - %if len(dataset_files): - <table class="grid"> - <thead> - <tr> - <th>Dataset File</th> - <th>Transfer Status</th> - </tr> - <thead> - <tbody> - %for dataset_index, dataset_file in enumerate(dataset_files): - ${sample_dataset_files( dataset_index, dataset_file[0], dataset_file[1] )} - %endfor - </tbody> - </table> - %else: - There are no dataset files. - %endif - </div> - </form> -</div> - -<%def name="sample_dataset_files( dataset_index, dataset_file, status )"> - <tr> - <td>${dataset_file.split('/')[-1]}</td> - <td> - %if status == sample.transfer_status.IN_PROGRESS: - <i>${status}</i> - %else: - ${status} - %endif - </td> - </tr> -</%def> --- /dev/null +++ b/lib/galaxy/web/controllers/requests_common.py @@ -0,0 +1,1099 @@ +from galaxy.web.base.controller import * +from galaxy.web.framework.helpers import time_ago, iff, grids +from galaxy.model.orm import * +from galaxy.datatypes import sniff +from galaxy import model, util +from galaxy.util.streamball import StreamBall +import logging, tempfile, zipfile, tarfile, os, sys, subprocess +from galaxy.web.form_builder import * +from datetime import datetime, timedelta +from galaxy.web.controllers.forms import get_all_forms +from sqlalchemy.sql.expression import func, and_ +from sqlalchemy.sql import select +import pexpect +import ConfigParser, threading, time +from amqplib import client_0_8 as amqp +import csv +log = logging.getLogger( __name__ ) + + +class RequestsCommon( BaseController ): + + @web.json + def sample_state_updates( self, trans, ids=None, states=None, cntrller=None ): + # Avoid caching + trans.response.headers['Pragma'] = 'no-cache' + trans.response.headers['Expires'] = '0' + # Create new HTML for any that have changed + rval = {} + if ids is not None and states is not None: + ids = map( int, ids.split( "," ) ) + states = states.split( "," ) + for id, state in zip( ids, states ): + sample = trans.sa_session.query( self.app.model.Sample ).get( id ) + if sample.current_state().name != state: + rval[id] = { + "state": sample.current_state().name, + "datasets": len(sample.dataset_files), + "html_state": unicode( trans.fill_template( "requests/common/sample_state.mako", sample=sample, cntrller=cntrller ), 'utf-8' ), + "html_datasets": unicode( trans.fill_template( "requests/common/sample_datasets.mako", trans=trans, sample=sample, cntrller=cntrller ), 'utf-8' ) + } + return rval + + + @web.expose + @web.require_login( "create/submit sequencing requests" ) + def new(self, trans, **kwd): + params = util.Params( kwd ) + cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) + if params.get('select_request_type', False) == 'True': + return trans.fill_template( '/requests/common/new_request.mako', + cntrller=cntrller, + select_request_type=self.__select_request_type(trans, 'none'), + widgets=[], + message=message, + status=status) + elif params.get('create_request_button', False) == 'Save' \ + or params.get('create_request_samples_button', False) == 'Add samples': + request_type = trans.sa_session.query( trans.app.model.RequestType ).get( int( params.select_request_type ) ) + if not util.restore_text(params.get('name', '')) \ + or util.restore_text(params.get('select_user', '')) == unicode('none'): + message = 'Please enter the <b>Name</b> of the request and the <b>user</b> on behalf of whom this request will be submitted before saving this request' + kwd['create'] = 'True' + kwd['status'] = 'error' + kwd['message'] = message + kwd['create_request_button'] = None + kwd['create_request_samples_button'] = None + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller=cntrller, + action='new', + **kwd) ) + request = self.__save_request(trans, None, **kwd) + message = 'The new request named <b>%s</b> has been created' % request.name + if params.get('create_request_button', False) == 'Save': + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + message=message , + status='done') ) + elif params.get('create_request_samples_button', False) == 'Add samples': + new_kwd = {} + new_kwd['id'] = trans.security.encode_id(request.id) + new_kwd['operation'] = 'show' + new_kwd['add_sample'] = True + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + message=message , + status='done', + **new_kwd) ) + elif params.get('refresh', False) == 'true': + return self.__show_request_form(trans, **kwd) + + def __select_request_type(self, trans, rtid): + requesttype_list = trans.user.accessible_request_types(trans) + rt_ids = ['none'] + for rt in requesttype_list: + if not rt.deleted: + rt_ids.append(str(rt.id)) + select_reqtype = SelectField('select_request_type', + refresh_on_change=True, + refresh_on_change_values=rt_ids[1:]) + if rtid == 'none': + select_reqtype.add_option('Select one', 'none', selected=True) + else: + select_reqtype.add_option('Select one', 'none') + for rt in requesttype_list: + if not rt.deleted: + if rtid == rt.id: + select_reqtype.add_option(rt.name, rt.id, selected=True) + else: + select_reqtype.add_option(rt.name, rt.id) + return select_reqtype + + def __show_request_form(self, trans, **kwd): + params = util.Params( kwd ) + cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) + try: + request_type = trans.sa_session.query( trans.app.model.RequestType ).get( int( params.select_request_type ) ) + except: + return trans.fill_template( '/requests/common/new_request.mako', + cntrller=cntrller, + select_request_type=self.__select_request_type(trans, 'none'), + widgets=[], + message=message, + status=status) + form_values = None + select_request_type = self.__select_request_type(trans, request_type.id) + # user + if cntrller == 'requests_admin' and trans.user_is_admin(): + user_id = params.get( 'select_user', 'none' ) + try: + user = trans.sa_session.query( trans.app.model.User ).get( int( user_id ) ) + except: + user = None + elif cntrller == 'requests': + user = trans.user + # list of widgets to be rendered on the request form + widgets = [] + if cntrller == 'requests_admin' and trans.user_is_admin(): + widgets.append(dict(label='Select user', + widget=self.__select_user(trans, user_id), + helptext='The request would be submitted on behalf of this user (Required)')) + widgets.append(dict(label='Name of the Experiment', + widget=TextField('name', 40, + util.restore_text( params.get( 'name', '' ) )), + helptext='(Required)')) + widgets.append(dict(label='Description', + widget=TextField('desc', 40, + util.restore_text( params.get( 'desc', '' ) )), + helptext='(Optional)')) + widgets = widgets + request_type.request_form.get_widgets( user, **kwd ) + widgets.append(dict(label='Send email notification when the sequencing request is complete', + widget=CheckboxField('email_notify', False), + helptext='Email would be sent to the lab admin and the user for whom this request has been created.')) + return trans.fill_template( '/requests/common/new_request.mako', + cntrller=cntrller, + select_request_type=select_request_type, + request_type=request_type, + widgets=widgets, + message=message, + status=status) + def __select_user(self, trans, userid): + user_list = trans.sa_session.query( trans.app.model.User )\ + .order_by( trans.app.model.User.email.asc() ) + user_ids = ['none'] + for user in user_list: + if not user.deleted: + user_ids.append(str(user.id)) + select_user = SelectField('select_user', + refresh_on_change=True, + refresh_on_change_values=user_ids[1:]) + if userid == 'none': + select_user.add_option('Select one', 'none', selected=True) + else: + select_user.add_option('Select one', 'none') + for user in user_list: + if not user.deleted: + if userid == str(user.id): + select_user.add_option(user.email, user.id, selected=True) + else: + select_user.add_option(user.email, user.id) + return select_user + def __save_request(self, trans, request, **kwd): + ''' + This method saves a new request if request_id is None. + ''' + params = util.Params( kwd ) + cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + request_type = trans.sa_session.query( trans.app.model.RequestType ).get( int( params.select_request_type ) ) + if request: + user = request.user + else: + if cntrller == 'requests_admin' and trans.user_is_admin(): + user = trans.sa_session.query( trans.app.model.User ).get( int( params.get( 'select_user', '' ) ) ) + elif cntrller == 'requests': + user = trans.user + name = util.restore_text(params.get('name', '')) + desc = util.restore_text(params.get('desc', '')) + notify = CheckboxField.is_checked( params.get('email_notify', '') ) + # fields + values = [] + for index, field in enumerate(request_type.request_form.fields): + if field['type'] == 'AddressField': + value = util.restore_text(params.get('field_%i' % index, '')) + 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() + trans.sa_session.refresh( user ) + values.append(int(user_address.id)) + elif value == unicode('none'): + values.append('') + else: + values.append(int(value)) + elif field['type'] == 'CheckboxField': + values.append(CheckboxField.is_checked( params.get('field_%i' % index, '') )) + else: + values.append(util.restore_text(params.get('field_%i' % index, ''))) + form_values = trans.app.model.FormValues(request_type.request_form, values) + trans.sa_session.add( form_values ) + trans.sa_session.flush() + if not request: + request = trans.app.model.Request(name, desc, request_type, + user, form_values, notify) + trans.sa_session.add( request ) + trans.sa_session.flush() + trans.sa_session.refresh( request ) + # create an event with state 'New' for this new request + if request.user.email is not trans.user: + comments = "Request created by admin (%s) on behalf of %s." % (trans.user.email, request.user.email) + else: + comments = "Request created." + event = trans.app.model.RequestEvent(request, request.states.NEW, comments) + trans.sa_session.add( event ) + trans.sa_session.flush() + else: + request.name = name + request.desc = desc + request.type = request_type + request.user = user + request.notify = notify + request.values = form_values + trans.sa_session.add( request ) + trans.sa_session.flush() + return request + + @web.expose + @web.require_login( "create/submit sequencing requests" ) + def edit(self, trans, **kwd): + params = util.Params( kwd ) + cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) + try: + request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id( params.get( 'id', None ) ) ) + except: + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + status='error', + message="Invalid request ID") ) + if params.get('show', False) == 'True': + return self.__edit_request(trans, **kwd) + elif params.get('save_changes_request_button', False) == 'Save changes' \ + or params.get('edit_samples_button', False) == 'Edit samples': + request_type = trans.sa_session.query( trans.app.model.RequestType ).get( int( params.select_request_type ) ) + if not util.restore_text(params.get('name', '')): + message = 'Please enter the <b>Name</b> of the request' + kwd['status'] = 'error' + kwd['message'] = message + kwd['show'] = 'True' + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller=cntrller, + action='edit', + **kwd) ) + request = self.__save_request(trans, request, **kwd) + message = 'The changes made to the request named %s has been saved' % request.name + if params.get('save_changes_request_button', False) == 'Save changes': + return trans.response.send_redirect( web.url_for( controller=cntrller, + cntrller=cntrller, + action='list', + message=message , + status='done') ) + elif params.get('edit_samples_button', False) == 'Edit samples': + new_kwd = {} + new_kwd['id'] = request.id + new_kwd['edit_samples_button'] = 'Edit samples' + return trans.response.send_redirect( web.url_for( controller=cntrller, + cntrller=cntrller, + action='show', + message=message , + status='done', + **new_kwd) ) + elif params.get('refresh', False) == 'true': + return self.__edit_request(trans, **kwd) + + def __edit_request(self, trans, **kwd): + try: + request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) ) + except: + message = "Invalid request ID" + log.warn( message ) + return trans.response.send_redirect( web.url_for( controller=cntrller, + cntrller=cntrller, + action='list', + status='error', + message=message) ) + params = util.Params( kwd ) + cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) + select_request_type = self.__select_request_type(trans, request.type.id) + # list of widgets to be rendered on the request form + widgets = [] + if util.restore_text( params.get( 'name', '' ) ): + name = util.restore_text( params.get( 'name', '' ) ) + else: + name = request.name + widgets.append(dict(label='Name', + widget=TextField('name', 40, name), + helptext='(Required)')) + if util.restore_text( params.get( 'desc', '' ) ): + desc = util.restore_text( params.get( 'desc', '' ) ) + else: + desc = request.desc + widgets.append(dict(label='Description', + widget=TextField('desc', 40, desc), + helptext='(Optional)')) + widgets = widgets + request.type.request_form.get_widgets( request.user, request.values.content, **kwd ) + widgets.append(dict(label='Send email notification once the sequencing request is complete', + widget=CheckboxField('email_notify', request.notify), + helptext='')) + return trans.fill_template( 'requests/common/edit_request.mako', + cntrller=cntrller, + select_request_type=select_request_type, + request_type=request.type, + request=request, + widgets=widgets, + message=message, + status=status) + def __validate(self, trans, cntrller, request): + ''' + Validates the request entered by the user + ''' + if not request.samples: + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + operation='show', + message='Please add one or more samples to this request before submitting.', + status='error', + id=trans.security.encode_id(request.id)) ) + empty_fields = [] + # check rest of the fields of the form + for index, field in enumerate(request.type.request_form.fields): + if field['required'] == 'required' and request.values.content[index] in ['', None]: + empty_fields.append(field['label']) + if empty_fields: + message = 'Fill the following fields of the request <b>%s</b> before submitting<br/>' % request.name + for ef in empty_fields: + message = message + '<b>' +ef + '</b><br/>' + return message + return None + @web.expose + @web.require_login( "create/submit sequencing requests" ) + def submit(self, trans, **kwd): + params = util.Params( kwd ) + cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + try: + request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) ) + except: + message = "Invalid request ID" + log.warn( message ) + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + status='error', + message=message, + **kwd) ) + message = self.__validate(trans, cntrller, request) + if message: + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + operation='edit', + status = 'error', + message=message, + id=trans.security.encode_id(request.id) ) ) + # change the request state to 'Submitted' + if request.user.email is not trans.user: + comments = "Request submitted by admin (%s) on behalf of %s." % (trans.user.email, request.user.email) + else: + comments = "" + event = trans.app.model.RequestEvent(request, request.states.SUBMITTED, comments) + trans.sa_session.add( event ) + trans.sa_session.flush() + # change the state of each of the samples of thus request + new_state = request.type.states[0] + for s in request.samples: + event = trans.app.model.SampleEvent(s, new_state, 'Samples created.') + trans.sa_session.add( event ) + trans.sa_session.add( request ) + trans.sa_session.flush() + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + id=trans.security.encode_id(request.id), + status='done', + message='The request <b>%s</b> has been submitted.' % request.name + ) ) + @web.expose + @web.require_login( "create/submit sequencing requests" ) + def delete(self, trans, **kwd): + params = util.Params( kwd ) + cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + id_list = util.listify( kwd['id'] ) + for id in id_list: + try: + request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(id) ) + except: + message = "Invalid request ID" + log.warn( message ) + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + status='error', + message=message, + **kwd) ) + request.deleted = True + trans.sa_session.add( request ) + # delete all the samples belonging to this request + for s in request.samples: + s.deleted = True + trans.sa_session.add( s ) + trans.sa_session.flush() + message = '%i request(s) has been deleted.' % len(id_list) + status = 'done' + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + status=status, + message=message) ) + @web.expose + @web.require_login( "create/submit sequencing requests" ) + def undelete(self, trans, **kwd): + params = util.Params( kwd ) + cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + id_list = util.listify( kwd['id'] ) + for id in id_list: + try: + request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(id) ) + except: + message = "Invalid request ID" + log.warn( message ) + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + status='error', + message=message, + **kwd) ) + request.deleted = False + trans.sa_session.add( request ) + # undelete all the samples belonging to this request + for s in request.samples: + s.deleted = False + trans.sa_session.add( s ) + trans.sa_session.flush() + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + status='done', + message='%i request(s) has been undeleted.' % len(id_list) ) ) + @web.expose + @web.require_login( "create/submit sequencing requests" ) + def events(self, trans, **kwd): + params = util.Params( kwd ) + cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + try: + request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) ) + except: + message = "Invalid request ID" + log.warn( message ) + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + status='error', + message=message) ) + events_list = [] + all_events = request.events + for event in all_events: + events_list.append((event.state, time_ago(event.update_time), event.comment)) + return trans.fill_template( '/requests/common/events.mako', + cntrller=cntrller, + events_list=events_list, request=request) + @web.expose + @web.require_login( "create/submit sequencing requests" ) + def show(self, trans, **kwd): + params = util.Params( kwd ) + message = util.restore_text( params.get( 'message', '' ) ) + cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + status = params.get( 'status', 'done' ) + add_sample = params.get('add_sample', False) + try: + request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) ) + except: + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + status='error', + message="Invalid request ID") ) + # get all data libraries accessible to this user + libraries = request.user.accessible_libraries( trans, [ trans.app.security_agent.permitted_actions.LIBRARY_ADD ] ) + current_samples = [] + for i, s in enumerate(request.samples): + lib_widget, folder_widget = self.__library_widgets(trans, request.user, i, libraries, s, **kwd) + current_samples.append(dict(name=s.name, + barcode=s.bar_code, + library=s.library, + folder=s.folder, + dataset_files=s.dataset_files, + field_values=s.values.content, + lib_widget=lib_widget, + folder_widget=folder_widget)) + if add_sample: + lib_widget, folder_widget = self.__library_widgets(trans, request.user, + len(current_samples)+1, + libraries, None, **kwd) + current_samples.append(dict(name='Sample_%i' % (len(current_samples)+1), + barcode='', + library=None, + folder=None, + dataset_files=[], + field_values=['' for field in request.type.sample_form.fields], + lib_widget=lib_widget, + folder_widget=folder_widget)) + return trans.fill_template( '/requests/common/show_request.mako', + cntrller=cntrller, + request=request, + request_details=self.request_details(trans, request.id), + current_samples=current_samples, + sample_copy=self.__copy_sample(current_samples), + details='hide', edit_mode=util.restore_text( params.get( 'edit_mode', 'False' ) ), + message=message, status=status ) + + def __update_samples(self, trans, request, **kwd): + ''' + This method retrieves all the user entered sample information and + returns an list of all the samples and their field values + ''' + params = util.Params( kwd ) + details = params.get( 'details', 'hide' ) + edit_mode = params.get( 'edit_mode', 'False' ) + # get all data libraries accessible to this user + libraries = request.user.accessible_libraries( trans, [ trans.app.security_agent.permitted_actions.LIBRARY_ADD ] ) + + current_samples = [] + for i, s in enumerate(request.samples): + lib_widget, folder_widget = self.__library_widgets(trans, request.user, i, libraries, s, **kwd) + current_samples.append(dict(name=s.name, + barcode=s.bar_code, + library=s.library, + folder=s.folder, + field_values=s.values.content, + lib_widget=lib_widget, + folder_widget=folder_widget)) + if edit_mode == 'False': + sample_index = len(request.samples) + else: + sample_index = 0 + while True: + lib_id = None + folder_id = None + if params.get( 'sample_%i_name' % sample_index, '' ): + # data library + try: + library = trans.sa_session.query( trans.app.model.Library ).get( int( params.get( 'sample_%i_library_id' % sample_index, None ) ) ) + lib_id = library.id + except: + library = None + # folder + try: + folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get( int( params.get( 'sample_%i_folder_id' % sample_index, None ) ) ) + folder_id = folder.id + except: + if library: + folder = library.root_folder + else: + folder = None + sample_info = dict( name=util.restore_text( params.get( 'sample_%i_name' % sample_index, '' ) ), + barcode=util.restore_text( params.get( 'sample_%i_barcode' % sample_index, '' ) ), + library=library, + folder=folder) + sample_info['field_values'] = [] + for field_index in range(len(request.type.sample_form.fields)): + sample_info['field_values'].append(util.restore_text( params.get( 'sample_%i_field_%i' % (sample_index, field_index), '' ) )) + if edit_mode == 'False': + sample_info['lib_widget'], sample_info['folder_widget'] = self.__library_widgets(trans, request.user, + sample_index, libraries, + None, lib_id, folder_id, **kwd) + current_samples.append(sample_info) + else: + sample_info['lib_widget'], sample_info['folder_widget'] = self.__library_widgets(trans, + request.user, + sample_index, + libraries, + request.samples[sample_index], + **kwd) + current_samples[sample_index] = sample_info + sample_index = sample_index + 1 + else: + break + return current_samples, details, edit_mode, libraries + + def __library_widgets(self, trans, user, sample_index, libraries, sample=None, lib_id=None, folder_id=None, **kwd): + ''' + This method creates the data library & folder selectbox for creating & + editing samples. First we get a list of all the libraries accessible to + the current user and display it in a selectbox. If the user has selected an + existing library then display all the accessible sub folders of the selected + data library. + ''' + params = util.Params( kwd ) + # data library selectbox + if not lib_id: + lib_id = params.get( "sample_%i_library_id" % sample_index, 'none' ) + selected_lib = None + if sample and lib_id == 'none': + if sample.library: + lib_id = str(sample.library.id) + selected_lib = sample.library + # create data library selectbox with refresh on change enabled + lib_id_list = ['new'] + [str(lib.id) for lib in libraries.keys()] + lib_widget = SelectField( "sample_%i_library_id" % sample_index, + refresh_on_change=True, + refresh_on_change_values=lib_id_list ) + # fill up the options in the Library selectbox + # first option 'none' is the value for "Select one" option + if lib_id == 'none': + lib_widget.add_option('Select one', 'none', selected=True) + else: + lib_widget.add_option('Select one', 'none') + # all the libraries available to the selected user + for lib, hidden_folder_ids in libraries.items(): + if str(lib.id) == str(lib_id): + lib_widget.add_option(lib.name, lib.id, selected=True) + selected_lib, selected_hidden_folder_ids = lib, hidden_folder_ids.split(',') + else: + lib_widget.add_option(lib.name, lib.id) + lib_widget.refresh_on_change_values.append(lib.id) + # create the folder selectbox + folder_widget = SelectField( "sample_%i_folder_id" % sample_index ) + # when editing a request, either the user has already selected a subfolder or not + if sample: + if sample.folder: + current_fid = sample.folder.id + else: + # when a folder not yet associated with the request then the + # the current folder is set to the root_folder of the + # parent data library if present. + if sample.library: + current_fid = sample.library.root_folder.id + else: + current_fid = params.get( "sample_%i_folder_id" % sample_index, 'none' ) + else: + if folder_id: + current_fid = folder_id + else: + current_fid = 'none' + # first option + if lib_id == 'none': + folder_widget.add_option('Select one', 'none', selected=True) + else: + folder_widget.add_option('Select one', 'none') + if selected_lib: + # get all show-able folders for the selected library + showable_folders = trans.app.security_agent.get_showable_folders( user, user.all_roles(), + selected_lib, + [ trans.app.security_agent.permitted_actions.LIBRARY_ADD ], + selected_hidden_folder_ids ) + for f in showable_folders: + if str(f.id) == str(current_fid): + folder_widget.add_option(f.name, f.id, selected=True) + else: + folder_widget.add_option(f.name, f.id) + return lib_widget, folder_widget + + def __copy_sample(self, current_samples): + copy_list = SelectField('copy_sample') + copy_list.add_option('None', -1, selected=True) + for i, s in enumerate(current_samples): + copy_list.add_option(s['name'], i) + return copy_list + + @web.expose + @web.require_login( "create/submit sequencing requests" ) + def request_page(self, trans, **kwd): + params = util.Params( kwd ) + cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) + try: + request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id( kwd['id']) ) + except: + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + status='error', + message="Invalid request ID") ) + # get the user entered sample details + current_samples, details, edit_mode, libraries = self.__update_samples( trans, request, **kwd ) + if params.get('import_samples_button', False) == 'Import samples': + return self.__import_samples(trans, cntrller, request, current_samples, details, libraries, **kwd) + elif params.get('add_sample_button', False) == 'Add New': + # add an empty or filled sample + # if the user has selected a sample no. to copy then copy the contents + # of the src sample to the new sample else an empty sample + src_sample_index = int(params.get( 'copy_sample', -1 )) + # get the number of new copies of the src sample + num_sample_to_copy = int(params.get( 'num_sample_to_copy', 1 )) + if src_sample_index == -1: + for ns in range(num_sample_to_copy): + # empty sample + lib_widget, folder_widget = self.__library_widgets(trans, request.user, + len(current_samples), + libraries, None, **kwd) + current_samples.append(dict(name='Sample_%i' % (len(current_samples)+1), + barcode='', + library=None, + folder=None, + field_values=['' for field in request.type.sample_form.fields], + lib_widget=lib_widget, + folder_widget=folder_widget)) + else: + src_library_id = current_samples[src_sample_index]['lib_widget'].get_selected()[1] + src_folder_id = current_samples[src_sample_index]['folder_widget'].get_selected()[1] + for ns in range(num_sample_to_copy): + lib_widget, folder_widget = self.__library_widgets(trans, request.user, + len(current_samples), + libraries, sample=None, + lib_id=src_library_id, + folder_id=src_folder_id, + **kwd) + current_samples.append(dict(name=current_samples[src_sample_index]['name']+'_%i' % (len(current_samples)+1), + barcode='', + library_id='none', + folder_id='none', + field_values=[val for val in current_samples[src_sample_index]['field_values']], + lib_widget=lib_widget, + folder_widget=folder_widget)) + return trans.fill_template( '/requests/common/show_request.mako', + cntrller=cntrller, + request=request, + request_details=self.request_details(trans, request.id), + current_samples=current_samples, + sample_copy=self.__copy_sample(current_samples), + details=details, + edit_mode=edit_mode) + elif params.get('save_samples_button', False) == 'Save': + # check for duplicate sample names + message = '' + for index in range(len(current_samples)-len(request.samples)): + sample_index = index + len(request.samples) + sample_name = current_samples[sample_index]['name'] + if not sample_name.strip(): + message = 'Please enter the name of sample number %i' % sample_index + break + count = 0 + for i in range(len(current_samples)): + if sample_name == current_samples[i]['name']: + count = count + 1 + if count > 1: + message = "This request has <b>%i</b> samples with the name <b>%s</b>.\nSamples belonging to a request must have unique names." % (count, sample_name) + break + if message: + return trans.fill_template( '/requests/common/show_request.mako', + cntrller=cntrller, + request=request, + request_details=self.request_details(trans, request.id), + current_samples = current_samples, + sample_copy=self.__copy_sample(current_samples), + details=details, edit_mode=edit_mode, + status='error', message=message) + # save all the new/unsaved samples entered by the user + if edit_mode == 'False': + for index in range(len(current_samples)-len(request.samples)): + sample_index = len(request.samples) + form_values = trans.app.model.FormValues(request.type.sample_form, + current_samples[sample_index]['field_values']) + trans.sa_session.add( form_values ) + trans.sa_session.flush() + s = trans.app.model.Sample(current_samples[sample_index]['name'], '', + request, form_values, + current_samples[sample_index]['barcode'], + current_samples[sample_index]['library'], + current_samples[sample_index]['folder'], + dataset_files=[]) + trans.sa_session.add( s ) + trans.sa_session.flush() + + else: + status = 'done' + message = 'Changes made to the sample(s) are saved. ' + for sample_index in range(len(current_samples)): + sample = request.samples[sample_index] + sample.name = current_samples[sample_index]['name'] + sample.library = current_samples[sample_index]['library'] + sample.folder = current_samples[sample_index]['folder'] + if request.submitted(): + bc_message = self.__validate_barcode(trans, sample, current_samples[sample_index]['barcode']) + if bc_message: + status = 'error' + message += bc_message + else: + if not sample.bar_code: + # if this is a 'new' (still in its first state) sample + # change the state to the next + if sample.current_state().id == request.type.states[0].id: + event = trans.app.model.SampleEvent(sample, + request.type.states[1], + 'Sample added to the system') + trans.sa_session.add( event ) + trans.sa_session.flush() + sample.bar_code = current_samples[sample_index]['barcode'] + trans.sa_session.add( sample ) + trans.sa_session.flush() + form_values = trans.sa_session.query( trans.app.model.FormValues ).get( sample.values.id ) + form_values.content = current_samples[sample_index]['field_values'] + trans.sa_session.add( form_values ) + trans.sa_session.flush() + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + operation='show', + id=trans.security.encode_id(request.id), + status=status, + message=message )) + elif params.get('edit_samples_button', False) == 'Edit samples': + edit_mode = 'True' + return trans.fill_template( '/requests/common/show_request.mako', + cntrller=cntrller, + request=request, + request_details=self.request_details(trans, request.id), + current_samples=current_samples, + sample_copy=self.__copy_sample(current_samples), + details=details, libraries=libraries, + edit_mode=edit_mode) + elif params.get('cancel_changes_button', False) == 'Cancel': + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + operation='show', + id=trans.security.encode_id(request.id)) ) + else: + return trans.fill_template( '/requests/common/show_request.mako', + cntrller=cntrller, + request=request, + request_details=self.request_details(trans, request.id), + current_samples=current_samples, + sample_copy=self.__copy_sample(current_samples), + details=details, libraries=libraries, + edit_mode=edit_mode, status=status, message=message) + + def __import_samples(self, trans, cntrller, request, current_samples, details, libraries, **kwd): + ''' + This method reads the samples csv file and imports all the samples + The format of the csv file is: + SampleName,DataLibrary,DataLibraryFolder,Field1,Field2.... + ''' + try: + params = util.Params( kwd ) + edit_mode = params.get( 'edit_mode', 'False' ) + file_obj = params.get('file_data', '') + reader = csv.reader(file_obj.file) + for row in reader: + lib_id = None + folder_id = None + lib = trans.sa_session.query( trans.app.model.Library ) \ + .filter( and_( trans.app.model.Library.table.c.name==row[1], \ + trans.app.model.Library.table.c.deleted==False ) )\ + .first() + if lib: + folder = trans.sa_session.query( trans.app.model.LibraryFolder ) \ + .filter( and_( trans.app.model.LibraryFolder.table.c.name==row[2], \ + trans.app.model.LibraryFolder.table.c.deleted==False ) )\ + .first() + if folder: + lib_id = lib.id + folder_id = folder.id + lib_widget, folder_widget = self.__library_widgets(trans, request.user, len(current_samples), + libraries, None, lib_id, folder_id, **kwd) + current_samples.append(dict(name=row[0], + barcode='', + library=None, + folder=None, + lib_widget=lib_widget, + folder_widget=folder_widget, + field_values=row[3:])) + return trans.fill_template( '/requests/common/show_request.mako', + cntrller=cntrller, + request=request, + request_details=self.request_details(trans, request.id), + current_samples=current_samples, + sample_copy=self.__copy_sample(current_samples), + details=details, + edit_mode=edit_mode) + except: + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + operation='show', + id=trans.security.encode_id(request.id), + status='error', + message='Error in importing samples file' )) + + def __validate_barcode(self, trans, sample, barcode): + ''' + This method makes sure that the given barcode about to be assigned to + the given sample is gobally unique. That is, barcodes must be unique + across requests in Galaxy LIMS + ''' + message = '' + for index in range(len(sample.request.samples)): + # check for empty bar code + if not barcode.strip(): + message = 'Please fill the barcode for sample <b>%s</b>.' % sample.name + break + # check all the saved bar codes + all_samples = trans.sa_session.query( trans.app.model.Sample ) + for s in all_samples: + if barcode == s.bar_code: + if sample.id == s.id: + continue + else: + message = '''The bar code <b>%s</b> of sample <b>%s</b> + belongs another sample. The sample bar codes must be + unique throughout the system''' % \ + (barcode, sample.name) + break + if message: + break + return message + + + @web.expose + @web.require_login( "create/submit sequencing requests" ) + def delete_sample(self, trans, **kwd): + params = util.Params( kwd ) + cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + request = trans.sa_session.query( trans.app.model.Request ).get( int( params.get( 'request_id', 0 ) ) ) + current_samples, details, edit_mode, libraries = self.__update_samples( trans, request, **kwd ) + sample_index = int(params.get('sample_id', 0)) + sample_name = current_samples[sample_index]['name'] + s = request.has_sample(sample_name) + if s: + trans.sa_session.delete( s.values ) + trans.sa_session.delete( s ) + trans.sa_session.flush() + del current_samples[sample_index] + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + operation='show', + id=trans.security.encode_id(request.id), + status='done', + message='Sample <b>%s</b> has been deleted.' % sample_name )) + return trans.fill_template( '/requests/common/show_request.mako', + controller=cntrller, + request=request, + request_details=self.request_details(trans, request.id), + current_samples = current_samples, + sample_copy=self.__copy_sample(current_samples), + details=details, + edit_mode=edit_mode) + def request_details(self, trans, id): + ''' + Shows the request details + ''' + request = trans.sa_session.query( trans.app.model.Request ).get( id ) + # list of widgets to be rendered on the request form + request_details = [] + # main details + request_details.append(dict(label='User', + value=str(request.user.email), + helptext='')) + request_details.append(dict(label='Description', + value=request.desc, + helptext='')) + request_details.append(dict(label='Type', + value=request.type.name, + helptext='')) + request_details.append(dict(label='State', + value=request.state(), + helptext='')) + request_details.append(dict(label='Date created', + value=request.create_time, + helptext='')) + # form fields + for index, field in enumerate(request.type.request_form.fields): + if field['required']: + req = 'Required' + else: + req = 'Optional' + if field['type'] == 'AddressField': + if request.values.content[index]: + request_details.append(dict(label=field['label'], + value=trans.sa_session.query( trans.app.model.UserAddress ).get( int( request.values.content[index] ) ).get_html(), + helptext=field['helptext']+' ('+req+')')) + else: + request_details.append(dict(label=field['label'], + value=None, + helptext=field['helptext']+' ('+req+')')) + else: + request_details.append(dict(label=field['label'], + value=request.values.content[index], + helptext=field['helptext']+' ('+req+')')) + if request.notify: + notify = 'Yes' + else: + notify = 'No' + request_details.append(dict(label='Send email notification once the sequencing request is complete', + value=notify, + helptext='')) + return request_details + @web.expose + @web.require_login( "create/submit sequencing requests" ) + def sample_events(self, trans, **kwd): + params = util.Params( kwd ) + cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + try: + sample_id = int(params.get('sample_id', False)) + sample = trans.sa_session.query( trans.app.model.Sample ).get( sample_id ) + except: + message = "Invalid sample ID" + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + status='error', + message=message) ) + events_list = [] + all_events = sample.events + for event in all_events: + events_list.append((event.state.name, event.state.desc, + time_ago(event.update_time), + event.comment)) + widgets, title = self.__change_state_widgets(trans, sample) + return trans.fill_template( '/requests/common/sample_events.mako', + cntrller=cntrller, + events_list=events_list, + sample=sample, widgets=widgets, title=title) + def __change_state_widgets(self, trans, sample): + possible_states = sample.request.type.states + curr_state = sample.current_state() + states_input = SelectField('select_state') + for state in possible_states: + if curr_state.name == state.name: + states_input.add_option(state.name+' (Current)', state.id, selected=True) + else: + states_input.add_option(state.name, state.id) + widgets = [] + widgets.append(('Select the new state of the sample from the list of possible state(s)', + states_input)) + widgets.append(('Comments', TextArea('comment'))) + title = 'Change current state' + return widgets, title + @web.expose + @web.require_admin + def show_datatx_page( self, trans, **kwd ): + params = util.Params( kwd ) + cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) + try: + sample = trans.sa_session.query( trans.app.model.Sample ).get( trans.security.decode_id( kwd['sample_id'] ) ) + except: + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + status='error', + message="Invalid sample ID") ) + # check if a library and folder has been set for this sample yet. + if not sample.library or not sample.folder: + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + operation='show', + status='error', + message="Set a data library and folder for <b>%s</b> to transfer dataset(s)." % sample.name, + id=trans.security.encode_id(sample.request.id) ) ) + if params.get( 'folder_path', '' ): + folder_path = util.restore_text( params.get( 'folder_path', '' ) ) + else: + if len(sample.dataset_files): + folder_path = os.path.dirname(sample.dataset_files[-1]['filepath'][:-1]) + else: + folder_path = util.restore_text( sample.request.type.datatx_info.get('data_dir', '') ) + if folder_path and folder_path[-1] != os.sep: + folder_path += os.sep + if not sample.request.type.datatx_info['host'] or not sample.request.type.datatx_info['username'] \ + or not sample.request.type.datatx_info['password']: + status = 'error' + message = 'The sequencer login information is incomplete. Click on the <b>Sequencer information</b> to add login details.' + return trans.fill_template( '/requests/common/get_data.mako', + cntrller=cntrller, sample=sample, + dataset_files=sample.dataset_files, + message=message, status=status, files=[], + folder_path=folder_path ) --- a/templates/requests/events.mako +++ /dev/null @@ -1,39 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - -<h2>History of Sequencing Request "${request.name}"</h2> -<ul class="manage-table-actions"> - <li> - <a class="action-button" href="${h.url_for( controller='requests', action='list', operation='show_request', id=trans.security.encode_id(request.id) )}"> - <span>Browse this request</span></a> - </li> - <li> - <a class="action-button" href="${h.url_for( controller='requests', action='list')}"> - <span>Browse all requests</span></a> - </li> -</ul> - -%if message: - ${render_msg( message, status )} -%endif - -<div class="toolForm"> - <table class="grid"> - <thead> - <tr> - <th>State</th> - <th>Last Update</th> - <th>Comments</th> - </tr> - </thead> - <tbody> - %for state, updated, comments in events_list: - <tr class="libraryRow libraryOrFolderRow" id="libraryRow"> - <td><b><a>${state}</a></b></td> - <td><a>${updated}</a></td> - <td><a>${comments}</a></td> - </tr> - %endfor - </tbody> - </table> -</div> --- /dev/null +++ b/templates/requests/common/sample_state.mako @@ -0,0 +1,5 @@ +<%def name="render_sample_state( cntrller, sample )"> + <a href="${h.url_for( controller='requests_common', cntrller=cntrller, action='sample_events', sample_id=sample.id)}">${sample.current_state().name}</a> +</%def> + +${render_sample_state( cntrller, sample )} --- /dev/null +++ b/templates/requests/common/get_data.mako @@ -0,0 +1,239 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + + +%if message: + ${render_msg( message, status )} +%endif + +<script type="text/javascript"> +$(document).ready(function(){ + //hide the all of the element with class msg_body + $(".msg_body").hide(); + //toggle the componenet with class msg_body + $(".msg_head").click(function(){ + $(this).next(".msg_body").slideToggle(450); + }); +}); + + + + +</script> + +<script type="text/javascript"> + function display_file_details(sample_id, folder_path) + { + var w = document.get_data.files_list.selectedIndex; + var selected_value = document.get_data.files_list.options[w].value; + var cell = $("#file_details"); + if(selected_value.charAt(selected_value.length-1) != '/') + { + // Make ajax call + $.ajax( { + type: "POST", + url: "${h.url_for( controller='requests_admin', action='get_file_details' )}", + dataType: "json", + data: { id: sample_id, folder_path: document.get_data.folder_path.value+selected_value }, + success : function ( data ) { + cell.html( '<label>'+data+'</label>' ) + } + }); + } + else + { + cell.html( '' ) + } + + + } +</script> + +<script type="text/javascript"> + function open_folder1(sample_id, folder_path) + { + var w = document.get_data.files_list.selectedIndex; + var selected_value = document.get_data.files_list.options[w].value; + var cell = $("#file_details"); + if(selected_value.charAt(selected_value.length-1) == '/') + { + document.get_data.folder_path.value = document.get_data.folder_path.value+selected_value + // Make ajax call + $.ajax( { + type: "POST", + url: "${h.url_for( controller='requests_admin', action='open_folder' )}", + dataType: "json", + data: { id: sample_id, folder_path: document.get_data.folder_path.value }, + success : function ( data ) { + document.get_data.files_list.options.length = 0 + for(i=0; i<data.length; i++) + { + var newOpt = new Option(data[i], data[i]); + document.get_data.files_list.options[i] = newOpt; + } + //cell.html( '<label>'+data+'</label>' ) + + } + }); + } + else + { + cell.html( '' ) + } + } +</script> + + +<style type="text/css"> +.msg_head { + padding: 0px 0px; + cursor: pointer; +} + +} +</style> + + +<h2>Data transfer from Sequencer</h2> +<h3>Sample "${sample.name}" of Request "${sample.request.name}"</h3> +<br/> +<br/> + +<ul class="manage-table-actions"> + %if sample.request.submitted() and sample.inprogress_dataset_files(): + <li> + <a class="action-button" href="${h.url_for( controller='requests_common', cntrller=cntrller, action='show_datatx_page', sample_id=trans.security.encode_id(sample.id) )}"> + <span>Refresh this page</span></a> + </li> + %endif + %if cntrller == 'requests_admin' and trans.user_is_admin(): + <li> + <a class="action-button" href="${h.url_for( controller='requests_admin', action='manage_request_types', operation='view', id=trans.security.encode_id(sample.request.type.id) )}"> + <span>Sequencer information</span></a> + </li> + + <li> + <a class="action-button" href="${h.url_for( controller='library_common', action='browse_library', cntrller='library_admin', id=trans.security.encode_id( sample.library.id ) )}"> + <span>${sample.library.name} Data Library</span></a> + </li> + %else: + <li> + <a class="action-button" href="${h.url_for( controller='library_common', action='browse_library', cntrller='library', id=trans.security.encode_id( sample.library.id ) )}"> + <span>${sample.library.name} Data Library</span></a> + </li> + %endif + <li> + <a class="action-button" href="${h.url_for( controller=cntrller, action='list', operation='show', id=trans.security.encode_id(sample.request.id) )}"> + <span>Browse this request</span></a> + </li> +</ul> + +<div class="toolForm"> + %if len(dataset_files): + <div class="form-row"> + <h4>Sample Dataset(s)</h4> + %if sample.untransferred_dataset_files() and cntrller == 'requests_admin': + <div class="form-row"> + <ul class="manage-table-actions"> + <li> + <a class="action-button" href="${h.url_for( controller='requests_admin', action='get_data', start_transfer_button=True, sample_id=sample.id )}"> + <span>Start transfer</span></a> + </li> + </ul> + </div> + %endif + <div class="form-row"> + <table class="grid"> + <thead> + <tr> + <th>Dataset File</th> + <th>Transfer Status</th> + <th></th> + </tr> + <thead> + <tbody> + %for dataset_index, dataset_file in enumerate(dataset_files): + ${sample_dataset_files( dataset_index, dataset_file['name'], dataset_file['status'] )} + %endfor + </tbody> + </table> + </div> + </div> + %else: + <div class="form-row"> + There are no dataset files associated with this sample. + </div> + %endif + + <br/> + <br/> + + %if cntrller == 'requests_admin' and trans.user_is_admin(): + <form name="get_data" id="get_data" action="${h.url_for( controller='requests_admin', cntrller=cntrller, action='get_data', sample_id=sample.id)}" method="post" > + <div class="form-row"> + ##<div class="toolFormTitle">Select files for transfer</div> + <h4>Select files for transfer</h4> + <div style="width: 60%;"> + <div class="form-row"> + <label>Folder path on the sequencer:</label> + <input type="text" name="folder_path" value="${folder_path}" size="100"/> + <input type="submit" name="browse_button" value="List contents"/> + ##<input type="submit" name="open_folder" value="Open folder"/> + <input type="submit" name="folder_up" value="Up"/> + </div> + <div class="form-row"> + <select name="files_list" id="files_list" style="max-width: 98%; width: 98%; height: 150px; font-size: 100%;" ondblclick="open_folder1(${sample.id}, '${folder_path}')" onChange="display_file_details(${sample.id}, '${folder_path}')" multiple> + %for index, f in enumerate(files): + <option value="${f}">${f}</option> + %endfor + </select> + <br/> + <div id="file_details" class="toolParamHelp" style="clear: both;"> + + </div> + </div> + <div class="form-row"> + <div class="toolParamHelp" style="clear: both;"> + After selecting dataset(s), be sure to click on the <b>Start transfer</b> button. + Once the transfer is complete the dataset(s) will show up on this page. + </div> + <input type="submit" name="select_files_button" value="Select"/> + </div> + </div> + </div> + </form> + %endif +</div> + + + + +<%def name="sample_dataset_files( dataset_index, dataset_name, status )"> + <tr> + + <td> + %if cntrller == 'requests_admin' and trans.user_is_admin(): + <label class="msg_head"><a href="${h.url_for( controller='requests_admin', action='dataset_details', sample_id=trans.security.encode_id(sample.id), dataset_index=dataset_index )}">${dataset_name}</a></label> + %else: + ${dataset_name} + %endif + </td> + <td> + %if status not in [sample.transfer_status.NOT_STARTED, sample.transfer_status.COMPLETE]: + <i>${status}</i> + %else: + ${status} + %endif + </td> + ##<td></td> + %if status == sample.transfer_status.NOT_STARTED and cntrller == 'requests_admin' and trans.user_is_admin(): + <td> + <a class="action-button" href="${h.url_for( controller='requests_admin', action='get_data', sample_id=sample.id, remove_dataset_button=True, dataset_index=dataset_index )}"> + <img src="${h.url_for('/static/images/delete_icon.png')}" /> + <span></span></a> + </td> + %else: + <td></td> + %endif + </tr> +</%def> --- a/templates/admin/requests/events.mako +++ /dev/null @@ -1,36 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - -<h2>History of Sequencing Request "${request.name}"</h2> -<ul class="manage-table-actions"> - <li> - <a class="action-button" href="${h.url_for( controller='requests_admin', action='list', operation='show_request', id=trans.security.encode_id(request.id) )}"> - <span>Browse this request</span></a> - </li> -</ul> -<h3>User: ${request.user.email}</h3> - -%if message: - ${render_msg( message, status )} -%endif - -<div class="toolForm"> - <table class="grid"> - <thead> - <tr> - <th>State</th> - <th>Last Update</th> - <th>Comments</th> - </tr> - </thead> - <tbody> - %for state, updated, comments in events_list: - <tr class="libraryRow libraryOrFolderRow" id="libraryRow"> - <td><b><a>${state}</a></b></td> - <td><a>${updated}</a></td> - <td><a>${comments}</a></td> - </tr> - %endfor - </tbody> - </table> -</div> --- a/lib/galaxy/web/controllers/requests_admin.py +++ b/lib/galaxy/web/controllers/requests_admin.py @@ -95,7 +95,7 @@ class RequestsGrid( grids.Grid ): NameColumn( "Name", key="name", model_class=model.Request, - link=( lambda item: iff( item.deleted, None, dict( operation="show_request", id=item.id ) ) ), + link=( lambda item: iff( item.deleted, None, dict( operation="show", id=item.id ) ) ), attach_popup=True, filterable="advanced" ), DescriptionColumn( "Description", @@ -103,7 +103,7 @@ class RequestsGrid( grids.Grid ): model_class=model.Request, filterable="advanced" ), SamplesColumn( "Sample(s)", - link=( lambda item: iff( item.deleted, None, dict( operation="show_request", id=item.id ) ) ), ), + link=( lambda item: iff( item.deleted, None, dict( operation="show", id=item.id ) ) ), ), TypeColumn( "Type", link=( lambda item: iff( item.deleted, None, dict( operation="view_type", id=item.type.id ) ) ), ), grids.GridColumn( "Last Updated", key="update_time", format=time_ago ), @@ -137,7 +137,8 @@ class RequestsGrid( grids.Grid ): grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ) ), ] global_actions = [ - grids.GridAction( "Create new request", dict( controller='requests_admin', + grids.GridAction( "Create new request", dict( controller='requests_common', + cntrller='requests_admin', action='new', select_request_type='True' ) ) ] @@ -218,6 +219,58 @@ class RequestsAdmin( BaseController ): @web.require_admin def index( self, trans ): return trans.fill_template( "/admin/requests/index.mako" ) + + @web.expose + @web.require_admin + def list( self, trans, **kwd ): + ''' + List all request made by the current user + ''' + if 'operation' in kwd: + operation = kwd['operation'].lower() + if not kwd.get( 'id', None ): + return trans.response.send_redirect( web.url_for( controller='requests_admin', + action='list', + status='error', + message="Invalid request ID") ) + if operation == "show": + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests_admin', + action='show', + **kwd ) ) + elif operation == "submit": + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests_admin', + action='submit', + **kwd ) ) + elif operation == "delete": + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests_admin', + action='delete', + **kwd ) ) + elif operation == "undelete": + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests_admin', + action='undelete', + **kwd ) ) + elif operation == "edit": + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests_admin', + action='edit', + show=True, **kwd ) ) + elif operation == "events": + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests_admin', + action='events', + **kwd ) ) + elif operation == "reject": + return self.__reject_request( trans, **kwd ) + elif operation == "view_type": + return self.__view_request_type( trans, **kwd ) + elif operation == "upload_datasets": + return self.__upload_datasets( trans, **kwd ) + # Render the grid view + return self.request_grid( trans, **kwd ) @web.json def get_file_details( self, trans, id=None, folder_path=None ): @@ -246,239 +299,6 @@ class RequestsAdmin( BaseController ): sample = trans.sa_session.query( self.app.model.Sample ).get( int(id) ) return self.__get_files(trans, sample, folder_path) - - @web.json - def sample_state_updates( self, trans, ids=None, states=None ): - # Avoid caching - trans.response.headers['Pragma'] = 'no-cache' - trans.response.headers['Expires'] = '0' - # Create new HTML for any that have changed - rval = {} - if ids is not None and states is not None: - ids = map( int, ids.split( "," ) ) - states = states.split( "," ) - for id, state in zip( ids, states ): - sample = trans.sa_session.query( self.app.model.Sample ).get( id ) - if sample.current_state().name != state: - rval[id] = { - "state": sample.current_state().name, - "datasets": len(sample.dataset_files), - "html_state": unicode( trans.fill_template( "requests/sample_state.mako", sample=sample ), 'utf-8' ), - "html_datasets": unicode( trans.fill_template( "requests/sample_datasets.mako", trans=trans, sample=sample ), 'utf-8' ) - } - return rval - - @web.expose - @web.require_admin - def list( self, trans, **kwd ): - ''' - List all request made by the current user - ''' - if 'operation' in kwd: - operation = kwd['operation'].lower() - if not kwd.get( 'id', None ): - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status='error', - message="Invalid request ID") ) - if operation == "show_request": - return self.__show_request( trans, **kwd ) - elif operation == "submit": - return self.__submit_request( trans, **kwd ) - elif operation == "delete": - return self.__delete_request( trans, **kwd ) - elif operation == "undelete": - return self.__undelete_request( trans, **kwd ) - elif operation == "edit": - return self.__edit_request( trans, **kwd ) - elif operation == "reject": - return self.__reject_request( trans, **kwd ) - elif operation == "events": - return self.__request_events( trans, **kwd ) - elif operation == "view_type": - return self.__view_request_type( trans, **kwd ) - elif operation == "upload_datasets": - return self.__upload_datasets( trans, **kwd ) - # Render the grid view - return self.request_grid( trans, **kwd ) - @web.expose - @web.require_admin - def edit(self, trans, **kwd): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - try: - request = trans.sa_session.query( trans.app.model.Request ).get( int( params.get( 'request_id', None ) ) ) - except: - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status='error', - message="Invalid request ID", - **kwd) ) - if params.get('show', False) == 'True': - return self.__edit_request(trans, id=trans.security.encode_id(request.id), **kwd) - elif params.get('save_changes_request_button', False) == 'Save changes' \ - or params.get('edit_samples_button', False) == 'Edit samples': - request_type = trans.sa_session.query( trans.app.model.RequestType ).get( int( params.select_request_type ) ) - if not util.restore_text(params.get('name', '')): - message = 'Please enter the <b>Name</b> of the request' - kwd['status'] = 'error' - kwd['message'] = message - kwd['show'] = 'True' - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='edit', - **kwd) ) - request = self.__save_request(trans, request, **kwd) - message = 'The changes made to the request named %s has been saved' % request.name - if params.get('save_changes_request_button', False) == 'Save changes': - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - message=message , - status='done') ) - elif params.get('edit_samples_button', False) == 'Edit samples': - new_kwd = {} - new_kwd['request_id'] = request.id - new_kwd['edit_samples_button'] = 'Edit samples' - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='show_request', - message=message , - status='done', - **new_kwd) ) - elif params.get('refresh', False) == 'true': - return self.__edit_request(trans, id=trans.security.encode_id(request.id), **kwd) - - def __edit_request(self, trans, **kwd): - try: - request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) ) - except: - message = "Invalid request ID" - log.warn( message ) - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status='error', - message=message) ) - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - select_request_type = self.__select_request_type(trans, request.type.id) - # list of widgets to be rendered on the request form - widgets = [] - if util.restore_text( params.get( 'name', '' ) ): - name = util.restore_text( params.get( 'name', '' ) ) - else: - name = request.name - widgets.append(dict(label='Name', - widget=TextField('name', 40, name), - helptext='(Required)')) - if util.restore_text( params.get( 'desc', '' ) ): - desc = util.restore_text( params.get( 'desc', '' ) ) - else: - desc = request.desc - widgets.append(dict(label='Description', - widget=TextField('desc', 40, desc), - helptext='(Optional)')) - widgets = widgets + request.type.request_form.get_widgets( request.user, request.values.content, **kwd ) - widgets.append(dict(label='Send email notification once the sequencing request is complete', - widget=CheckboxField('email_notify', request.notify), - helptext='')) - return trans.fill_template( '/admin/requests/edit_request.mako', - select_request_type=select_request_type, - request_type=request.type, - request=request, - widgets=widgets, - message=message, - status=status) - return self.__show_request_form(trans) - def __delete_request(self, trans, **kwd): - id_list = util.listify( kwd['id'] ) - for id in id_list: - try: - request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(id) ) - except: - message = "Invalid request ID" - log.warn( message ) - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status='error', - message=message, - **kwd) ) - request.deleted = True - trans.sa_session.add( request ) - # delete all the samples belonging to this request - for s in request.samples: - s.deleted = True - trans.sa_session.add( s ) - trans.sa_session.flush() - message = '%i request(s) has been deleted.' % len(id_list) - status = 'done' - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status=status, - message=message) ) - def __undelete_request(self, trans, **kwd): - id_list = util.listify( kwd['id'] ) - for id in id_list: - try: - request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(id) ) - except: - message = "Invalid request ID" - log.warn( message ) - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status='error', - message=message, - **kwd) ) - request.deleted = False - trans.sa_session.add( request ) - # undelete all the samples belonging to this request - for s in request.samples: - s.deleted = False - trans.sa_session.add( s ) - trans.sa_session.flush() - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status='done', - message='%i request(s) has been undeleted.' % len(id_list) ) ) - def __submit_request(self, trans, **kwd): - try: - request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) ) - except: - message = "Invalid request ID" - log.warn( message ) - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status='error', - message=message, - **kwd) ) - message = self.__validate(trans, request) - if message: - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - operation='edit', - status = 'error', - message=message, - id=trans.security.encode_id(request.id) ) ) - # change the request state to 'Submitted' - if request.user.email is not trans.user: - comments = "Request submitted by admin (%s) on behalf of %s." % (trans.user.email, request.user.email) - else: - comments = "" - event = trans.app.model.RequestEvent(request, request.states.SUBMITTED, comments) - trans.sa_session.add( event ) - trans.sa_session.flush() - # change the state of each of the samples of thus request - new_state = request.type.states[0] - for s in request.samples: - event = trans.app.model.SampleEvent(s, new_state, 'Samples created.') - trans.sa_session.add( event ) - trans.sa_session.add( request ) - trans.sa_session.flush() - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - id=trans.security.encode_id(request.id), - status='done', - message='The request <b>%s</b> has been submitted.' % request.name - ) ) def __reject_request(self, trans, **kwd): try: request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) ) @@ -526,759 +346,10 @@ class RequestsAdmin( BaseController ): status='done', message='Request <b>%s</b> has been rejected.' % request.name) ) - def __request_events(self, trans, **kwd): - try: - request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) ) - except: - message = "Invalid request ID" - log.warn( message ) - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status='error', - message=message, - **kwd) ) - events_list = [] - all_events = request.events - for event in all_events: - events_list.append((event.state, time_ago(event.update_time), event.comment)) - return trans.fill_template( '/admin/requests/events.mako', - events_list=events_list, request=request) - def __upload_datasets(self, trans, **kwd): return trans.fill_template( '/admin/requests/upload_datasets.mako' ) -# -#---- Request Creation ---------------------------------------------------------- -# - def __select_request_type(self, trans, rtid): - requesttype_list = trans.user.accessible_request_types(trans) - rt_ids = ['none'] - for rt in requesttype_list: - if not rt.deleted: - rt_ids.append(str(rt.id)) - select_reqtype = SelectField('select_request_type', - refresh_on_change=True, - refresh_on_change_values=rt_ids[1:]) - if rtid == 'none': - select_reqtype.add_option('Select one', 'none', selected=True) - else: - select_reqtype.add_option('Select one', 'none') - for rt in requesttype_list: - if not rt.deleted: - if rtid == rt.id: - select_reqtype.add_option(rt.name, rt.id, selected=True) - else: - select_reqtype.add_option(rt.name, rt.id) - return select_reqtype - @web.expose - @web.require_admin - def new(self, trans, **kwd): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - if params.get('select_request_type', False) == 'True': - return trans.fill_template( '/admin/requests/new_request.mako', - select_request_type=self.__select_request_type(trans, 'none'), - widgets=[], - message=message, - status=status) - elif params.get('create', False) == 'True': - if params.get('create_request_button', False) == 'Save' \ - or params.get('create_request_samples_button', False) == 'Add samples': - request_type = trans.sa_session.query( trans.app.model.RequestType ).get( int( params.select_request_type ) ) - if not util.restore_text(params.get('name', '')) \ - or util.restore_text(params.get('select_user', '')) == unicode('none'): - message = 'Please enter the <b>Name</b> of the request and the <b>user</b> on behalf of whom this request will be submitted before saving this request' - kwd['create'] = 'True' - kwd['status'] = 'error' - kwd['message'] = message - kwd['create_request_button'] = None - kwd['create_request_samples_button'] = None - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='new', - **kwd) ) - request = self.__save_request(trans, None, **kwd) - message = 'The new request named %s has been created' % request.name - if params.get('create_request_button', False) == 'Save': - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - message=message , - status='done') ) - elif params.get('create_request_samples_button', False) == 'Add samples': - new_kwd = {} - new_kwd['id'] = trans.security.encode_id(request.id) - new_kwd['operation'] = 'show_request' - new_kwd['add_sample'] = True - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - message=message , - status='done', - **new_kwd) ) - else: - return self.__show_request_form(trans, **kwd) - elif params.get('refresh', False) == 'true': - return self.__show_request_form(trans, **kwd) - def __show_request_form(self, trans, **kwd): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - try: - request_type = trans.sa_session.query( trans.app.model.RequestType ).get( int( params.select_request_type ) ) - except: - return trans.fill_template( '/admin/requests/new_request.mako', - select_request_type=self.__select_request_type(trans, 'none'), - widgets=[], - message=message, - status=status) - form_values = None - select_request_type = self.__select_request_type(trans, request_type.id) - # user - user_id = params.get( 'select_user', 'none' ) - try: - user = trans.sa_session.query( trans.app.model.User ).get( int( user_id ) ) - except: - user = None - # list of widgets to be rendered on the request form - widgets = [] - widgets.append(dict(label='Select user', - widget=self.__select_user(trans, user_id), - helptext='The request would be submitted on behalf of this user (Required)')) - widgets.append(dict(label='Name of the Experiment', - widget=TextField('name', 40, - util.restore_text( params.get( 'name', '' ) )), - helptext='(Required)')) - widgets.append(dict(label='Description', - widget=TextField('desc', 40, - util.restore_text( params.get( 'desc', '' ) )), - helptext='(Optional)')) - widgets = widgets + request_type.request_form.get_widgets( user, **kwd ) - widgets.append(dict(label='Send email notification once the sequencing request is complete', - widget=CheckboxField('email_notify', False), - helptext='Email would be sent to the lab admin and the user for whom this request has been created.')) - return trans.fill_template( '/admin/requests/new_request.mako', - select_request_type=select_request_type, - request_type=request_type, - widgets=widgets, - message=message, - status=status) - def __select_user(self, trans, userid): - user_list = trans.sa_session.query( trans.app.model.User )\ - .order_by( trans.app.model.User.email.asc() ) - user_ids = ['none'] - for user in user_list: - if not user.deleted: - user_ids.append(str(user.id)) - select_user = SelectField('select_user', - refresh_on_change=True, - refresh_on_change_values=user_ids[1:]) - if userid == 'none': - select_user.add_option('Select one', 'none', selected=True) - else: - select_user.add_option('Select one', 'none') - for user in user_list: - if not user.deleted: - if userid == str(user.id): - select_user.add_option(user.email, user.id, selected=True) - else: - select_user.add_option(user.email, user.id) - return select_user - def __validate(self, trans, request): - ''' - Validates the request entered by the user - ''' - if not request.samples: - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - operation='show_request', - message='Please add one or more samples to this request before submitting.', - status='error', - id=trans.security.encode_id(request.id)) ) - empty_fields = [] - # check rest of the fields of the form - for index, field in enumerate(request.type.request_form.fields): - if field['required'] == 'required' and request.values.content[index] in ['', None]: - empty_fields.append(field['label']) - if empty_fields: - message = 'Fill the following fields of the request <b>%s</b> before submitting<br/>' % request.name - for ef in empty_fields: - message = message + '<b>' +ef + '</b><br/>' - return message - return None - def __save_request(self, trans, request=None, **kwd): - ''' - This method saves a new request if request_id is None. - ''' - params = util.Params( kwd ) - request_type = trans.sa_session.query( trans.app.model.RequestType ).get( int( params.select_request_type ) ) - if request: - user = request.user - else: - user = trans.sa_session.query( trans.app.model.User ).get( int( params.get( 'select_user', '' ) ) ) - name = util.restore_text(params.get('name', '')) - desc = util.restore_text(params.get('desc', '')) - notify = CheckboxField.is_checked( params.get('email_notify', '') ) - # fields - values = [] - for index, field in enumerate(request_type.request_form.fields): - if field['type'] == 'AddressField': - value = util.restore_text(params.get('field_%i' % index, '')) - 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() - trans.sa_session.refresh( trans.user ) - values.append(int(user_address.id)) - elif value == unicode('none'): - values.append('') - else: - values.append(int(value)) - elif field['type'] == 'CheckboxField': - values.append(CheckboxField.is_checked( params.get('field_%i' % index, '') )) - else: - values.append(util.restore_text(params.get('field_%i' % index, ''))) - form_values = trans.app.model.FormValues(request_type.request_form, values) - trans.sa_session.add( form_values ) - trans.sa_session.flush() - if not request: - request = trans.app.model.Request(name, desc, request_type, - user, form_values, notify) - trans.sa_session.add( request ) - trans.sa_session.flush() - trans.sa_session.refresh( request ) - # create an event with state 'New' for this new request - if request.user.email is not trans.user: - comments = "Request created by admin (%s) on behalf of %s." % (trans.user.email, request.user.email) - else: - comments = "Request created." - event = trans.app.model.RequestEvent(request, request.states.NEW, comments) - trans.sa_session.add( event ) - trans.sa_session.flush() - else: - request.name = name - request.desc = desc - request.type = request_type - request.user = user - request.notify = notify - request.values = form_values - trans.sa_session.add( request ) - trans.sa_session.flush() - return request -# -#---- Request Page ---------------------------------------------------------- -# - def __show_request(self, trans, **kwd): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - add_sample = params.get('add_sample', False) - try: - request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) ) - except: - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status='error', - message="Invalid request ID") ) - # get all data libraries accessible to this user - libraries = request.user.accessible_libraries( trans, [ trans.app.security_agent.permitted_actions.LIBRARY_ADD ] ) - current_samples = [] - for i, s in enumerate(request.samples): - lib_widget, folder_widget = self.__library_widgets(trans, request.user, i, libraries, s, **kwd) - current_samples.append(dict(name=s.name, - barcode=s.bar_code, - library=s.library, - folder=s.folder, - dataset_files=s.dataset_files, - field_values=s.values.content, - lib_widget=lib_widget, - folder_widget=folder_widget)) - if add_sample: - lib_widget, folder_widget = self.__library_widgets(trans, request.user, - len(current_samples)+1, - libraries, None, **kwd) - current_samples.append(dict(name='Sample_%i' % (len(current_samples)+1), - barcode='', - library=None, - folder=None, - dataset_files=[], - field_values=['' for field in request.type.sample_form.fields], - lib_widget=lib_widget, - folder_widget=folder_widget)) - return trans.fill_template( '/admin/requests/show_request.mako', - request=request, - request_details=self.request_details(trans, request.id), - current_samples=current_samples, - sample_copy=self.__copy_sample(current_samples), - details='hide', edit_mode=util.restore_text( params.get( 'edit_mode', 'False' ) ), - message=message, status=status ) - def __library_widgets(self, trans, user, sample_index, libraries, sample=None, lib_id=None, folder_id=None, **kwd): - ''' - This method creates the data library & folder selectbox for creating & - editing samples. First we get a list of all the libraries accessible to - the current user and display it in a selectbox. If the user has selected an - existing library then display all the accessible sub folders of the selected - data library. - ''' - params = util.Params( kwd ) - # data library selectbox - if not lib_id: - lib_id = params.get( "sample_%i_library_id" % sample_index, 'none' ) - selected_lib = None - if sample and lib_id == 'none': - if sample.library: - lib_id = str(sample.library.id) - selected_lib = sample.library - # create data library selectbox with refresh on change enabled - lib_id_list = ['new'] + [str(lib.id) for lib in libraries.keys()] - lib_widget = SelectField( "sample_%i_library_id" % sample_index, - refresh_on_change=True, - refresh_on_change_values=lib_id_list ) - # fill up the options in the Library selectbox - # first option 'none' is the value for "Select one" option - if lib_id == 'none': - lib_widget.add_option('Select one', 'none', selected=True) - else: - lib_widget.add_option('Select one', 'none') - # all the libraries available to the selected user - for lib, hidden_folder_ids in libraries.items(): - if str(lib.id) == str(lib_id): - lib_widget.add_option(lib.name, lib.id, selected=True) - selected_lib, selected_hidden_folder_ids = lib, hidden_folder_ids.split(',') - else: - lib_widget.add_option(lib.name, lib.id) - lib_widget.refresh_on_change_values.append(lib.id) - # create the folder selectbox - folder_widget = SelectField( "sample_%i_folder_id" % sample_index ) - # when editing a request, either the user has already selected a subfolder or not - if sample: - if sample.folder: - current_fid = sample.folder.id - else: - # when a folder not yet associated with the request then the - # the current folder is set to the root_folder of the - # parent data library if present. - if sample.library: - current_fid = sample.library.root_folder.id - else: - current_fid = params.get( "sample_%i_folder_id" % sample_index, 'none' ) - else: - if folder_id: - current_fid = folder_id - else: - current_fid = 'none' - # first option - if lib_id == 'none': - folder_widget.add_option('Select one', 'none', selected=True) - else: - folder_widget.add_option('Select one', 'none') - if selected_lib: - # get all show-able folders for the selected library - showable_folders = trans.app.security_agent.get_showable_folders( user, user.all_roles(), - selected_lib, - [ trans.app.security_agent.permitted_actions.LIBRARY_ADD ], - selected_hidden_folder_ids ) - for f in showable_folders: - if str(f.id) == str(current_fid): - folder_widget.add_option(f.name, f.id, selected=True) - else: - folder_widget.add_option(f.name, f.id) - return lib_widget, folder_widget - def __update_samples(self, trans, request, **kwd): - ''' - This method retrieves all the user entered sample information and - returns an list of all the samples and their field values - ''' - params = util.Params( kwd ) - details = params.get( 'details', 'hide' ) - edit_mode = params.get( 'edit_mode', 'False' ) - # get all data libraries accessible to this user - libraries = request.user.accessible_libraries( trans, [ trans.app.security_agent.permitted_actions.LIBRARY_ADD ] ) - - current_samples = [] - for i, s in enumerate(request.samples): - lib_widget, folder_widget = self.__library_widgets(trans, request.user, i, libraries, s, **kwd) - current_samples.append(dict(name=s.name, - barcode=s.bar_code, - library=s.library, - folder=s.folder, - field_values=s.values.content, - lib_widget=lib_widget, - folder_widget=folder_widget)) - if edit_mode == 'False': - sample_index = len(request.samples) - else: - sample_index = 0 - while True: - lib_id = None - folder_id = None - if params.get( 'sample_%i_name' % sample_index, '' ): - # data library - try: - library = trans.sa_session.query( trans.app.model.Library ).get( int( params.get( 'sample_%i_library_id' % sample_index, None ) ) ) - lib_id = library.id - except: - library = None - # folder - try: - folder = trans.sa_session.query( trans.app.model.LibraryFolder ).get( int( params.get( 'sample_%i_folder_id' % sample_index, None ) ) ) - folder_id = folder.id - except: - if library: - folder = library.root_folder - else: - folder = None - sample_info = dict( name=util.restore_text( params.get( 'sample_%i_name' % sample_index, '' ) ), - barcode=util.restore_text( params.get( 'sample_%i_barcode' % sample_index, '' ) ), - library=library, - folder=folder) - sample_info['field_values'] = [] - for field_index in range(len(request.type.sample_form.fields)): - sample_info['field_values'].append(util.restore_text( params.get( 'sample_%i_field_%i' % (sample_index, field_index), '' ) )) - if edit_mode == 'False': - sample_info['lib_widget'], sample_info['folder_widget'] = self.__library_widgets(trans, request.user, - sample_index, libraries, - None, lib_id, folder_id, **kwd) - current_samples.append(sample_info) - else: - sample_info['lib_widget'], sample_info['folder_widget'] = self.__library_widgets(trans, - request.user, - sample_index, - libraries, - request.samples[sample_index], - **kwd) - current_samples[sample_index] = sample_info - sample_index = sample_index + 1 - else: - break - return current_samples, details, edit_mode, libraries - def __copy_sample(self, current_samples): - copy_list = SelectField('copy_sample') - copy_list.add_option('None', -1, selected=True) - for i, s in enumerate(current_samples): - copy_list.add_option(s['name'], i) - return copy_list - def __import_samples(self, trans, request, current_samples, details, libraries, **kwd): - ''' - This method reads the samples csv file and imports all the samples - The format of the csv file is: - SampleName,DataLibrary,DataLibraryFolder,Field1,Field2.... - ''' - try: - params = util.Params( kwd ) - edit_mode = params.get( 'edit_mode', 'False' ) - file_obj = params.get('file_data', '') - reader = csv.reader(file_obj.file) - for row in reader: - lib_id = None - folder_id = None - lib = trans.sa_session.query( trans.app.model.Library ) \ - .filter( and_( trans.app.model.Library.table.c.name==row[1], \ - trans.app.model.Library.table.c.deleted==False ) )\ - .first() - if lib: - folder = trans.sa_session.query( trans.app.model.LibraryFolder ) \ - .filter( and_( trans.app.model.LibraryFolder.table.c.name==row[2], \ - trans.app.model.LibraryFolder.table.c.deleted==False ) )\ - .first() - if folder: - lib_id = lib.id - folder_id = folder.id - lib_widget, folder_widget = self.__library_widgets(trans, request.user, len(current_samples), - libraries, None, lib_id, folder_id, **kwd) - current_samples.append(dict(name=row[0], - barcode='', - library=None, - folder=None, - lib_widget=lib_widget, - folder_widget=folder_widget, - field_values=row[3:])) - return trans.fill_template( '/admin/requests/show_request.mako', - request=request, - request_details=self.request_details(trans, request.id), - current_samples=current_samples, - sample_copy=self.__copy_sample(current_samples), - details=details, - edit_mode=edit_mode) - except: - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - operation='show_request', - id=trans.security.encode_id(request.id), - status='error', - message='Error in importing samples file' )) - @web.expose - @web.require_login( "create/submit sequencing requests" ) - def show_request(self, trans, **kwd): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - try: - request = trans.sa_session.query( trans.app.model.Request ).get( int( params.get( 'request_id', None ) ) ) - except: - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status='error', - message="Invalid request ID", - **kwd) ) - # get the user entered sample details - current_samples, details, edit_mode, libraries = self.__update_samples( trans, request, **kwd ) - if params.get('import_samples_button', False) == 'Import samples': - return self.__import_samples(trans, request, current_samples, details, libraries, **kwd) - elif params.get('add_sample_button', False) == 'Add New': - # add an empty or filled sample - # if the user has selected a sample no. to copy then copy the contents - # of the src sample to the new sample else an empty sample - src_sample_index = int(params.get( 'copy_sample', -1 )) - # get the number of new copies of the src sample - num_sample_to_copy = int(params.get( 'num_sample_to_copy', 1 )) - if src_sample_index == -1: - for ns in range(num_sample_to_copy): - # empty sample - lib_widget, folder_widget = self.__library_widgets(trans, request.user, - len(current_samples), - libraries, None, **kwd) - current_samples.append(dict(name='Sample_%i' % (len(current_samples)+1), - barcode='', - library=None, - folder=None, - field_values=['' for field in request.type.sample_form.fields], - lib_widget=lib_widget, - folder_widget=folder_widget)) - else: - src_library_id = current_samples[src_sample_index]['lib_widget'].get_selected()[1] - src_folder_id = current_samples[src_sample_index]['folder_widget'].get_selected()[1] - for ns in range(num_sample_to_copy): - lib_widget, folder_widget = self.__library_widgets(trans, request.user, - len(current_samples), - libraries, sample=None, - lib_id=src_library_id, - folder_id=src_folder_id, - **kwd) - current_samples.append(dict(name=current_samples[src_sample_index]['name']+'_%i' % (len(current_samples)+1), - barcode='', - library_id='none', - folder_id='none', - field_values=[val for val in current_samples[src_sample_index]['field_values']], - lib_widget=lib_widget, - folder_widget=folder_widget)) - return trans.fill_template( '/admin/requests/show_request.mako', - request=request, - request_details=self.request_details(trans, request.id), - current_samples=current_samples, - sample_copy=self.__copy_sample(current_samples), - details=details, - edit_mode=edit_mode) - elif params.get('save_samples_button', False) == 'Save': - # check for duplicate sample names - message = '' - for index in range(len(current_samples)-len(request.samples)): - sample_index = index + len(request.samples) - sample_name = current_samples[sample_index]['name'] - if not sample_name.strip(): - message = 'Please enter the name of sample number %i' % sample_index - break - count = 0 - for i in range(len(current_samples)): - if sample_name == current_samples[i]['name']: - count = count + 1 - if count > 1: - message = "This request has <b>%i</b> samples with the name <b>%s</b>.\nSamples belonging to a request must have unique names." % (count, sample_name) - break - if message: - return trans.fill_template( '/admin/requests/show_request.mako', - request=request, - request_details=self.request_details(trans, request.id), - current_samples = current_samples, - sample_copy=self.__copy_sample(current_samples), - details=details, edit_mode=edit_mode, - status='error', message=message) - # save all the new/unsaved samples entered by the user - if edit_mode == 'False': - for index in range(len(current_samples)-len(request.samples)): - sample_index = len(request.samples) - form_values = trans.app.model.FormValues(request.type.sample_form, - current_samples[sample_index]['field_values']) - trans.sa_session.add( form_values ) - trans.sa_session.flush() - s = trans.app.model.Sample(current_samples[sample_index]['name'], '', - request, form_values, - current_samples[sample_index]['barcode'], - current_samples[sample_index]['library'], - current_samples[sample_index]['folder'], - dataset_files=[]) - trans.sa_session.add( s ) - trans.sa_session.flush() + - else: - status = 'done' - message = 'Changes made to the sample(s) are saved. ' - for sample_index in range(len(current_samples)): - sample = request.samples[sample_index] - sample.name = current_samples[sample_index]['name'] - sample.library = current_samples[sample_index]['library'] - sample.folder = current_samples[sample_index]['folder'] - if request.submitted(): - bc_message = self.__validate_barcode(trans, sample, current_samples[sample_index]['barcode']) - if bc_message: - status = 'error' - message += bc_message - else: - if not sample.bar_code: - # if this is a 'new' (still in its first state) sample - # change the state to the next - if sample.current_state().id == request.type.states[0].id: - event = trans.app.model.SampleEvent(sample, - request.type.states[1], - 'Sample added to the system') - trans.sa_session.add( event ) - trans.sa_session.flush() - sample.bar_code = current_samples[sample_index]['barcode'] - trans.sa_session.add( sample ) - trans.sa_session.flush() - form_values = trans.sa_session.query( trans.app.model.FormValues ).get( sample.values.id ) - form_values.content = current_samples[sample_index]['field_values'] - trans.sa_session.add( form_values ) - trans.sa_session.flush() - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - operation='show_request', - id=trans.security.encode_id(request.id), - status=status, - message=message )) - elif params.get('edit_samples_button', False) == 'Edit samples': - edit_mode = 'True' - return trans.fill_template( '/admin/requests/show_request.mako', - request=request, - request_details=self.request_details(trans, request.id), - current_samples=current_samples, - sample_copy=self.__copy_sample(current_samples), - details=details, libraries=libraries, - edit_mode=edit_mode) - elif params.get('cancel_changes_button', False) == 'Cancel': - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - operation='show_request', - id=trans.security.encode_id(request.id)) ) - else: - return trans.fill_template( '/admin/requests/show_request.mako', - request=request, - request_details=self.request_details(trans, request.id), - current_samples=current_samples, - sample_copy=self.__copy_sample(current_samples), - details=details, libraries=libraries, - edit_mode=edit_mode, status=status, message=message) - - - @web.expose - @web.require_login( "create/submit sequencing requests" ) - def delete_sample(self, trans, **kwd): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - request = trans.sa_session.query( trans.app.model.Request ).get( int( params.get( 'request_id', 0 ) ) ) - current_samples, details, edit_mode, libraries = self.__update_samples( trans, request, **kwd ) - sample_index = int(params.get('sample_id', 0)) - sample_name = current_samples[sample_index]['name'] - s = request.has_sample(sample_name) - if s: - trans.sa_session.delete( s.values ) - trans.sa_session.delete( s ) - trans.sa_session.flush() - del current_samples[sample_index] - return trans.fill_template( '/admin/requests/show_request.mako', - request=request, - request_details=self.request_details(trans, request.id), - current_samples = current_samples, - sample_copy=self.__copy_sample(current_samples), - details=details, - edit_mode=edit_mode) - @web.expose - @web.require_admin - def request_details(self, trans, id): - ''' - Shows the request details - ''' - request = trans.sa_session.query( trans.app.model.Request ).get( id ) - # list of widgets to be rendered on the request form - request_details = [] - # main details - request_details.append(dict(label='User', - value=str(request.user.email), - helptext='')) - request_details.append(dict(label='Description', - value=request.desc, - helptext='')) - request_details.append(dict(label='Type', - value=request.type.name, - helptext='')) - request_details.append(dict(label='State', - value=request.state(), - helptext='')) - request_details.append(dict(label='Date created', - value=request.create_time, - helptext='')) - # form fields - for index, field in enumerate(request.type.request_form.fields): - if field['required']: - req = 'Required' - else: - req = 'Optional' - if field['type'] == 'AddressField': - if request.values.content[index]: - request_details.append(dict(label=field['label'], - value=trans.sa_session.query( trans.app.model.UserAddress ).get( int( request.values.content[index] ) ).get_html(), - helptext=field['helptext']+' ('+req+')')) - else: - request_details.append(dict(label=field['label'], - value=None, - helptext=field['helptext']+' ('+req+')')) - else: - request_details.append(dict(label=field['label'], - value=request.values.content[index], - helptext=field['helptext']+' ('+req+')')) - if request.notify: - notify = 'Yes' - else: - notify = 'No' - request_details.append(dict(label='Send email notification once the sequencing request is complete', - value=notify, - helptext='')) - return request_details - def __validate_barcode(self, trans, sample, barcode): - ''' - This method makes sure that the given barcode about to be assigned to - the given sample is gobally unique. That is, barcodes must be unique - across requests in Galaxy LIMS - ''' - message = '' - for index in range(len(sample.request.samples)): - # check for empty bar code - if not barcode.strip(): - message = 'Please fill the barcode for sample <b>%s</b>.' % sample.name - break - # check all the saved bar codes - all_samples = trans.sa_session.query( trans.app.model.Sample ) - for s in all_samples: - if barcode == s.bar_code: - if sample.id == s.id: - continue - else: - message = '''The bar code <b>%s</b> of sample <b>%s</b> - belongs another sample. The sample bar codes must be - unique throughout the system''' % \ - (barcode, sample.name) - break - if message: - break - return message @web.expose @web.require_admin def bar_codes(self, trans, **kwd): @@ -1410,21 +481,7 @@ class RequestsAdmin( BaseController ): email_content = "To: %s\nFrom: no-reply@nowhere.edu\nSubject: %s\n\n%s" % (request.user.email, subject, body) mail.write( email_content ) x = mail.close() - def change_state(self, trans, sample): - possible_states = sample.request.type.states - curr_state = sample.current_state() - states_input = SelectField('select_state') - for state in possible_states: - if curr_state.name == state.name: - states_input.add_option(state.name+' (Current)', state.id, selected=True) - else: - states_input.add_option(state.name, state.id) - widgets = [] - widgets.append(('Select the new state of the sample from the list of possible state(s)', - states_input)) - widgets.append(('Comments', TextArea('comment'))) - title = 'Change current state' - return widgets, title + @web.expose @web.require_admin def save_state(self, trans, **kwd): @@ -1449,71 +506,14 @@ class RequestsAdmin( BaseController ): trans.sa_session.add( event ) trans.sa_session.flush() self.__set_request_state( trans, sample.request ) - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='show_events', + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests_admin', + action='sample_events', sample_id=sample.id)) - @web.expose - @web.require_admin - def show_events(self, trans, **kwd): - params = util.Params( kwd ) - try: - sample_id = int(params.get('sample_id', False)) - sample = trans.sa_session.query( trans.app.model.Sample ).get( sample_id ) - except: - message = "Invalid sample ID" - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status='error', - message=message, - **kwd) ) - events_list = [] - all_events = sample.events - for event in all_events: - events_list.append((event.state.name, event.state.desc, - time_ago(event.update_time), event.comment)) - widgets, title = self.change_state(trans, sample) - return trans.fill_template( '/admin/samples/events.mako', - events_list=events_list, - sample=sample, widgets=widgets, title=title) - # # Data transfer from sequencer # - @web.expose - @web.require_admin - def show_datatx_page( self, trans, **kwd ): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - try: - sample = trans.sa_session.query( trans.app.model.Sample ).get( trans.security.decode_id( kwd['sample_id'] ) ) - except: - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status='error', - message="Invalid sample ID", - **kwd) ) - # check if a library and folder has been set for this sample yet. - if not sample.library or not sample.folder: - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - operation='show_request', - status='error', - message="Set a data library and folder for <b>%s</b> to transfer dataset(s)." % sample.name, - id=trans.security.encode_id(sample.request.id) ) ) - if params.get( 'folder_path', '' ): - folder_path = util.restore_text( params.get( 'folder_path', '' ) ) - else: - if len(sample.dataset_files): - folder_path = os.path.dirname(sample.dataset_files[-1]['filepath'][:-1]) - else: - folder_path = util.restore_text( sample.request.type.datatx_info.get('data_dir', '') ) - if folder_path[-1] != os.sep: - folder_path += os.sep - return trans.fill_template( '/admin/requests/get_data.mako', - sample=sample, dataset_files=sample.dataset_files, - message=message, status=status, files=[], - folder_path=folder_path ) + def __get_files(self, trans, sample, folder_path): ''' This method retrieves the filenames to be transfer from the remote host. @@ -1521,7 +521,8 @@ class RequestsAdmin( BaseController ): datatx_info = sample.request.type.datatx_info if not datatx_info['host'] or not datatx_info['username'] or not datatx_info['password']: message = "Error in sequencer login information." - return trans.response.send_redirect( web.url_for( controller='requests_admin', + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests_admin' , action='show_datatx_page', sample_id=trans.security.encode_id(sample.id), status='error', @@ -1536,7 +537,8 @@ class RequestsAdmin( BaseController ): timeout=10) if 'No such file or directory' in output: message = "No such folder (%s) exists on the sequencer." % folder_path - return trans.response.send_redirect( web.url_for( controller='requests_admin', + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests_admin' , action='show_datatx_page', sample_id=trans.security.encode_id(sample.id), message=message, status='error', @@ -1574,7 +576,8 @@ class RequestsAdmin( BaseController ): if params.get( 'start_transfer_button', False ) == 'True': return self.__start_datatx(trans, sample) if not folder_path: - return trans.fill_template( '/admin/requests/get_data.mako', + return trans.fill_template( '/requests/common/get_data.mako', + cntrller='requests_admin', sample=sample, files=[], dataset_files=sample.dataset_files, folder_path=folder_path ) @@ -1585,7 +588,8 @@ class RequestsAdmin( BaseController ): files = self.__get_files(trans, sample, folder_path) if folder_path[-1] != os.sep: folder_path += os.sep - return trans.fill_template( '/admin/requests/get_data.mako', + return trans.fill_template( '/requests/common/get_data.mako', + cntrller='requests_admin', sample=sample, files=files, dataset_files=sample.dataset_files, folder_path=folder_path ) @@ -1596,7 +600,8 @@ class RequestsAdmin( BaseController ): files = self.__get_files(trans, sample, folder_path) if folder_path[-1] != os.sep: folder_path += os.sep - return trans.fill_template( '/admin/requests/get_data.mako', + return trans.fill_template( '/requests/common/get_data.mako', + cntrller='requests_admin', sample=sample, files=files, dataset_files=sample.dataset_files, folder_path=folder_path ) @@ -1607,7 +612,8 @@ class RequestsAdmin( BaseController ): files = self.__get_files(trans, sample, folder_path) if folder_path[-1] != os.sep: folder_path += os.sep - return trans.fill_template( '/admin/requests/get_data.mako', + return trans.fill_template( '/requests/common/get_data.mako', + cntrller='requests_admin', sample=sample, files=files, dataset_files=sample.dataset_files, folder_path=folder_path ) @@ -1618,7 +624,8 @@ class RequestsAdmin( BaseController ): del sample.dataset_files[dataset_index] trans.sa_session.add( sample ) trans.sa_session.flush() - return trans.fill_template( '/admin/requests/get_data.mako', + return trans.fill_template( '/requests/common/get_data.mako', + cntrller='requests_admin', sample=sample, files=files, dataset_files=sample.dataset_files, folder_path=folder_path) @@ -1651,7 +658,8 @@ class RequestsAdmin( BaseController ): folder_path=folder_path, open_folder=True)) - return trans.response.send_redirect( web.url_for( controller='requests_admin', + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests_admin' , action='show_datatx_page', sample_id=trans.security.encode_id(sample.id), folder_path=folder_path)) @@ -1780,13 +788,15 @@ class RequestsAdmin( BaseController ): not datatx_info['username'] or \ not datatx_info['password']: message = "Error in sequencer login information." - return trans.response.send_redirect( web.url_for( controller='requests_admin', + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests_admin' , action='show_datatx_page', sample_id=trans.security.encode_id(sample.id), status='error', message=message)) self.__send_message(trans, datatx_info, sample) - return trans.response.send_redirect( web.url_for( controller='requests_admin', + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller='requests_admin' , action='show_datatx_page', sample_id=trans.security.encode_id(sample.id), folder_path=datatx_info['data_dir']))