194 Raises: |
194 Raises: |
195 HTTPError: If there was an error fetching the authentication cookies. |
195 HTTPError: If there was an error fetching the authentication cookies. |
196 """ |
196 """ |
197 continue_location = "http://localhost/" |
197 continue_location = "http://localhost/" |
198 args = {"continue": continue_location, "auth": auth_token} |
198 args = {"continue": continue_location, "auth": auth_token} |
199 req = self._CreateRequest("http://%s/_ah/login?%s" % |
199 login_path = os.environ.get("APPCFG_LOGIN_PATH", "/_ah") |
200 (self.host, urllib.urlencode(args))) |
200 req = self._CreateRequest("http://%s%s/login?%s" % |
|
201 (self.host, login_path, urllib.urlencode(args))) |
201 try: |
202 try: |
202 response = self.opener.open(req) |
203 response = self.opener.open(req) |
203 except urllib2.HTTPError, e: |
204 except urllib2.HTTPError, e: |
204 response = e |
205 response = e |
205 if (response.code != 302 or |
206 if (response.code != 302 or |
925 if self.num_days: |
926 if self.num_days: |
926 patterns = [] |
927 patterns = [] |
927 for i in xrange(self.num_days): |
928 for i in xrange(self.num_days): |
928 then = time.gmtime(now - 24*3600 * i) |
929 then = time.gmtime(now - 24*3600 * i) |
929 patterns.append(re.escape(time.strftime("%d/%m/%Y", then))) |
930 patterns.append(re.escape(time.strftime("%d/%m/%Y", then))) |
|
931 patterns.append(re.escape(time.strftime("%d/%b/%Y", then))) |
930 self.valid_dates = re.compile(r"[^[]+\[(" + "|".join(patterns) + r"):") |
932 self.valid_dates = re.compile(r"[^[]+\[(" + "|".join(patterns) + r"):") |
931 |
933 |
932 def DownloadLogs(self): |
934 def DownloadLogs(self): |
933 """Download the requested logs. |
935 """Download the requested logs. |
934 |
936 |
1451 options: The command line options parsed by 'parser'. |
1453 options: The command line options parsed by 'parser'. |
1452 argv: The original command line as a list. |
1454 argv: The original command line as a list. |
1453 args: The positional command line args left over after parsing the options. |
1455 args: The positional command line args left over after parsing the options. |
1454 raw_input_fn: Function used for getting raw user input, like email. |
1456 raw_input_fn: Function used for getting raw user input, like email. |
1455 password_input_fn: Function used for getting user password. |
1457 password_input_fn: Function used for getting user password. |
|
1458 error_fh: Unexpected HTTPErrors are printed to this file handle. |
1456 |
1459 |
1457 Attributes for testing: |
1460 Attributes for testing: |
1458 parser_class: The class to use for parsing the command line. Because |
1461 parser_class: The class to use for parsing the command line. Because |
1459 OptionsParser will exit the program when there is a parse failure, it |
1462 OptionsParser will exit the program when there is a parse failure, it |
1460 is nice to subclass OptionsParser and catch the error before exiting. |
1463 is nice to subclass OptionsParser and catch the error before exiting. |
1461 """ |
1464 """ |
1462 |
1465 |
1463 def __init__(self, argv, parser_class=optparse.OptionParser, |
1466 def __init__(self, argv, parser_class=optparse.OptionParser, |
1464 rpc_server_class=HttpRpcServer, |
1467 rpc_server_class=HttpRpcServer, |
1465 raw_input_fn=raw_input, |
1468 raw_input_fn=raw_input, |
1466 password_input_fn=getpass.getpass): |
1469 password_input_fn=getpass.getpass, |
|
1470 error_fh=sys.stderr): |
1467 """Initializer. Parses the cmdline and selects the Action to use. |
1471 """Initializer. Parses the cmdline and selects the Action to use. |
1468 |
1472 |
1469 Initializes all of the attributes described in the class docstring. |
1473 Initializes all of the attributes described in the class docstring. |
1470 Prints help or error messages if there is an error parsing the cmdline. |
1474 Prints help or error messages if there is an error parsing the cmdline. |
1471 |
1475 |
1473 argv: The list of arguments passed to this program. |
1477 argv: The list of arguments passed to this program. |
1474 parser_class: Options parser to use for this application. |
1478 parser_class: Options parser to use for this application. |
1475 rpc_server_class: RPC server class to use for this application. |
1479 rpc_server_class: RPC server class to use for this application. |
1476 raw_input_fn: Function used for getting user email. |
1480 raw_input_fn: Function used for getting user email. |
1477 password_input_fn: Function used for getting user password. |
1481 password_input_fn: Function used for getting user password. |
|
1482 error_fh: Unexpected HTTPErrors are printed to this file handle. |
1478 """ |
1483 """ |
1479 self.parser_class = parser_class |
1484 self.parser_class = parser_class |
1480 self.argv = argv |
1485 self.argv = argv |
1481 self.rpc_server_class = rpc_server_class |
1486 self.rpc_server_class = rpc_server_class |
1482 self.raw_input_fn = raw_input_fn |
1487 self.raw_input_fn = raw_input_fn |
1483 self.password_input_fn = password_input_fn |
1488 self.password_input_fn = password_input_fn |
|
1489 self.error_fh = error_fh |
1484 |
1490 |
1485 self.parser = self._GetOptionParser() |
1491 self.parser = self._GetOptionParser() |
1486 for action in self.actions.itervalues(): |
1492 for action in self.actions.itervalues(): |
1487 action.options(self, self.parser) |
1493 action.options(self, self.parser) |
1488 |
1494 |
1507 logging.getLogger().setLevel(logging.DEBUG) |
1513 logging.getLogger().setLevel(logging.DEBUG) |
1508 |
1514 |
1509 global verbosity |
1515 global verbosity |
1510 verbosity = self.options.verbose |
1516 verbosity = self.options.verbose |
1511 |
1517 |
1512 def Run(self, error_fh=sys.stderr): |
1518 def Run(self): |
1513 """Executes the requested action. |
1519 """Executes the requested action. |
1514 |
1520 |
1515 Catches any HTTPErrors raised by the action and prints them to stderr. |
1521 Catches any HTTPErrors raised by the action and prints them to stderr. |
1516 |
|
1517 Args: |
|
1518 error_fh: Print any HTTPErrors to this file handle. |
|
1519 """ |
1522 """ |
1520 try: |
1523 try: |
1521 self.action.function(self) |
1524 self.action.function(self) |
1522 except urllib2.HTTPError, e: |
1525 except urllib2.HTTPError, e: |
1523 body = e.read() |
1526 body = e.read() |
1524 print >>error_fh, ("Error %d: --- begin server output ---\n" |
1527 print >>self.error_fh, ("Error %d: --- begin server output ---\n" |
1525 "%s\n--- end server output ---" % |
1528 "%s\n--- end server output ---" % |
1526 (e.code, body.rstrip("\n"))) |
1529 (e.code, body.rstrip("\n"))) |
1527 except yaml_errors.EventListenerError, e: |
1530 except yaml_errors.EventListenerError, e: |
1528 print >>error_fh, ("Error parsing yaml file:\n%s" % e) |
1531 print >>self.error_fh, ("Error parsing yaml file:\n%s" % e) |
1529 |
1532 |
1530 def _GetActionDescriptions(self): |
1533 def _GetActionDescriptions(self): |
1531 """Returns a formatted string containing the short_descs for all actions.""" |
1534 """Returns a formatted string containing the short_descs for all actions.""" |
1532 action_names = self.actions.keys() |
1535 action_names = self.actions.keys() |
1533 action_names.sort() |
1536 action_names.sort() |
1733 lambda path: open(os.path.join(basepath, path), "rb")) |
1736 lambda path: open(os.path.join(basepath, path), "rb")) |
1734 |
1737 |
1735 index_defs = self._ParseIndexYaml(basepath) |
1738 index_defs = self._ParseIndexYaml(basepath) |
1736 if index_defs: |
1739 if index_defs: |
1737 index_upload = IndexDefinitionUpload(rpc_server, appyaml, index_defs) |
1740 index_upload = IndexDefinitionUpload(rpc_server, appyaml, index_defs) |
1738 index_upload.DoUpload() |
1741 try: |
|
1742 index_upload.DoUpload() |
|
1743 except urllib2.HTTPError, e: |
|
1744 StatusUpdate("Error %d: --- begin server output ---\n" |
|
1745 "%s\n--- end server output ---" % |
|
1746 (e.code, e.read().rstrip("\n"))) |
|
1747 print >> self.error_fh, ( |
|
1748 "Your app was updated, but there was an error updating your indexes. " |
|
1749 "Please retry later with appcfg.py update_indexes.") |
1739 |
1750 |
1740 def _UpdateOptions(self, parser): |
1751 def _UpdateOptions(self, parser): |
1741 """Adds update-specific options to 'parser'. |
1752 """Adds update-specific options to 'parser'. |
1742 |
1753 |
1743 Args: |
1754 Args: |