Skip to content

Instantly share code, notes, and snippets.

@sfuller
Created July 6, 2016 06:26
Show Gist options
  • Save sfuller/a6c29b405d0a289aee2a9faffe015d99 to your computer and use it in GitHub Desktop.
Save sfuller/a6c29b405d0a289aee2a9faffe015d99 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
import threading
import sys
import time
class Getch:
"""Gets a single character from standard input. Does not echo to the
screen."""
def __init__(self):
try:
self.impl = _GetchWindows()
except ImportError:
self.impl = _GetchUnix()
def __enter__(self):
return self.impl.__enter__()
def __exit__(self, *args):
self.impl.__exit__(*args)
class _GetchUnix:
def __init__(self):
import termios
self.fd = sys.stdin.fileno()
self.old_settings = termios.tcgetattr(self.fd)
self.__enter__()
def __enter__(self):
import tty, sys, termios
tty.setraw(sys.stdin.fileno())
return self
def __exit__(self, *args):
import termios
termios.tcsetattr(self.fd, termios.TCSADRAIN, self.old_settings)
def __call__(self):
return sys.stdin.read(1)
class _GetchWindows:
def __init__(self):
import msvcrt
def __enter__self():
pass
def __call__(self):
import msvcrt
return msvcrt.getch()
def __exit__(self, *args):
pass
class SpinnerThread(threading.Thread):
def __init__(self, *args, **kwargs):
super(SpinnerThread, self).__init__(*args, **kwargs)
self.daemon = True
def run(self):
print('hi')
while True:
sys.stdout.write('.')
sys.stdout.flush()
time.sleep(1)
sys.stdout.write('.')
sys.stdout.flush()
time.sleep(1)
sys.stdout.write('.')
sys.stdout.flush()
time.sleep(1)
sys.stdout.write('\033[2K\r')
sys.stdout.flush()
time.sleep(1)
class InputThread(threading.Thread):
def __init__(self, main_cv, getch, *args, **kwargs):
super(InputThread, self).__init__(*args, **kwargs)
self.main_cv = main_cv
self.getch = getch
self.daemon = True
self.should_quit = False
def run(self):
while True:
ch = None
with self.getch as getch:
ch = getch()
if ch == '\03':
self.should_quit = True
self.main_cv.acquire()
self.main_cv.notify_all()
self.main_cv.release()
sys.stdout.write('@')
sys.stdout.flush()
def main():
getch = Getch()
cv = threading.Condition()
spinner_thread = SpinnerThread()
spinner_thread.start()
input_thread = InputThread(cv, getch)
input_thread.start()
running = True
while running:
cv.acquire()
cv.wait()
if input_thread.should_quit:
running = False
cv.release()
getch.__exit__()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment