Skip to content

Instantly share code, notes, and snippets.

@tos-kamiya
Last active August 28, 2015 10:40
Show Gist options
  • Save tos-kamiya/a13107b71d3f1677fe84 to your computer and use it in GitHub Desktop.
Save tos-kamiya/a13107b71d3f1677fe84 to your computer and use it in GitHub Desktop.
Spinner in terminal
# coding: utf-8
import sys
import time
import threading
import Queue
import contextlib
ANIMATION = '|/-\\'
class TerminalSpinner(threading.Thread):
def __init__(self):
super(TerminalSpinner, self).__init__()
self.exit_requested = False
self.message_que = Queue.Queue()
self.animation = ANIMATION
self._spin_count = 0
self._showing_spinner = ''
def _hide_spinner(self):
w = len(self._showing_spinner)
e = '\b' * w + ' ' * w + '\b' * w
sys.stderr.write(e)
self._showing_spinner = ''
def _show_spinner(self, increment=False):
if increment:
self._spin_count += 1
self._spin_count %= len(self.animation)
self._showing_spinner = self.animation[self._spin_count]
sys.stderr.write(self._showing_spinner)
def _flush_queued_messages(self):
buf = []
try:
while True:
m = self.message_que.get_nowait()
buf.append(m)
except Queue.Empty:
pass
if buf:
sys.stderr.write(''.join(buf))
def run(self):
self._flush_queued_messages()
self._show_spinner()
try:
while not self.exit_requested:
time.sleep(0.1)
self._hide_spinner()
self._flush_queued_messages()
self._show_spinner(True)
finally:
self._hide_spinner()
self._flush_queued_messages()
def write(self, message):
self.message_que.put(message)
if self.exit_requested:
self._flush_queued_messages()
def join(self):
self.exit_requested = True
super(TerminalSpinner, self).join()
@contextlib.contextmanager
def terminal_spinner():
s = TerminalSpinner()
s.start()
try:
yield s
finally:
s.join()
if __name__ == '__main__':
s = TerminalSpinner()
s.animation = '(^_^),( ^_),( ^),( ),(^ ),(_^ )'.split(',')
s.write("> doing 1st task ")
s.start()
time.sleep(1)
s.write("then 2nd task ")
time.sleep(1)
s.join()
s.write("... done.\n")
with terminal_spinner() as a:
a.write("> another spinner starts")
time.sleep(1)
a.write("\n> and messages are shown")
time.sleep(1)
a.write("\n> like this.\n")
# Author: Toshihioro Kamiya
# License: Public Domain
# Programming Language: Pyhon 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment