| #!/usr/bin/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 |
| from email.MIMEBase import MIMEBase |
| from email.MIMEMultipart import MIMEMultipart |
| from email.MIMEText import MIMEText |
| import os |
| import smtplib |
| import tempfile |
| |
| from 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) |