Coverage for silkaj/tui.py: 98%
55 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-20 12:29 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-20 12:29 +0000
1# Copyright 2016-2025 Maël Azimi <m.a@moul.re>
2#
3# Silkaj is free software: you can redistribute it and/or modify
4# it under the terms of the GNU Affero General Public License as published by
5# the Free Software Foundation, either version 3 of the License, or
6# (at your option) any later version.
7#
8# Silkaj is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU Affero General Public License for more details.
12#
13# You should have received a copy of the GNU Affero General Public License
14# along with Silkaj. If not, see <https://www.gnu.org/licenses/>.
16import shutil
17import sys
18from typing import Optional
20import rich_click as click
21from texttable import Texttable
23from silkaj import constants
25VERT_TABLE_CHARS = ["─", "│", "│", "═"]
28def endpoint_link(endpoint_host: str) -> str:
29 return f"https://{endpoint_host}/node/summary"
32def send_doc_confirmation(document_name: str) -> None:
33 if not click.confirm(f"Do you confirm sending this {document_name}?"):
34 sys.exit(constants.SUCCESS_EXIT_STATUS)
37class Table(Texttable):
38 def __init__(
39 self,
40 style="default",
41 ):
42 super().__init__(max_width=shutil.get_terminal_size().columns)
44 if style == "columns":
45 self.set_deco(self.HEADER | self.VLINES | self.BORDER)
46 self.set_chars(VERT_TABLE_CHARS)
48 def fill_rows(self, rows: list[list], header: Optional[list] = None) -> None:
49 """
50 Fills a table from header and rows list.
51 `rows` is a list of lists representing each row content.
52 each element of `rows` and header must be of same length.
53 """
54 if header:
55 if len(rows) == 0:
56 rows.append([""] * len(header))
57 assert len(header) == len(rows[0])
58 self.header(header)
59 for line in rows:
60 assert len(line) == len(rows[0])
61 self.add_row(line)
63 def fill_from_dict(self, _dict: dict) -> None:
64 """
65 Given a dict where each value represents a column,
66 fill a table where labels are dict keys and columns are dict values
67 This function stops on the first line with only empty cells
68 """
69 keys = list(_dict.keys())
70 rows = []
72 n = 0
73 while True:
74 row = []
75 empty_cells_number = 0
77 for key in keys:
78 try:
79 row.append(_dict[key][n])
80 except IndexError:
81 row.append("")
82 empty_cells_number += 1
83 # break on first empty row
84 if empty_cells_number == len(keys):
85 break
86 rows.append(row)
87 n += 1
89 return self.fill_rows(rows, keys)
91 def fill_from_dict_list(self, dict_list: list[dict]) -> None:
92 """
93 Given a list of dict with same keys,
94 fills the table with keys as header
95 """
96 header = list(dict_list[0].keys())
97 content = []
98 for _dict in dict_list:
99 assert list(_dict.keys()) == header
100 line = []
101 for head in header:
102 line.append(_dict[head])
103 content.append(line)
104 return self.fill_rows(content, header)