cli: Pygments based output in cloudmonkey and new cfg processing

- Pygments based colored output for tabular and normal list outputs
- Fix cfg processing as per new cfg paths and ds
- Get rid of clint and old way of parsing and color printing

Signed-off-by: Rohit Yadav <bhaisaab@apache.org>
This commit is contained in:
Rohit Yadav 2013-01-28 17:59:37 -08:00
parent 233c0adcf3
commit cb8705c756
2 changed files with 51 additions and 52 deletions

View File

@ -20,7 +20,6 @@
try:
import atexit
import cmd
import clint
import codecs
import json
import logging
@ -32,14 +31,15 @@ try:
import time
import types
from clint.textui import colored
from ConfigParser import ConfigParser, SafeConfigParser
from urllib2 import HTTPError, URLError
from httplib import BadStatusLine
from prettytable import PrettyTable
from common import __version__, config_file, config_fields
from common import __version__, config_dir, config_file, config_fields
from common import precached_verbs
from lexer import monkeyprint
from marvin.cloudstackConnection import cloudConnection
from marvin.cloudstackException import cloudstackAPIException
from marvin.cloudstackAPI import *
@ -70,37 +70,47 @@ class CloudMonkeyShell(cmd.Cmd, object):
intro = ("☁ Apache CloudStack 🐵 cloudmonkey " + __version__ +
". Type help or ? to list commands.\n")
ruler = "="
config_dir = config_dir
config_file = config_file
config_fields = config_fields
# datastructure {'verb': {cmd': ['api', [params], doc, required=[]]}}
cache_verbs = precached_verbs
config_options = []
def __init__(self, pname, verbs):
self.program_name = pname
self.verbs = verbs
global config_fields
first_time = False
if not os.path.exists(self.config_dir):
os.makedirs(self.config_dir)
if os.path.exists(self.config_file):
config = self.read_config()
else:
for key in self.config_fields.keys():
setattr(self, key, self.config_fields[key])
config = self.write_config()
first_time = True
config = self.write_config(first_time)
for section in config_fields.keys():
for key in config_fields[section].keys():
try:
self.config_options.append(key)
setattr(self, key, config.get(section, key))
except Exception:
print "Please fix `%s` in %s" % (key, self.config_file)
sys.exit()
if first_time:
print "Welcome! Using `set` configure the necessary settings:"
print " ".join(sorted(self.config_fields.keys()))
print " ".join(sorted(self.config_options))
print "Config file:", self.config_file
print "For debugging, tail -f", self.log_file, "\n"
for key in self.config_fields.keys():
try:
setattr(self, key, config.get('CLI', key))
self.config_fields[key] = config.get('CLI', key)
except Exception:
print "Please fix `%s` config in %s" % (key, self.config_file)
sys.exit()
self.prompt = self.prompt.strip() + " " # Cosmetic fix for prompt
logging.basicConfig(filename=self.log_file,
level=logging.DEBUG, format=log_fmt)
logger.debug("Loaded config fields:\n%s" % self.config_fields)
logger.debug("Loaded config fields:\n%s" % map(lambda x: "%s=%s" %
(x, getattr(self, x)),
self.config_options))
cmd.Cmd.__init__(self)
if not os.path.exists(self.config_file):
@ -122,11 +132,16 @@ class CloudMonkeyShell(cmd.Cmd, object):
self.print_shell("Error: config_file not found", e)
return config
def write_config(self):
def write_config(self, first_time=False):
global config_fields
config = ConfigParser()
config.add_section('CLI')
for key in self.config_fields.keys():
config.set('CLI', key, getattr(self, key))
for section in config_fields.keys():
config.add_section(section)
for key in config_fields[section].keys():
if first_time:
config.set(section, key, config_fields[section][key])
else:
config.set(section, key, getattr(self, key))
with open(self.config_file, 'w') as cfg:
config.write(cfg)
return config
@ -144,35 +159,19 @@ class CloudMonkeyShell(cmd.Cmd, object):
print("^C")
def print_shell(self, *args):
output = ""
try:
for arg in args:
arg = str(arg)
if isinstance(type(args), types.NoneType):
continue
if self.color == 'true':
if str(arg).count(self.ruler) == len(str(arg)):
print colored.green(arg),
elif 'Error' in arg:
print colored.red(arg),
elif ":\n=" in arg:
print colored.red(arg),
elif ':' in arg:
print colored.blue(arg),
elif 'type' in arg:
print colored.green(arg),
elif 'state' in arg or 'count' in arg:
print colored.magenta(arg),
elif 'id =' in arg:
print colored.yellow(arg),
elif 'name =' in arg:
print colored.cyan(arg),
else:
print arg,
else:
print arg,
print
output += arg
if self.color == 'true':
monkeyprint(output)
else:
print output
except Exception, e:
print colored.red("Error: "), e
self.print_shell("Error: " + e)
def print_result(self, result, result_filter=None):
if result is None or len(result) == 0:
@ -180,7 +179,7 @@ class CloudMonkeyShell(cmd.Cmd, object):
def printer_helper(printer, toprow):
if printer:
print printer
self.print_shell(printer)
return PrettyTable(toprow)
def print_result_tabular(result, result_filter=None):
@ -201,16 +200,16 @@ class CloudMonkeyShell(cmd.Cmd, object):
if printer and row:
printer.add_row(row)
if printer:
print printer
self.print_shell(printer)
def print_result_as_dict(result, result_filter=None):
for key in sorted(result.keys(),
key=lambda x: x != 'id' and x != 'count' and x):
for key in sorted(result.keys(), key=lambda x:
x not in ['id', 'count', 'name'] and x):
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.ruler)
self.print_shell(key + ":")
self.print_result(result[key], result_filter)
def print_result_as_list(result, result_filter=None):
@ -360,7 +359,7 @@ class CloudMonkeyShell(cmd.Cmd, object):
command.required)
if len(missing_args) > 0:
self.print_shell("Missing arguments:", ' '.join(missing_args))
self.print_shell("Missing arguments: ", ' '.join(missing_args))
return
isAsync = False
@ -441,7 +440,7 @@ class CloudMonkeyShell(cmd.Cmd, object):
def complete_set(self, text, line, begidx, endidx):
mline = line.partition(" ")[2]
offs = len(mline) - len(text)
return [s[offs:] for s in self.config_fields.keys()
return [s[offs:] for s in self.config_options
if s.startswith(mline)]
def do_shell(self, args):

View File

@ -51,7 +51,7 @@ def get_colorscheme():
class MonkeyLexer(RegexLexer):
keywords = ['[a-z]*id', '[a-zA-Z]*:']
keywords = ['[a-z]*id', '^[a-z A-Z]*:']
attributes = ['[Tt]rue', '[Ff]alse']
params = ['[a-z]*[Nn]ame', 'type', '[Ss]tate']