# HG changeset patch # User Goffi # Date 1579982917 -3600 # Node ID 040ca99e25fe37567fe09769911e151f80036a7d # Parent 0c29155ac68b0db97f9ab2b38cc3191fca1c16ed 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 diff -r 0c29155ac68b -r 040ca99e25fe sat_frontends/jp/cmd_event.py --- a/sat_frontends/jp/cmd_event.py Sat Jan 25 21:08:32 2020 +0100 +++ b/sat_frontends/jp/cmd_event.py Sat Jan 25 21:08:37 2020 +0100 @@ -316,7 +316,7 @@ show_table = OUTPUT_OPT_TABLE in self.args.output_opts - table = common.Table.fromDict( + table = common.Table.fromListDict( self.host, data, ("nick",) diff -r 0c29155ac68b -r 040ca99e25fe sat_frontends/jp/cmd_file.py --- a/sat_frontends/jp/cmd_file.py Sat Jan 25 21:08:32 2020 +0100 +++ b/sat_frontends/jp/cmd_file.py Sat Jan 25 21:08:37 2020 +0100 @@ -642,7 +642,7 @@ 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, diff -r 0c29155ac68b -r 040ca99e25fe sat_frontends/jp/common.py --- a/sat_frontends/jp/common.py Sat Jan 25 21:08:32 2020 +0100 +++ b/sat_frontends/jp/common.py Sat Jan 25 21:08:37 2020 +0100 @@ -24,6 +24,7 @@ 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 @@ - 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ @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 @@ ) # 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)