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 = {
"timeout": "30",
"hsize": "100",
"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),
"expert": "%s/expert"%BaseDirectory.save_data_path(cccli.canonical_name),
}
......
......@@ -5,29 +5,30 @@
CloudControl CLI main module
'''
import os, os.path
import sys
import re
import subprocess
import platform
import shlex
import StringIO
import cccli
from cccli.exception import *
from cccli.printer import Printer, color
from cccli.commands import Commands, Alias
from cccli.handler import CliHandler
from cccli.tagdisplay import TagDisplay
from sjrpc.core.exceptions import *
from sjrpc.client import SimpleRpcClient
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):
def __init__(self, settings):
self.settings = settings
self.rpc = None
self.alias = Alias()
self.tagdisplay = TagDisplay()
self.prompt = ""
def start(self, line=""):
......@@ -60,6 +61,8 @@ class Cli(object):
# load alias
self.alias.load(self.settings.get("alias", ""))
self.printer.debug("Loaded aliases: %d"%len(self.alias))
# load tagdisplay
self.tagdisplay.load(self.settings.get("tag", ""))
# connecting
self._connect()
# auth
......
......@@ -15,17 +15,25 @@ class Command_list(OptionCommand):
def __init__(self, cli, argv0):
OptionCommand.__init__(self, cli, argv0)
self.option.set_usage("%prog [options] <tql>")
self.option.add_option("-c", action="store_true", dest="table",
self.option.set_usage("%prog [options] [tql]")
self.option.add_option("-t", action="store_true", dest="table",
help="column aligment display")
self.option.add_option("-l", action="store_true", dest="align",
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):
try:
(options, args) = self.option.parse_args(argv[1:])
except SystemExit:
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:
args.append("")
try:
......@@ -39,48 +47,65 @@ class Command_list(OptionCommand):
elif options.table:
self._list_table(objs)
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:
id = o.pop("id")
tags = " ".join([ "%s%s:%s%s"%(color["green"], t, color["reset"], v) for (t,v) in o.items() ])
self.printer.out("%sid:%s%s%s %s"%(color["green"], color["yellow"], id, color["reset"], tags))
id = self.td("id", o.pop("id"))
tags = " ".join([ "%s%s:%s%s"%(color["green"],
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):
# get all tag list
'''Listing line aligned'''
# get max size by tag
tags = dict()
for o in objs:
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:
id = str(o.pop("id"))
line = "%sid:%s%s%s"%(color["green"], color["yellow"], id.ljust(tags["id"] + 2), color["reset"])
taglist = o.keys()
taglist.sort()
for tagname in taglist:
line += "%s%s:%s%s"%(color["green"], tagname, color["reset"],
str(o[tagname]).ljust(tags[tagname] + 1))
self.printer.out(line)
# show id tag
line = "%sid:%s%s"%(color["green"],
self.tc("id"),
self.td("id", o.pop("id")).ljust(idsize + 2))
# show others tags
for tagname in sorted(tags.keys()):
line += "%s%s:%s%s"%(color["green"],
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):
# get all tag list
'''Listing table style'''
# get max size by tag
tags = dict()
for o in objs:
for t,v in o.items():
tags[t] = max(len(str(v)), tags.get(t, len(str(t))))
# extract id info
tags[t] = max(len(self.td(t, v)), tags.get(t, len(str(t))))
# extract id size
idsize = tags.pop("id")
# print titles
# print id title
self.printer.out(color["green"], nl="")
self.printer.out("id".ljust(idsize+1), nl=" ")
# print others titles
for t,v in tags.items():
self.printer.out(t.ljust(v), nl=" ")
self.printer.out(color["reset"])
# print obj
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():
self.printer.out(str(obj.get(t, "")).ljust(v) ,nl=" ")
self.printer.out()
self.printer.out(self.tc(t), nl="")
self.printer.out(self.td(t, obj.get(t, "")).ljust(v) ,nl=" ")
self.printer.out(color["reset"])
......@@ -11,6 +11,7 @@ import os
from cccli.exception import *
class Commands(object):
'''Command manager'''
def __init__(self, cli):
# save cli context
......
......@@ -5,17 +5,15 @@
CloudControl CLI RPC Handler
'''
import os, os.path
import subprocess
import platform
import cccli
from cccli.exception import *
from cccli.printer import Printer, color
from sjrpc.client import SimpleRpcClient
from sjrpc.utils import RpcHandler, pure
from sjrpc.core.exceptions import *
import cccli
import os, os.path
import subprocess
import platform
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