Spinner: display activity

This was inspired by some code found in imapbackup. Sometimes you need to display activity on the text console to inform the user that the program is actually doing something.

That is the purpose of this small python class. The test() function shows the usage. Here’s what test() displays:
Spinner screencast

[download spinner.py]

# Licensed under the Python License (see http://www.python.org/psf/license/)
# Copyright (C) 2008 Pierre Duquesne <stackp@online.fr>
 
import sys
 
class Spinner:
    """A class to show a spinning ascii animation on a character terminal.
 
    It informs the user that some processing is being done.
    """
 
    def __init__(self, message=''):
        self.message = message
        self.symbols = list('-\|/')
        self.nsym = len(self.symbols)
        self.n = 0
 
    def spin(self):
        print '\r', self.message + self.symbols[self.n],
        sys.stdout.flush()
        self.n = (self.n + 1) % self.nsym
 
    def stop(self, stop_message=''):
        print '\r', self.message + stop_message
 
    def set_message(self, message):
        self.message = message
 
 
class DummySpinner:
    """A class that mock Spinner and do not spin.
 
    To be used when output is not a character terminal (e.g. a log file). 
    For example::
 
        if sys.stdout.isatty():
            s = Spinner()
        else:
            s = DummySpinner()
 
    """   
    def __init__(self, message=''):
        self.message = message
 
    def spin(self):
        pass
 
    def stop(self, stop_message=''):
        print self.message + stop_message
 
    def set_message(self, message):
        self.message = message
 
 
if __name__ == "__main__":
 
    import time
 
    def test():
        if sys.stdout.isatty():
            s = Spinner()
        else:
            s = DummySpinner()
 
        # simple usage
        for i in range(10):
            s.spin()
            time.sleep(0.1)
 
        s.set_message('Initialization ... ')
        for i in range(10):
            s.spin()
            time.sleep(0.1)
        s.stop('Done')
 
        s.set_message('Loading ... ')
        for i in range(10):
            s.spin()
            time.sleep(0.1)
        s.stop('Done')
 
    test()

Posted by pierre on 5 March 2008 in python

Leave a Reply

*