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/12/24 01:57:38 UTC

[32/50] [abbrv] git commit: CLOUDSTACK-545: Tabularize cloudmonkey's response using filter= argument

CLOUDSTACK-545: Tabularize cloudmonkey's response using filter=<fields,> argument

- Adds new cloudmonkey config field, tabularize
- If tabularize is set to true, all the list of dict in response are printed as
  table
- The columns of the tables can be filtered using the filter= argument, for ex:
  list domains listall=true filter=id,name,path
- filter arg will take comma separated values, if they have space put them under
  quotes
- Empty filter argument will cause it to print the whole table
- Multiple fields with the same name will cause it to print the column again
- In case there is a typo in the field, that column is skipped. It takes an
  intersection of response dict keys and filter keys provided
- Uses opensource prettytable library to pretty print tabular data

TODOs:
- Handle recursive table printing for nested list of dicts
- Colorize table columns if community wants such a feature

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/8f51c630
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/8f51c630
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/8f51c630

Branch: refs/heads/api_refactoring
Commit: 8f51c630bdb874f9522ec3873c881b1c4e7cfdf7
Parents: 264a067
Author: Rohit Yadav <bh...@apache.org>
Authored: Thu Dec 20 16:28:32 2012 -0800
Committer: Rohit Yadav <bh...@apache.org>
Committed: Thu Dec 20 16:33:08 2012 -0800

----------------------------------------------------------------------
 tools/cli/cloudmonkey/cloudmonkey.py |   54 ++++++++++++++++++++++++-----
 tools/cli/cloudmonkey/common.py      |    1 +
 tools/cli/setup.py                   |    4 ++-
 3 files changed, 49 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8f51c630/tools/cli/cloudmonkey/cloudmonkey.py
----------------------------------------------------------------------
diff --git a/tools/cli/cloudmonkey/cloudmonkey.py b/tools/cli/cloudmonkey/cloudmonkey.py
index e59a3b3..34cf5ca 100644
--- a/tools/cli/cloudmonkey/cloudmonkey.py
+++ b/tools/cli/cloudmonkey/cloudmonkey.py
@@ -37,6 +37,7 @@ try:
     from urllib2 import HTTPError, URLError
     from httplib import BadStatusLine
 
+    from prettytable import PrettyTable
     from common import __version__, config_file, config_fields
     from common import grammar, precached_verbs
     from marvin.cloudstackConnection import cloudConnection
@@ -173,29 +174,58 @@ class CloudStackShell(cmd.Cmd, object):
         except Exception, e:
             print colored.red("Error: "), e
 
-    def print_result(self, result):
+    def print_result(self, result, result_filter=None):
         if result is None or len(result) == 0:
             return
 
-        def print_result_as_dict(result):
+        def printer_helper(printer, toprow):
+            if printer:
+                print printer
+            return PrettyTable(toprow)
+
+        def print_result_tabular(result, result_filter=None):
+            toprow = None
+            printer = None
+            for node in result:
+                if toprow != node.keys():
+                    if result_filter is not None and len(result_filter) != 0:
+                        commonkeys = filter(lambda x: x in node.keys(),
+                                            result_filter)
+                        if commonkeys != toprow:
+                            toprow = commonkeys
+                            printer = printer_helper(printer, toprow)
+                    else:
+                        toprow = node.keys()
+                        printer = printer_helper(printer, toprow)
+                row = map(lambda x: node[x], toprow)
+                if printer and row:
+                    printer.add_row(row)
+            if printer:
+                print printer
+
+        def print_result_as_dict(result, result_filter=None):
             for key in result.keys():
                 if not (isinstance(result[key], list) or
                         isinstance(result[key], dict)):
                     self.print_shell("%s = %s" % (key, result[key]))
                 else:
-                    self.print_shell(key + ":\n" + len(key) * "=")
-                    self.print_result(result[key])
+                    self.print_shell(key + ":\n" + len(key) * self.ruler)
+                    self.print_result(result[key], result_filter)
 
-        def print_result_as_list(result):
+        def print_result_as_list(result, result_filter=None):
             for node in result:
+                # Tabular print if it's a list of dict and tabularize is true
+                if isinstance(node, dict) and self.tabularize == 'true':
+                    print_result_tabular(result, result_filter)
+                    break
                 self.print_result(node)
                 if len(result) > 1:
                     self.print_shell(self.ruler * 80)
 
         if isinstance(result, dict):
-            print_result_as_dict(result)
+            print_result_as_dict(result, result_filter)
         elif isinstance(result, list):
-            print_result_as_list(result)
+            print_result_as_list(result, result_filter)
         elif isinstance(result, str):
             print result
         elif not (str(result) is None):
@@ -281,6 +311,11 @@ class CloudStackShell(cmd.Cmd, object):
         args_dict = dict(map(lambda x: [x.partition("=")[0],
                                         x.partition("=")[2]],
                              args[1:])[x] for x in range(len(args) - 1))
+        field_filter = None
+        if 'filter' in args_dict:
+            field_filter = filter(lambda x: x is not '',
+                                  map(lambda x: x.strip(),
+                                      args_dict.pop('filter').split(',')))
 
         api_cmd_str = "%sCmd" % api_name
         api_mod = self.get_api_module(api_name, [api_cmd_str])
@@ -313,7 +348,8 @@ class CloudStackShell(cmd.Cmd, object):
             return
         try:
             # Response is in the key "apiname+response" (lowercase)
-            self.print_result(result[api_name.lower()+'response'])
+            self.print_result(result[api_name.lower() + 'response'],
+                              field_filter)
             print
         except Exception as e:
             self.print_shell("🙈  Error on parsing and printing", e)
@@ -367,6 +403,7 @@ class CloudStackShell(cmd.Cmd, object):
                                   self.cache_verbs[verb][subject][1])
             search_string = text
 
+        autocompletions.append("filter=")
         return [s for s in autocompletions if s.startswith(search_string)]
 
     def do_api(self, args):
@@ -496,7 +533,6 @@ def main():
                 try:
                     args_partition = args.partition(" ")
                     res = self.cache_verbs[rule][args_partition[0]]
-
                 except KeyError, e:
                     self.print_shell("Error: invalid %s api arg" % rule, e)
                     return

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8f51c630/tools/cli/cloudmonkey/common.py
----------------------------------------------------------------------
diff --git a/tools/cli/cloudmonkey/common.py b/tools/cli/cloudmonkey/common.py
index 8a64a5d..3199af2 100644
--- a/tools/cli/cloudmonkey/common.py
+++ b/tools/cli/cloudmonkey/common.py
@@ -33,6 +33,7 @@ config_fields = {'host': 'localhost', 'port': '8080',
                  'apikey': '', 'secretkey': '',
                  'timeout': '3600', 'asyncblock': 'true',
                  'prompt': '🐵 cloudmonkey>', 'color': 'true',
+                 'tabularize': 'false',
                  'log_file':
                  os.path.expanduser('~/.cloudmonkey_log'),
                  'history_file':

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8f51c630/tools/cli/setup.py
----------------------------------------------------------------------
diff --git a/tools/cli/setup.py b/tools/cli/setup.py
index 4343eef..e6ee1b5 100644
--- a/tools/cli/setup.py
+++ b/tools/cli/setup.py
@@ -26,7 +26,9 @@ from cloudmonkey import __version__
 
 name = 'cloudmonkey'
 version = __version__
-requires = ['clint>=0.3.0',]
+requires = ['clint>=0.3.0',
+            'prettytable>=0.5',
+           ]
 
 try:
     import readline