#! /usr/bin/python # # Copyright (c) 2021 Gavin D. Howard # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # Stolen from http://stackoverflow.com/a/3041990/3281147 and modified for my # purposes. import sys import signal import argparse def sighandler(signum, frame): raise Exception("timeout") def query(question, default=None, timeout=0): """Ask a yes/no question via raw_input() and return their answer. "question" is a string that is presented to the user. "default" is the presumed answer if the user just hits . It must be "yes" (the default), "no" or None (meaning an answer is required of the user). The "answer" return value is True for "yes" or False for "no". """ valid = {"yes": True, "y": True, "ye": True, "no": False, "n": False} if default is None or default == "": prompt = " [y/n]" elif default == "yes" or default == "y": prompt = " [Y/n]" elif default == "no" or default == "n": prompt = " [y/N]" else: raise ValueError("invalid default answer: '{}'".format(default)) if timeout < 0: raise ValueError("timeout must be positive or zero") signal.signal(signal.SIGALRM, sighandler) try: while True: if timeout != 0: signal.alarm(timeout) sys.stdout.write(question + prompt + ': ') choice = input().lower() signal.alarm(0) if default is not None and default != '' and choice == '': return valid[default] elif choice.casefold() in valid: return valid[choice.casefold()] else: sys.stdout.write("Please respond with 'yes' or 'no' " "(or 'y' or 'n').\n") except Exception: sys.stdout.write('{}\n'.format(default)) return valid[default] if __name__ == "__main__": parser = argparse.ArgumentParser(description='Provide a yes/no prompt and return the answer') parser.add_argument('--default', action='store', default='', nargs='?', help='the default answer') parser.add_argument('--timeout', action='store', default=0, type=int, nargs='?', help='how long to wait; 0 means wait forever') parser.add_argument('query', action='store', help='the query to show the user') args = vars(parser.parse_args()) ret = query(args['query'], default=args['default'], timeout=args['timeout']) sys.exit(not ret)