diff --git a/lib/galaxy/web/controllers/forms.py b/lib/galaxy/web/controllers/forms.py index 4a1b9c8b14b..98a196e917e 100644 --- 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 %s file' % csv_file, - **kwd)) + message='Error in importing %s file' % csv_file.file)) self.__imported_from_file = True return fields, list(layouts) def __validate_form(self, **kwd): diff --git a/lib/galaxy/web/controllers/requests.py b/lib/galaxy/web/controllers/requests.py index 618bc095bf3..fa4cc59d371 100644 --- 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 %i samples with the name %s.\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 Name 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 %s 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 %s before submitting
' % request.name - for ef in empty_fields: - message = message + '' +ef + '
' - 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 %s before submitting
' % request.name - for sname, ef in empty_fields: - message = message + '%s field of sample %s
' % (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 Name 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 %s 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 ) + \ No newline at end of file diff --git a/lib/galaxy/web/controllers/requests_admin.py b/lib/galaxy/web/controllers/requests_admin.py index 2ea0967a61e..b4d716b5022 100644 --- 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 Name 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 %s 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 %s 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 Name of the request and the user 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 %s before submitting
' % request.name - for ef in empty_fields: - message = message + '' +ef + '
' - 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 %i samples with the name %s.\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 %s.' % 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 %s of sample %s - 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 %s 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'])) diff --git a/lib/galaxy/web/controllers/requests_common.py b/lib/galaxy/web/controllers/requests_common.py new file mode 100644 index 00000000000..dd0e5528393 --- /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 Name of the request and the user 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 %s 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 Name 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 %s before submitting
' % request.name + for ef in empty_fields: + message = message + '' +ef + '
' + 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 %s 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 %i samples with the name %s.\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 %s.' % 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 %s of sample %s + 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 %s 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 %s 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 Sequencer information 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 ) diff --git a/scripts/galaxy_messaging/server/data_transfer.py b/scripts/galaxy_messaging/server/data_transfer.py index dccea539051..b0a29772961 100755 --- 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: diff --git a/scripts/galaxy_messaging/server/galaxydb_interface.py b/scripts/galaxy_messaging/server/galaxydb_interface.py index 3f0107ac458..174781dc7e3 100644 --- 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 ) diff --git a/templates/admin/requests/add_states.mako b/templates/admin/requests/add_states.mako deleted file mode 100644 index c433fe9b812..00000000000 --- 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 - -
-
Create ${num_states} states for the '${request_type_name}' request type
-
-
- %for element_count in range( num_states ): -
- - - - -
-
- %endfor -
-
- -
-
-
\ No newline at end of file diff --git a/templates/admin/requests/dataset.mako b/templates/admin/requests/dataset.mako index 08a53f6788a..e25c47ed04f 100644 --- a/templates/admin/requests/dataset.mako +++ b/templates/admin/requests/dataset.mako @@ -11,7 +11,7 @@ diff --git a/templates/admin/requests/edit_request.mako b/templates/admin/requests/edit_request.mako deleted file mode 100644 index 341f5326d6b..00000000000 --- 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 - - - -
-
- - -
-
Edit request "${request.name}" from ${request.user.email}
- %if len(select_request_type.options) == 1: - There are no request types created for a new request. - %else: -
-
-
- - ${select_request_type.get_html()} -
- - %if select_request_type.get_selected() != ('Select one', 'none'): - %for i, field in enumerate(widgets): -
- - ${field['widget'].get_html()} - %if field['label'] == 'Library' and new_library: - ${new_library.get_html()} - %endif -
- ${field['helptext']} -
-
-
- %endfor -
-
- -
-
-
-
- - ## -
- %endif -
-
-
-%endif \ No newline at end of file diff --git a/templates/admin/requests/events.mako b/templates/admin/requests/events.mako deleted file mode 100644 index 50712a602d9..00000000000 --- a/templates/admin/requests/events.mako +++ /dev/null @@ -1,36 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - -

History of Sequencing Request "${request.name}"

- -

User: ${request.user.email}

- -%if message: - ${render_msg( message, status )} -%endif - -
- - - - - - - - - - %for state, updated, comments in events_list: - - - - - - %endfor - -
StateLast UpdateComments
${state}${updated}${comments}
-
diff --git a/templates/admin/requests/get_data.mako b/templates/admin/requests/get_data.mako deleted file mode 100644 index bd185dc9b30..00000000000 --- 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 - - - - - - - - - - - -

Data transfer from Sequencer

-

Sample "${sample.name}" of Request "${sample.request.name}"

-
-
- - - -
- %if len(dataset_files): -##
-
-

Sample Dataset(s)

- %if sample.untransferred_dataset_files(): -
- -
- %endif -
- - - - - - - - - - %for dataset_index, dataset_file in enumerate(dataset_files): - ${sample_dataset_files( dataset_index, dataset_file['name'], dataset_file['status'] )} - %endfor - -
Dataset FileTransfer Status
-
-
- -##
-##
- - -
-
-%endif - -##
-
-
- ##
Select files for transfer
-

Select files for transfer

-
-
- - - - ## - -
-
- -
-
- -
-
-
-
- After selecting dataset(s), be sure to click on the Start transfer button. - Once the transfer is complete the dataset(s) will show up on this page. -
- -
-
-
-
-
- -<%def name="sample_dataset_files( dataset_index, dataset_name, status )"> - - - -##
${dataset_file.split('/')[-1]}
-##
-## ${dataset_file} -##
- - - %if status not in [sample.transfer_status.NOT_STARTED, sample.transfer_status.COMPLETE]: - ${status} - %else: - ${status} - %endif - - ## - %if status == sample.transfer_status.NOT_STARTED: - - - - - - %else: - - %endif - - \ No newline at end of file diff --git a/templates/admin/samples/bar_codes.mako b/templates/admin/samples/bar_codes.mako deleted file mode 100644 index 24adf55d4ae..00000000000 --- 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 - - -

Bar codes for Samples of Request "${request.name}"

-

User: ${user.email}

- - - -
-
- - - - - - - - - - %for index, sample in enumerate(samples_list): - - - - - - %endfor - -
NameDescriptionBar code
${sample.name}${sample.desc} - ${widgets[index].get_html()} -
-
- -
-
-
\ No newline at end of file diff --git a/templates/admin/samples/events.mako b/templates/admin/samples/events.mako deleted file mode 100644 index f64c24695d9..00000000000 --- 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} - -

Events for Sample "${sample.name}"

- -

User: ${sample.request.user.email}

- -%if message: - ${render_msg( message, status )} -%endif - -
- - - - - - - - - - - %for state, desc, updated, comments in events_list: - - - - - - - %endfor - -
StateDescriptionLast UpdateComments
${state}${desc}${updated}${comments}
-
-
-
Change current state
-
-
- %for w in widgets: -
- - ${w[1].get_html()} - %if w[0] == 'Comments': -
- Optional -
- %endif -
- %endfor -
- -
-
-
-
\ No newline at end of file diff --git a/templates/requests/edit_request.mako b/templates/requests/common/edit_request.mako similarity index 94% rename from templates/requests/edit_request.mako rename to templates/requests/common/edit_request.mako index 7ef58849376..e769edd600f 100644 --- a/templates/requests/edit_request.mako +++ b/templates/requests/common/edit_request.mako @@ -34,7 +34,7 @@ $( function() {
@@ -45,7 +45,7 @@ $( function() { There are no request types created for a new request. %else:
-
+
diff --git a/templates/requests/common/sample_datasets.mako b/templates/requests/common/sample_datasets.mako new file mode 100644 index 00000000000..9029b0cf56b --- /dev/null +++ b/templates/requests/common/sample_datasets.mako @@ -0,0 +1,7 @@ +<%def name="render_sample_datasets( cntrller, sample )"> + ${sample.transferred_dataset_files()}/${len(sample.dataset_files)} + + + + +${render_sample_datasets( cntrller, sample )} diff --git a/templates/requests/common/sample_events.mako b/templates/requests/common/sample_events.mako new file mode 100644 index 00000000000..12697fe51c4 --- /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} + +

Events for Sample "${sample.name}"

+ +

User: ${sample.request.user.email}

+ +%if message: + ${render_msg( message, status )} +%endif + +
+ + + + + + + + + + + %for state, desc, updated, comments in events_list: + + + + + + + %endfor + +
StateDescriptionLast UpdateComments
${state}${desc}${updated}${comments}
+
+%if cntrller == 'requests_admin' and trans.user_is_admin(): +
+
Change current state
+
+
+ %for w in widgets: +
+ + ${w[1].get_html()} + %if w[0] == 'Comments': +
+ Optional +
+ %endif +
+ %endfor +
+ +
+
+
+
+%endif \ No newline at end of file diff --git a/templates/requests/common/sample_state.mako b/templates/requests/common/sample_state.mako new file mode 100644 index 00000000000..318893d1b15 --- /dev/null +++ b/templates/requests/common/sample_state.mako @@ -0,0 +1,5 @@ +<%def name="render_sample_state( cntrller, sample )"> + ${sample.current_state().name} + + +${render_sample_state( cntrller, sample )} diff --git a/templates/admin/requests/show_request.mako b/templates/requests/common/show_request.mako similarity index 87% rename from templates/admin/requests/show_request.mako rename to templates/requests/common/show_request.mako index bca77d5ce56..c60158b3c66 100644 --- a/templates/admin/requests/show_request.mako +++ b/templates/requests/common/show_request.mako @@ -1,11 +1,9 @@ <%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" /> +<%namespace file="/requests/common/sample_state.mako" import="render_sample_state" /> +<%namespace file="/requests/common/sample_datasets.mako" import="render_sample_datasets" /> + -%if message: - ${render_msg( message, status )} -%endif - -<%def name="javascripts()"> - ${parent.javascripts()} - ${h.js("jquery.autocomplete", "autocomplete_tagging" )} - - -<%def name="stylesheets()"> - ${parent.stylesheets()} - ${h.css( "autocomplete_tagging" )} - - -
-
- - -
-
Add a new request
- %if len(select_request_type.options) == 1: - There are no request types created for a new request. - %else: -
-
-
- - ${select_request_type.get_html()} -
- - %if select_request_type.get_selected() != ('Select one', 'none'): - %for i, field in enumerate(widgets): -
- - ${field['widget'].get_html()} - ##%if field['label'] == 'Data library' and new_library: - ## ${new_library.get_html()} - ##%endif -
- ${field['helptext']} -
-
-
- %endfor -
-
- -
-
-
-
- - -
- %endif -
-
-
-%endif \ No newline at end of file diff --git a/templates/requests/sample_datasets.mako b/templates/requests/sample_datasets.mako deleted file mode 100644 index 4eeb7422781..00000000000 --- a/templates/requests/sample_datasets.mako +++ /dev/null @@ -1,7 +0,0 @@ -<%def name="render_sample_datasets( sample )"> - ${sample.transferred_dataset_files()}/${len(sample.dataset_files)} - - - - -${render_sample_datasets( sample )} diff --git a/templates/requests/sample_state.mako b/templates/requests/sample_state.mako deleted file mode 100644 index 08623ce9c4e..00000000000 --- a/templates/requests/sample_state.mako +++ /dev/null @@ -1,5 +0,0 @@ -<%def name="render_sample_state( sample )"> - ${sample.current_state().name} - - -${render_sample_state( sample )} diff --git a/templates/requests/show_data.mako b/templates/requests/show_data.mako deleted file mode 100644 index 3fbeb92e52b..00000000000 --- 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 - - - - - -

Data transfer from Sequencer

-

Sample "${sample.name}" of Request "${sample.request.name}"

- - - -
-
-
- %if len(dataset_files): - - - - - - - - - %for dataset_index, dataset_file in enumerate(dataset_files): - ${sample_dataset_files( dataset_index, dataset_file[0], dataset_file[1] )} - %endfor - -
Dataset FileTransfer Status
- %else: - There are no dataset files. - %endif -
-
-
- -<%def name="sample_dataset_files( dataset_index, dataset_file, status )"> - - ${dataset_file.split('/')[-1]} - - %if status == sample.transfer_status.IN_PROGRESS: - ${status} - %else: - ${status} - %endif - - - \ No newline at end of file diff --git a/templates/requests/show_request.mako b/templates/requests/show_request.mako deleted file mode 100644 index d80ff89706a..00000000000 --- 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 - - - - - - - -%if request.rejected(): - ${render_msg( "Reason for rejection: "+request.last_comment(), "warning" )} -%endif - -
-

Sequencing Request "${request.name}"

-
- - - -<%def name="show_basic_info_form( sample_index, sample, info )"> - - -
- ${' (required)' } -
- - %if sample: - %if sample.request.unsubmitted(): - - %else: - - %endif - %else: - - %endif - %if sample: - %if not sample.current_state(): - Unsubmitted - %else: - ${sample.current_state().name} - %endif - %else: - - %endif - ${info['lib_widget'].get_html()} - ${info['folder_widget'].get_html()} - %if request.submitted() or request.complete(): - %if sample: - ${len(sample.dataset_files)} - %else: - Add - %endif - %endif - - -## This function displays the "Basic Information" grid -<%def name="render_basic_info_grid()"> -

Sample Information

- - - - - - - - - %if request.submitted() or request.complete(): - - %endif - - - - - <% - 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': - - ${show_basic_info_form( sample_index, sample, info )} - - %else: - - %if sample_index in range(len(request.samples)): - - - - %if info['library']: - - %else: - - %endif - %if info['folder']: - - %else: - - %endif - %if request.submitted() or request.complete(): - - %endif - - - %else: - ${show_basic_info_form( sample_index, sample, info )} - %endif - %if request.unsubmitted() or request.rejected(): - - %endif - - %endif - %endfor - -
NameBarcodeStateData LibraryFolderDataset(s) Transferred
${info['name']}${info['barcode']} - %if sample.current_state(): - ${sample.current_state().name} - %else: - Unsubmitted - %endif - ${info['library'].name}${info['folder'].name} - ${len(sample.dataset_files)} - - %if sample: - %if sample.request.unsubmitted(): - - - - %endif - %endif -
- - -<%def name="render_sample_form( index, sample_name, sample_values, fields_dict )"> - - ${sample_name} - - %for field_index, field in fields_dict.items(): - - %if field['type'] == 'TextField': - - %elif field['type'] == 'SelectField': - - %elif field['type'] == 'WorkflowField': - - %elif field['type'] == 'CheckboxField': - - %endif -
- ${'('+field['required']+')' } -
- - %endfor - - -<%def name="render_sample( index, sample_name, sample_values, fields_dict )"> - - ${sample_name} - - %for field_index, field in fields_dict.items(): - - %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]) ) %> - ${workflow.name} - %endif - %else: - ${sample_values[field_index]} - %endif - %else: - None - %endif - - - %endfor - - -<%def name="render_grid( grid_index, grid_name, fields_dict )"> -
-
- %if grid_name: -

${grid_name}

- %else: -

Grid ${grid_index}

- %endif - %if edit_mode == 'False' or len(current_samples) <= len(request.samples): -
- %else: -
- %endif - - - - - %for index, field in fields_dict.items(): - - %endfor - - - - - <% - trans.sa_session.refresh( request ) - %> - %for sample_index, sample in enumerate(current_samples): - %if edit_mode == 'True': - - ${render_sample_form( sample_index, sample['name'], sample['field_values'], fields_dict)} - - %else: - - %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 - - %endif - %endfor - -
Name - ${field['label']} -
- ${field['helptext']} -
-
-
-
- - -
-
-
-
-

Request Information

-
- %for index, rd in enumerate(request_details): -
- - %if not rd['value']: - None - %else: - %if rd['label'] == 'State': - ${rd['value']} - %else: - ${rd['value']} - %endif - %endif -
-
- %endfor - -
-
-
-
-
-
- %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 ) )} -
- %endfor - %else: - - %endif -
- %if request.unsubmitted() and edit_mode == 'False': - - - -
-
- - - - -
- %if current_samples: - - - - ${sample_copy.get_html()} - %endif - - - %if len(current_samples) and len(current_samples) <= len(request.samples): - - %endif -
- %endif - %if request.unsubmitted() and (request.samples or current_samples): -
-
- -
-
-
-
- - %if edit_mode == 'True': - - %endif -
- %endif - -
-
- - -
-%if request.unsubmitted(): -
-
-
-
-

Import samples from csv file

-
- - -
-
- The csv file must be in the following format:
- SampleName,DataLibrary,DataLibraryFolder,FieldValue1,FieldValue2... -
-
-
-
- -
-
-%endif diff --git a/templates/sample/sample_events.mako b/templates/sample/sample_events.mako deleted file mode 100644 index 6ff45c163e9..00000000000 --- 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} - - -

Events for Sample "${sample_name}"

- - - -%if message: - ${render_msg( message, status )} -%endif - -
- - - - - - - - - - - %for state, desc, updated, comments in events_list: - - - - - - - %endfor - -
StateDescriptionUpdatedComments
${state}${desc}${updated}${comments}
-
\ No newline at end of file diff --git a/test/base/twilltestcase.py b/test/base/twilltestcase.py index 2e48d0a5d73..aa1ea8e957c 100644 --- 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 %s 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 ) diff --git a/test/functional/test_forms_and_requests.py b/test/functional/test_forms_and_requests.py index b633acf4b89..95731ba35ca 100644 --- a/test/functional/test_forms_and_requests.py +++ b/test/functional/test_forms_and_requests.py @@ -189,7 +189,7 @@ class TestFormsAndRequests( TwillTestCase ): # 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( TwillTestCase ): 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( TwillTestCase ): 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 %s 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( TwillTestCase ): # 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()