ade@google.com | ac41d84 | 2010-08-20 17:11:25 +0100 | [diff] [blame] | 1 | # Copyright (C) 2010 Google Inc. |
| 2 | # |
| 3 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | # you may not use this file except in compliance with the License. |
| 5 | # You may obtain a copy of the License at |
| 6 | # |
| 7 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | # |
| 9 | # Unless required by applicable law or agreed to in writing, software |
| 10 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | # See the License for the specific language governing permissions and |
| 13 | # limitations under the License. |
| 14 | |
| 15 | __author__ = 'ade@google.com' |
| 16 | |
| 17 | import apiclient.discovery |
| 18 | import logging |
| 19 | import oauth_wrap |
| 20 | import oauth2 as oauth |
| 21 | import urllib |
| 22 | import urlparse |
| 23 | |
| 24 | try: |
| 25 | from urlparse import parse_qs, parse_qsl, urlparse |
| 26 | except ImportError: |
| 27 | from cgi import parse_qs, parse_qsl |
| 28 | |
| 29 | # TODO(ade) Replace user-agent with something specific |
| 30 | HEADERS = { |
| 31 | 'user-agent': 'gdata-python-v3-sample-client/0.1', |
| 32 | 'content-type': 'application/x-www-form-urlencoded' |
| 33 | } |
| 34 | |
| 35 | REQUEST_TOKEN_URL = 'https://www.google.com/accounts/OAuthGetRequestToken?domain=anonymous&scope=https://www.googleapis.com/auth/buzz' |
| 36 | AUTHORIZE_URL = 'https://www.google.com/buzz/api/auth/OAuthAuthorizeToken?domain=anonymous&scope=https://www.googleapis.com/auth/buzz' |
| 37 | ACCESS_TOKEN_URL = 'https://www.google.com/accounts/OAuthGetAccessToken' |
| 38 | |
ade@google.com | 2ab0de7 | 2010-09-27 23:26:54 +0100 | [diff] [blame] | 39 | # TODO(ade) This class is really a BuzzGaeBuilder. Rename it. |
ade@google.com | ac41d84 | 2010-08-20 17:11:25 +0100 | [diff] [blame] | 40 | class BuzzGaeClient(object): |
| 41 | def __init__(self, consumer_key='anonymous', consumer_secret='anonymous'): |
| 42 | self.consumer = oauth.Consumer(consumer_key, consumer_secret) |
| 43 | self.consumer_key = consumer_key |
| 44 | self.consumer_secret = consumer_secret |
| 45 | |
| 46 | def _make_post_request(self, client, url, parameters): |
| 47 | resp, content = client.request(url, 'POST', headers=HEADERS, |
| 48 | body=urllib.urlencode(parameters, True)) |
| 49 | |
| 50 | if resp['status'] != '200': |
| 51 | logging.warn('Request: %s failed with status: %s. Content was: %s' % (url, resp['status'], content)) |
| 52 | raise Exception('Invalid response %s.' % resp['status']) |
| 53 | return resp, content |
| 54 | |
| 55 | def get_request_token(self, callback_url, display_name = None): |
| 56 | parameters = { |
| 57 | 'oauth_callback': callback_url |
| 58 | } |
| 59 | |
| 60 | if display_name is not None: |
| 61 | parameters['xoauth_displayname'] = display_name |
| 62 | |
| 63 | client = oauth.Client(self.consumer) |
| 64 | resp, content = self._make_post_request(client, REQUEST_TOKEN_URL, parameters) |
| 65 | |
| 66 | request_token = dict(parse_qsl(content)) |
| 67 | return request_token |
| 68 | |
| 69 | def generate_authorisation_url(self, request_token): |
| 70 | """Returns the URL the user should be redirected to in other to gain access to their account.""" |
| 71 | |
| 72 | base_url = urlparse.urlparse(AUTHORIZE_URL) |
| 73 | query = parse_qs(base_url.query) |
| 74 | query['oauth_token'] = request_token['oauth_token'] |
| 75 | |
| 76 | logging.info(urllib.urlencode(query, True)) |
| 77 | |
| 78 | url = (base_url.scheme, base_url.netloc, base_url.path, base_url.params, |
| 79 | urllib.urlencode(query, True), base_url.fragment) |
| 80 | authorisation_url = urlparse.urlunparse(url) |
| 81 | return authorisation_url |
| 82 | |
| 83 | def upgrade_to_access_token(self, request_token, oauth_verifier): |
| 84 | token = oauth.Token(request_token['oauth_token'], |
| 85 | request_token['oauth_token_secret']) |
| 86 | token.set_verifier(oauth_verifier) |
| 87 | client = oauth.Client(self.consumer, token) |
| 88 | |
| 89 | parameters = {} |
| 90 | resp, content = self._make_post_request(client, ACCESS_TOKEN_URL, parameters) |
| 91 | access_token = dict(parse_qsl(content)) |
| 92 | |
| 93 | d = { |
| 94 | 'consumer_key' : self.consumer_key, |
| 95 | 'consumer_secret' : self.consumer_secret |
| 96 | } |
| 97 | d.update(access_token) |
| 98 | return d |
| 99 | |
ade@google.com | e80fec8 | 2010-08-20 23:42:08 +0100 | [diff] [blame] | 100 | def build_api_client(self, oauth_params=None): |
| 101 | if oauth_params is not None: |
| 102 | http = oauth_wrap.get_authorised_http(oauth_params) |
| 103 | return apiclient.discovery.build('buzz', 'v1', http = http) |
| 104 | else: |
| 105 | return apiclient.discovery.build('buzz', 'v1') |