Last active
November 26, 2022 19:32
-
-
Save thusoy/e6706ab24574868f7b17 to your computer and use it in GitHub Desktop.
Convert your Google contacts to mutt format
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# -*- coding: utf-8 -*- | |
# This script is designed to sync mutt aliases with Google contacts | |
from __future__ import unicode_literals | |
import sys | |
import datetime | |
import atom | |
import argparse | |
from oauth2client import tools | |
from oauth2client.client import OAuth2WebServerFlow | |
from oauth2client.file import Storage | |
import gdata.contacts | |
import gdata.contacts.data | |
from collections import namedtuple | |
import gdata.contacts.client | |
import gdata.gauth | |
import gdata.contacts.service | |
import httplib2 | |
client_id = '<ADD_CLIENT_ID_HERE>' | |
client_secret = '<ADD_CLIENT_SECRET_HERE>' | |
class OAuthToken(object): | |
def __init__(self, access_token): | |
self.access_token = access_token | |
def modify_request(self, http_request): | |
print 'modify_request' | |
http_request.headers['Authorization'] = 'Bearer %s' % (self.access_token) | |
return http_request | |
def main(client_id, client_secret): | |
def remove_aliases(email): | |
lookup_key = name.replace(' ', '-').lower() | |
emails_without_known_alias = [] | |
# Extract the emails with a known relation, such as work and home, | |
# and add separate aliases for them | |
for i, email in enumerate(emails[:]): | |
rel_name = rel_map.get(email.rel) | |
if rel_name: | |
lookup_key += '-%s' % rel_name | |
aliases.append(Alias(lookup_key, name, email.address)) | |
else: | |
emails_without_known_alias.append(email) | |
if len(emails_without_known_alias) == 1: | |
email = emails_without_known_alias[0] | |
aliases.append(Alias(lookup_key, name, email.address)) | |
return [] | |
return emails_without_known_alias | |
scope = 'https://www.google.com/m8/feeds/' | |
flow = OAuth2WebServerFlow(client_id=client_id, | |
client_secret=client_secret, | |
scope=scope, | |
redirect_uri='urn:ietf:wg:oauth:2.0:oob') | |
query = gdata.contacts.client.ContactsQuery() | |
query.max_results = 4000 | |
storage = Storage('a_credentials_file') | |
parser = argparse.ArgumentParser(parents=[tools.argparser]) | |
flags = parser.parse_args() | |
credentials = storage.get() | |
# Google returns 'invalid_grant' when trying to refresh the token, but fails | |
# to properly describe why this happens. Thus we create a new set of credentials | |
# from scratch if they have expired | |
if not credentials or datetime.datetime.utcnow() > credentials.token_expiry: | |
credentials = tools.run_flow(flow, storage, flags) | |
contacts = [] | |
access_token = credentials.get_access_token() | |
auth_token = OAuthToken(access_token.access_token) | |
gd_client = gdata.contacts.client.ContactsClient() | |
try: | |
with open('contact_feed.atom') as fh: | |
feed_body = fh.read() | |
desired_class = gdata.contacts.data.ContactsFeed | |
feed = atom.core.parse(feed_body, desired_class) | |
except IOError: | |
try: | |
feed = gd_client.GetContacts(q=query, auth_token=auth_token) | |
with open('contact_feed.atom', 'w') as fh: | |
fh.write(feed.to_string()) | |
except Exception as e: | |
print e.status | |
sys.exit(1) | |
wtf_contacts = [] | |
for contact in feed.entry: | |
if contact.name: | |
contacts.append(contact) | |
else: | |
wtf_contacts.append(contact) | |
rel_map = { | |
'http://schemas.google.com/g/2005#home': 'privat', | |
'http://schemas.google.com/g/2005#work': 'work', | |
} | |
Alias = namedtuple('Alias', ['identifier', 'name', 'email']) | |
aliases = [] | |
for contact in contacts: | |
name = contact.name.full_name.text | |
lookup_key = name.replace(' ', '-').lower() | |
emails = contact.email | |
if len(emails) == 0: | |
print 'No email for %s' % name | |
elif len(emails) > 1: | |
emails = remove_aliases(emails) | |
if emails: | |
handle_multiple_emails(name, emails) | |
else: | |
email = emails[0] | |
aliases.append(Alias(lookup_key, name, email.address)) | |
with open('mutt_aliases.txt', 'w') as fh: | |
for alias in aliases: | |
fh.write(('%s %s <%s>\n' % (alias.identifier, alias.name, alias.email)).encode('utf-8')) | |
def handle_multiple_emails(name, emails): | |
for i, email in enumerate(emails): | |
print '%d: %s' % (i, email.address) | |
chosen_email_num = -1 | |
while not 0 <= chosen_email_num < len(emails): | |
try: | |
chosen_email_num = int(raw_input(('Select email to use for %s:' % name).encode('utf-8'))) | |
except ValueError as e: | |
print 'Enter a number between 0 and %d to indicate which email to use for %s' % ( | |
len(emails) -1, name) | |
except Exception as e: | |
import pdb; pdb.set_trace() | |
print e | |
email = emails[chosen_email_num] | |
if __name__ == '__main__': | |
main(client_id, client_secret) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment