|
Server : Apache System : Linux ecngx264.inmotionhosting.com 4.18.0-553.77.1.lve.el8.x86_64 #1 SMP Wed Oct 8 14:21:00 UTC 2025 x86_64 User : lonias5 ( 3576) PHP Version : 7.3.33 Disable Function : NONE Directory : /proc/self/root/proc/thread-self/root/opt/saltstack/salt/extras-3.10/rads/ |
Upload File : |
"""Functions for obtaining CLI input"""
import termios
import signal
import sys
import os
from typing import Union
from . import color
def get_keypress() -> str:
"""Get a single keypress, the ugly POSIX way"""
fileno = sys.stdin.fileno()
old = termios.tcgetattr(fileno)
new = termios.tcgetattr(fileno)
new[3] = new[3] & ~termios.ICANON & ~termios.ECHO
new[6][termios.VMIN] = 1
new[6][termios.VTIME] = 0
termios.tcsetattr(fileno, termios.TCSANOW, new)
key = None
try:
key = str(os.read(fileno, 4), 'ascii')
finally:
termios.tcsetattr(fileno, termios.TCSAFLUSH, old)
keylist = {
'\t': 'TAB',
'\n': 'ENTER',
'\x7f': 'BACKSPACE',
'\x1b': 'ESC',
'\x1b[Z': 'BACKTAB',
'\x1bOH': 'HOME',
'\x1bOP': 'F1',
'\x1bOQ': 'F2',
'\x1bOR': 'F3',
'\x1bOS': 'F4',
'\x1b[15': 'F5',
'\x1b[17': 'F6',
'\x1b[18': 'F7',
'\x1b[19': 'F8',
'\x1b[20': 'F9',
'\x1b[21': 'F10',
'\x1b[23': 'F11',
'\x1b[24': 'F12',
'\x1b[A': 'ARROW_UP',
'\x1b[B': 'ARROW_DN',
'\x1b[C': 'ARROW_RT',
'\x1b[D': 'ARROW_LT',
}
return key if key not in keylist else keylist[key]
get_keypress.__module__ = 'rads'
def _prompt_timeout(signum, _frame):
raise TimeoutError("Prompt timed out")
def prompt_y_n(
question: str,
*,
timeout: Union[int, None] = 604800,
sigint_exit: bool = True,
) -> bool:
"""Prompt for a yes or no answer
Args:
question: text to display before [y/n] prompt
timeout: time in seconds after which to raise TimeoutError. Defaults
to one week
sigint_exit: Whether to sys.exit(1) on ctrl+c; Defaults True.
Raises:
SystemExit: if SIGINT is received
KeyboardInterrupt: if sigint_exit=False and a sigint is received
TimeoutError: if timeout= is set and no response in that time
"""
valid = {"yes": True, "y": True, "no": False, "n": False}
while True:
print(question, '[y/n]')
try:
if timeout:
signal.signal(signal.SIGALRM, _prompt_timeout)
signal.alarm(timeout)
choice = input().lower()
if timeout:
signal.alarm(0) # disable the alarm
except KeyboardInterrupt:
if not sigint_exit:
raise
print("\nCancelled")
sys.exit(1)
if choice in valid:
return valid[choice]
print('Invalid answer. Try again:', color.bold('[y/n]'))
prompt_y_n.__module__ = 'rads'