| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright 2007 Google Inc. | 3 # Copyright 2007 Google Inc. |
| 4 # | 4 # |
| 5 # Licensed under the Apache License, Version 2.0 (the "License"); | 5 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 # you may not use this file except in compliance with the License. | 6 # you may not use this file except in compliance with the License. |
| 7 # You may obtain a copy of the License at | 7 # You may obtain a copy of the License at |
| 8 # | 8 # |
| 9 # http://www.apache.org/licenses/LICENSE-2.0 | 9 # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 # | 10 # |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 sys.exit(1) | 164 sys.exit(1) |
| 165 | 165 |
| 166 | 166 |
| 167 class ClientLoginError(urllib2.HTTPError): | 167 class ClientLoginError(urllib2.HTTPError): |
| 168 """Raised to indicate there was an error authenticating with ClientLogin.""" | 168 """Raised to indicate there was an error authenticating with ClientLogin.""" |
| 169 | 169 |
| 170 def __init__(self, url, code, msg, headers, args): | 170 def __init__(self, url, code, msg, headers, args): |
| 171 urllib2.HTTPError.__init__(self, url, code, msg, headers, None) | 171 urllib2.HTTPError.__init__(self, url, code, msg, headers, None) |
| 172 self.args = args | 172 self.args = args |
| 173 self.reason = args["Error"] | 173 self.reason = args["Error"] |
| 174 self.info = args.get("Info", None) |
| 174 | 175 |
| 175 | 176 |
| 176 class AbstractRpcServer(object): | 177 class AbstractRpcServer(object): |
| 177 """Provides a common interface for a simple RPC server.""" | 178 """Provides a common interface for a simple RPC server.""" |
| 178 | 179 |
| 179 def __init__(self, host, auth_function, host_override=None, extra_headers={}, | 180 def __init__(self, host, auth_function, host_override=None, extra_headers={}, |
| 180 save_cookies=False, account_type=AUTH_ACCOUNT_TYPE): | 181 save_cookies=False, account_type=AUTH_ACCOUNT_TYPE): |
| 181 """Creates a new HttpRpcServer. | 182 """Creates a new HttpRpcServer. |
| 182 | 183 |
| 183 Args: | 184 Args: |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 | 308 |
| 308 If we attempt to access the upload API without first obtaining an | 309 If we attempt to access the upload API without first obtaining an |
| 309 authentication cookie, it returns a 401 response (or a 302) and | 310 authentication cookie, it returns a 401 response (or a 302) and |
| 310 directs us to authenticate ourselves with ClientLogin. | 311 directs us to authenticate ourselves with ClientLogin. |
| 311 """ | 312 """ |
| 312 for i in range(3): | 313 for i in range(3): |
| 313 credentials = self.auth_function() | 314 credentials = self.auth_function() |
| 314 try: | 315 try: |
| 315 auth_token = self._GetAuthToken(credentials[0], credentials[1]) | 316 auth_token = self._GetAuthToken(credentials[0], credentials[1]) |
| 316 except ClientLoginError, e: | 317 except ClientLoginError, e: |
| 318 print >>sys.stderr, '' |
| 317 if e.reason == "BadAuthentication": | 319 if e.reason == "BadAuthentication": |
| 318 print >>sys.stderr, "Invalid username or password." | 320 if e.info == "InvalidSecondFactor": |
| 319 continue | 321 print >>sys.stderr, ( |
| 320 if e.reason == "CaptchaRequired": | 322 "Use an application-specific password instead " |
| 323 "of your regular account password.\n" |
| 324 "See http://www.google.com/" |
| 325 "support/accounts/bin/answer.py?answer=185833") |
| 326 else: |
| 327 print >>sys.stderr, "Invalid username or password." |
| 328 elif e.reason == "CaptchaRequired": |
| 321 print >>sys.stderr, ( | 329 print >>sys.stderr, ( |
| 322 "Please go to\n" | 330 "Please go to\n" |
| 323 "https://www.google.com/accounts/DisplayUnlockCaptcha\n" | 331 "https://www.google.com/accounts/DisplayUnlockCaptcha\n" |
| 324 "and verify you are a human. Then try again.\n" | 332 "and verify you are a human. Then try again.\n" |
| 325 "If you are using a Google Apps account the URL is:\n" | 333 "If you are using a Google Apps account the URL is:\n" |
| 326 "https://www.google.com/a/yourdomain.com/UnlockCaptcha") | 334 "https://www.google.com/a/yourdomain.com/UnlockCaptcha") |
| 327 break | 335 elif e.reason == "NotVerified": |
| 328 if e.reason == "NotVerified": | |
| 329 print >>sys.stderr, "Account not verified." | 336 print >>sys.stderr, "Account not verified." |
| 330 break | 337 elif e.reason == "TermsNotAgreed": |
| 331 if e.reason == "TermsNotAgreed": | |
| 332 print >>sys.stderr, "User has not agreed to TOS." | 338 print >>sys.stderr, "User has not agreed to TOS." |
| 333 break | 339 elif e.reason == "AccountDeleted": |
| 334 if e.reason == "AccountDeleted": | |
| 335 print >>sys.stderr, "The user account has been deleted." | 340 print >>sys.stderr, "The user account has been deleted." |
| 336 break | 341 elif e.reason == "AccountDisabled": |
| 337 if e.reason == "AccountDisabled": | |
| 338 print >>sys.stderr, "The user account has been disabled." | 342 print >>sys.stderr, "The user account has been disabled." |
| 339 break | 343 break |
| 340 if e.reason == "ServiceDisabled": | 344 elif e.reason == "ServiceDisabled": |
| 341 print >>sys.stderr, ("The user's access to the service has been " | 345 print >>sys.stderr, ("The user's access to the service has been " |
| 342 "disabled.") | 346 "disabled.") |
| 343 break | 347 elif e.reason == "ServiceUnavailable": |
| 344 if e.reason == "ServiceUnavailable": | |
| 345 print >>sys.stderr, "The service is not available; try again later." | 348 print >>sys.stderr, "The service is not available; try again later." |
| 346 break | 349 else: |
| 347 raise | 350 # Unknown error. |
| 351 raise |
| 352 print >>sys.stderr, '' |
| 353 continue |
| 348 self._GetAuthCookie(auth_token) | 354 self._GetAuthCookie(auth_token) |
| 349 return | 355 return |
| 350 | 356 |
| 351 def Send(self, request_path, payload=None, | 357 def Send(self, request_path, payload=None, |
| 352 content_type="application/octet-stream", | 358 content_type="application/octet-stream", |
| 353 timeout=None, | 359 timeout=None, |
| 354 extra_headers=None, | 360 extra_headers=None, |
| 355 **kwargs): | 361 **kwargs): |
| 356 """Sends an RPC and returns the response. | 362 """Sends an RPC and returns the response. |
| 357 | 363 |
| (...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1331 return (base_content, new_content, is_binary, status) | 1337 return (base_content, new_content, is_binary, status) |
| 1332 | 1338 |
| 1333 def GenerateDiff(self, extra_args): | 1339 def GenerateDiff(self, extra_args): |
| 1334 cmd = ["cvs", "diff", "-u", "-N"] | 1340 cmd = ["cvs", "diff", "-u", "-N"] |
| 1335 if self.options.revision: | 1341 if self.options.revision: |
| 1336 cmd += ["-r", self.options.revision] | 1342 cmd += ["-r", self.options.revision] |
| 1337 | 1343 |
| 1338 cmd.extend(extra_args) | 1344 cmd.extend(extra_args) |
| 1339 data, retcode = RunShellWithReturnCode(cmd) | 1345 data, retcode = RunShellWithReturnCode(cmd) |
| 1340 count = 0 | 1346 count = 0 |
| 1341 if retcode == 0: | 1347 if retcode in [0, 1]: |
| 1342 for line in data.splitlines(): | 1348 for line in data.splitlines(): |
| 1343 if line.startswith("Index:"): | 1349 if line.startswith("Index:"): |
| 1344 count += 1 | 1350 count += 1 |
| 1345 logging.info(line) | 1351 logging.info(line) |
| 1346 | 1352 |
| 1347 if not count: | 1353 if not count: |
| 1348 ErrorExit("No valid patches found in output from cvs diff") | 1354 ErrorExit("No valid patches found in output from cvs diff") |
| 1349 | 1355 |
| 1350 return data | 1356 return data |
| 1351 | 1357 |
| 1352 def GetUnknownFiles(self): | 1358 def GetUnknownFiles(self): |
| 1353 status = RunShell(["cvs", "diff"], | 1359 data, retcode = RunShellWithReturnCode(["cvs", "diff"]) |
| 1354 silent_ok=True) | 1360 if retcode not in [0, 1]: |
| 1361 ErrorExit("Got error status from 'cvs diff':\n%s" % (data,)) |
| 1355 unknown_files = [] | 1362 unknown_files = [] |
| 1356 for line in status.split("\n"): | 1363 for line in data.split("\n"): |
| 1357 if line and line[0] == "?": | 1364 if line and line[0] == "?": |
| 1358 unknown_files.append(line) | 1365 unknown_files.append(line) |
| 1359 return unknown_files | 1366 return unknown_files |
| 1360 | 1367 |
| 1361 class MercurialVCS(VersionControlSystem): | 1368 class MercurialVCS(VersionControlSystem): |
| 1362 """Implementation of the VersionControlSystem interface for Mercurial.""" | 1369 """Implementation of the VersionControlSystem interface for Mercurial.""" |
| 1363 | 1370 |
| 1364 def __init__(self, options, repo_dir): | 1371 def __init__(self, options, repo_dir): |
| 1365 super(MercurialVCS, self).__init__(options) | 1372 super(MercurialVCS, self).__init__(options) |
| 1366 # Absolute path to repository (we can be in a subdir) | 1373 # Absolute path to repository (we can be in a subdir) |
| (...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2230 os.environ['LC_ALL'] = 'C' | 2237 os.environ['LC_ALL'] = 'C' |
| 2231 RealMain(sys.argv) | 2238 RealMain(sys.argv) |
| 2232 except KeyboardInterrupt: | 2239 except KeyboardInterrupt: |
| 2233 print | 2240 print |
| 2234 StatusUpdate("Interrupted.") | 2241 StatusUpdate("Interrupted.") |
| 2235 sys.exit(1) | 2242 sys.exit(1) |
| 2236 | 2243 |
| 2237 | 2244 |
| 2238 if __name__ == "__main__": | 2245 if __name__ == "__main__": |
| 2239 main() | 2246 main() |
| OLD | NEW |