@@ -594,7 +594,7 @@ def create(cls, user, parameters, force=False):
594594 if vals [0 ] == 'artifact' :
595595 artifact_info = parameters .values [pname ]
596596 # If the artifact_info is a list, then the artifact
597- # still doesn't exists because the current job is part
597+ # still doesn't exist because the current job is part
598598 # of a workflow, so we can't link
599599 if not isinstance (artifact_info , list ):
600600 TTRN .add (sql , [artifact_info , job_id ])
@@ -703,6 +703,101 @@ def status(self):
703703 qdb .sql_connection .TRN .add (sql , [self .id ])
704704 return qdb .sql_connection .TRN .execute_fetchlast ()
705705
706+ def _generate_notification_message (self , value , error_msg ):
707+ ignored_software = ('artifact definition' ,)
708+ ignored_commands = ('Validate' , 'complete_job' , 'release_validators' )
709+
710+ # abort early conditions (don't send an email notification)
711+ # tentatively accept the overhead of a function-call, even when a
712+ # notification isn't sent, just to keep the logic clean and
713+ # centralized.
714+
715+ if value == 'waiting' :
716+ # notification not needed.
717+ return None
718+
719+ if not self .user .info ['receive_processing_job_emails' ]:
720+ # notification not needed.
721+ return None
722+
723+ if self .command .software .name in ignored_software :
724+ # notification not needed.
725+ return None
726+
727+ if self .command .name in ignored_commands :
728+ # notification not needed.
729+ return None
730+
731+ # generate subject line
732+ subject = 'Job status change: %s (%s)' % (self .command .name , self .id )
733+
734+ # generate message line
735+ message = ''
736+
737+ input_artifacts = self .input_artifacts
738+ if input_artifacts is None :
739+ # this is an admin job. display command name and parameters
740+ message = (f'Admin Job { self .command .name } '
741+ f'{ self .command .parameters } ' )
742+ else :
743+ for artifact in input_artifacts :
744+ if artifact .prep_templates is not None :
745+ # this is a processing job. display the study id as link,
746+ # prep ids, data_type, and command name.
747+ study_ids = [x .study_id for x in artifact .prep_templates ]
748+ prep_ids = [x .id for x in artifact .prep_templates ]
749+ data_types = [x .data_type () for x in
750+ artifact .prep_templates ]
751+
752+ # there should only be one study id
753+ study_ids = set (study_ids )
754+ if len (study_ids ) > 1 :
755+ raise qdb .exceptions .QiitaError ("More than one Study "
756+ "ID was found: "
757+ f"{ study_ids } " )
758+ study_id = study_ids .pop ()
759+
760+ # there should be at least one prep_id and probably more.
761+ prep_ids = set (prep_ids )
762+ if len (prep_ids ) == 0 :
763+ raise qdb .exceptions .QiitaError ("No Prep IDs were "
764+ "found" )
765+ # convert into a string for presentation.
766+ prep_ids = [str (x ) for x in prep_ids ]
767+ prep_ids = ', ' .join (prep_ids )
768+
769+ # there should be only one data type.
770+ data_types = set (data_types )
771+ if len (data_types ) > 1 :
772+ raise qdb .exceptions .QiitaError ("More than one data "
773+ "type was found: "
774+ f"{ data_types } " )
775+ data_type = data_types .pop ()
776+
777+ message = f'Processing Job: { self .command .name } \n '
778+ message += 'Study <A HREF="https://qiita.ucsd.edu/study/'
779+ message += f'description/{ study_id } ">{ study_id } '
780+ message += '</A>\n '
781+ message += f'Prep IDs: { prep_ids } \n '
782+ message += f'Data Type: { data_type } \n '
783+ elif artifact .analysis is not None :
784+ # this is an analysis job. display analysis id as link and
785+ # the command name.
786+ message = f'Analysis Job { self .command .name } '
787+ message += '<A HREF="https://qiita.ucsd.edu/analysis/'
788+ message += f'description/{ artifact .analysis .id } ">'
789+ message += f'{ artifact .analysis .id } </A>\n '
790+ else :
791+ raise qdb .exceptions .QiitaError ("Unknown Condition" )
792+
793+ # append legacy message line
794+ message += 'New status: %s' % (value )
795+
796+ if value == 'error' and error_msg is not None :
797+ message += f'\n \n Error:\n { error_msg } '
798+
799+ return {'subject' : subject , 'message' : message }
800+
706801 def _set_status (self , value , error_msg = None ):
707802 """Sets the status of the job
708803
@@ -734,22 +829,11 @@ def _set_status(self, value, error_msg=None):
734829 new_status = qdb .util .convert_to_id (
735830 value , "processing_job_status" )
736831
737- if value not in {'waiting' }:
738- if self .user .info ['receive_processing_job_emails' ]:
739- # skip if software is artifact definition
740- ignore_software = ('artifact definition' , )
741- if self .command .software .name not in ignore_software :
742- ignore_commands = ('Validate' , 'complete_job' ,
743- 'release_validators' )
744- if self .command .name not in ignore_commands :
745- subject = 'Job status change: %s (%s)' % (
746- self .command .name , self .id )
747- message = 'New status: %s' % (value )
748-
749- if value == 'error' and error_msg is not None :
750- message += f'\n \n Error:\n { error_msg } '
751- qdb .util .send_email (
752- self .user .email , subject , message )
832+ msg = self ._generate_notification_message (value , error_msg )
833+ if msg is not None :
834+ # send email
835+ qdb .util .send_email (self .user .email , msg ['subject' ],
836+ msg ['message' ])
753837
754838 sql = """UPDATE qiita.processing_job
755839 SET processing_job_status_id = %s
0 commit comments