+#!/usr/bin/python
+#
+# Interactive shell for testing PLCAPI
+#
+# Mark Huang <mlhuang@cs.princeton.edu>
+# Copyright (C) 2005 The Trustees of Princeton University
+#
+# $Id: Shell.py,v 1.1 2007/01/08 18:10:30 mlhuang Exp $
+#
+
+import os
+import sys
+from optparse import OptionParser
+from traceback import print_exc
+
+sys.path.append(os.path.dirname(os.path.realpath(sys.argv[0])))
+from PLC.Shell import Shell
+
+parser = OptionParser(add_help_option = False)
+parser.add_option("-f", "--config", help = "PLC configuration file")
+parser.add_option("-h", "--url", help = "API URL")
+parser.add_option("-c", "--cacert", help = "API SSL certificate")
+parser.add_option("-m", "--method", help = "API authentication method")
+parser.add_option("-u", "--user", help = "API user name")
+parser.add_option("-p", "--password", help = "API password")
+parser.add_option("-r", "--role", help = "API role")
+parser.add_option("-x", "--xmlrpc", action = "store_true", default = False, help = "Use XML-RPC interface")
+parser.add_option("--help", action = "help", help = "show this help message and exit")
+(options, args) = parser.parse_args()
+
+# If user is specified but password is not
+if options.user is not None and options.password is None:
+ try:
+ options.password = getpass.getpass()
+ except (EOFError, KeyboardInterrupt):
+ print
+ sys.exit(0)
+
+# Initialize a single global instance (scripts may re-initialize
+# this instance and/or create additional instances).
+try:
+ shell = Shell(globals = globals(),
+ config = options.config,
+ url = options.url, xmlrpc = options.xmlrpc, cacert = options.cacert,
+ method = options.method, role = options.role,
+ user = options.user, password = options.password)
+except Exception, err:
+ print "Error:", err
+ print
+ parser.print_help()
+ sys.exit(1)
+
+# If called by a script
+if len(sys.argv) > 1 and os.path.exists(sys.argv[1]):
+ # Pop us off the argument stack
+ sys.argv.pop(0)
+ execfile(sys.argv[0])
+
+# Otherwise, run an interactive shell environment
+else:
+ if shell.server is None:
+ print "PlanetLab Central Direct API Access"
+ prompt = ""
+ elif shell.auth['AuthMethod'] == "anonymous":
+ prompt = "[anonymous]"
+ print "Connected anonymously"
+ else:
+ prompt = "[%s]" % shell.auth['Username']
+ print "%s connected using %s authentication" % \
+ (shell.auth['Username'], shell.auth['AuthMethod'])
+
+ # Readline and tab completion support
+ import atexit
+ import readline
+ import rlcompleter
+
+ print 'Type "system.listMethods()" or "help(method)" for more information.'
+ # Load command history
+ history_path = os.path.join(os.environ["HOME"], ".plcapi_history")
+ try:
+ file(history_path, 'a').close()
+ readline.read_history_file(history_path)
+ atexit.register(readline.write_history_file, history_path)
+ except IOError:
+ pass
+
+ # Enable tab completion
+ readline.parse_and_bind("tab: complete")
+
+ try:
+ while True:
+ command = ""
+ while True:
+ # Get line
+ try:
+ if command == "":
+ sep = ">>> "
+ else:
+ sep = "... "
+ line = raw_input(prompt + sep)
+ # Ctrl-C
+ except KeyboardInterrupt:
+ command = ""
+ print
+ break
+
+ # Build up multi-line command
+ command += line
+
+ # Blank line or first line does not end in :
+ if line == "" or (command == line and line[-1] != ':'):
+ break
+
+ command += os.linesep
+
+ # Blank line
+ if command == "":
+ continue
+ # Quit
+ elif command in ["q", "quit", "exit"]:
+ break
+
+ try:
+ try:
+ # Try evaluating as an expression and printing the result
+ result = eval(command)
+ if result is not None:
+ print result
+ except SyntaxError:
+ # Fall back to executing as a statement
+ exec command
+ except Exception, err:
+ print_exc()
+
+ except EOFError:
+ print
+ pass