blob: 4dcb704fa958a15605ee8d13300d1d48458077fd [file] [log] [blame]
# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import signal
import sys
from portage import _unicode_decode
from portage.output import bold, create_color_func
class UserQuery:
"""The UserQuery class is used to prompt the user with a set of responses,
as well as accepting and handling the responses."""
def __init__(self, myopts):
self.myopts = myopts
def query(self, prompt, enter_invalid, responses=None, colours=None):
"""Display a prompt and a set of responses, then waits for user input
and check it against the responses. The first match is returned.
An empty response will match the first value in the list of responses,
unless enter_invalid is True. The input buffer is *not* cleared prior
to the prompt!
prompt: The String to display as a prompt.
responses: a List of Strings with the acceptable responses.
colours: a List of Functions taking and returning a String, used to
process the responses for display. Typically these will be functions
like red() but could be e.g. lambda x: "DisplayString".
If responses is omitted, it defaults to ["Yes", "No"], [green, red].
If only colours is omitted, it defaults to [bold, ...].
Returns a member of the List responses. (If called without optional
arguments, it returns "Yes" or "No".)
KeyboardInterrupt is converted to SystemExit to avoid tracebacks being
printed."""
if responses is None:
responses = ["Yes", "No"]
colours = [
create_color_func("PROMPT_CHOICE_DEFAULT"),
create_color_func("PROMPT_CHOICE_OTHER"),
]
elif colours is None:
colours = [bold]
colours = (colours * len(responses))[: len(responses)]
responses = [_unicode_decode(x) for x in responses]
if "--alert" in self.myopts:
prompt = "\a" + prompt
print(bold(prompt), end=" ")
try:
while True:
try:
response = input(
"[%s] "
% "/".join(
[colours[i](responses[i]) for i in range(len(responses))]
)
)
except UnicodeDecodeError as e:
response = _unicode_decode(e.object).rstrip("\n")
if response or not enter_invalid:
for key in responses:
# An empty response will match the
# first value in responses.
if response.upper() == key[: len(response)].upper():
return key
print("Sorry, response '%s' not understood." % response, end=" ")
except (EOFError, KeyboardInterrupt):
print("Interrupted.")
sys.exit(128 + signal.SIGINT)