aboutsummaryrefslogtreecommitdiff
blob: e20bbc6c3ab38518e94f1ab7922e5aeb5d8b29b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# 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)