diff options
| author | Scott Gasch <[email protected]> | 2021-03-24 18:08:54 -0700 |
|---|---|---|
| committer | Scott Gasch <[email protected]> | 2021-03-24 18:08:54 -0700 |
| commit | 497fb9e21f45ec08e1486abaee6dfa7b20b8a691 (patch) | |
| tree | 47aa97a0fca36c4e7025cee5ad4e9ec6db49b881 /input_utils.py | |
Initial revision
Diffstat (limited to 'input_utils.py')
| -rw-r--r-- | input_utils.py | 74 |
1 files changed, 74 insertions, 0 deletions
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(")") |
