# -*- coding: utf-8 -*- from typing import Any, Optional, Callable from wtforms import Form class TablePrinter: separator: str headers: Optional[list[str]] widths: list[int] def __init__( self, headers: Optional[list[str]] = None, separator: str = "|" ) -> None: self.headers = headers self.separator = separator self.format_string = "" self.widths = list() if headers is not None: self._calulate_widths([headers]) def _calulate_widths(self, rows: list[list[str]]) -> None: def _get_column_count(rows: list[list[str]]) -> int: return min([len(row) for row in rows]) def _column_width(column: tuple[str, ...], width: int) -> int: widths = [len(str(elem)) for elem in column] widths.append(width) return max(widths) columns = _get_column_count(rows) while len(self.widths) < columns: self.widths.append(0) self.widths = [ _column_width(column, width) for column, width in zip(list(zip(*rows)), self.widths) ] self._update_format_string() def _update_format_string(self) -> None: sep = " %s " % self.separator self.format_string = "%s %s %s" % ( self.separator, sep.join(["%%-%ds" % width for width in self.widths]), self.separator, ) def output(self, rows: list[list[str]]) -> None: if len(rows) > 0: self._calulate_widths(rows) if self.headers is not None: self._print_row(self.headers) self._print_headline() for row in rows: self._print_row(row) def _print_headline(self) -> None: print( ( "%s%s%s" % ( self.separator, self.separator.join( ["-" * (width + 2) for width in self.widths] ), self.separator, ) ) ) def _print_row(self, row: list[str]) -> None: print((self.format_string % tuple(row))) class ConsoleForm: _ready = False def __init__( self, formcls: Callable[..., Form], **kwargs: Any ) -> None: self.form = formcls(meta={"csrf": False}) self._fill(kwargs) self._ready = True def _fill(self, data: dict[str, Any]) -> None: for key, value in list(data.items()): field = getattr(self.form, key, None) if field is not None: field.data = value def print_errors(self) -> None: for field, errors in list(self.form.errors.items()): if len(errors) > 1: print(("%s:" % field)) for error in errors: print((" %s" % error)) else: print(("%s: %s" % (field, errors[0]))) def __getattr__(self, name: str) -> Any: return getattr(self.form, name) def __setattr__(self, name: str, value: Any) -> None: if self._ready and name not in self.__dict__: setattr(self.form, name, value) else: super(ConsoleForm, self).__setattr__(name, value) def __delattr__(self, name: str) -> None: if self._ready and name not in self.__dict__: delattr(self.form, name) else: super(ConsoleForm, self).__delattr__(name)