2323# SOFTWARE.
2424#
2525###############################################################################
26+ from textwrap import wrap
27+
2628from nodescraper .interfaces import PluginResultCollator
2729from nodescraper .models import PluginResult , TaskResult
2830
@@ -40,45 +42,114 @@ def collate_results(
4042 connection_results (list[TaskResult]): list of connection results to collate
4143 """
4244
43- def gen_str_table (headers : list [str ], rows : list [list [str | None ]]):
44- column_widths = [len (header ) for header in headers ]
45- for row in rows :
46- for i , cell in enumerate (row ):
47- column_widths [i ] = max (
48- column_widths [i ],
49- len (str (cell )),
50- )
51- border = f"+{ '+' .join ('-' * (width + 2 ) for width in column_widths )} +"
45+ def gen_str_table (
46+ headers : list [str ],
47+ rows : list [list [str | None ]],
48+ max_widths : dict [str , int ] | None = None ,
49+ ) -> str :
50+ """
51+ Wrap cells.
52+ """
53+ max_widths = max_widths or {}
54+
55+ norm_rows : list [list [str ]] = [
56+ ["" if c is None else str (c ) for c in row ] for row in rows
57+ ]
58+
59+ ncols = len (headers )
60+
61+ raw_widths : list [int ] = [len (h ) for h in headers ]
62+ for norm_row in norm_rows :
63+ for i , cell in enumerate (norm_row ):
64+ for part in cell .splitlines () or ["" ]:
65+ if len (part ) > raw_widths [i ]:
66+ raw_widths [i ] = len (part )
5267
53- def gen_row (row ):
54- return f"| { ' | ' .join (str (cell ).ljust (width ) for cell , width in zip (row , column_widths , strict = False ))} |"
68+ target_widths : list [int ] = []
69+ for i , h in enumerate (headers ):
70+ cap = max_widths .get (h )
71+ if cap is None :
72+ target_widths .append (raw_widths [i ])
73+ else :
74+ target_widths .append (max (len (h ), min (raw_widths [i ], cap )))
5575
56- table = [border , gen_row (headers ), border , * [gen_row (row ) for row in rows ], border ]
57- return "\n " .join (table )
76+ wrapped_rows : list [list [list [str ]]] = []
77+ for norm_row in norm_rows :
78+ wrapped_cells : list [list [str ]] = []
79+ for i , cell in enumerate (norm_row ):
80+ cell_lines : list [str ] = []
81+ paragraphs = cell .splitlines () or ["" ]
82+ for para in paragraphs :
83+ chunked = wrap (para , width = target_widths [i ]) or ["" ]
84+ cell_lines .extend (chunked )
85+ wrapped_cells .append (cell_lines )
86+ wrapped_rows .append (wrapped_cells )
87+
88+ col_widths : list [int ] = []
89+ for i in range (ncols ):
90+ widest_line = len (headers [i ])
91+ for wrow in wrapped_rows :
92+ for line in wrow [i ]:
93+ if len (line ) > widest_line :
94+ widest_line = len (line )
95+ col_widths .append (widest_line )
96+
97+ border = "+" + "+" .join ("-" * (w + 2 ) for w in col_widths ) + "+"
98+
99+ def render_physical_row (parts : list [str ]) -> str :
100+ return (
101+ "| "
102+ + " | " .join (p .ljust (w ) for p , w in zip (parts , col_widths , strict = False ))
103+ + " |"
104+ )
105+
106+ table_lines : list [str ] = [border , render_physical_row (headers ), border ]
107+ for wrow in wrapped_rows :
108+ height = max (len (cell_lines ) for cell_lines in wrow )
109+ for idx in range (height ):
110+ parts = [
111+ (wrow [col ][idx ] if idx < len (wrow [col ]) else "" ) for col in range (ncols )
112+ ]
113+ table_lines .append (render_physical_row (parts ))
114+ table_lines .append (border )
115+ return "\n " .join (table_lines )
58116
59117 tables = ""
60118 if connection_results :
61- rows = []
119+ # Allow Optional[str] elements
120+ conn_rows : list [list [str | None ]] = []
62121 for connection_result in connection_results :
63- rows .append (
122+ conn_rows .append (
64123 [
65124 connection_result .task ,
66125 connection_result .status .name ,
67126 connection_result .message ,
68127 ]
69128 )
70129
71- table = gen_str_table (["Connection" , "Status" , "Message" ], rows )
130+ table = gen_str_table (
131+ ["Connection" , "Status" , "Message" ],
132+ conn_rows ,
133+ max_widths = {"Connection" : 32 , "Status" : 16 , "Message" : 80 },
134+ )
72135 tables += f"\n \n { table } "
73136
74137 if plugin_results :
75- rows = []
138+ # Allow Optional[str] elements
139+ plug_rows : list [list [str | None ]] = []
76140 for plugin_result in plugin_results :
77- rows .append (
78- [plugin_result .source , plugin_result .status .name , plugin_result .message ]
141+ plug_rows .append (
142+ [
143+ plugin_result .source ,
144+ plugin_result .status .name ,
145+ plugin_result .message ,
146+ ]
79147 )
80-
81- table = gen_str_table (["Plugin" , "Status" , "Message" ], rows )
148+ table = gen_str_table (
149+ ["Plugin" , "Status" , "Message" ],
150+ plug_rows ,
151+ max_widths = {"Plugin" : 32 , "Status" : 16 , "Message" : 80 },
152+ )
82153 tables += f"\n \n { table } "
83154
84155 if tables :
0 commit comments