Source code for snsxt.mail

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Sends email output of the pipeline results
"""
# ~~~~~ LOGGING ~~~~~~ #
import os
import shutil
from util import log
import logging
import config
from util import tools
from util import mutt
import _exceptions as _e

logger = logging.getLogger(__name__)

# path to the script's dir
scriptdir = os.path.dirname(os.path.realpath(__file__))
scriptname = os.path.basename(__file__)
script_timestamp = log.timestamp()

# ~~~~~ SETUP FUNCTIONS ~~~~~ #
[docs]def check_default_address(address, server, default_key = '__self__'): """ Checks if the provided ``address`` matches the ``default_key``, and if so, returns a default email address made from the username of the user running the program + the ``server``. Parameters ---------- address: str email address(es) in the format 'email1@server.com,email2@server.com' server: str email server to use for a default email address default_key: str value to use for recognizing when a default address should be returned Returns ------- str either the original ``address`` string, or an email address composed of the user's system name + ``server`` """ if address == default_key: default_address = mutt.get_reply_to_address(server = server) return(default_address) else: return(address)
# ~~~~~ LOAD CONFIGS ~~~~~ # configs = config.config reply_to_server = configs['reply_to_server'] success_recipients = check_default_address(address = configs['success_recipients'], server = reply_to_server) error_recipients = check_default_address(address = configs['error_recipients'], server = reply_to_server) notification_recipients = check_default_address(address = configs['notification_recipients'], server = reply_to_server) default_recipients = success_recipients default_reply_to = mutt.get_reply_to_address(server = configs['reply_to_server']) success_subject_line_base = configs['success_subject_line_base'] error_subject_line_base = configs['error_subject_line_base'] notification_subject_line_base = configs['notification_subject_line_base'] # list to hold files to send as attachments # other modults should append to this # TODO: is there a better way to handle this ?? email_files = [] """ This list should contain file paths output by analysis tasks for inclusion as email attachments at the end of a successful analysis pipeline. It should be accessed by other parts of the program external to this module Examples -------- Example usage:: task_output_file = 'foo.txt' mail.email_files.append(task_output_file) """ # ~~~~ CUSTOM FUNCTIONS ~~~~~~ #
[docs]def sns_start_email(analysis_dir, **kwargs): """ Emails the user when the sns pipeline starts Parameters ---------- analysis_dir: str path to a directory to hold the analysis output kwargs: dict dictionary containing extra args to pass to `run_tasks` """ recipient_list = kwargs.pop('recipient_list', notification_recipients) reply_to = kwargs.pop('reply_to', default_reply_to) subject_line = kwargs.pop('subject_line', notification_subject_line_base) subject_line = subject_line + ' sns analysis started' message = "sns analysis started in directory:\n{0}".format(analysis_dir) mail_command = mutt.mutt_mail(recipient_list = recipient_list, reply_to = reply_to, subject_line = subject_line, message = message, return_only_mode = True) run_cmd = tools.SubprocessCmd(command = mail_command).run() # print run command output messages logger.debug(run_cmd.proc_stdout) logger.debug(run_cmd.proc_stderr)
[docs]def validate_email_files(): """ Makes sure all the items in the ``email_files`` list exist and are considered valid for inclusion in email output Notes ----- Since the email output is sent by an external program such as ``mutt``, it is important that file attachments be valid before attempting to include them, since it will be more difficult to ensure that the email is sent successfully. """ for i, item in enumerate(email_files): if not tools.item_exists(item): logger.error('email file does not exist: {0}'.format(item)) email_files.pop(i)
[docs]def email_error_output(message_file, *args, **kwargs): """ Sends an email in the event that errors occurred during the analysis. Parameters ---------- message_file: str path to a file to use as the body of the email, typically the program's log file Keyword Arguments ----------------- subject_line: str the subject line that should be used for the email recipient_list: str the recipients for the email, in the format ``recipient_list = "user1@server.com,user2@server.com" `` """ email_output(message_file = message_file, subject_line = error_subject_line_base, recipient_list = error_recipients)
[docs]def email_output(message_file, *args, **kwargs): """ Sends an email upon the successful completion of the analysis pipeline. If any ``email_files`` were set by the program while running, they will be validated and included as email attachments. Parameters ---------- message_file: str path to a file to use as the body of the email, typically the program's log file args: list a list containing extra args to pass to ``email_output()`` kwargs: dict a dictionary containing extra args to pass to ``email_output()`` Keyword Arguments ----------------- recipient_list: str the recipients for the email, in the format ``recipient_list = "user1@server.com,user2@server.com" `` reply_to: str email address to use in the 'Reply To' field of the email subject_line: str the subject line that should be used for the email """ recipient_list = kwargs.pop('recipient_list', default_recipients) reply_to = kwargs.pop('reply_to', default_reply_to) subject_line = kwargs.pop('subject_line', success_subject_line_base) validate_email_files() logger.debug('email_files: {0}'.format(email_files)) mail_command = mutt.mutt_mail(recipient_list = recipient_list, reply_to = reply_to, subject_line = subject_line, message_file = message_file, attachment_files = email_files, return_only_mode = True) run_cmd = tools.SubprocessCmd(command = mail_command).run() # print run command output messages logger.debug(run_cmd.proc_stdout) logger.debug(run_cmd.proc_stderr) # check for success of the command if run_cmd.process.returncode != 0: err_message = 'The mutt email command did not complete successfully' raise _e.SubprocessCmdError(message = err_message, errors = '')
# TODO: need a backup email function to run in case this gets raised