173 lines
4.8 KiB
Python
173 lines
4.8 KiB
Python
|
from __future__ import print_function
|
||
|
import httplib2
|
||
|
import json
|
||
|
import logging
|
||
|
import os
|
||
|
import time
|
||
|
from pprint import pprint
|
||
|
|
||
|
from apiclient import discovery
|
||
|
from googleapiclient.errors import HttpError
|
||
|
from oauth2client import client
|
||
|
from oauth2client import tools
|
||
|
from oauth2client.file import Storage
|
||
|
|
||
|
try:
|
||
|
import argparse
|
||
|
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
|
||
|
except ImportError:
|
||
|
flags = None
|
||
|
|
||
|
# If modifying these scopes, delete your previously saved credentials
|
||
|
# at ~/.credentials/people.googleapis.com-python-quickstart.json
|
||
|
SCOPES = 'https://www.googleapis.com/auth/contacts.readonly'
|
||
|
CLIENT_SECRET_FILE = 'client_secret.json'
|
||
|
APPLICATION_NAME = 'People API Python Quickstart'
|
||
|
|
||
|
logging.basicConfig(level=logging.DEBUG)
|
||
|
|
||
|
|
||
|
def safe_execute_with_backoff(request):
|
||
|
"""
|
||
|
Executes an http request and retries rate limit errors
|
||
|
|
||
|
Catches HttpError and, if it's a 429, sleepts for .5s and retries
|
||
|
"""
|
||
|
attempt = 0
|
||
|
sleep_time = .5
|
||
|
|
||
|
while True:
|
||
|
try:
|
||
|
return request.execute()
|
||
|
except HttpError as error:
|
||
|
logging.info('Got HttpError')
|
||
|
if error.resp.status == 429:
|
||
|
sleep_for = sleep_time * (2 ** attempt)
|
||
|
logging.info('Sleeping for %.3g second(s)', sleep_for)
|
||
|
time.sleep(sleep_for)
|
||
|
attempt += 1
|
||
|
else:
|
||
|
raise error
|
||
|
|
||
|
|
||
|
def get_all_results(api, request, key='connections'):
|
||
|
logging.info('Getting first results')
|
||
|
results = safe_execute_with_backoff(request)
|
||
|
|
||
|
for result in results.get(key, []):
|
||
|
yield result
|
||
|
|
||
|
request = api.list_next(request, results)
|
||
|
while request:
|
||
|
logging.info('Getting next...')
|
||
|
results = safe_execute_with_backoff(request)
|
||
|
|
||
|
for result in results.get(key, []):
|
||
|
yield result
|
||
|
|
||
|
request = api.list_next(request, results)
|
||
|
if not request:
|
||
|
logging.info('No next page :(')
|
||
|
|
||
|
|
||
|
def write_map_to_file(email_to_photo):
|
||
|
with open('email_to_photo.json', 'w') as f:
|
||
|
f.write(json.dumps(email_to_photo))
|
||
|
|
||
|
|
||
|
def get_credentials():
|
||
|
"""Gets valid user credentials from storage.
|
||
|
|
||
|
If nothing has been stored, or if the stored credentials are invalid,
|
||
|
the OAuth2 flow is completed to obtain the new credentials.
|
||
|
|
||
|
Returns:
|
||
|
Credentials, the obtained credential.
|
||
|
"""
|
||
|
home_dir = os.path.expanduser('~')
|
||
|
credential_dir = os.path.join(home_dir, '.credentials')
|
||
|
if not os.path.exists(credential_dir):
|
||
|
os.makedirs(credential_dir)
|
||
|
credential_path = os.path.join(
|
||
|
credential_dir,
|
||
|
'people.googleapis.com-python-quickstart.json'
|
||
|
)
|
||
|
|
||
|
store = Storage(credential_path)
|
||
|
credentials = store.get()
|
||
|
if not credentials or credentials.invalid:
|
||
|
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
|
||
|
flow.user_agent = APPLICATION_NAME
|
||
|
if flags:
|
||
|
credentials = tools.run_flow(flow, store, flags)
|
||
|
else: # Needed only for compatibility with Python 2.6
|
||
|
credentials = tools.run(flow, store)
|
||
|
print('Storing credentials to ' + credential_path)
|
||
|
return credentials
|
||
|
|
||
|
|
||
|
def get_primary_photo(person):
|
||
|
"""Accepts a person from a connections request and returns the primary photo
|
||
|
if it exists."""
|
||
|
for photo in person.get('photos', []):
|
||
|
if photo.get('metadata', {}).get('primary'):
|
||
|
return photo['url']
|
||
|
|
||
|
return None
|
||
|
|
||
|
|
||
|
def main():
|
||
|
"""Shows basic usage of the Google People API.
|
||
|
|
||
|
Creates a Google People API service object and outputs the name if
|
||
|
available of 10 connections.
|
||
|
"""
|
||
|
credentials = get_credentials()
|
||
|
http = credentials.authorize(httplib2.Http())
|
||
|
service = discovery.build(
|
||
|
'people', 'v1', http=http,
|
||
|
discoveryServiceUrl='https://people.googleapis.com/$discovery/rest'
|
||
|
)
|
||
|
|
||
|
connections = get_all_results(
|
||
|
api=service.people().connections(),
|
||
|
request=service.people().connections().list(
|
||
|
resourceName='people/me',
|
||
|
pageSize=100,
|
||
|
personFields='emailAddresses,photos',
|
||
|
),
|
||
|
key='connections',
|
||
|
)
|
||
|
|
||
|
all_photos = set()
|
||
|
email_to_photo = {}
|
||
|
count = 0
|
||
|
|
||
|
for person in connections:
|
||
|
count += 1
|
||
|
|
||
|
primary_photo = get_primary_photo(person)
|
||
|
if not primary_photo:
|
||
|
continue
|
||
|
|
||
|
emails = person.get('emailAddresses', [])
|
||
|
if emails:
|
||
|
all_photos.add(primary_photo)
|
||
|
|
||
|
for email in emails:
|
||
|
email_to_photo[email['value']] = primary_photo
|
||
|
|
||
|
if count % 50 == 0:
|
||
|
logging.info('Found {} photos for {} emails'.format(
|
||
|
len(all_photos),
|
||
|
len(email_to_photo),
|
||
|
))
|
||
|
|
||
|
# pprint(email_to_photo)
|
||
|
write_map_to_file(email_to_photo)
|
||
|
print('All done!')
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
main()
|