diff --git a/silkaj/tui.py b/silkaj/tui.py index 87463bd2c0fc51888de8dc3ef2d64a41e9b759cd..df76760f69a17663d9f2bb6f544bde78e85c6b16 100644 --- a/silkaj/tui.py +++ b/silkaj/tui.py @@ -18,11 +18,17 @@ along with Silkaj. If not, see <https://www.gnu.org/licenses/>. import sys import click from datetime import datetime +from texttable import Texttable +from collections import OrderedDict from silkaj import network_tools, constants, wot_tools from silkaj import crypto_tools as ct +HORIZ_TABLE_CHARS = ["─", "│", "─", "─"] +VERT_TABLE_CHARS = ["─", "│", "│", "═"] + + def display_amount(tx, message, amount, ud_value, currency_symbol): """ Displays an amount in unit and relative reference. @@ -67,3 +73,91 @@ async def send_doc_confirmation(document_name): client = network_tools.ClientInstance().client await client.close() sys.exit(constants.SUCCESS_EXIT_STATUS) + + +def create_table(style="default"): + """ + Creates a table. + Applies a style on it, to chose between: + * default (table with all boxes drawn, text on the left) + * columns (tabls with only columns, text centered) + """ + table = Texttable(max_width=click.get_terminal_size()[0]) + if style == "columns": + table.set_chars(VERT_TABLE_CHARS) + return table.set_deco(table.HEADER | table.VLINES | table.BORDER) + return table.set_chars(HORIZ_TABLE_CHARS) + + +def fill_table_from_dict_list(table, dict_list: list, type="horiz"): + """ + Given a list of OrderedDictict with same keys, + returns a table with keys as header. + type can be either "vert" or "horiz" + """ + headers = list(dict_list[0].keys()) + content = list() + for dict in dict_list: + assert list(dict.keys()) == headers + line = list() + for head in headers: + line.append(dict[head]) + content.append(line) + if type == "vert": + return vert_table(table, content, headers) + elif type == "horiz": + return horiz_table(table, content, headers) + + +def fill_table_from_dict(table, dict: OrderedDict): + """ + Given an OrderedDict where each value is a list of same length, + fill a table where labels are keys and columns are values. + """ + labels = list(dict.keys()) + content = list() + n = 0 + while True: + line = list() + err_count = 0 + for label in labels: + try: + line.append(dict[label][n]) + except IndexError: + line.append("") + err_count += 1 + if err_count == len(labels): + return horiz_table(table, content, labels) + content.append(line) + n += 1 + + +def horiz_table(table, content_list: list, headers=[]): + """ + Fills a table from headers and content list. + content_list is a list of lists representing rows. + each element of content_list and headers must be of sme length. + """ + if headers: + assert len(headers) == len(content_list[0]) + table.header(headers) + for content in content_list: + assert len(content) == len(content_list[0]) + table.add_row(content) + return table.draw() + + +def vert_table(table, content_list: list, labels=[]): + """ + Fills a vertical table, where labels are displayed on the first column + """ + if len(labels) > 0: + assert len(labels) == len(content_list) + for label, line in zip(labels, content_list): + assert len(line) == len(content_list[0]) + table.add_row([label] + line) + else: + for line in content_list: + assert len(line) == len(content_list[0]) + table.add_row(line) + return table.draw() diff --git a/tests/test_tui.py b/tests/test_tui.py index 3fd413d132c2cad988246eeb61a170fad52103d7..38a28fbc8daaf768a7a4df833e32ac8be886500e 100644 --- a/tests/test_tui.py +++ b/tests/test_tui.py @@ -16,7 +16,13 @@ along with Silkaj. If not, see <https://www.gnu.org/licenses/>. """ import pytest -from silkaj.tui import display_pubkey, display_amount, display_pubkey_and_checksum +from silkaj.tui import ( + display_pubkey, + display_amount, + display_pubkey_and_checksum, + horiz_table, + vert_table, +) from silkaj.constants import G1_SYMBOL, SHORT_PUBKEY_SIZE from silkaj import wot_tools @@ -81,3 +87,138 @@ def test_display_pubkey_and_checksum(pubkey, checksum): assert pubkey[:14] + "…:" + checksum == display_pubkey_and_checksum( pubkey, short=True, length=14 ) + + +# horiz_table +@pytest.mark.parametrize( + "content, headers, expected", + [ + ( + [ + ["three", "o'clock"], + ["four", "o'clock"], + ["rock", "rock around the clock"], + ], + ["one", "two"], + "+-------+-----------------------+\n\ +| one | two |\n\ ++=======+=======================+\n\ +| three | o'clock |\n\ ++-------+-----------------------+\n\ +| four | o'clock |\n\ ++-------+-----------------------+\n\ +| rock | rock around the clock |\n\ ++-------+-----------------------+", + ), + ( + [ + ["three", "o'clock"], + ["four", "o'clock"], + ["rock", "rock around the clock"], + ], + None, + "+-------+-----------------------+\n\ +| three | o'clock |\n\ ++-------+-----------------------+\n\ +| four | o'clock |\n\ ++-------+-----------------------+\n\ +| rock | rock around the clock |\n\ ++-------+-----------------------+", + ), + ( + ["one", "two"], + [ + ["three", "o'clock"], + ["four", "o'clock"], + ["rock"], + ], + False, + ), + ], +) +def test_horiz_table(content, headers, expected): + if expected == False: + with pytest.raises(AssertionError) as pytest_error: + table = horiz_table(headers, content) + assert pytest_error.type == AssertionError # is it useful ? + else: + table = horiz_table(content, headers) + assert table == expected + + +# vert_table +@pytest.mark.parametrize( + "content, headers, expected", + [ + ( + [ + ["o'clock"], + ["four"], + ["o'clock"], + ], + ["one", "two", "three"], + "+-------+---------+\n\ +| one | o'clock |\n\ ++-------+---------+\n\ +| two | four |\n\ ++-------+---------+\n\ +| three | o'clock |\n\ ++-------+---------+", + ), + ( + [ + ["o'clock"], + ["four"], + ["o'clock"], + ], + [], + "+---------+\n\ +| o'clock |\n\ ++---------+\n\ +| four |\n\ ++---------+\n\ +| o'clock |\n\ ++---------+", + ), + ( + [ + ["three", "o'clock"], + ["four", "o'clock"], + ], + ["one", "two"], + "+-----+-------+---------+\n\ +| one | three | o'clock |\n\ ++-----+-------+---------+\n\ +| two | four | o'clock |\n\ ++-----+-------+---------+", + ), + ( + ["one", "two"], + [["three", "o'clock"], ["four", "o'clock"], ["rock", "rock"]], + False, + ), + ( + ["one", "two"], + [ + ["three", "o'clock"], + [ + "four", + ], + ], + False, + ), + ], +) +def test_vert_table(content, headers, expected): + if expected == False: + with pytest.raises(AssertionError) as pytest_error: + table = vert_table(headers, content) + assert pytest_error.type == AssertionError # is it useful ? + else: + table = vert_table(content, headers) + print(table) + assert table == expected + + +# TODO +# create_table_from_dict_list