details: http://www.bx.psu.edu/hg/galaxy/rev/b8b7b6c67839 changeset: 2548:b8b7b6c67839 user: Dan Blankenberg <dan@bx.psu.edu> date: Fri Aug 07 11:14:03 2009 -0400 description: Prevent metadata or datatype from being changed by the user when the dataset is part of a running/queued job. 1 file(s) affected in this change: lib/galaxy/web/controllers/root.py diffs (87 lines): diff -r e97c45040b3e -r b8b7b6c67839 lib/galaxy/web/controllers/root.py --- a/lib/galaxy/web/controllers/root.py Thu Aug 06 16:04:52 2009 -0400 +++ b/lib/galaxy/web/controllers/root.py Fri Aug 07 11:14:03 2009 -0400 @@ -226,7 +226,14 @@ @web.expose def edit(self, trans, id=None, hid=None, **kwd): - """Returns data directly into the browser. Sets the mime-type according to the extension""" + """Allows user to modify parameters of an HDA.""" + def __ok_to_edit_metadata( dataset_id ): + #prevent modifying metadata when dataset is queued or running as input/output + #This code could be more efficient, i.e. by using mappers, but to prevent slowing down loading a History panel, we'll leave the code here for now + for job_to_dataset_association in self.app.model.JobToInputDatasetAssociation.filter_by( dataset_id=dataset_id ).all() + self.app.model.JobToOutputDatasetAssociation.filter_by( dataset_id=dataset_id ).all(): + if job_to_dataset_association.job.state not in [ job_to_dataset_association.job.states.OK, job_to_dataset_association.job.states.ERROR, job_to_dataset_association.job.states.DELETED ]: + return False + return True if hid is not None: history = trans.get_history() # TODO: hid handling @@ -248,6 +255,9 @@ if params.change: # The user clicked the Save button on the 'Change data type' form if data.datatype.allow_datatype_change and trans.app.datatypes_registry.get_datatype_by_extension( params.datatype ).allow_datatype_change: + #prevent modifying datatype when dataset is queued or running as input/output + if not __ok_to_edit_metadata( data.id ): + return trans.show_error_message( "This dataset is currently being used as input or output. You cannot change datatype until the jobs have completed or you have canceled them." ) trans.app.datatypes_registry.change_datatype( data, params.datatype ) trans.app.model.flush() else: @@ -256,27 +266,32 @@ # The user clicked the Save button on the 'Edit Attributes' form data.name = params.name data.info = params.info - - # The following for loop will save all metadata_spec items - for name, spec in data.datatype.metadata_spec.items(): - if spec.get("readonly"): - continue - optional = params.get("is_"+name, None) - other = params.get("or_"+name, None) - if optional and optional == 'true': - # optional element... == 'true' actually means it is NOT checked (and therefore omitted) - setattr(data.metadata, name, None) - else: - if other: - setattr( data.metadata, name, other ) + msg = '' + if __ok_to_edit_metadata( data.id ): + # The following for loop will save all metadata_spec items + for name, spec in data.datatype.metadata_spec.items(): + if spec.get("readonly"): + continue + optional = params.get("is_"+name, None) + other = params.get("or_"+name, None) + if optional and optional == 'true': + # optional element... == 'true' actually means it is NOT checked (and therefore omitted) + setattr(data.metadata, name, None) else: - setattr( data.metadata, name, spec.unwrap( params.get (name, None) ) ) - - data.datatype.after_edit( data ) + if other: + setattr( data.metadata, name, other ) + else: + setattr( data.metadata, name, spec.unwrap( params.get (name, None) ) ) + data.datatype.after_edit( data ) + else: + msg = ' (Metadata could not be changed because this dataset is currently being used as input or output. You must cancel or wait for these jobs to complete before changing metadata.)' trans.app.model.flush() - return trans.show_ok_message( "Attributes updated", refresh_frames=['history'] ) + return trans.show_ok_message( "Attributes updated%s" % msg, refresh_frames=['history'] ) elif params.detect: # The user clicked the Auto-detect button on the 'Edit Attributes' form + #prevent modifying metadata when dataset is queued or running as input/output + if not __ok_to_edit_metadata( data.id ): + return trans.show_error_message( "This dataset is currently being used as input or output. You cannot change metadata until the jobs have completed or you have canceled them." ) for name, spec in data.metadata.spec.items(): # We need to be careful about the attributes we are resetting if name not in [ 'name', 'info', 'dbkey' ]: @@ -314,6 +329,7 @@ # returns the metadata dbkey unless it is None, in which # case it resorts to the old dbkey. Setting the dbkey # sets it properly in the metadata + #### This is likely no longer required, since the dbkey exists entirely within metadata (the old_dbkey field is gone): REMOVE ME? data.metadata.dbkey = data.dbkey # let's not overwrite the imported datatypes module with the variable datatypes? # the built-in 'id' is overwritten in lots of places as well