Skip to content
This repository has been archived by the owner on Mar 31, 2024. It is now read-only.

Added option prompt #134

Merged
merged 1 commit into from
Jan 9, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 93 additions & 1 deletion clint/textui/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from .core import puts
from .colored import yellow
from .validators import RegexValidator
from .validators import RegexValidator, OptionValidator

try:
raw_input
Expand Down Expand Up @@ -88,3 +88,95 @@ def query(prompt, default='', validators=None, batch=False):
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:
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I actually didn't add in the "please select 1-3" text, but I suppose it could be put in pretty easily.


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))
18 changes: 18 additions & 0 deletions clint/textui/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,21 @@ def __call__(self, value):
return int(value)
except (TypeError, ValueError):
raise ValidationError(self.message)

class OptionValidator(object):
message = 'Select from the list of valid options.'

def __init__(self, options, message=None):
self.options = options
if message is not None:
self.message = message

def __call__(self, value):
"""
Validates that the input is in the options list.
"""
if value in self.options:
return value
else:
raise ValidationError(self.message)

9 changes: 8 additions & 1 deletion examples/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,14 @@
# Set validators to an empty list for an optional input
language = prompt.query("Your favorite tool (optional)?", validators=[])

# Shows a list of options to select from
inst_options = [{'selector':'1','prompt':'Full','return':'full'},
{'selector':'2','prompt':'Partial','return':'partial'},
{'selector':'3','prompt':'None','return':'no install'}]
inst = prompt.options("Full or Partial Install", inst_options)

# Use a default value and a validator
path = prompt.query('Installation Path', default='/usr/local/bin/', validators=[validators.PathValidator()])

puts(colored.blue('Hi {0}. Install {1} to {2}'.format(name, language or 'nothing', path)))
puts(colored.blue('Hi {0}. Install {1} {2} to {3}'.format(name, inst, language or 'nothing', path)))