Update email sender to use sendgmr, if it's available.

BUG=None
TEST=Tested with crosperf tests on my system.

Change-Id: I4db4cd70d74e5f13b1fe8bb022e5403f6902d1ee
Reviewed-on: https://chrome-internal-review.googlesource.com/216312
Reviewed-by: David Sharp <dhsharp@google.com>
Commit-Queue: Caroline Tice <cmtice@google.com>
Tested-by: Caroline Tice <cmtice@google.com>
diff --git a/utils/email_sender.py b/utils/email_sender.py
index f8c0d62..6bf696c 100644
--- a/utils/email_sender.py
+++ b/utils/email_sender.py
@@ -10,7 +10,9 @@
 import os
 import smtplib
 import sys
+import tempfile
 
+from utils import command_executer
 
 class EmailSender(object):
   class Attachment(object):
@@ -27,6 +29,24 @@
                 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()
 
@@ -60,3 +80,74 @@
     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()
+
+    try:
+      os.write(body_fd, text_to_send)
+      os.close(body_fd)
+      to_be_deleted = [body_filename]
+
+      # 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)