2025-04-08 18:46:12 +08:00

183 lines
5.2 KiB
Python

# -*- coding: utf8 -*-
"""
clint.textui.prompt
~~~~~~~~~~~~~~~~~~~
Module for simple interactive prompts handling
"""
from __future__ import absolute_import, print_function
from re import match, I
from .core import puts
from .colored import yellow
from .validators import RegexValidator, OptionValidator
try:
raw_input
except NameError:
raw_input = input
def yn(prompt, default='y', batch=False):
# A sanity check against default value
# If not y/n then y is assumed
if default not in ['y', 'n']:
default = 'y'
# Let's build the prompt
choicebox = '[Y/n]' if default == 'y' else '[y/N]'
prompt = prompt + ' ' + choicebox + ' '
# If input is not a yes/no variant or empty
# keep asking
while True:
# If batch option is True then auto reply
# with default input
if not batch:
input = raw_input(prompt).strip()
else:
print(prompt)
input = ''
# If input is empty default choice is assumed
# so we return True
if input == '':
return True
# Given 'yes' as input if default choice is y
# then return True, False otherwise
if match('y(?:es)?', input, I):
return True if default == 'y' else False
# Given 'no' as input if default choice is n
# then return True, False otherwise
elif match('n(?:o)?', input, I):
return True if default == 'n' else False
def query(prompt, default='', validators=None, batch=False):
# Set the nonempty validator as default
if validators is None:
validators = [RegexValidator(r'.+')]
# Let's build the prompt
if prompt[-1] is not ' ':
prompt += ' '
if default:
prompt += '[' + default + '] '
# If input is not valid keep asking
while True:
# If batch option is True then auto reply
# with default input
if not batch:
user_input = raw_input(prompt).strip() or default
else:
print(prompt)
user_input = ''
# Validate the user input
try:
for validator in validators:
user_input = validator(user_input)
return user_input
except Exception as e:
puts(yellow(e.message))
def options(prompt, options, default=None, batch=False):
'''
:param prompt:
:param options:
this can be either a list of strings, in which case it will be presented like:
prompt:
(1) this is the first string
(2) this is the second string
(3) this is the third string
please select 1-3:
or a list of dictionaries in the format of:
{ { 'selector' : 'this is what the user will enter to select the option'
'prompt': 'this is the string that will be displayed, this can be omitted if the selector is also a prompt',
'return': 'this is what is returned to the calling procedure, if omitted, the option selector will be used' }
so, to replicate the above, the dict could look like:
[ {'selector':1,'prompt':'this is the first string','return':1},
{'selector':2,'prompt':'this is the second string','return':2},
{'selector':3,'prompt':'this is the third string'}
:param default: should be set to the default selector (if desired)
:param batch: True/False, will auto-return the default
:return:
'''
# Build fix options and build validator
validator_list = []
return_dict = {}
if isinstance(options[0],dict):
for item in options:
item['selector'] = str(item['selector'])
item['prompt'] = str(item['prompt'])
if 'return' not in item:
item['return'] = item['selector']
validator_list.append(item['selector'])
return_dict[item['selector']] = item['return']
else:
options_strings = options
options = []
for key, opt in enumerate(options_strings):
item = {}
item['selector'] = str(key+1)
item['prompt'] = str(opt)
item['return'] = key+1
return_dict[item['selector']] = item['return']
validator_list.append(item['selector'])
options.append(item)
validators = [OptionValidator(validator_list)]
# Let's build the prompt
prompt += '\n'
# building the options list
for o in options:
prompt += '[{selector}] {prompt}\n'.format(**o)
prompt += '\n'
if default:
prompt += '[' + default + '] '
# If input is not valid keep asking
while True:
# If batch option is True then auto reply
# with default input
if not batch:
user_input = raw_input(prompt).strip() or default
else:
print(prompt)
user_input = ''
# Validate the user input
try:
for validator in validators:
user_input = validator(user_input)
# convert user input to defined return value
user_input = return_dict[user_input]
return user_input
except Exception as e:
puts(yellow(e.message))