3 # Copyright 2014 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
7 '''A set of utilities to interface with the Chrome Webstore API.'''
9 import SimpleHTTPServer
21 'client_id': ('937534751394-gbj5334v9144c57qjqghl7d283plj5r4'
22 '.apps.googleusercontent.com'),
23 'grant_type': 'authorization_code',
24 'redirect_uri': 'http://localhost:8000'
27 # Persists across all utility methods for authentication.
31 # The app id to use for all utility methods.
36 OAUTH_DOMAIN
= 'accounts.google.com'
37 OAUTH_AUTH_COMMAND
= '/o/oauth2/auth'
38 OAUTH_TOKEN_COMMAND
= '/o/oauth2/token'
39 WEBSTORE_API_SCOPE
= 'https://www.googleapis.com/auth/chromewebstore'
40 API_ENDPOINT_DOMAIN
= 'www.googleapis.com'
42 def GetUploadStatusCommand():
44 return '/chromewebstore/v1.1/items/%s?projection=draft' % g_app_id
46 def GetPublishCommand():
48 return '/chromewebstore/v1.1/items/%s/publish' % g_app_id
50 def GetUploadCommand():
52 return '/upload/chromewebstore/v1.1/items/%s' % g_app_id
54 class CodeRequestHandler(SocketServer
.StreamRequestHandler
):
56 content
= self
.rfile
.readline()
57 self
.server
.code
= re
.search('code=(.*) ', content
).groups()[0]
65 Handler
= CodeRequestHandler
66 httpd
= SocketServer
.TCPServer(("", PORT
), Handler
)
67 query
= '&'.join(['response_type=code',
68 'scope=%s' % WEBSTORE_API_SCOPE
,
69 'client_id=%(client_id)s' % PROJECT_ARGS
,
70 'redirect_uri=%(redirect_uri)s' % PROJECT_ARGS
])
71 auth_url
= 'https://%s%s?%s' % (OAUTH_DOMAIN
, OAUTH_AUTH_COMMAND
, query
)
72 print 'Navigating to %s' % auth_url
73 webbrowser
.open(auth_url
)
74 httpd
.handle_request()
76 g_auth_code
= httpd
.code
79 def GetOauthToken(code
, client_secret
):
84 PROJECT_ARGS
['code'] = code
85 PROJECT_ARGS
['client_secret'] = client_secret
86 body
= urllib
.urlencode(PROJECT_ARGS
)
87 conn
= httplib
.HTTPSConnection(OAUTH_DOMAIN
)
88 conn
.putrequest('POST', OAUTH_TOKEN_COMMAND
)
89 conn
.putheader('content-type', 'application/x-www-form-urlencoded')
90 conn
.putheader('content-length', len(body
))
93 content
= conn
.getresponse().read()
95 g_oauth_token
= json
.loads(content
)
98 def GetPopulatedHeader(client_secret
):
100 access_token
= GetOauthToken(code
, client_secret
)
102 url
= 'www.googleapis.com'
104 return {'Authorization': 'Bearer %(access_token)s' % access_token
,
105 'x-goog-api-version': 2,
109 def SendGetCommand(command
, client_secret
):
110 headers
= GetPopulatedHeader(client_secret
)
111 conn
= httplib
.HTTPSConnection(API_ENDPOINT_DOMAIN
)
112 conn
.request('GET', command
, '', headers
)
113 r
= conn
.getresponse()
117 def SendPostCommand(command
, client_secret
, header_additions
= {}, body
=None):
118 headers
= GetPopulatedHeader(client_secret
)
119 headers
= dict(headers
.items() + header_additions
.items())
120 conn
= httplib
.HTTPSConnection(API_ENDPOINT_DOMAIN
)
121 conn
.request('POST', command
, body
, headers
)
122 r
= conn
.getresponse()
126 def GetUploadStatus(client_secret
):
127 '''Gets the status of a previous upload.
129 client_secret ChromeVox's client secret creds.
131 return SendGetCommand(GetUploadStatusCommand(), client_secret
)
133 # httplib fails to persist the connection during upload; use curl instead.
134 def PostUpload(file, client_secret
):
135 '''Posts an uploaded version of ChromeVox.
137 file A string path to the ChromeVox extension zip.
138 client_secret ChromeVox's client secret creds.
140 header
= GetPopulatedHeader(client_secret
)
141 curl_command
= ' '.join(['curl',
142 '-H "Authorization: %(Authorization)s"' % header
,
143 '-H "x-goog-api-version: 2"',
147 'https://%s%s' % (API_ENDPOINT_DOMAIN
,
148 GetUploadCommand())])
150 print 'Running %s' % curl_command
151 if os
.system(curl_command
) != 0:
154 def PostPublishTrustedTesters(client_secret
):
155 '''Publishes a previously uploaded ChromeVox extension to trusted testers.
157 client_secret ChromeVox's client secret creds.
159 return SendPostCommand(GetPublishCommand(),
161 { 'publishTarget': 'trustedTesters'})
163 def PostPublish(client_secret
):
164 '''Publishes a previously uploaded ChromeVox extension publically.
166 client_secret ChromeVox's client secret creds.
168 return SendPostCommand(GetPublishCommand(), client_secret
)