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

Proposed by Chad Smith
Status: Merged
Merged at revision: 3168
Proposed branch: lp:~chad.smith/apport/add-multichar-response-for-long-lists
Merge into: lp:~apport-hackers/apport/trunk
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
Apport upstream developers 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.
Revision history for this message
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
=== modified file 'bin/apport-cli'
--- bin/apport-cli 2016-12-10 11:28:27 +0000
+++ bin/apport-cli 2017-10-24 16:35:43 +0000
@@ -34,8 +34,12 @@
34 self.buttons = []34 self.buttons = []
35 self.visible = False35 self.visible = False
3636
37 def raw_input_char(self, prompt):37 def raw_input_char(self, prompt, multi_char=False):
38 '''raw_input, but read only one character'''38 '''raw_input, but read a single character unless multi_char is True.
39
40 @param: prompt: the text presented to the user to solict a response.
41 @param: multi_char: Boolean True if we need to read until <enter>.
42 '''
3943
40 sys.stdout.write(prompt)44 sys.stdout.write(prompt)
41 sys.stdout.write(' ')45 sys.stdout.write(' ')
@@ -48,14 +52,16 @@
48 attributes[6][termios.VMIN] = 152 attributes[6][termios.VMIN] = 1
49 attributes[6][termios.VTIME] = 053 attributes[6][termios.VTIME] = 0
50 termios.tcsetattr(file, termios.TCSANOW, attributes)54 termios.tcsetattr(file, termios.TCSANOW, attributes)
51
52 try:55 try:
53 ch = str(sys.stdin.read(1))56 if multi_char:
57 response = str(sys.stdin.readline()).strip()
58 else:
59 response = str(sys.stdin.read(1))
54 finally:60 finally:
55 termios.tcsetattr(file, termios.TCSANOW, saved_attributes)61 termios.tcsetattr(file, termios.TCSANOW, saved_attributes)
5662
57 sys.stdout.write('\n')63 sys.stdout.write('\n')
58 return ch64 return response
5965
60 def show(self):66 def show(self):
61 self.visible = True67 self.visible = True
@@ -82,9 +88,19 @@
82 for index, button in enumerate(self.buttons):88 for index, button in enumerate(self.buttons):
83 print(' %s: %s' % (self.keys[index], button))89 print(' %s: %s' % (self.keys[index], button))
8490
85 response = self.raw_input_char(_('Please choose (%s):') % ('/'.join(self.keys)))91 if len(self.keys) <= 10:
92 # A 10 option prompt would can still be a single character
93 # response because the 10 options listed will be 1-9 and C.
94 # Therefore there are 10 unique responses which can be
95 # given.
96 multi_char = False
97 else:
98 multi_char = True
99 response = self.raw_input_char(
100 _('Please choose (%s):') % ('/'.join(self.keys)),
101 multi_char)
86 try:102 try:
87 return self.keys.index(response[0].upper()) + 1103 return self.keys.index(response.upper()) + 1
88 except ValueError:104 except ValueError:
89 pass105 pass
90 except KeyboardInterrupt:106 except KeyboardInterrupt:

Subscribers

People subscribed via source and target branches