1 # Copyright 2016 The Chromium OS Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 """Sequenced feedback request.""" 6 7 from __future__ import print_function 8 9 import input_handlers 10 import request 11 import textwrap 12 13 14 class _RequestAction(object): 15 """An interface of a single action in a sequenced feedback request.""" 16 17 def execute(self): 18 """Performs the action.""" 19 raise NotImplementedError 20 21 22 class _QuestionRequestAction(_RequestAction): 23 """A question to be presented to a user.""" 24 25 def __init__(self, blurb, input_handler, prompt=None): 26 self.input_handler = input_handler 27 blurb_supp, prompt_supp = input_handler.get_choices_supplements() 28 29 # Initialize the question blurb string. 30 self.blurb = self._format_text(blurb) 31 if blurb_supp: 32 self.blurb += '\n' + blurb_supp 33 34 # Initialize the input prompt string. 35 if prompt is None: 36 prompt = '' 37 if prompt_supp: 38 if prompt: 39 prompt += ' ' 40 prompt += prompt_supp 41 self.prompt = self._format_text(prompt) 42 if self.prompt: 43 self.prompt += ' ' 44 45 def _format_text(self, text): 46 """Formats a blob of text for writing to standard output.""" 47 return textwrap.fill(text.strip()) 48 49 50 def execute(self): 51 if self.blurb: 52 print(self.blurb, end=('\n' if self.prompt else ' ')) 53 while True: 54 try: 55 return self.input_handler.process(raw_input(self.prompt)) 56 except input_handlers.InputError: 57 print('Invalid input, try again') 58 59 60 class SequencedFeedbackRequest(request.FeedbackRequest): 61 """A request consisting of a sequence of interactive actions.""" 62 63 def __init__(self, *args): 64 super(SequencedFeedbackRequest, self).__init__(*args) 65 self._actions = [] 66 67 68 def _append_action(self, action): 69 self._actions.append(action) 70 71 72 def append_question(self, blurb, input_handler, prompt=None): 73 """Appends a question to the request sequence. 74 75 @param blurb: The text to print prior to asking for input. 76 @param input_handler: The input handler object. 77 @param prompt: String to print when polling for input. 78 """ 79 attrs = {'test': self.test, 'dut': self.dut} 80 blurb = blurb or '' 81 self._append_action(_QuestionRequestAction( 82 blurb % attrs, input_handler, 83 prompt=(prompt and prompt % attrs))) 84 85 86 def execute(self): 87 """Executes the sequence of request actions. 88 89 @return: The return value of the last action. 90 91 @raise request.FeedbackRequestError: Failed during sequence execution. 92 """ 93 ret = None 94 for action in self._actions: 95 ret = action.execute() 96 return ret 97