vultron/vultron/display.py

126 lines
2.7 KiB
Python

class OutFormat:
def __init__(self, data):
self.data = data
self.spans = { }
self.rows = [ ]
for row in data:
vals = { }
for field in row:
vals[field] = self.normalize(row[field])
if field in self.spans:
self.spans[field] = max(self.spans[field], len(vals[field]))
else:
self.spans[field] = max(len(field), len(vals[field]))
self.rows.append(vals)
self.cols = list(self.spans.keys())
def normalize(self, field):
if type(field) == list:
return ", ".join(field)
else:
return str(field)
def render(self):
return self.data
class Basic(OutFormat):
def __init__(self, data):
super().__init__(data)
self.top = {
"left": "+", "right": "+",
"divide": "+", "fill": "-"
}
self.base = {
"left": "+", "right": "+",
"divide": "+", "fill": "-"
}
self.sep = {
"left": "|", "right": "|",
"divide": "+", "fill": "-"
}
self.row = {
"left": "|", "right": "|",
"divide": "|", "fill": " "
}
def render(self):
sep = ""
top = ""
hdr = ""
base = ""
fill = self.row["fill"]
for col in self.cols:
width = self.spans[col] + 2
sep += self.sep["divide"] + self.sep["fill"] * width
top += self.top["divide"] + self.top["fill"] * width
hdr += self.row["divide"] + fill + col.ljust(width - 1, fill)
base += self.base["divide"] + self.base["fill"] * width
sep = self.sep["left"] + sep[1:] + self.sep["right"] + "\n"
top = self.top["left"] + top[1:] + self.top["right"] + "\n"
hdr = self.row["left"] + hdr[1:] + self.row["right"] + "\n"
base = self.base["left"] + base[1:] + self.base["right"]
lines = [ ]
for row in self.rows:
line = ""
for col in self.cols:
width = self.spans[col] + 2
if col in row:
line += self.row["divide"] + fill + row[col].ljust(width - 1, fill)
else:
line += slef.row["divide"] + fill * width
lines.append(self.row["left"] + line[1:] + self.row["right"] + "\n")
return top + sep.join([hdr, *lines]) + base
class Table(Basic):
def __init__(self, data):
super().__init__(data)
self.top = {
"left": "\u250F", "right": "\u2513",
"divide": "\u2533", "fill": "\u2501"
}
self.base = {
"left": "\u2517", "right": "\u251B",
"divide": "\u253B", "fill": "\u2501"
}
self.sep = {
"left": "\u2523", "right": "\u252B",
"divide": "\u254B", "fill": "\u2501"
}
self.row = {
"left": "\u2503", "right": "\u2503",
"divide": "\u2503", "fill": " "
}
class Json(OutFormat):
pass
class Csv(OutFormat):
pass
FORMATS = {
"basic": Basic,
"table": Table,
"json": Json,
"csv": Csv
}