4 from oauth import oauth
5 from xml.dom.minidom import parseString
6 from org.maemo.hermes.engine.phonenumber import PhoneNumber
7 from org.maemo.hermes.engine.friend import Friend
8 from org.maemo.hermes.engine.service import CredentialsExpiredException
11 """LinkedIn API for Hermes.
13 Copyright (c) Fredrik Wendt <fredrik@wendt.se> 2010.
14 Copyright (c) Andrew Flegg <andrew@bleb.org> 2010.
15 Released under the Artistic Licence."""
17 LI_API_URL = "https://api.linkedin.com"
18 LI_CONN_API_URL = LI_API_URL + "/v1/people/~/connections:(id,first-name,last-name,picture-url,site-standard-profile-request:(url),date-of-birth,main-address,location:(country:(code)),phone-numbers,member-url-resources)"
19 LI_PROFILE_API_URL = LI_API_URL + "/v1/people/~"
22 # -----------------------------------------------------------------------
23 def __init__(self, consumer, api_request):
24 """Instantiate with an OAuth consumer"""
25 self.consumer = consumer
26 self._make_api_request = api_request
29 # -----------------------------------------------------------------------
30 def verify_verifier(self, access_token):
32 xml = self._make_api_request(self.LI_PROFILE_API_URL)
33 dom = parseString(xml)
34 friends = self._parse_dom(dom)
35 return friends[0].get_name()
39 raise Exception("LinkedIn authorization failed, try again")
43 # -----------------------------------------------------------------------
44 def get_friends(self):
45 """ Returns a Friend object for each LinkedIn connection."""
47 xml = self._make_api_request(self.LI_CONN_API_URL)
48 dom = parseString(xml)
49 friends = self._parse_dom(dom)
54 # -----------------------------------------------------------------------
55 def get_friend_details(self, url, header_value):
56 oauth_request = oauth.OAuthRequest.from_consumer_and_token(self.consumer, token=self.access_token, http_url=url)
57 oauth_request.sign_request(self.sig_method, self.consumer, self.access_token)
59 headers = oauth_request.to_header()
60 headers[u'x-li-auth-token'] = header_value
61 connection = httplib.HTTPConnection("api.linkedin.com")
62 connection.request(oauth_request.http_method, url, headers=headers)
63 data = connection.getresponse().read()
67 # -----------------------------------------------------------------------
68 def _parse_dom(self, dom):
69 def get_first_tag(node, tagName):
71 tags = node.getElementsByTagName(tagName)
72 if tags and len(tags) > 0:
75 def extract(node, tagName):
76 tag = get_first_tag(node, tagName)
78 return tag.firstChild.nodeValue
80 def extract_public_url(node):
81 tag = get_first_tag(node, 'site-standard-profile-request')
83 url = extract(tag, 'url').replace("&", "&")
84 return re.sub('[?&](auth|trk)\w*=[^&]*', '', url)
86 def extract_phone_numbers(node):
87 country = extract(get_first_tag(node, 'country'), 'code')
88 tag = get_first_tag(node, 'phone-numbers')
91 for element in tag.childNodes:
92 if element.nodeName != 'phone-number':
95 phone_type = extract(element, 'phone-type')
96 device = phone_type == 'mobile' and phone_type or None
97 type = phone_type in set(['home', 'work']) and phone_type or None
99 number = PhoneNumber(extract(element, 'phone-number'), device = device, type = type, country = country)
100 numbers.append(number)
103 def extract_urls(node):
104 tag = get_first_tag(node, 'member-url-resources')
107 for element in tag.getElementsByTagName('url'):
108 urls.append(element.firstChild.nodeValue.replace("&", "&"))
111 def extract_birthday(node):
112 tag = get_first_tag(node, 'date-of-birth')
115 month = extract(tag, 'month')
116 day = extract(tag, 'day')
117 year = extract(tag, 'year')
119 bday = '%s/%s' % (extract(tag, 'month'), extract(tag, 'day'))
121 bday = '%s/%s' % (bday, year)
126 errors = dom.getElementsByTagName('error')
127 if errors and len(errors) > 0:
130 details = " (" + extract(errors[0], "message") + ")"
133 if details.startswith('([unauth'):
134 raise CredentialsExpiredException('LinkedIn')
136 raise Exception("LinkedIn communication errors detected" + details)
139 people = dom.getElementsByTagName('person')
141 fn = extract(p, 'first-name')
142 ln = extract(p, 'last-name')
143 photo_url = extract(p, 'picture-url')
144 id = extract(p, 'id')
145 public_url = extract_public_url(p)
146 bday = extract_birthday(p)
149 friend = Friend(name)
150 friend.add_url(public_url)
152 friend.set_photo_url(photo_url)
155 friend.set_birthday_date(bday)
157 for number in extract_phone_numbers(p):
158 friend.add_phone(number)
160 for url in extract_urls(p):
163 friends.append(friend)