Source code for gmailtool.mailstream

# -*- coding: utf-8 -*-
"""The mailstream module
"""

import apiclient
import email
import json


[docs]class GmailMailStream(object): """Present the Gmail API as a mail stream which can be sequentially accessed by .read() """ def __init__(self, http, mailbox, cursor=None): """Initialize a Gmail mail stream object Args: http (http): An oauthed http object from the google oauth system mailbox (str): The mailbox to read (e.g. example@gmail.com) cursor (str): The cursor data to load the current position in the inbox """ self._api = apiclient.discovery.build('gmail', 'v1', http=http) self._mailbox = mailbox if cursor is None: profile = self._api.users().getProfile(userId=mailbox).execute() self._cursor_last_history_id = int(profile['historyId']) else: cursor_dict = json.loads(cursor) self._cursor_last_history_id = cursor_dict['last_history_id'] @property def cursor(self): """str: JSON representation of the inbox cursor""" cursor_data = json.dumps({'last_history_id': self._cursor_last_history_id}) return cursor_data
[docs] def read(self): """Read a bunch of messages from gmail. Each time read is called it will attempt advance one history at at time. If advancing the history was successful then a list of email messages that were added to the mailbox will be returned. If we are at the most current history for the inbox and thus history was not advanced then None is returned. It is possible that an empty list is returned signifiying that history was advanced but no new emails were added in the new history. Call read() another time to advance further. Returns: List of email message or None: A list of email messasges in the next page of history. Returns None if we are already at the latest history and can not read any more """ history_list = self._api.users().history().list(userId=self._mailbox, historyTypes='messageAdded', maxResults=1, startHistoryId=self._cursor_last_history_id).execute() histories = history_list.get('history', []) if len(histories) > 0: next_history = histories[0] next_history_id = int(next_history['id']) messages = [] for message_info in next_history.get('messagesAdded', []): message_id = message_info['message']['id'] message_info_raw = self._api.users().messages().get(userId=self._mailbox, id=message_id, format='raw').execute() message_raw = message_info_raw['raw'].decode('base64') message = email.message_from_string(message_raw) messages.append(message) self._cursor_last_history_id = next_history_id return messages else: return None