Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: chrome/test/chromedriver/third_party/googlecode/googlecode_upload.py

Issue 12052004: [chromedriver] Create release script and handle Chrome/ChromeDriver versions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 #
3 # Copyright 2006, 2007 Google Inc. All Rights Reserved.
4 # Author: danderson@google.com (David Anderson)
5 #
6 # Script for uploading files to a Google Code project.
7 #
8 # This is intended to be both a useful script for people who want to
9 # streamline project uploads and a reference implementation for
10 # uploading files to Google Code projects.
11 #
12 # To upload a file to Google Code, you need to provide a path to the
13 # file on your local machine, a small summary of what the file is, a
14 # project name, and a valid account that is a member or owner of that
15 # project. You can optionally provide a list of labels that apply to
16 # the file. The file will be uploaded under the same name that it has
17 # in your local filesystem (that is, the "basename" or last path
18 # component). Run the script with '--help' to get the exact syntax
19 # and available options.
20 #
21 # Note that the upload script requests that you enter your
22 # googlecode.com password. This is NOT your Gmail account password!
23 # This is the password you use on googlecode.com for committing to
24 # Subversion and uploading files. You can find your password by going
25 # to http://code.google.com/hosting/settings when logged in with your
26 # Gmail account. If you have already committed to your project's
27 # Subversion repository, the script will automatically retrieve your
28 # credentials from there (unless disabled, see the output of '--help'
29 # for details).
30 #
31 # If you are looking at this script as a reference for implementing
32 # your own Google Code file uploader, then you should take a look at
33 # the upload() function, which is the meat of the uploader. You
34 # basically need to build a multipart/form-data POST request with the
35 # right fields and send it to https://PROJECT.googlecode.com/files .
36 # Authenticate the request using HTTP Basic authentication, as is
37 # shown below.
38 #
39 # Licensed under the terms of the Apache Software License 2.0:
40 # http://www.apache.org/licenses/LICENSE-2.0
41 #
42 # Questions, comments, feature requests and patches are most welcome.
43 # Please direct all of these to the Google Code users group:
44 # http://groups.google.com/group/google-code-hosting
45 #
46 # Licensed under the Apache License, Version 2.0 (the "License");
47 # you may not use this file except in compliance with the License.
48 # You may obtain a copy of the License at
49 #
50 # http://www.apache.org/licenses/LICENSE-2.0
51
52 """Google Code file uploader script.
53 """
54
55 __author__ = 'danderson@google.com (David Anderson)'
56
57 import httplib
58 import os.path
59 import optparse
60 import getpass
61 import base64
62 import sys
63
64
65 def upload(file, project_name, user_name, password, summary, labels=None):
66 """Upload a file to a Google Code project's file server.
67
68 Args:
69 file: The local path to the file.
70 project_name: The name of your project on Google Code.
71 user_name: Your Google account name.
72 password: The googlecode.com password for your account.
73 Note that this is NOT your global Google Account password!
74 summary: A small description for the file.
75 labels: an optional list of label strings with which to tag the file.
76
77 Returns: a tuple:
78 http_status: 201 if the upload succeeded, something else if an
79 error occured.
80 http_reason: The human-readable string associated with http_status
81 file_url: If the upload succeeded, the URL of the file on Google
82 Code, None otherwise.
83 """
84 # The login is the user part of user@gmail.com. If the login provided
85 # is in the full user@domain form, strip it down.
86 if user_name.endswith('@gmail.com'):
87 user_name = user_name[:user_name.index('@gmail.com')]
88
89 form_fields = [('summary', summary)]
90 if labels is not None:
91 form_fields.extend([('label', l.strip()) for l in labels])
92
93 content_type, body = encode_upload_request(form_fields, file)
94
95 upload_host = '%s.googlecode.com' % project_name
96 upload_uri = '/files'
97 auth_token = base64.b64encode('%s:%s'% (user_name, password))
98 headers = {
99 'Authorization': 'Basic %s' % auth_token,
100 'User-Agent': 'Googlecode.com uploader v0.9.4',
101 'Content-Type': content_type,
102 }
103
104 server = httplib.HTTPSConnection(upload_host)
105 server.request('POST', upload_uri, body, headers)
106 resp = server.getresponse()
107 server.close()
108
109 if resp.status == 201:
110 location = resp.getheader('Location', None)
111 else:
112 location = None
113 return resp.status, resp.reason, location
114
115
116 def encode_upload_request(fields, file_path):
117 """Encode the given fields and file into a multipart form body.
118
119 fields is a sequence of (name, value) pairs. file is the path of
120 the file to upload. The file will be uploaded to Google Code with
121 the same file name.
122
123 Returns: (content_type, body) ready for httplib.HTTP instance
124 """
125 BOUNDARY = '----------Googlecode_boundary_reindeer_flotilla'
126 CRLF = '\r\n'
127
128 body = []
129
130 # Add the metadata about the upload first
131 for key, value in fields:
132 body.extend(
133 ['--' + BOUNDARY,
134 'Content-Disposition: form-data; name="%s"' % key,
135 '',
136 value,
137 ])
138
139 # Now add the file itself
140 file_name = os.path.basename(file_path)
141 f = open(file_path, 'rb')
142 file_content = f.read()
143 f.close()
144
145 body.extend(
146 ['--' + BOUNDARY,
147 'Content-Disposition: form-data; name="filename"; filename="%s"'
148 % file_name,
149 # The upload server determines the mime-type, no need to set it.
150 'Content-Type: application/octet-stream',
151 '',
152 file_content,
153 ])
154
155 # Finalize the form body
156 body.extend(['--' + BOUNDARY + '--', ''])
157
158 return 'multipart/form-data; boundary=%s' % BOUNDARY, CRLF.join(body)
159
160
161 def upload_find_auth(file_path, project_name, summary, labels=None,
162 user_name=None, password=None, tries=3):
163 """Find credentials and upload a file to a Google Code project's file server.
164
165 file_path, project_name, summary, and labels are passed as-is to upload.
166
167 Args:
168 file_path: The local path to the file.
169 project_name: The name of your project on Google Code.
170 summary: A small description for the file.
171 labels: an optional list of label strings with which to tag the file.
172 config_dir: Path to Subversion configuration directory, 'none', or None.
173 user_name: Your Google account name.
174 tries: How many attempts to make.
175 """
176 if user_name is None or password is None:
177 from netrc import netrc
178 authenticators = netrc().authenticators("code.google.com")
179 if authenticators:
180 if user_name is None:
181 user_name = authenticators[0]
182 if password is None:
183 password = authenticators[2]
184
185 while tries > 0:
186 if user_name is None:
187 # Read username if not specified or loaded from svn config, or on
188 # subsequent tries.
189 sys.stdout.write('Please enter your googlecode.com username: ')
190 sys.stdout.flush()
191 user_name = sys.stdin.readline().rstrip()
192 if password is None:
193 # Read password if not loaded from svn config, or on subsequent tries.
194 print 'Please enter your googlecode.com password.'
195 print '** Note that this is NOT your Gmail account password! **'
196 print 'It is the password you use to access Subversion repositories,'
197 print 'and can be found here: http://code.google.com/hosting/settings'
198 password = getpass.getpass()
199
200 status, reason, url = upload(file_path, project_name, user_name, password,
201 summary, labels)
202 # Returns 403 Forbidden instead of 401 Unauthorized for bad
203 # credentials as of 2007-07-17.
204 if status in [httplib.FORBIDDEN, httplib.UNAUTHORIZED]:
205 # Rest for another try.
206 user_name = password = None
207 tries = tries - 1
208 else:
209 # We're done.
210 break
211
212 return status, reason, url
213
214
215 def main():
216 parser = optparse.OptionParser(usage='googlecode-upload.py -s SUMMARY '
217 '-p PROJECT [options] FILE')
218 parser.add_option('-s', '--summary', dest='summary',
219 help='Short description of the file')
220 parser.add_option('-p', '--project', dest='project',
221 help='Google Code project name')
222 parser.add_option('-u', '--user', dest='user',
223 help='Your Google Code username')
224 parser.add_option('-w', '--password', dest='password',
225 help='Your Google Code password')
226 parser.add_option('-l', '--labels', dest='labels',
227 help='An optional list of comma-separated labels to attach '
228 'to the file')
229
230 options, args = parser.parse_args()
231
232 if not options.summary:
233 parser.error('File summary is missing.')
234 elif not options.project:
235 parser.error('Project name is missing.')
236 elif len(args) < 1:
237 parser.error('File to upload not provided.')
238 elif len(args) > 1:
239 parser.error('Only one file may be specified.')
240
241 file_path = args[0]
242
243 if options.labels:
244 labels = options.labels.split(',')
245 else:
246 labels = None
247
248 status, reason, url = upload_find_auth(file_path, options.project,
249 options.summary, labels,
250 options.user, options.password)
251 if url:
252 print 'The file was uploaded successfully.'
253 print 'URL: %s' % url
254 return 0
255 else:
256 print 'An error occurred. Your file was not uploaded.'
257 print 'Google Code upload server said: %s (%s)' % (reason, status)
258 return 1
259
260
261 if __name__ == '__main__':
262 sys.exit(main())
OLDNEW
« no previous file with comments | « chrome/test/chromedriver/third_party/googlecode/README.chromium ('k') | chrome/test/chromedriver/version.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698