You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bh...@apache.org on 2012/11/05 17:29:19 UTC
[7/7] git commit: cli: add logic to complete api parameters and use
caching to optimize runtime
cli: add logic to complete api parameters and use caching to optimize runtime
Signed-off-by: Rohit Yadav <bh...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/5611a8ed
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/5611a8ed
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/5611a8ed
Branch: refs/heads/master
Commit: 5611a8eda212d0d564c4f0fe0da9ed7f6cf3f196
Parents: fe7b28e
Author: Rohit Yadav <bh...@apache.org>
Authored: Mon Nov 5 21:36:07 2012 +0530
Committer: Rohit Yadav <bh...@apache.org>
Committed: Mon Nov 5 21:59:02 2012 +0530
----------------------------------------------------------------------
tools/cli/cloudmonkey/cloudmonkey.py | 89 +++++++++++++++++++++--------
1 files changed, 65 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/5611a8ed/tools/cli/cloudmonkey/cloudmonkey.py
----------------------------------------------------------------------
diff --git a/tools/cli/cloudmonkey/cloudmonkey.py b/tools/cli/cloudmonkey/cloudmonkey.py
index 1cc166c..c519126 100644
--- a/tools/cli/cloudmonkey/cloudmonkey.py
+++ b/tools/cli/cloudmonkey/cloudmonkey.py
@@ -52,6 +52,9 @@ class CloudStackShell(cmd.Cmd):
ruler = "-"
config_file = os.path.expanduser('~/.cloudmonkey_config')
+ # datastructure {'list': {'users': ['listUsers', [params], docstring]}}
+ cache_verbs = {}
+
def __init__(self):
self.config_fields = {'host': 'localhost', 'port': '8080',
'apiKey': '', 'secretKey': '',
@@ -212,6 +215,15 @@ class CloudStackShell(cmd.Cmd):
return None
return response
+ def get_api_module(self, api_name, api_class_strs=[]):
+ try:
+ api_mod = __import__("marvin.cloudstackAPI.%s" % api_name,
+ globals(), locals(), api_class_strs, -1)
+ except ImportError, e:
+ self.print_shell("Error: API %s not found!" % e)
+ return None
+ return api_mod
+
def default(self, args):
args = args.split(" ")
api_name = args[0]
@@ -219,11 +231,10 @@ class CloudStackShell(cmd.Cmd):
try:
api_cmd_str = "%sCmd" % api_name
api_rsp_str = "%sResponse" % api_name
- api_mod = __import__("marvin.cloudstackAPI.%s" % api_name,
- globals(), locals(), [api_cmd_str], -1)
+ api_mod = self.get_api_module(api_name, [api_cmd_str, api_rsp_str])
api_cmd = getattr(api_mod, api_cmd_str)
api_rsp = getattr(api_mod, api_rsp_str)
- except ImportError, e:
+ except AttributeError, e:
self.print_shell("Error: API %s not found!" % e)
return
@@ -243,10 +254,43 @@ class CloudStackShell(cmd.Cmd):
except Exception as e:
self.print_shell("🙈 Error on parsing and printing", e)
+ def cache_verb_miss(self, verb):
+ completions_found = filter(lambda x: x.startswith(verb), completions)
+ self.cache_verbs[verb] = {}
+ for api_name in completions_found:
+ try:
+ api_cmd_str = "%sCmd" % api_name
+ api_mod = self.get_api_module(api_name, [api_cmd_str])
+ api_cmd = getattr(api_mod, api_cmd_str)
+ doc = api_mod.__doc__
+ except AttributeError, e:
+ self.print_shell("Error: API attribute %s not found!" % e)
+ params = filter(lambda x: '__' not in x, dir(api_cmd()))
+ api_name_lower = api_name.replace(verb, '').lower()
+ self.cache_verbs[verb][api_name_lower] = [api_name, params, doc]
+
def completedefault(self, text, line, begidx, endidx):
- mline = line.partition(" ")[2]
- offs = len(mline) - len(text)
- return [s[offs:] for s in completions if s.startswith(mline)]
+ partitions = line.partition(" ")
+ verb = partitions[0]
+ rline = partitions[2].partition(" ")
+ subject = rline[0]
+ separator = rline[1]
+ params = rline[2]
+
+ autocompletions = []
+ search_string = ""
+
+ if not verb in self.cache_verbs:
+ self.cache_verb_miss(verb)
+
+ if separator != " ": # Complete verb subjects
+ autocompletions = self.cache_verbs[verb].keys()
+ search_string = subject
+ else: # Complete subject params
+ autocompletions = self.cache_verbs[verb][subject][1]
+ search_string = text
+
+ return [s for s in autocompletions if s.startswith(search_string)]
def do_api(self, args):
"""
@@ -259,7 +303,9 @@ class CloudStackShell(cmd.Cmd):
self.print_shell("Please use a valid syntax")
def complete_api(self, text, line, begidx, endidx):
- return self.completedefault(text, line, begidx, endidx)
+ mline = line.partition(" ")[2]
+ offs = len(mline) - len(text)
+ return [s[offs:] for s in completions if s.startswith(mline)]
def do_set(self, args):
"""
@@ -284,6 +330,7 @@ class CloudStackShell(cmd.Cmd):
def main():
+ # Add verbs in grammar
grammar = ['create', 'list', 'delete', 'update',
'enable', 'disable', 'add', 'remove', 'attach', 'detach',
'assign', 'authorize', 'change', 'register',
@@ -294,13 +341,19 @@ def main():
self = CloudStackShell
for rule in grammar:
- setattr(self, 'completions_' + rule, map(lambda x: x.replace(rule, ''),
- filter(lambda x: x.startswith(rule),
- completions)))
-
def add_grammar(rule):
def grammar_closure(self, args):
- self.default(rule + args)
+ if not rule in self.cache_verbs:
+ self.cache_verb_miss(rule)
+ try:
+ res = self.cache_verbs[rule][args.partition(" ")[0]]
+ except KeyError, e:
+ self.print_shell("Error: no such command on %s" % rule)
+ return
+ if '--help' in args:
+ self.print_shell(res[2])
+ return
+ self.default(res[0])
return grammar_closure
grammar_handler = add_grammar(rule)
@@ -308,18 +361,6 @@ def main():
grammar_handler.__name__ = 'do_' + rule
setattr(self, grammar_handler.__name__, grammar_handler)
- def add_completer(rule):
- def completer_closure(self, text, line, begidx, endidx):
- mline = line.partition(" ")[2]
- offs = len(mline) - len(text)
- return [s[offs:] for s in getattr(self, 'completions_' + rule)
- if s.startswith(mline)]
- return completer_closure
-
- completion_handler = add_completer(rule)
- completion_handler.__name__ = 'complete_' + rule
- setattr(self, completion_handler.__name__, completion_handler)
-
if len(sys.argv) > 1:
CloudStackShell().onecmd(' '.join(sys.argv[1:]))
else: