Skip to content
Snippets Groups Projects
Commit 5c11d336 authored by Seblu's avatar Seblu
Browse files

Implement tagdisplay. This allow per tag coloring and typing.

parent 6ade2a7d
No related branches found
No related tags found
No related merge requests found
...@@ -24,6 +24,7 @@ settings = { ...@@ -24,6 +24,7 @@ settings = {
"timeout": "30", "timeout": "30",
"hsize": "100", "hsize": "100",
"alias": "%s/alias"%BaseDirectory.save_config_path(cccli.canonical_name), "alias": "%s/alias"%BaseDirectory.save_config_path(cccli.canonical_name),
"tag": "%s/tag"%BaseDirectory.save_config_path(cccli.canonical_name),
"history": "%s/history"%BaseDirectory.save_data_path(cccli.canonical_name), "history": "%s/history"%BaseDirectory.save_data_path(cccli.canonical_name),
"expert": "%s/expert"%BaseDirectory.save_data_path(cccli.canonical_name), "expert": "%s/expert"%BaseDirectory.save_data_path(cccli.canonical_name),
} }
......
...@@ -5,29 +5,30 @@ ...@@ -5,29 +5,30 @@
CloudControl CLI main module CloudControl CLI main module
''' '''
import os, os.path
import sys
import re
import subprocess
import platform
import shlex
import StringIO
import cccli import cccli
from cccli.exception import * from cccli.exception import *
from cccli.printer import Printer, color from cccli.printer import Printer, color
from cccli.commands import Commands, Alias from cccli.commands import Commands, Alias
from cccli.handler import CliHandler from cccli.handler import CliHandler
from cccli.tagdisplay import TagDisplay
from sjrpc.core.exceptions import *
from sjrpc.client import SimpleRpcClient from sjrpc.client import SimpleRpcClient
from sjrpc.utils import RpcHandler, pure from sjrpc.utils import RpcHandler, pure
from sjrpc.core.exceptions import * import os, os.path
import sys
import re
import subprocess
import platform
import shlex
import StringIO
class Cli(object): class Cli(object):
def __init__(self, settings): def __init__(self, settings):
self.settings = settings self.settings = settings
self.rpc = None self.rpc = None
self.alias = Alias() self.alias = Alias()
self.tagdisplay = TagDisplay()
self.prompt = "" self.prompt = ""
def start(self, line=""): def start(self, line=""):
...@@ -60,6 +61,8 @@ class Cli(object): ...@@ -60,6 +61,8 @@ class Cli(object):
# load alias # load alias
self.alias.load(self.settings.get("alias", "")) self.alias.load(self.settings.get("alias", ""))
self.printer.debug("Loaded aliases: %d"%len(self.alias)) self.printer.debug("Loaded aliases: %d"%len(self.alias))
# load tagdisplay
self.tagdisplay.load(self.settings.get("tag", ""))
# connecting # connecting
self._connect() self._connect()
# auth # auth
......
...@@ -15,17 +15,25 @@ class Command_list(OptionCommand): ...@@ -15,17 +15,25 @@ class Command_list(OptionCommand):
def __init__(self, cli, argv0): def __init__(self, cli, argv0):
OptionCommand.__init__(self, cli, argv0) OptionCommand.__init__(self, cli, argv0)
self.option.set_usage("%prog [options] <tql>") self.option.set_usage("%prog [options] [tql]")
self.option.add_option("-c", action="store_true", dest="table", self.option.add_option("-t", action="store_true", dest="table",
help="column aligment display") help="column aligment display")
self.option.add_option("-l", action="store_true", dest="align", self.option.add_option("-l", action="store_true", dest="align",
help="line aligment display") help="line aligment display")
self.option.add_option("-n", "--no-tagdisplay", action="store_false", dest="tagdisplay", default=True,
help="No tag display system")
def __call__(self, argv): def __call__(self, argv):
try: try:
(options, args) = self.option.parse_args(argv[1:]) (options, args) = self.option.parse_args(argv[1:])
except SystemExit: except SystemExit:
return return
if options.tagdisplay:
self.td = self.cli.tagdisplay.resolve
self.tc = self.cli.tagdisplay.color
else:
self.td = lambda tagname, tagvalue: tagvalue
self.tc = lambda tagname: color["reset"]
if len(args) == 0: if len(args) == 0:
args.append("") args.append("")
try: try:
...@@ -39,48 +47,65 @@ class Command_list(OptionCommand): ...@@ -39,48 +47,65 @@ class Command_list(OptionCommand):
elif options.table: elif options.table:
self._list_table(objs) self._list_table(objs)
else: else:
self._list(objs) self._trivial_list(objs)
def _list(self, objs): def _trivial_list(self, objs):
'''Trivial listing of tag'''
for o in objs: for o in objs:
id = o.pop("id") id = self.td("id", o.pop("id"))
tags = " ".join([ "%s%s:%s%s"%(color["green"], t, color["reset"], v) for (t,v) in o.items() ]) tags = " ".join([ "%s%s:%s%s"%(color["green"],
self.printer.out("%sid:%s%s%s %s"%(color["green"], color["yellow"], id, color["reset"], tags)) t,
self.tc(t),
self.td(t, v))
for (t,v) in o.items() ])
self.printer.out("%sid:%s%s %s%s"%(color["green"], color["lblue"], id, tags, color["reset"]))
def _list_align(self, objs): def _list_align(self, objs):
# get all tag list '''Listing line aligned'''
# get max size by tag
tags = dict() tags = dict()
for o in objs: for o in objs:
for t,v in o.items(): for t,v in o.items():
tags[t] = max(len(str(v)), tags.get(t, len(str(t)))) tags[t] = max(len(self.td(t, v)), tags.get(t, len(str(t))))
# extract id size
idsize = tags.pop("id")
# dislay each object by line
for o in objs: for o in objs:
id = str(o.pop("id")) # show id tag
line = "%sid:%s%s%s"%(color["green"], color["yellow"], id.ljust(tags["id"] + 2), color["reset"]) line = "%sid:%s%s"%(color["green"],
taglist = o.keys() self.tc("id"),
taglist.sort() self.td("id", o.pop("id")).ljust(idsize + 2))
for tagname in taglist: # show others tags
line += "%s%s:%s%s"%(color["green"], tagname, color["reset"], for tagname in sorted(tags.keys()):
str(o[tagname]).ljust(tags[tagname] + 1)) line += "%s%s:%s%s"%(color["green"],
self.printer.out(line) tagname,
self.tc(tagname),
self.td(tagname, o.get(tagname, "")).ljust(tags[tagname] + 1))
self.printer.out("%s%s"%(line, color["reset"]))
def _list_table(self, objs): def _list_table(self, objs):
# get all tag list '''Listing table style'''
# get max size by tag
tags = dict() tags = dict()
for o in objs: for o in objs:
for t,v in o.items(): for t,v in o.items():
tags[t] = max(len(str(v)), tags.get(t, len(str(t)))) tags[t] = max(len(self.td(t, v)), tags.get(t, len(str(t))))
# extract id info # extract id size
idsize = tags.pop("id") idsize = tags.pop("id")
# print titles # print id title
self.printer.out(color["green"], nl="") self.printer.out(color["green"], nl="")
self.printer.out("id".ljust(idsize+1), nl=" ") self.printer.out("id".ljust(idsize+1), nl=" ")
# print others titles
for t,v in tags.items(): for t,v in tags.items():
self.printer.out(t.ljust(v), nl=" ") self.printer.out(t.ljust(v), nl=" ")
self.printer.out(color["reset"]) self.printer.out(color["reset"])
# print obj # print obj
for obj in objs: for obj in objs:
self.printer.out("%s%s%s"%(color["yellow"], obj.pop("id").ljust(idsize+1), color["reset"]) ,nl=" ") # print id first
self.printer.out(self.tc("id"), nl="")
self.printer.out(self.td("id", obj.pop("id")).ljust(idsize+1), nl=" ")
# print others tags
for (t, v) in tags.items(): for (t, v) in tags.items():
self.printer.out(str(obj.get(t, "")).ljust(v) ,nl=" ") self.printer.out(self.tc(t), nl="")
self.printer.out() self.printer.out(self.td(t, obj.get(t, "")).ljust(v) ,nl=" ")
self.printer.out(color["reset"])
...@@ -11,6 +11,7 @@ import os ...@@ -11,6 +11,7 @@ import os
from cccli.exception import * from cccli.exception import *
class Commands(object): class Commands(object):
'''Command manager'''
def __init__(self, cli): def __init__(self, cli):
# save cli context # save cli context
......
...@@ -5,17 +5,15 @@ ...@@ -5,17 +5,15 @@
CloudControl CLI RPC Handler CloudControl CLI RPC Handler
''' '''
import os, os.path
import subprocess
import platform
import cccli
from cccli.exception import * from cccli.exception import *
from cccli.printer import Printer, color from cccli.printer import Printer, color
from sjrpc.client import SimpleRpcClient from sjrpc.client import SimpleRpcClient
from sjrpc.utils import RpcHandler, pure from sjrpc.utils import RpcHandler, pure
from sjrpc.core.exceptions import * from sjrpc.core.exceptions import *
import cccli
import os, os.path
import subprocess
import platform
class CliHandler(RpcHandler): class CliHandler(RpcHandler):
......
#!/usr/bin/env python
#coding=utf8
'''
CloudControl Tag displaying stuff
'''
from cccli.exception import *
from cccli.printer import Printer, color
import os
import re
import math
import ConfigParser
import time
class TagDisplay(object):
'''Handle tagdisplay stuff'''
def __init__(self):
self.option = dict()
self.tagtype = dict()
self.tagcolor = { "id": "lblue" }
self.types = [ x[5:] for x in dir(self) if x.startswith("type_") ]
def load(self, filename):
'''load tagdisplay settings from file'''
if os.access(filename, os.R_OK):
fparser = ConfigParser.RawConfigParser()
fparser.read(filename)
self.__init__()
if fparser.has_section("option"):
self.option.update(fparser.items("option"))
if fparser.has_section("type"):
self.tagtype.update(fparser.items("type"))
if fparser.has_section("color"):
self.tagcolor.update(fparser.items("color"))
def save(self, filename):
'''save tagdisplay settings on file'''
if os.access(filename, os.R_OK or os.W_OK):
fparser = ConfigParser.RawConfigParser()
fparser.read(filename)
for n,d in (("type", self.tagtype), ("color", self.tagcolor), ("option", self.option)):
fparser.remove_section(n)
fparser.add_section(n)
for k,v in d.items():
fparser.set(n, k, v)
fparser.write(open(filename, "w"))
def color(self, tagname):
'''Return the current tag color'''
if tagname in self.tagcolor and self.tagcolor[tagname] in color:
return color[self.tagcolor[tagname]]
return color["reset"]
def resolve(self, tagname, tagvalue):
'''Transform a tagvalue respecting custom display settings'''
tagname = unicode(tagname)
tagvalue = unicode(tagvalue)
if bool(self.option.get("quotespace", False)):
if re.search("\s", tagvalue) is not None:
tagvalue = "'%s'"%re.sub("'", "\'", tagvalue)
if tagname in self.tagtype and self.tagtype[tagname] in self.types:
return getattr(self, "type_%s"%self.tagtype[tagname])(tagvalue)
return tagvalue
def type_lower(self, value):
'''Lower case type'''
return value.lower()
def type_upper(self, value):
'''Upper case type'''
return value.upper()
def type_si(self, value):
'''System International type'''
if value.isdecimal():
v = float(value)
if v >= 1000:
si = "KMGTPEZY"
p = min(math.floor(math.log10(abs(v))/3.0), len(si))
d = v / pow(10, 3*p)
u = si[int(p-1)]
value = "%.1f%s"%(d, u)
return value
def type_bit(self, value):
'''Bit type'''
if value.isdecimal():
v = float(value)
if v >= 1000:
si = "KMGTPEZY"
p = min(math.floor(math.log(abs(v), 2)/10.0), pow(2, len(si)))
d = v / pow(2, 10*p)
u = si[int(p-1)]
value = "%.1f%si"%(d, u)
return value
def type_second(self, value):
'''Second type'''
if value.isdecimal():
v = long(value)
if v < 60:
return "%ss"%value
elif v < 3600:
return "%dm%ds"%(v/60, v%60)
elif v < 86400:
return "%dh%dm%ds"%(v/3600, v/60%60, v%60)
else:
return "%dd%dh%dm%ds"%(v/86400, v/3600%3600, v/60%60, v%60)
return value
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment