File: prompt.py

package info (click to toggle)
python-clint 0.5.1-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 328 kB
  • sloc: python: 1,815; makefile: 3
file content (182 lines) | stat: -rw-r--r-- 5,287 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# -*- 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] != ' ':
        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))