#!/usr/bin/env python2 # Copyright 2011 Google Inc. All Rights Reserved. """Utilities to send email either through SMTP or SendGMR.""" from __future__ import print_function from email import encoders as Encoders from email.mime.base import MIMEBase from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText import os import smtplib import tempfile from cros_utils import command_executer class EmailSender(object): """Utility class to send email through SMTP or SendGMR.""" class Attachment(object): """Small class to keep track of attachment info.""" def __init__(self, name, content): self.name = name self.content = content def SendEmail(self, email_to, subject, text_to_send, email_cc=None, email_bcc=None, email_from=None, msg_type='plain', attachments=None): """Choose appropriate email method and call it.""" if os.path.exists('/usr/bin/sendgmr'): self.SendGMREmail(email_to, subject, text_to_send, email_cc, email_bcc, email_from, msg_type, attachments) else: self.SendSMTPEmail(email_to, subject, text_to_send, email_cc, email_bcc, email_from, msg_type, attachments) def SendSMTPEmail(self, email_to, subject, text_to_send, email_cc, email_bcc, email_from, msg_type, attachments): """Send email via standard smtp mail.""" # Email summary to the current user. msg = MIMEMultipart() if not email_from: email_from = os.path.basename(__file__) msg['To'] = ','.join(email_to) msg['Subject'] = subject if email_from: msg['From'] = email_from if email_cc: msg['CC'] = ','.join(email_cc) email_to += email_cc if email_bcc: msg['BCC'] = ','.join(email_bcc) email_to += email_bcc msg.attach(MIMEText(text_to_send, msg_type)) if attachments: for attachment in attachments: part = MIMEBase('application', 'octet-stream') part.set_payload(attachment.content) Encoders.encode_base64(part) part.add_header('Content-Disposition', "attachment; filename=\"%s\"" % attachment.name) msg.attach(part) # Send the message via our own SMTP server, but don't include the # envelope header. s = smtplib.SMTP('localhost') s.sendmail(email_from, email_to, msg.as_string()) s.quit() def SendGMREmail(self, email_to, subject, text_to_send, email_cc, email_bcc, email_from, msg_type, attachments): """Send email via sendgmr program.""" ce = command_executer.GetCommandExecuter(log_level='none') if not email_from: email_from = os.path.basename(__file__) to_list = ','.join(email_to) if not text_to_send: text_to_send = 'Empty message body.' body_fd, body_filename = tempfile.mkstemp() to_be_deleted = [body_filename] try: os.write(body_fd, text_to_send) os.close(body_fd) # Fix single-quotes inside the subject. In bash, to escape a single quote # (e.g 'don't') you need to replace it with '\'' (e.g. 'don'\''t'). To # make Python read the backslash as a backslash rather than an escape # character, you need to double it. So... subject = subject.replace("'", "'\\''") if msg_type == 'html': command = ("sendgmr --to='%s' --subject='%s' --html_file='%s' " '--body_file=/dev/null' % (to_list, subject, body_filename)) else: command = ("sendgmr --to='%s' --subject='%s' --body_file='%s'" % (to_list, subject, body_filename)) if email_from: command += ' --from=%s' % email_from if email_cc: cc_list = ','.join(email_cc) command += " --cc='%s'" % cc_list if email_bcc: bcc_list = ','.join(email_bcc) command += " --bcc='%s'" % bcc_list if attachments: attachment_files = [] for attachment in attachments: if '<html>' in attachment.content: report_suffix = '_report.html' else: report_suffix = '_report.txt' fd, fname = tempfile.mkstemp(suffix=report_suffix) os.write(fd, attachment.content) os.close(fd) attachment_files.append(fname) files = ','.join(attachment_files) command += " --attachment_files='%s'" % files to_be_deleted += attachment_files # Send the message via our own GMR server. status = ce.RunCommand(command) return status finally: for f in to_be_deleted: os.remove(f)