#!/usr/bin/python # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import bisect import curses import errno import fcntl import re import select import signal import string import struct import sys TIOCGWINSZ = 0x5413 screen_width = screen_height = -1 def screen_size(): global screen_width, screen_height res = fcntl.ioctl(2, TIOCGWINSZ, "\0" * 4) screen_height, screen_width = struct.unpack("hh", res) return screen_height, screen_width number = re.compile("([0-9.]+(?:[GKkM]i?)?)") def human_key(s): r = [] parts = number.split(s) for p in parts: if p and p[0] in "0123456789.": if p.endswith("Gi"): p = -float(p[:-2]) * 1024 ** 3 elif p.endswith("G"): p = -float(p[:-1]) * 1000 ** 3 elif p.endswith("Mi"): p = -float(p[:-2]) * 1024 ** 2 elif p.endswith("M"): p = -float(p[:-1]) * 1000 ** 2 elif p.endswith("ki"): p = -float(p[:-2]) * 1024 ** 1 elif p.endswith("k"): p = -float(p[:-1]) * 1000 ** 1 elif p.endswith("Ki"): p = -float(p[:-2]) * 1024 ** 1 elif p.endswith("K"): p = -float(p[:-1]) * 1000 ** 1 # everyone who writes '10mB' means '10MB', so cater to them elif p.endswith("mi"): p = -float(p[:-2]) * 1024 ** 2 elif p.endswith("m"): p = -float(p[:-1]) * 1000 ** 2 else: try: p = -float(p) except ValueError: pass r.append(p) return r force_update = False def update_screen_size(signal, frame): global force_update force_update = True screen_size() signal.signal(signal.SIGWINCH, update_screen_size) curses.setupterm() ti_el = curses.tigetstr('el') ti_ed = curses.tigetstr('ed') ti_ho = curses.tigetstr('ho') if not ti_ho: ti_cup = curses.tigetstr('cup') ti_ho = curses.tparm(ti_cup, 0, 0) bol = '\r' screen_size() top = [] while 1: otop = top[:screen_height] try: line = sys.stdin.readline() if not line: break key = human_key(line.split(None, 1)[0]) bisect.insort(top, (key, line)) except IOError, e: if e == errno.EINTR: pass ntop = top[:screen_height] if otop != ntop or force_update: force_update = False sys.stdout.write(ti_ho) for i, (key, line) in enumerate(ntop): if i: sys.stdout.write('\n') line = line.rstrip() line = string.expandtabs(line)[:screen_width] sys.stdout.write(line) if len(line) != screen_width: sys.stdout.write(ti_el) sys.stdout.write(ti_ed) sys.stdout.flush() sys.stdout.write(bol + ti_el)