jp (common): various Table fixes:

- renamed fromDict to more accurate fromListDict
- fixed handling of None filter in fromListDict
- fixes show_header when no header exist
- escape headers when using namedtuple, so it won't fail
This commit is contained in:
Goffi 2020-01-25 21:08:37 +01:00
commit da3b7b5fea
3 changed files with 20 additions and 12 deletions

View file

@ -316,7 +316,7 @@ class InviteesList(base.CommandBase):
show_table = OUTPUT_OPT_TABLE in self.args.output_opts
table = common.Table.fromDict(
table = common.Table.fromListDict(
self.host,
data,
("nick",)

View file

@ -642,7 +642,7 @@ class ShareList(base.CommandBase):
show_header = True
keys = ("name", "type", "size", "file_hash")
headers = ("name", "type", "size", "hash")
table = common.Table.fromDict(
table = common.Table.fromListDict(
self.host,
files_data,
keys=keys,

View file

@ -24,6 +24,7 @@ import time
import tempfile
import asyncio
import shlex
import re
from pathlib import Path
from sat_frontends.jp.constants import Const as C
from sat.core.i18n import _
@ -479,7 +480,8 @@ class Table(object):
- RowData with all columns values
if may also only use 1 argument, which will then be current col value.
the callable must return a string
if it's unicode, it will be used with .format and must countain u'{}' which will be replaced with the string
if it's unicode, it will be used with .format and must countain u'{}' which
will be replaced with the string.
if not None, must have same number of columns as data
@param use_buffer(bool): if True, bufferise output instead of printing it directly
"""
@ -495,7 +497,9 @@ class Table(object):
size = None
if headers:
row_cls = namedtuple("RowData", headers)
# we use a namedtuple to make the value easily accessible from filters
headers_safe = [re.sub(r'[^a-zA-Z_]', '_', h) for h in headers]
row_cls = namedtuple("RowData", headers_safe)
else:
row_cls = tuple
@ -512,8 +516,8 @@ class Table(object):
col_value = filter_(value, row_cls(*row_data_list))
except TypeError:
col_value = filter_(value)
# we count size without ANSI code as they will change length of the string
# when it's mostly style/color changes.
# we count size without ANSI code as they will change length of the
# string when it's mostly style/color changes.
col_size = len(regex.ansiRemove(col_value))
else:
col_value = str(value)
@ -557,11 +561,12 @@ class Table(object):
raise e
@classmethod
def fromDict(cls, host, data, keys=None, headers=None, filters=None, defaults=None):
"""Prepare a table to display it
def fromListDict(
cls, host, data, keys=None, headers=None, filters=None, defaults=None):
"""Create a table from a list of dictionaries
the whole data will be read and kept into memory,
to be printed
each dictionary is a row of the table, keys being columns names.
the whole data will be read and kept into memory, to be printed
@param data(list[dict[unicode, unicode]]): data to create the table from
@param keys(iterable[unicode], None): keys to get
if None, all keys will be used
@ -579,6 +584,8 @@ class Table(object):
keys = list(data[0].keys())
if headers is None:
headers = keys
if filters is None:
filters = {}
filters = [filters.get(k) for k in keys]
return cls(
host, (cls.readDictValues(d, keys, defaults) for d in data), headers, filters
@ -650,7 +657,8 @@ class Table(object):
@param show_borders(bool): True if borders need no be shown
@param hide_cols(None, iterable(unicode)): columns which should not be displayed
@param head_alignment(unicode): how to align headers, can be left, center or right
@param columns_alignment(unicode): how to align columns, can be left, center or right
@param columns_alignment(unicode): how to align columns, can be left, center or
right
@param col_sep(unicode): separator betweens columns
@param head_line(unicode): character to use to make line under head
@param disp(callable, None): method to use to display the table
@ -693,7 +701,7 @@ class Table(object):
)
# headers
if show_header:
if show_header and self.headers is not None:
self._disp(
left
+ self._headers(head_sep, headers, sizes, head_alignment, head_style)