Beispiel #1
0
def color_rep(ss, is_top_menu: bool = False):
    """
    格式化菜单文本(添加颜色)

    Format menu text (add color)

    :param is_top_menu:
    :param ss: 文本
    :return: 处理后的文本
    """
    from rich.table import Table, Column
    from rich.box import SIMPLE
    ss = ss.strip().split('\n')

    tb = Table(
        *([Column('1', style='bold magenta', justify='left'), Column('2', style='bold yellow', justify='center'),
           Column('3', style='bold green', justify='right')] if is_top_menu else
          [Column('1', style='bold magenta', justify='left'), Column('2', style='bold yellow', justify='right')]),
        title=f'[bold underline]{"QuickStart_Rhy" if is_top_menu else ss[0].strip().strip(":")}' + '\n',
        show_header=False, show_edge=False, box=SIMPLE
    )
    for i, line in enumerate(ss if is_top_menu else ss[1:]):
        if ':->' in line:
            line = [i.strip() for i in line.split(':->')]
            if '|' in line[1]:
                line += [i.strip() for i in line.pop(-1).split('|')]
        tb.add_row(*line)
    qs_default_console.print(tb, justify="center")
Beispiel #2
0
    def run(self, manager: "pwncat.manager.Manager", args):

        modules = list(manager.target.find_module(f"*{args.module}*"))
        min_width = max(
            len(module.name.removeprefix("agnostic.")) for module in modules)

        table = Table(
            Column(header="Name", style="cyan", min_width=min_width),
            Column(header="Description"),
            title="Results",
            box=box.MINIMAL_DOUBLE_HEAD,
            expand=True,
        )

        for module in modules:
            # Rich will ellipsize the column, but we need to squeze
            # white space and remove newlines. `textwrap.shorten` is
            # the easiest way to do that, so we use a large size for
            # width.
            description = module.__doc__ if module.__doc__ is not None else ""
            module_name = module.name.removeprefix("agnostic.")

            if self.manager.target is not None:
                module_name = module_name.removeprefix(
                    self.manager.target.platform.name + ".")

            table.add_row(
                f"[cyan]{module_name}[/cyan]",
                textwrap.shorten(description.replace("\n", " "),
                                 width=80,
                                 placeholder="..."),
            )

        console.print(table)
Beispiel #3
0
    def __init__(self) -> None:
        self.console = Console(highlight=False)

        self._crawl_progress = Progress(
            TextColumn("{task.description}", table_column=Column(ratio=1)),
            BarColumn(),
            TimeRemainingColumn(),
            expand=True,
        )
        self._download_progress = Progress(
            TextColumn("{task.description}", table_column=Column(ratio=1)),
            TransferSpeedColumn(),
            DownloadColumn(),
            BarColumn(),
            TimeRemainingColumn(),
            expand=True,
        )

        self._live = Live(console=self.console, transient=True)
        self._update_live()

        self._showing_progress = False
        self._progress_suspended = False
        self._lock = asyncio.Lock()
        self._lines: List[str] = []

        # Whether different parts of the output are enabled or disabled
        self.output_explain = False
        self.output_status = True
        self.output_report = True
Beispiel #4
0
    def _create_rich_progress(self):

        desc_column = TextColumn("{task.description}", table_column=Column(ratio=1))
        bar_column = BarColumn(bar_width=None, table_column=Column(ratio=2))
        progress = Progress(desc_column, bar_column, "[progress.percentage]{task.percentage}%", expand=True)

        return progress
Beispiel #5
0
def summarize(definitions):
    """
    Display a summary of bin set definitions.
    """
    table = Table(
        "ID",
        "Description",
        "Quad. type",
        Column("Quad. nodes", justify="right"),
        Column("wmin \[nm]", justify="right"),
        Column("wmax \[nm]", justify="right"),
        Column("wres \[nm]", justify="right"),
        title="Bin set definitions",
    )

    for bin_set_id in sorted(definitions.keys()):
        params = definitions[bin_set_id]

        row_items = [bin_set_id]
        row_items.append(params.get("description", "—"))

        row_items.extend([
            f"{params[x]}" for x in
            ["quadrature_type", "quadrature_n", "wmin", "wmax", "wres"]
        ])

        table.add_row(*row_items)

    console.print()
    console.print(table)
    console.print()
Beispiel #6
0
 def download(self, batch, articles, folder):
     """
         Download a pdf batch
     """
     log_file = os.path.join(folder, 'missing.log')
     logger.remove()
     logger.add(log_file,
                format="{time} {level} {message}",
                mode='w',
                level="INFO")
     assert len(articles) > 0, 'no article.'
     progress = Progress(TextColumn(
         "[progress.description]{task.description}",
         table_column=Column(ratio=1)),
                         TimeElapsedColumn(table_column=Column(ratio=1)),
                         BarColumn(table_column=Column(ratio=2)),
                         "| {task.completed} of {task.total:>2.0f}",
                         expand=False)
     missing = 0
     with progress:
         task = progress.add_task(f" {batch} |", total=len(articles))
         for article in articles:
             done = self.get_article(
                 article['article_url'],
                 os.path.join(folder, article['file_name']))
             if done:
                 progress.update(task, advance=1)
             else:
                 missing += 1
                 logger.info("NOT_FOUND_IN_SCI-HUB | " +
                             article['warning_str'])
     return missing, log_file
Beispiel #7
0
    def run(self, manager: "pwncat.manager.Manager", args):
        if args.topic:
            for command in manager.parser.commands:
                if command.PROG == args.topic:
                    if command.parser is not None:
                        command.parser.print_help()
                    else:
                        console.print(textwrap.dedent(command.__doc__).strip())
                    break
        else:
            table = Table(
                Column("Command", style="green"),
                Column("Description", no_wrap=True),
                box=rich.box.SIMPLE,
            )

            for command in manager.parser.commands:
                doc = command.__doc__
                if doc is None:
                    doc = ""
                else:
                    doc = textwrap.shorten(
                        textwrap.dedent(doc).strip().replace("\n", ""), 60)

                table.add_row(command.PROG, doc)

            console.print(table)
Beispiel #8
0
 def table(self) -> Table:
     table = Table(
         Column("Баланс", style="cyan", justify="center"),
         Column("Размер армии", style="magenta", justify="center"),
         Column("Сила армии", style="green", justify="center"),
         title="github.com/monosans/vk-vbitve-bot v20220110",
     )
     table.add_row(*map(str, (self.balance, len(self.army), self.power)))
     return table
Beispiel #9
0
    def __rich__(self) -> Table:
        table = Table(
            Column("Option", justify="left", style="magenta"),
            Column("Value", justify="left", style="green"),
        )
        for section in self._config.sections():
            for key, value in self._config[section].items():
                table.add_row(f"{section}.{key}", value, end_section=True)

        return table
Beispiel #10
0
 def __rich__(self) -> Table:
     """Table that is used to display info about note in case of error"""
     table = Table(
         Column("Field", justify="left", style="magenta"),
         Column("Value", justify="left", style="green"),
         title="[bold]Basic Note[bold]",
     )
     table.add_row("Text", self.raw_text_md, end_section=True)
     table.add_row("Tags", ", ".join(self.tags), end_section=True)
     table.add_row("Deck", self.deck_name, end_section=True)
     return table
Beispiel #11
0
def create_progress():
    """Returns a Rich Progress class."""

    return Progress(
        SpinnerColumn(),
        TextColumn("[progress.description]{task.description}",
                   table_column=Column(ratio=1)),
        BarColumn(bar_width=None, table_column=Column(ratio=1)),
        TextColumn("[progress.percentage]{task.percentage:>3.0f}%"),
        CustomTimeElapsedColumn(),
        expand=True,
    )
 def __init__(self, host):
     """ Create progressbar instance """
     self.host = host
     desc = TextColumn("{task.description}", table_column=Column(ratio=1))
     progress = BarColumn(bar_width=None, table_column=Column(ratio=1))
     time_elapsed = TimeElapsedColumn(table_column=Column())
     self.progress = Progress(
         desc,
         progress,
         "[white][progress.percentage]{task.percentage:>3.0f}%",
         time_elapsed,
         expand=True,
     )
    def add_row(
        self,
        *renderables: T.Optional[RenderableType],
        style: T.Optional[StyleType] = None,
        end_section: bool = False,
    ) -> None:
        def add_cell(column: Column, renderable: RenderableType) -> None:
            column._cells.insert(0, renderable)

        cell_renderables: T.List[T.Optional[RenderableType]] = list(
            renderables)

        columns = self.columns
        if len(cell_renderables) < len(columns):
            cell_renderables = [
                *cell_renderables,
                *[None] * (len(columns) - len(cell_renderables)),
            ]
        for index, renderable in enumerate(cell_renderables):
            if index == len(columns):
                column = Column(_index=index)
                for _ in self.rows:
                    add_cell(column, T.Text(""))
                self.columns.append(column)
            else:
                column = columns[index]
            if renderable is None:
                add_cell(column, "")
            elif is_renderable(renderable):
                add_cell(column, renderable)
            else:
                raise NotRenderableError(
                    f"unable to render {type(renderable).__name__};"
                    "a string or other renderable object is required")
        self.rows.insert(0, Row(style=style, end_section=end_section))
Beispiel #14
0
    def draw_error_table(self):
        lErrsTable = Table.grid(Column('error_tables'))

        if self.parser.errors:
            t = self.draw_parsing_errors()
            t.title = "Dep tree parsing error(s)"
            t.title_style = 'bold red'
            t.title_justify = 'left'
            lErrsTable.add_row(t)

        if self.parser.unresolved:
            if self.parser.unresolved_packages:
                t = self.draw_unresolved_packages()
                t.title = "[bold red]Unresolved packages[/bold red]"
                lErrsTable.add_row(t)
            # ------
            lCNF = self.parser.unresolved_components
            if lCNF:
                t = self.draw_unresolved_components()
                t.title = "[bold red]Unresolved components[/bold red]"
                lErrsTable.add_row(t)

        if self.parser.unresolved_files:
            t = self.draw_unresolved_files()
            t.title = "Unresolved files"
            t.title_style = 'bold red'
            t.title_justify = 'left'
            lErrsTable.add_row(t)

        return lErrsTable
def main() -> None:
    """ Make a jazz noise here """

    args = get_args()
    table = Table('Name',
                  Column(header='Min. Len', justify='right'),
                  Column(header='Max. Len', justify='right'),
                  Column(header='Avg. Len', justify='right'),
                  Column(header='Num. Seqs', justify='right'),
                  header_style="bold black")

    for file in track([process(fh) for fh in args.file]):
        table.add_row(file.filename, str(file.min_len), str(file.max_len),
                      str(file.avg_len), str(file.num_seqs))

    Console().print(table)
Beispiel #16
0
def format_table(values: ResponseOrObjects):
    """Format model objects as a table. If ``rich`` isn't installed or the model doesn't have a
    table format defined, just return a basic list of stringified objects.
    """
    try:
        from rich.box import SIMPLE_HEAVY
        from rich.table import Column, Table

        if isinstance(values, Table):
            return values

        values = ensure_model_list(values)
        headers = {k: HEADER_COLORS.get(k, '') for k in values[0]._row.keys()}
    except (ImportError, NotImplementedError):
        return '\n'.join([str(obj) for obj in ensure_model_list(values)])

    # Display any date/datetime values in short format
    def _str(value):
        if isinstance(value, (date, datetime)):
            return value.strftime(DATETIME_SHORT_FORMAT)
        return str(value) if value is not None else ''

    columns = [
        Column(header, style=style) for header, style in headers.items()
    ]
    table = Table(*columns,
                  box=SIMPLE_HEAVY,
                  header_style='bold white',
                  row_styles=['dim', 'none'])

    for obj in values:
        table.add_row(*[_str(value) for value in obj._row.values()])
    return table
Beispiel #17
0
    def start_progress_bar(self, of=None):
        """
        Starts the progress bar for the current epoch.

        Args:
             of: The total number of batches in the epoch or None
                  if that is unknown.
        """
        if of is None:
            if self.n_batches_last is None:
                of = 0
            else:
                of = self.n_batches_last
        if self.progress is None:
            self.progress = Progress(
                TextColumn("Epoch {task.fields[epoch]}"),
                SpinnerColumn(),
                TextColumn(
                    "Batch {task.fields[batch]:3} / {task.fields[of]:3}"),
                BarColumn(),
                TimeElapsedColumn(table_column=Column(header="Elapsed")),
                TextColumn("/"),
                TimeRemainingColumn(table_column=Column(header="Remaining")),
                TextColumn("|"),
                TextColumn("[red]Loss: {task.fields[batch_loss]:1.3f}[red],"),
                TextColumn(
                    "[red][b]Avg.: {task.fields[running_mean]:1.3f}[/b][/red]"
                ),
                auto_refresh=False,
                transient=True,
            )
            fields = {
                "epoch": 1,
                "running_mean": np.nan,
                "batch_loss": np.nan,
                "of": of,
                "batch": 0,
            }
            self.task = self.progress.add_task(f"Epoch {self.i_epoch + 1}",
                                               total=of,
                                               **fields)
        self.progress.update(self.task,
                             completed=0,
                             total=of,
                             epoch=self.i_epoch + 1,
                             mode="training")
Beispiel #18
0
    def status_table(self):
        from rich.table import Table, Column
        from rich import box

        info = (
            self.machines,
            self.machines_live,
            self.machines_free,
            self.machines_known,
        )

        b, l, f, t = [sum(i.values()) for i in info]

        def pct(a, b, digits=0):
            return "%.*f" % (
                max(0, digits),
                round(100 * a / (b or 1), digits),
            )

        tab = Table(
            Column("Machine \\ CPUs", "Total"),
            Column("live %", pct(l, b), justify="right"),
            Column("live", str(l), justify="right"),
            Column("booked", str(b), justify="right"),
            Column("total", str(t), justify="right"),
            Column("free", str(f), justify="right"),
            Column("free %", pct(f, t), justify="right"),
            show_footer=True,
            box=box.SIMPLE,
        )
        for m in sorted(info[-1]):
            b, l, f, t = [i.get(m, 0) for i in info]
            tab.add_row(m, pct(l, b), str(l), str(b), str(t), str(f), pct(f, t))

        return tab
Beispiel #19
0
def test_init_append_column():
    header_names = ["header1", "header2", "header3"]
    test_columns = [
        Column(_index=index, header=header) for index, header in enumerate(header_names)
    ]

    # Test appending of strings for header names
    assert Table(*header_names).columns == test_columns
    # Test directly passing a Table Column objects
    assert Table(*test_columns).columns == test_columns
Beispiel #20
0
def status_bar():
    """
    Get progress bar to display overall progress.
    """
    progress_bar = Progress(
        TimeElapsedColumn(Column(min_width=7, no_wrap=True)),
        TextColumn(
            "{task.completed} out of {task.total} easyconfigs done{task.description}"
        ),
    )

    return progress_bar
 def setup_info_table() -> None:
     nonlocal infos_table
     infos_table = ReversedTable(
         Column("Time", style="dim"),
         "Type",
         "Origin",
         title="Events",
         expand=True,
         show_header=True,
         header_style="bold white",
     )
     layout["info"].update(infos_table)
Beispiel #22
0
def menu_output(menu):
    from rich.table import Table, Column
    from rich.box import SIMPLE

    tb = Table(
        *[
            Column('Parameter', justify='full', style='bold yellow'),
            Column('Description', justify='right', style='bold cyan')
        ],
        show_edge=False,
        show_header=False,
        row_styles=['none', 'dim'],
        box=SIMPLE,
        pad_edge=False,
        title=f'[bold underline] {menu["title"]}[dim]Author: RhythmLian\n')
    for line in menu['lines']:
        tb.add_row((menu['prefix'] + ' ' if line[0].startswith('-') else '') +
                   line[0], line[1])
    QproDefaultConsole.print(tb, justify='center')
    QproDefaultConsole.print(
        '\nDOC: https://rhythmlian.cn/2020/02/14/QuickProject/',
        justify='center')
Beispiel #23
0
    def run(self, args):

        table = Table(
            Column(header="Name", ratio=0.2),
            Column(header="Description", no_wrap=True, ratio=0.8),
            title="Results",
            box=box.MINIMAL_DOUBLE_HEAD,
            expand=True,
        )

        for module in pwncat.modules.match(f"*{args.module}*"):
            # Rich will ellipsize the column, but we need to squeze
            # white space and remove newlines. `textwrap.shorten` is
            # the easiest way to do that, so we use a large size for
            # width.
            description = module.__doc__ if module.__doc__ is not None else ""
            table.add_row(
                f"[cyan]{module.name}[/cyan]",
                textwrap.shorten(description.replace("\n", " "),
                                 width=200,
                                 placeholder="..."),
            )

        console.print(table)
Beispiel #24
0
 def __get_table(self):
     tab = Table(
         Column(justify='right', no_wrap=True),
         title="Nonogram game",
         caption="[link=https://github.com/rafaelurben/python-nonogram]python-nonogram[/link] by "
                 "[link=https://github.com/rafaelurben]rafaelurben[/link]",
     )
     for col in range(self.width):
         tab.add_column(
             "\n".join(map(str, self.yinfo[col])),
             justify='center'
         )
     for row in range(self.height):
         tab.add_row(
             " ".join(map(str, self.xinfo[row])),
             *map(_cell, self.rows[row])
         )
     return tab
Beispiel #25
0
def _calendar_print(tasks: List[Tuple[Arrow, TaskDB]], date: Arrow) -> None:
    cols = [Column(f"{d}", justify="left") for d in weekdays]
    table = Table(*cols, title=date.format("MMMM"), box=box.MINIMAL, show_lines=True)
    today = (
        lambda d: "bold yellow"
        if d.isocalendar() == date.isocalendar()
        else "white"
        if d.month == date.month
        else "bright_black"
    )
    format = lambda date, db: Text("\n").join(
        [Text(f"{date.day}          ", style=today(date)), format_tdb(db, False, False)]
    )
    days = [format(date, db) for date, db in tasks]
    weeks = [days[i : i + 7] for i in range(0, len(days), 7)]
    for w in weeks:
        table.add_row(*w)
    print(table)
Beispiel #26
0
def format_taxa(results, verbose: bool = False) -> Table:
    """Format taxon autocomplete results into a table"""
    table = Table(
        Column('#', style='bold white'),
        'Rank',
        'Name',
        'Common name',
        box=SIMPLE_HEAVY,
        header_style='bold cyan',
    )
    if verbose:
        table.add_column('Matched term')
        table.add_column('ID')

    for i, t in enumerate(results):
        icon = ICONIC_EMOJI.get(t['iconic_taxon_id'], ' ')
        row = [str(i), t['rank'], f'{icon} {t["name"]}', t.get('preferred_common_name')]
        if verbose:
            row += [t['matched_term'], str(t['id'])]
        table.add_row(*row)

    return table
    def _print_results(results: List[_OUT_DICT], stage: str) -> None:
        # remove the dl idx suffix
        results = [{k.split("/dataloader_idx_")[0]: v for k, v in result.items()} for result in results]
        metrics_paths = {k for keys in apply_to_collection(results, dict, EvaluationLoop._get_keys) for k in keys}
        if not metrics_paths:
            return

        metrics_strs = [":".join(metric) for metric in metrics_paths]
        # sort both lists based on metrics_strs
        metrics_strs, metrics_paths = zip(*sorted(zip(metrics_strs, metrics_paths)))

        headers = [f"DataLoader {i}" for i in range(len(results))]

        # fallback is useful for testing of printed output
        term_size = shutil.get_terminal_size(fallback=(120, 30)).columns or 120
        max_length = int(min(max(len(max(metrics_strs, key=len)), len(max(headers, key=len)), 25), term_size / 2))

        rows: List[List[Any]] = [[] for _ in metrics_paths]

        for result in results:
            for metric, row in zip(metrics_paths, rows):
                val = EvaluationLoop._find_value(result, metric)
                if val is not None:
                    if isinstance(val, torch.Tensor):
                        val = val.item() if val.numel() == 1 else val.tolist()
                    row.append(f"{val}")
                else:
                    row.append(" ")

        # keep one column with max length for metrics
        num_cols = int((term_size - max_length) / max_length)

        for i in range(0, len(headers), num_cols):
            table_headers = headers[i : (i + num_cols)]
            table_rows = [row[i : (i + num_cols)] for row in rows]

            table_headers.insert(0, f"{stage} Metric".capitalize())

            if _RICH_AVAILABLE:
                columns = [Column(h, justify="center", style="magenta", width=max_length) for h in table_headers]
                columns[0].style = "cyan"

                table = Table(*columns)
                for metric, row in zip(metrics_strs, table_rows):
                    row.insert(0, metric)
                    table.add_row(*row)

                console = get_console()
                console.print(table)
            else:
                row_format = f"{{:^{max_length}}}" * len(table_headers)
                half_term_size = int(term_size / 2)

                try:
                    # some terminals do not support this character
                    if sys.stdout.encoding is not None:
                        "─".encode(sys.stdout.encoding)
                except UnicodeEncodeError:
                    bar_character = "-"
                else:
                    bar_character = "─"
                bar = bar_character * term_size

                lines = [bar, row_format.format(*table_headers).rstrip(), bar]
                for metric, row in zip(metrics_strs, table_rows):
                    # deal with column overflow
                    if len(metric) > half_term_size:
                        while len(metric) > half_term_size:
                            row_metric = metric[:half_term_size]
                            metric = metric[half_term_size:]
                            lines.append(row_format.format(row_metric, *row).rstrip())
                        lines.append(row_format.format(metric, " ").rstrip())
                    else:
                        lines.append(row_format.format(metric, *row).rstrip())
                lines.append(bar)
                print(os.linesep.join(lines))
Beispiel #28
0
    def print(
        self,
        output: str,
        current_title: str | None = None,
        current_album: str | None = None,
        current_artist: str | None = None,
        shuffle: bool = False,
        interleave: bool = False,
        file: IO | None = None,
    ) -> None:
        musics = self.musics
        if interleave:
            musics_by_artist = PrettyDefaultDict(list)
            for music in self.musics:
                musics_by_artist[music.artist].append(music)
            musics = list(
                itertools.chain(*itertools.zip_longest(
                    *musics_by_artist.values())))

        if shuffle:
            random.shuffle(musics)

        table = Table(
            Column("T/N", vertical="middle", justify="center", no_wrap=True),
            Column("Artist/Album/Title/Genre", vertical="middle",
                   no_wrap=True),
            Column("Rating", vertical="middle", justify="center",
                   no_wrap=True),
            Column("Keywords", vertical="middle"),
            Column("Links", no_wrap=True),
            Column("Infos", vertical="middle", no_wrap=True),
            show_lines=True,
        )
        links = []
        total_length = 0
        total_size = 0
        for music in musics:
            infos = formatted_seconds_to_human(music.length)
            infos += "\n"
            infos += bytes_to_human(music.size)
            raw_row: list[str] = [
                str(music.track),
                '\n'.join(
                    [music.title, music.artist, music.album, music.genre]),
                str(music.rating),
                '\n'.join(sorted(music.keywords)),
                '\n'.join(sorted(music.links)),
                infos,
            ]
            if music.title == current_title and music.album == current_album and music.artist == current_artist:
                colored_row = [Text(elem, style="green") for elem in raw_row]
                table.add_row(*colored_row)
            else:
                table.add_row(*raw_row)

            for link in music.links:
                links.append(link)

            total_length += music.length
            total_size += music.size

        if not musics and output != 'json':
            return

        if output == 'm3u':
            p = '#EXTM3U\n'
            p += '\n'.join(links)
            print(p, file=file)
        elif output == 'table':
            self.print_table(table, file=file)
        elif output == 'json':
            self.print_json([asdict(music) for music in self.musics],
                            file=file)
        else:
            self.err(f"unknown output type : {output}")
        self.success(
            f"Total length: {precise_seconds_to_human(total_length)} | Total size: {bytes_to_human(total_size)}"
        )
Beispiel #29
0
def show_entries_internal(tpm, console, tags, all, full_dates, started=False):
    total = 0
    open = 0

    entries = tpm.fetch_entries(tags, None)
    features = active_plugins[0].fetch_features(tpm.config)

    buckets = {}

    for e in entries:
        total += 1

        if not all and not e.open:
            continue

        if started and not e.state == 'doing':
            continue

        if e.open:
            open += 1

        bt = 'misc'
        for t in list(e.tags):
            if t in features:
                e.tags.remove(t)
                bt = t
                break

        if bt in buckets:
            buckets[bt].append(e)
        else:
            buckets[bt] = [e]

    now = datetime.now().strftime('%Y-%m-%d %H:%M')

    console.print(
        '[white][bold]{}[/bold]/{}[/white] issues [dim]| {} | teenypm v{}'.
        format(open, total, now, __version__),
        highlight=False)

    table = Table("id",
                  "tags",
                  Column("msg", style="msg"),
                  Column("dates", justify='right'),
                  "points",
                  show_header=False,
                  show_edge=False,
                  box=box.SIMPLE,
                  padding=[0, 0, 0, 1])

    for b in buckets:
        bstyle = 'bucket.done'
        for e in buckets[b]:
            if e.open:
                bstyle = 'bucket.open'
                break

        table.add_row('{} ({})'.format(b, len(buckets[b])),
                      None,
                      None,
                      None,
                      None,
                      style=bstyle)

        for e in buckets[b]:
            row_style = None

            if all and not e.open:
                row_style = Style(dim=True)
                dates = 'closed {}'.format(display_date(e.done, full_dates))

            elif e.state == 'doing':
                row_style = 'state.doing'
                now = datetime.now()
                if e.deadline:
                    if now > e.deadline:
                        dates = '[date.overdue]due {}'.format(
                            display_date(e.deadline, full_dates))
                    else:
                        dates = '[date.soon]{}'.format(
                            display_date(e.deadline, full_dates))
                else:
                    dates = '[date.created]{}'.format('{}'.format(
                        display_date(e.created, full_dates)))

            else:
                dates = '[date.created]{}'.format('{}'.format(
                    display_date(e.created, full_dates)))

            tags = [
                '[tag.default]{}[/]'.format(t)
                if t != 'bug' or e.deadline else '[tag.bug]bug[/]'
                for t in sorted(e.tags)
            ]
            display_tags = ','.join(tags)

            msg = e.summary()
            if e.points > 1:
                points = '[points]{}[/]'.format(str(points))
            else:
                points = ''

            table.add_row(e.displayid(),
                          display_tags,
                          e.summary(),
                          dates,
                          points,
                          style=row_style)

    console.print(table)
    def _print_results(results: List[_OUT_DICT], stage: str, file: Optional[IO[str]] = None) -> None:
        # remove the dl idx suffix
        results = [{k.split("/dataloader_idx_")[0]: v for k, v in result.items()} for result in results]
        metrics = sorted({k for keys in apply_to_collection(results, dict, EvaluationLoop._get_keys) for k in keys})
        if not metrics:
            return
        headers = [f"DataLoader {i}" for i in range(len(results))]

        # fallback is useful for testing of printed output
        term_size = shutil.get_terminal_size(fallback=(120, 30)).columns or 120
        max_length = int(min(max(len(max(metrics + headers, key=len)), 25), term_size / 2))

        rows: List[List[Any]] = [[] for _ in metrics]

        for result in results:
            for metric, row in zip(metrics, rows):
                v = list(EvaluationLoop._find_value(result, metric))
                if v:
                    val = v[0]
                    if isinstance(val, torch.Tensor):
                        val = val.item() if val.numel() == 1 else val.tolist()
                    row.append(f"{val}")
                else:
                    row.append(" ")

        # keep one column with max length for metrics
        num_cols = int((term_size - max_length) / max_length)

        for i in range(0, len(headers), num_cols):
            table_headers = headers[i : (i + num_cols)]
            table_rows = [row[i : (i + num_cols)] for row in rows]

            table_headers.insert(0, f"{stage} Metric".capitalize())

            if _RICH_AVAILABLE:
                console = Console(file=file)

                columns = [Column(h, justify="center", style="magenta", width=max_length) for h in table_headers]
                columns[0].style = "cyan"

                table = Table(*columns)
                for metric, row in zip(metrics, table_rows):
                    row.insert(0, metric)
                    table.add_row(*row)
                console.print(table)
            else:
                row_format = f"{{:^{max_length}}}" * len(table_headers)
                half_term_size = int(term_size / 2)

                bar = "─" * term_size
                lines = [bar, row_format.format(*table_headers).rstrip(), bar]
                for metric, row in zip(metrics, table_rows):
                    # deal with column overflow
                    if len(metric) > half_term_size:
                        while len(metric) > half_term_size:
                            row_metric = metric[:half_term_size]
                            metric = metric[half_term_size:]
                            lines.append(row_format.format(row_metric, *row).rstrip())
                        lines.append(row_format.format(metric, " ").rstrip())
                    else:
                        lines.append(row_format.format(metric, *row).rstrip())
                lines.append(bar)
                print(os.linesep.join(lines), file=file)