Merge lp:~chad.smith/apport/add-multichar-response-for-long-lists into lp:apport

Proposed by Chad Smith on 2017-10-24
Status: Merged
Merged at revision: 3168
Proposed branch: lp:~chad.smith/apport/add-multichar-response-for-long-lists
Merge into: lp:apport
Diff against target: 60 lines (+23/-7)
1 file modified
bin/apport-cli (+23/-7)
To merge this branch: bzr merge lp:~chad.smith/apport/add-multichar-response-for-long-lists
Reviewer Review Type Date Requested Status
Scott Moser (community) Approve on 2017-10-24
Apport upstream developers 2017-10-24 Pending
Review via email: mp+332729@code.launchpad.net

Description of the change

In cloud-init we have apport cli prompts what cloud are you on. Since there are two character responses required for options >= 10 we can't have apport limit the response to a single character.

This branch fixes lp: #1722564 by forcing apport to readline instead of read(1) for a given prompt if that prompt is > 10 choices (1-9 + the letter C (cancel)).

To post a comment you must log in.
Scott Moser (smoser) wrote :

This approach seems sane to me.

It preserves the old behavior of 1 character input for the vast majority of users.
In cases where there is > 10 choices, the user has to hit Enter, which is quite a common behavior.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/apport-cli'
2--- bin/apport-cli 2016-12-10 11:28:27 +0000
3+++ bin/apport-cli 2017-10-24 16:35:43 +0000
4@@ -34,8 +34,12 @@
5 self.buttons = []
6 self.visible = False
7
8- def raw_input_char(self, prompt):
9- '''raw_input, but read only one character'''
10+ def raw_input_char(self, prompt, multi_char=False):
11+ '''raw_input, but read a single character unless multi_char is True.
12+
13+ @param: prompt: the text presented to the user to solict a response.
14+ @param: multi_char: Boolean True if we need to read until <enter>.
15+ '''
16
17 sys.stdout.write(prompt)
18 sys.stdout.write(' ')
19@@ -48,14 +52,16 @@
20 attributes[6][termios.VMIN] = 1
21 attributes[6][termios.VTIME] = 0
22 termios.tcsetattr(file, termios.TCSANOW, attributes)
23-
24 try:
25- ch = str(sys.stdin.read(1))
26+ if multi_char:
27+ response = str(sys.stdin.readline()).strip()
28+ else:
29+ response = str(sys.stdin.read(1))
30 finally:
31 termios.tcsetattr(file, termios.TCSANOW, saved_attributes)
32
33 sys.stdout.write('\n')
34- return ch
35+ return response
36
37 def show(self):
38 self.visible = True
39@@ -82,9 +88,19 @@
40 for index, button in enumerate(self.buttons):
41 print(' %s: %s' % (self.keys[index], button))
42
43- response = self.raw_input_char(_('Please choose (%s):') % ('/'.join(self.keys)))
44+ if len(self.keys) <= 10:
45+ # A 10 option prompt would can still be a single character
46+ # response because the 10 options listed will be 1-9 and C.
47+ # Therefore there are 10 unique responses which can be
48+ # given.
49+ multi_char = False
50+ else:
51+ multi_char = True
52+ response = self.raw_input_char(
53+ _('Please choose (%s):') % ('/'.join(self.keys)),
54+ multi_char)
55 try:
56- return self.keys.index(response[0].upper()) + 1
57+ return self.keys.index(response.upper()) + 1
58 except ValueError:
59 pass
60 except KeyboardInterrupt:

Subscribers

People subscribed via source and target branches