| # Copyright 1999-2016 Gentoo Foundation |
| # Distributed under the terms of the GNU General Public License v2 |
| |
| from __future__ import print_function, unicode_literals |
| |
| import signal |
| import sys |
| |
| from portage import _unicode_decode |
| from portage.output import bold, create_color_func |
| |
| |
| class UserQuery(object): |
| """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: |
| if sys.hexversion >= 0x3000000: |
| 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') |
| else: |
| response=raw_input("["+"/".join([colours[i](responses[i]) |
| for i in range(len(responses))])+"] ") |
| response = _unicode_decode(response) |
| 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) |