Google Contacts import

 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
from BeautifulSoup import BeautifulSoup
import urllib
import httplib

GDATA_URL = '/accounts/ClientLogin'

class GdataError(Exception):
    pass

class Gdata:
    """
    A class to retrieve a users contacts from their Google Account.
    
    Dependencies:
    -------------
    * BeautifulSoup. 
    * That's it. :-)

    Usage:
    ------
    >>> g = Gdata('email@example.org', 'password')
    >>> g.login()
    (200, 'OK')
    >>> g.get_contacts()
    >>> g.contacts
    [(u'Persons Name', 'name@person.com'), ...]


    """
    def __init__(self, username='test@gmail.com', password='test', service='cp'):
        self.username = username
        self.password = password
        self.account_type = 'HOSTED_OR_GOOGLE'  # Allow both Google Domain and Gmail accounts
        self.service = service                  # Defaults to cp (contacts)
        self.source = 'google-data-import'            # Our application name
        self.code = ''                          # Empty by default, populated by self.login()
        self.contacts = []                      # Empty list by default, populated by self.get_contacts()
    
    def login(self):
        """
        Login to Google. No arguments.
        """
        data = urllib.urlencode({
            'accountType': self.account_type,
            'Email': self.username,
            'Passwd': self.password,
            'service': self.service,
            'source': self.source
        })
        headers = {
            'Content-type': 'application/x-www-form-urlencoded',
            'Accept': 'text/plain'
        }
        
        conn = httplib.HTTPSConnection('google.com')
        conn.request('POST', GDATA_URL, data, headers)
        response = conn.getresponse()
        if not str(response.status) == '200':
            raise GdataError("Couldn't log in. HTTP Code: %s, %s" % (response.status, response.reason))
            
        d = response.read()
        
        self.code = d.split("\n")[2].replace('Auth=', '')
        return response.status, response.reason
    
    def _request(self, max_results=200):
        """
        Base function for requesting the contacts. We'll allow other methods eventually
        """
        url = '/m8/feeds/contacts/%s/base/?max-results=%d' % (self.username, max_results)
        
        headers = {'Authorization': 'GoogleLogin auth=%s' % self.code}
        
        conn = httplib.HTTPConnection('www.google.com')
        conn.request('GET', url, headers=headers)
        response = conn.getresponse()
        if not str(response.status) == '200':
            raise GdataError("Couldn't log in. HTTP Code: %s, %s" % (response.status, response.reason))
        
        return response.read()
    
    def get_contacts(self, max_results=200):
        """ Parses the contacts (using BeautifulSoup) from self._request, and then populates self.contacts
        """
        soup = BeautifulSoup(self._request(max_results))
        self.contacts = []
        for entry in soup.findAll('title'):
            if len(entry.parent.findAll(['gd:email', 'title'])) == 2:
                s = entry.parent.findAll(['gd:email', 'title'])
                self.contacts.append((s[0].string, s[1].get('address')))
        
        return

More like this

  1. Google Contacts API friend finder by dgouldin 6 years ago
  2. Django google maps v3 snipplet by summerisgone 3 years, 9 months ago
  3. Using Google Apps Premium infrastructure for user management by tommy 5 years, 8 months ago
  4. Get Latitude and Longitude from google maps by b23 6 years, 4 months ago
  5. model queries to Google Visualization DataTables by banderkat 9 months, 1 week ago

Comments

henriklied (on March 22, 2008):

Yes, you're right, Simon, AuthSub is what most people should use. In my case, ClientLogin provided the most fluent experience for the user (which was what my client requested), so I went for it.

I could always throw up an example using AuthSub, for those interested.

#

(Forgotten your password?)