1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
from datetime import datetime
import os
from pathlib import Path
from apiclient.discovery import build
from apiclient import errors
from httplib2 import Http
import oauth2client
from oauth2client import client
from oauth2client import tools
import json
import base64
import binascii
from send_email import get_gmail_service
import argparse
import logging
def ListMessagesWithLabels(service, user_id, label_ids=[]):
"""List all Messages of the user's mailbox with label_ids applied.
Args:
service: Authorized Gmail API service instance.
user_id: User's email address. The special value "me"
can be used to indicate the authenticated user.
label_ids: Only return Messages with these labelIds applied.
Returns:
List of Messages that have all required Labels applied. Note that the
returned list contains Message IDs, you must use get with the
appropriate id to get the details of a Message.
"""
try:
response = service.users().messages().list(userId=user_id,
labelIds=label_ids).execute()
messages = []
if 'messages' in response:
messages.extend(response['messages'])
while 'nextPageToken' in response:
page_token = response['nextPageToken']
response = service.users().messages().list(userId=user_id,
labelIds=label_ids,
pageToken=page_token).execute()
messages.extend(response['messages'])
return messages
except errors.HttpError as error:
print(json.loads(error.content.decode('utf-8'))['error']['message'])
def labels_dict(service, user_id):
"""Returns a dictionary mapping labels to labelids.
Args:
service: Authorized Gmail API service instance.
user_id: User's email address. The special value "me"
Returns:
dictionary mapping labels to labelids.
"""
try:
response = service.users().labels().list(userId=user_id).execute()
labels = response['labels']
return {label['name']: label['id'] for label in labels}
except errors.HttpError as error:
print(json.loads(error.content.decode('utf-8'))['error']['message'])
def get_msg(service, user_id, msg_id):
try:
message = service.users().messages().get(userId=user_id, id=msg_id, format='full').execute()
return message
except errors.HttpError as error:
print(json.loads(error.content.decode('utf-8'))['error']['message'])
def msg_content(msg):
"""Extract subject and body from a gmail message"""
subject = [x['value'] for x in msg['payload']['headers'] if x['name']=='Subject'][0]
content = base64.urlsafe_b64decode(msg['payload']['body']['data']).decode('utf-8')
date = msg['internalDate'] ## date /1000 to get timestamp
return subject, content, date
def update_emails():
"""Download new emails that were labeled swaptions."""
service = get_gmail_service()
labelsdict = labels_dict(service, 'me')
p = Path(os.getenv("DATA_DIR")) / Path('swaptions')
current_msgs = set([f.name for f in p.iterdir() if f.is_file()])
for msg in ListMessagesWithLabels(service, 'me', labelsdict['swaptions']):
if msg['id'] not in current_msgs:
try:
subject, content, date = msg_content(get_msg(service, 'me', msg['id']))
except (binascii.Error, KeyError, UnicodeDecodeError) as e:
logging.error("error decoding " + msg['id'])
continue
else:
email = p / msg['id']
with email.open("w") as fh:
fh.write(date + "\r\n")
fh.write(subject + "\r\n")
fh.write(content)
if __name__ == '__main__':
update_emails()
|