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

Commit

Permalink
Merge pull request #134 from dstrohl/master
Browse files Browse the repository at this point in the history
Added option prompt
  • Loading branch information
kennethreitz committed Jan 9, 2015
2 parents 93d10a8 + 1c1f1c9 commit 140d858
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 2 deletions.
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:
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)))

0 comments on commit 140d858

Please sign in to comment.