summaryrefslogtreecommitdiffstats
path: root/accounts/utils/console.py
blob: cabfc08f557a20962ed749e3287a36e5463ebf32 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# -*- 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: dict[str, 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)