ttystatus is a Python library for showing progress reporting and status updates on terminals, for (Unix) command line programs. Output is automatically adapted to the width of the terminal: truncated if it does not fit, and re-sized if the terminal size changes.
Output is provided via widgets. Each widgets formats some data into a suitable form for output. It gets the data either via its initializer, or from key/value pairs maintained by the master object. The values are set by the user. Every time a value is updated, widgets get updated (although the terminal is only updated every so often to give user time to actually read the output).
Here’s an example program that searches for symlinks in a directory tree:
import os
import sys
import ttystatus
ts = ttystatus.TerminalStatus(period=0.1)
ts.format('%ElapsedTime() Looking for files: %Counter(pathname) found, '
'currently in %Pathname(dirname)')
pathnames = []
for dirname, subdirs, basenames in os.walk(sys.argv[1]):
ts['dirname'] = dirname
for basename in basenames:
pathname = os.path.join(dirname, basename)
ts['pathname'] = pathname
pathnames.append(pathname)
ts.clear()
ts.add(ttystatus.ElapsedTime())
ts.add(ttystatus.Literal(' Finding symlinks: '))
ts.add(ttystatus.Counter('symlink'))
ts.add(ttystatus.Literal(' found; now at '))
ts.add(ttystatus.Index('pathname', 'pathnames'))
ts.add(ttystatus.Literal(' ('))
ts.add(ttystatus.PercentDone('done', 'total', decimals=2))
ts.add(ttystatus.Literal(' done) '))
ts.add(ttystatus.RemainingTime('done', 'total'))
ts.add(ttystatus.Literal(' '))
ts.add(ttystatus.ProgressBar('done', 'total'))
ts['pathnames'] = pathnames
ts['done'] = 0
ts['total'] = len(pathnames)
for pathname in pathnames:
ts['pathname'] = pathname
if os.path.islink(pathname):
ts['symlink'] = pathname
ts.notify('Symlink! %s' % pathname)
ts['done'] += 1
ts.finish()
(See also the file example.py in the source distribution.)
Display the position of a value in a list of values.
Display data size in bytes, KiB, etc.
Wrapper around time.time for unit tests to overrride.
Parse format string.
Display a progress bar.
Base class for ttystatus widgets.
Widgets display stuff on screen. The value may depend on data provided by the user (at creation time), or may be computed from one or more values in the TerminalStatus object to which the widget object belongs.
There are two steps:
Widgets may have a static size, or their size may vary. The static_width property reveals this. This affects rendering: static sized widgets are rendered at their one static size; variable sized widgets are shrunk, if necessary, to make everything fit into the available space. If it’s not possible to shrink enough, widgets are rendered from beginning until the space is full: variable sized widgets are rendered as small as possible in this case.
Format the current value.
width is the available width for the widget. It need not use all of it. If it’s not possible for the widget to render itself small enough to fit into the given width, it may return a larger string, but the caller will probably truncate it.
This will be called only when the value actually needs to be formatted.
React to changes in values stored in a TerminalStatus.
Display a value as a string.
Display data size in bytes, KiB, etc.
Display a value as an integer.
Display a count of how many times a value has changed.
Manages messages to the terminal.
This includes disabling messages, allowing notifications, and becalming the flow of messages to avoid writing too fast. The speed is a performance thing: writing too much message text can slow an application down a lot (too much work for terminal emulators), and doesn’t actually help the user in any way.
Remove currently displayed message from terminal, if any.
Disable all output except notifications.
Enable output to happen.
Finalize output.
Show a notification message string to the user.
Notifications are meant for error messages and other things that do not belong in, say, progress bars. Whatever is currently on the terminal is wiped, then the notification message is shown, a new line is started, and the old message is restored.
Notifications are written even when the output is not going to a terminal.
Is it time to write now?
Write message to terminal.
Message may be multiple lines.
Display elapsed time since widget was first updated.
Wrapper around time.time() for unit tests to override.
Display a pathname.
If it won’t fit completely, truncate from the beginning of the string.
Manage the area on the terminal for displaying messages.
Clear area reserved for message needing a given number of lines.
The cursor is assumed to be at the last line of the message area and is left at the top.
Display a message, which may be on multiple lines.
The cursor is assumed to be at the last line of the message area. Long lines are chopped at terminal width - 1.
Make space for a message needing a given number of lines.
If the cursor is near the bottom of the terminal, scroll things up so that there’s space. Otherwise, effectively nothing happens, except that the cursor is left at the last line reserved for the message.
Display percent of task done.
Handle interaction with the physical terminal.
Return width of terminal in characters.
If this fails, assume 80.
Borrowed and adapted from bzrlib.
Write raw data to terminal.
We ignore IOErrors for terminal output.
Show status and progress information on a terminal.
All output is provided via widgets of various kinds. Many widgets format data that TerminalStatus stores. TerminalStatus provides a dict interface for setting and retrieving data items. Unlike a real dict, getting a value for a key that has not been set does not result in a KeyError exception, but in the empty string being returned.
Add a new widget to the status display.
Remove all widgets.
Disable all output.
Enable output if it has been disabled.
Write an error message.
Finish status display.
Force an update of current state to the screen.
This happens even if it is not yet time to output the screen.
Add new widgets based on format string.
The format string is taken literally, except that %% is a literal percent character, and %Foo(a,b,c) is a widget of type Foo with parameters a, b, and c. For example: format("hello, %String(name)").
Like dict.get.
Increase value for a key by a given amount.
Show a message.
Start a new line of widgets.