Fix sample tracking to correctly import samples from a csv file.

This commit is contained in:
Greg Von Kuster
2011-06-08 15:46:20 -04:00
parent 3959897d3d
commit b065817a95
4 changed files with 103 additions and 55 deletions
+85 -31
View File
@@ -826,7 +826,9 @@ class RequestsCommon( BaseController, UsesFormDefinitions ):
displayable_sample_widgets = self.__get_sample_widgets( trans, request, request.samples, **kwd )
if params.get( 'import_samples_button', False ):
# Import sample field values from a csv file
return self.__import_samples( trans, cntrller, request, displayable_sample_widgets, libraries, **kwd )
# TODO: should this be a mapper?
workflows = [ w.latest_workflow for w in trans.user.stored_workflows if not w.deleted ]
return self.__import_samples( trans, cntrller, request, displayable_sample_widgets, libraries, workflows, **kwd )
elif params.get( 'add_sample_button', False ):
return self.add_sample( trans, cntrller, request_id, **kwd )
elif params.get( 'save_samples_button', False ):
@@ -905,17 +907,17 @@ class RequestsCommon( BaseController, UsesFormDefinitions ):
folder_id=folder_id,
**kwd )
history_select_field = self.__build_history_select_field( trans=trans,
user=request.user,
sample_index=len( displayable_sample_widgets ),
history_id=history_id,
**kwd)
user=request.user,
sample_index=len( displayable_sample_widgets ),
history_id=history_id,
**kwd )
workflow_select_field = self.__build_workflow_select_field( trans=trans,
user=request.user,
request=request,
sample_index=len( displayable_sample_widgets ),
workflow_id=workflow_id,
history_id=history_id,
**kwd)
user=request.user,
request=request,
sample_index=len( displayable_sample_widgets ),
workflow_id=workflow_id,
history_id=history_id,
**kwd )
# Append the new sample to the current list of samples for the request
displayable_sample_widgets.append( dict( id=None,
name=name,
@@ -1045,47 +1047,99 @@ class RequestsCommon( BaseController, UsesFormDefinitions ):
transfer_status=transfer_status,
message=message,
status=status )
def __import_samples( self, trans, cntrller, request, displayable_sample_widgets, libraries, **kwd ):
def __import_samples( self, trans, cntrller, request, displayable_sample_widgets, libraries, workflows, **kwd ):
"""
Reads the samples csv file and imports all the samples. The format of the csv file is:
SampleName,DataLibrary,DataLibraryFolder,Field1,Field2....
SampleName,DataLibraryName,DataLibraryFolderName,HistoryName,WorkflowName,FieldValue1,FieldValue2...
"""
params = util.Params( kwd )
current_user_roles = trans.get_current_user_roles()
is_admin = trans.user_is_admin() and cntrller == 'requests_admin'
file_obj = params.get( 'file_data', '' )
try:
reader = csv.reader( file_obj.file )
for row in reader:
library_id = None
library = None
folder_id = None
# FIXME: this is bad - what happens when multiple libraries have the same name??
lib = trans.sa_session.query( trans.model.Library ) \
.filter( and_( trans.model.Library.table.c.name==row[1],
trans.model.Library.table.c.deleted==False ) ) \
.first()
if lib:
folder = trans.sa_session.query( trans.model.LibraryFolder ) \
.filter( and_( trans.model.LibraryFolder.table.c.name==row[2],
trans.model.LibraryFolder.table.c.deleted==False ) ) \
.first()
folder = None
history_id = None
history = None
workflow_id = None
workflow = None
# Get the library
library = trans.sa_session.query( trans.model.Library ) \
.filter( and_( trans.model.Library.table.c.name==row[1],
trans.model.Library.table.c.deleted==False ) ) \
.first()
if library:
# Get the folder
for folder in trans.sa_session.query( trans.model.LibraryFolder ) \
.filter( and_( trans.model.LibraryFolder.table.c.name==row[2],
trans.model.LibraryFolder.table.c.deleted==False ) ):
if folder.parent_library == library:
break
if folder:
library_id = lib.id
folder_id = folder.id
library_id = trans.security.encode_id( library.id )
folder_id = trans.security.encode_id( folder.id )
library_select_field, folder_select_field = self.__build_library_and_folder_select_fields( trans,
request.user,
len( displayable_sample_widgets ),
len( displayable_sample_widgets ),
libraries,
None,
library_id,
folder_id,
**kwd )
# Get the history
history = trans.sa_session.query( trans.model.History ) \
.filter( and_( trans.model.History.table.c.name==row[3],
trans.model.History.table.c.deleted==False,
trans.model.History.user_id == trans.user.id ) ) \
.first()
if history:
history_id = trans.security.encode_id( history.id )
else:
history_id = 'none'
history_select_field = self.__build_history_select_field( trans=trans,
user=request.user,
sample_index=len( displayable_sample_widgets ),
history_id=history_id )
# Get the workflow
workflow = trans.sa_session.query( trans.model.StoredWorkflow ) \
.filter( and_( trans.model.StoredWorkflow.table.c.name==row[4],
trans.model.StoredWorkflow.table.c.deleted==False,
trans.model.StoredWorkflow.user_id == trans.user.id ) ) \
.first()
if workflow:
workflow_id = trans.security.encode_id( workflow.id )
else:
workflow_id = 'none'
workflow_select_field = self.__build_workflow_select_field( trans=trans,
user=request.user,
request=request,
sample_index=len( displayable_sample_widgets ),
workflow_id=workflow_id,
history_id=history_id )
field_values = {}
field_names = row[5:]
for field_name in field_names:
field_values[ field_name ] = ''
displayable_sample_widgets.append( dict( id=None,
name=row[0],
name=row[0],
bar_code='',
library=None,
folder=None,
library=library,
library_id=library_id,
library_select_field=library_select_field,
folder=folder,
folder_id=folder_id,
folder_select_field=folder_select_field,
field_values=row[3:] ) )
history=history,
history_id=history_id,
history_select_field=history_select_field,
workflow=workflow,
workflow_id=workflow_id,
workflow_select_field=workflow_select_field,
field_values=field_values ) )
except Exception, e:
if str( e ) == "'unicode' object has no attribute 'file'":
message = "Select a file"
@@ -1488,7 +1542,7 @@ class RequestsCommon( BaseController, UsesFormDefinitions ):
library_select_field=library_select_field,
folder_select_field=folder_select_field,
history_select_field=history_select_field,
workflow_select_field=workflow_select_field, ) )
workflow_select_field=workflow_select_field ) )
# There may be additional new samples on the form that have not yet been associated with the request.
# TODO: factor this code so it is not duplicating what's above.
index = len( samples )
@@ -269,9 +269,6 @@ class RepositoryController( BaseController, ItemRatings ):
category_ids = util.listify( params.get( 'category_id', '' ) )
selected_categories = [ trans.security.decode_id( id ) for id in category_ids ]
if params.get( 'create_repository_button', False ):
# TODOS:
# 1. Make sure we can update the version column in the repository table when new change set are pushed.
# If it's triclky, eliminate the column.
error = False
message = self.__validate_repository_name( name, trans.user )
if message:
+14 -19
View File
@@ -61,7 +61,7 @@ ${render_samples_messages(request, is_admin, is_submitted, message, status)}
<form id="add_samples" name="add_samples" action="${h.url_for( controller='requests_common', action='add_samples', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}" method="post">
%if displayable_sample_widgets:
<%
grid_header = '<h3>Add Samples to Sequencing Request "%s"</h3>' % request.name
grid_header = '<h3>Add samples to sequencing request "%s"</h3>' % request.name
%>
${render_samples_grid( cntrller, request, displayable_sample_widgets, action='edit_samples', adding_new_samples=True, encoded_selected_sample_ids=[], render_buttons=False, grid_header=grid_header )}
<div class="toolParamHelp" style="clear: both;">
@@ -89,8 +89,6 @@ ${render_samples_messages(request, is_admin, is_submitted, message, status)}
%endif
<p/>
<div class="form-row">
## hidden element to make twill work.
## Greg will fix this
<input type="hidden" name="twill" value=""/>
%if ( request.samples or displayable_sample_widgets ) and len( displayable_sample_widgets ) > len( request.samples ):
<input type="submit" name="add_sample_button" value="Add sample" />
@@ -111,22 +109,19 @@ ${render_samples_messages(request, is_admin, is_submitted, message, status)}
</div>
%if is_unsubmitted:
<p/>
##<div class="toolForm">
##<div class="toolFormTitle">Import samples from csv file</div>
<h4><img src="/static/images/silk/resultset_next.png" alt="Hide" onclick="showContent(this);" style="cursor:pointer;"/> Import samples from csv file</h4>
<div style="display:none;">
<div class="toolFormBody">
<form id="import" name="import" action="${h.url_for( controller='requests_common', action='add_samples', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}" enctype="multipart/form-data" method="post" >
<div class="form-row">
<input type="file" name="file_data" />
<input type="submit" name="import_samples_button" value="Import samples"/>
<div class="toolParamHelp" style="clear: both;">
The csv file must be in the following format:<br/>
SampleName,DataLibrary,DataLibraryFolder,FieldValue1,FieldValue2...
</div>
<h4><img src="/static/images/silk/resultset_next.png" alt="Hide" onclick="showContent(this);" style="cursor:pointer;"/>Import samples from csv file</h4>
<div style="display:none;">
<div class="toolFormBody">
<form id="import" name="import" action="${h.url_for( controller='requests_common', action='add_samples', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}" enctype="multipart/form-data" method="post" >
<div class="form-row">
<input type="file" name="file_data" />
<input type="submit" name="import_samples_button" value="Import samples"/>
<div class="toolParamHelp" style="clear: both;">
The csv file must be in the following format:<br/>
SampleName,DataLibraryName,DataLibraryFolderName,HistoryName,WorkflowName,FieldValue1,FieldValue2...
</div>
</form>
</div>
</div>
</form>
</div>
##</div>
</div>
%endif
+4 -2
View File
@@ -465,7 +465,7 @@ class TestFormsAndSampleTracking( TwillTestCase ):
request_id=self.security.encode_id( request1.id ),
sample_value_tuples=sample_value_tuples,
folder_options=folder_options,
strings_displayed=[ 'Add Samples to Sequencing Request "%s"' % request1.name,
strings_displayed=[ 'Add samples to sequencing request "%s"' % request1.name,
'<input type="text" name="sample_0_name" value="Sample_1" size="10"/>' ], # sample name input field
strings_displayed_after_submit=strings_displayed_after_submit )
# check the new sample field values on the request page
@@ -704,7 +704,7 @@ class TestFormsAndSampleTracking( TwillTestCase ):
self.add_samples( cntrller='requests_admin',
request_id=self.security.encode_id( request2.id ),
sample_value_tuples=sample_value_tuples,
strings_displayed=[ 'Add Samples to Sequencing Request "%s"' % request2.name,
strings_displayed=[ 'Add samples to sequencing request "%s"' % request2.name,
'<input type="text" name="sample_0_name" value="Sample_1" size="10"/>' ], # sample name input field
strings_displayed_after_submit=strings_displayed_after_submit )
# Submit the request
@@ -869,6 +869,7 @@ class TestFormsAndSampleTracking( TwillTestCase ):
sample1_dataset.transfer_status.NOT_STARTED ]
self.view_sample_dataset( sample_dataset_id=self.security.encode_id( sample1_dataset.id ),
strings_displayed=strings_displayed )
'''
def test_999_reset_data_for_later_test_runs( self ):
"""Reseting data to enable later test runs to pass"""
# Logged in as admin_user
@@ -934,3 +935,4 @@ class TestFormsAndSampleTracking( TwillTestCase ):
# Manually delete the group from the database
refresh( group )
delete_obj( group )
'''