From 497fb9e21f45ec08e1486abaee6dfa7b20b8a691 Mon Sep 17 00:00:00 2001 From: Scott Gasch Date: Wed, 24 Mar 2021 18:08:54 -0700 Subject: Initial revision --- input_utils.py | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 input_utils.py (limited to 'input_utils.py') diff --git a/input_utils.py b/input_utils.py new file mode 100644 index 0000000..913146a --- /dev/null +++ b/input_utils.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 + +"""Utilities related to user input.""" + +import readchar # type: ignore +import signal +import sys +from typing import List + + +def single_keystroke_response( + valid_responses: List[str], + *, + prompt: str = None, + default_response: str = None, + timeout_seconds: int = None, +) -> str: + class TimeoutError(Exception): + pass + + def _handle_timeout(signum, frame) -> None: + raise TimeoutError() + + def _single_keystroke_response_internal( + valid_responses: List[str], timeout_seconds=None + ) -> str: + if timeout_seconds is not None: + signal.signal(signal.SIGALRM, _handle_timeout) + signal.alarm(timeout_seconds) + + try: + while True: + response = readchar.readchar() + if response in valid_responses: + break + return response + finally: + if timeout_seconds is not None: + signal.alarm(0) + + if prompt is not None: + print(prompt, end="") + sys.stdout.flush() + try: + response = _single_keystroke_response_internal( + valid_responses, timeout_seconds + ) + except TimeoutError: + if default_response is not None: + response = default_response + if prompt is not None: + print(response) + return response + + +def yn_response(prompt: str = None, *, timeout_seconds=None) -> str: + return single_keystroke_response( + ["y", "n", "Y", "N"], prompt=prompt, timeout_seconds=timeout_seconds + ).lower() + + +def keystroke_helper() -> None: + print("Watching for keystrokes; ^C to quit.") + while True: + key = readchar.readkey() + if len(key) == 1: + print(f'That was "{key}" ({ord(key)}).') + if ord(key) == 3: + return + else: + print(f'That was sequence "{key}" (', end="") + for _ in key: + print(f" {ord(_)} ", end="") + print(")") -- cgit v1.3