From e4ecd1c0aa9c6bd3184fbcc474c8aebc013f2dc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fatih=20A=C5=9F=C4=B1c=C4=B1?= Date: Sat, 13 Mar 2010 22:22:52 +0000 Subject: [PATCH] util: Add utility functions to print a list of strings by columns --- pisi/util.py | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/pisi/util.py b/pisi/util.py index a25d1655..22a34d58 100644 --- a/pisi/util.py +++ b/pisi/util.py @@ -16,11 +16,14 @@ import os import sys -import hashlib +import fcntl import shutil import string +import struct import fnmatch +import hashlib import statvfs +import termios import operator import subprocess import unicodedata @@ -129,6 +132,62 @@ def human_readable_rate(size = 0): x = human_readable_size(size) return x[0], x[1] + '/s' +def format_by_columns(strings, sep_width=2): + longest_str_len = len(max(strings, key=len)) + term_rows, term_columns = get_terminal_size() + + def get_columns(max_count): + if longest_str_len > term_columns: + return [longest_str_len] + + columns = [] + for name in strings: + table_width = sum(columns) + len(name) + len(columns) * sep_width + if table_width > term_columns: + break + + columns.append(len(name)) + if len(columns) == max_count: + break + + return columns + + def check_size(columns): + total_sep_width = (len(columns) - 1) * sep_width + + for n, name in enumerate(strings): + col = n % len(columns) + if len(name) > columns[col]: + columns[col] = len(name) + + if len(columns) > 1: + width = sum(columns) + total_sep_width + if width > term_columns: + return False + + return True + + columns = get_columns(term_columns) + + while not check_size(columns): + columns = get_columns(len(columns) - 1) + + sep = " " * sep_width + lines = [] + current_line = [] + for n, name in enumerate(strings): + col = n % len(columns) + current_line.append(name.ljust(columns[col])) + + if col == len(columns) - 1: + lines.append(sep.join(current_line)) + current_line = [] + + if current_line: + lines.append(sep.join(current_line)) + + return "\n".join(lines) + ############################## # Process Releated Functions # ############################## @@ -182,6 +241,16 @@ def run_logged(cmd): # Terminal functions # ###################### +def get_terminal_size(): + try: + ret = fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ, "1234") + except IOError: + rows = int(os.environ.get("LINES", 25)) + cols = int(os.environ.get("COLUMNS", 80)) + return rows, cols + + return struct.unpack("hh", ret) + def xterm_title(message): """Set message as console window title.""" if os.environ.has_key("TERM") and sys.stderr.isatty():