blob: 57013f4ed419b7bc840aaf35e91035ba2fb3b857 [file] [log] [blame]
#!/usr/bin/python
# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""
Mail the content of standard input.
Example usage:
Use pipe:
$ echo "Some content" |./gmail_lib.py -s "subject" abc@bb.com xyz@gmail.com
Manually input:
$ ./gmail_lib.py -s "subject" abc@bb.com xyz@gmail.com
> Line 1
> Line 2
Ctrl-D to end standard input.
"""
import argparse
import base64
import httplib2
import logging
import sys
import os
from email.mime.text import MIMEText
import common
from autotest_lib.client.common_lib import global_config
try:
from apiclient.discovery import build as apiclient_build
from apiclient import errors as apiclient_errors
from oauth2client import file as oauth_client_fileio
except ImportError as e:
apiclient_build = None
logging.debug("API client for gmail disabled. %s", e)
DEFAULT_GMAIL_CREDS_PATH = global_config.global_config.get_config_value(
'NOTIFICATIONS', 'gmail_api_credentials', default='')
class GmailApiException(Exception):
"""Exception raised in accessing Gmail API."""
class Message():
"""An email message."""
def __init__(self, to, subject, message_text):
"""Initialize a message.
@param to: The recievers saperated by comma.
e.g. 'abc@gmail.com,xyz@gmail.com'
@param subject: String, subject of the message
@param message_text: String, content of the message.
"""
self.to = to
self.subject = subject
self.message_text = message_text
def get_payload(self):
"""Get the payload that can be sent to the Gmail API.
@return: A dictionary representing the message.
"""
message = MIMEText(self.message_text)
message['to'] = self.to
message['subject'] = self.subject
return {'raw': base64.urlsafe_b64encode(message.as_string())}
class GmailApiClient():
"""Client that talks to Gmail API."""
def __init__(self, oauth_credentials):
"""Init Gmail API client
@param oauth_credentials: Path to the oauth credential token.
"""
if not apiclient_build:
raise GmailApiException('Cannot get apiclient library.')
storage = oauth_client_fileio.Storage(oauth_credentials)
credentials = storage.get()
if not credentials or credentials.invalid:
raise GmailApiException('Invalid credentials for Gmail API, '
'could not send email.')
http = credentials.authorize(httplib2.Http())
self._service = apiclient_build('gmail', 'v1', http=http)
def send_message(self, message):
"""Send an email message.
@param message: Message to be sent.
"""
try:
# 'me' represents the default authorized user.
message = self._service.users().messages().send(
userId='me', body=message.get_payload()).execute()
logging.debug('Email sent: %s' , message['id'])
except apiclient_errors.HttpError as error:
logging.error('Failed to send email: %s', error)
def get_default_creds_abspath():
"""Returns the abspath of the gmail api credentials file.
@return: A path to the oauth2 credentials file.
"""
auth_creds = DEFAULT_GMAIL_CREDS_PATH
return (auth_creds if os.path.isabs(auth_creds) else
os.path.join(common.autotest_dir, auth_creds))
def send_email(to, subject, message_text):
"""Send email.
@param to: The recipients, separated by comma.
@param subject: Subject of the email.
@param message_text: Text to send.
"""
auth_creds = get_default_creds_abspath()
if not os.path.isfile(auth_creds):
logging.error('Failed to send email to %s: Credential file does not'
'exist: %s. If this is a prod server, puppet should'
'install it. If you need to be able to send email, '
'find the credential file from chromeos-admin repo and '
'copy it to %s', to, auth_creds, auth_creds)
return
client = GmailApiClient(oauth_credentials=auth_creds)
m = Message(to, subject, message_text)
client.send_message(message=m)
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
parser = argparse.ArgumentParser(
description=__doc__, formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('-s', '--subject', type=str, dest='subject',
required=True, help='Subject of the mail')
parser.add_argument('recipients', nargs='*',
help='Email addresses separated by space.')
args = parser.parse_args()
if not args.recipients or not args.subject:
print 'Requires both recipients and subject.'
sys.exit(1)
message_text = sys.stdin.read()
send_email(','.join(args.recipients), args.subject , message_text)