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
|
import sys
class UserOption:
def __init__(self, char, action, help, default=False):
self.char = char
self.action = action
self.default = default
self.help = help
class UserInteractor(object):
# Special actions
RESTART = 0
QUIT = 1
FINISH = 2
def __init__(self):
self.items = []
def add_item(self, item):
self.items.append(item)
self.__total_items = len(self.items)
def set_items(self, item_list):
self.items = item_list
self.__total_items = len(self.items)
def set_item_callback(self, cb):
self.item_callback = cb
def set_start_callback(self, cb):
self.start_callback = cb
def set_end_callback(self, cb):
self.end_callback = cb
def set_prompt(self, prompt):
self.prompt = prompt
def set_options(self, opt_list):
self._options = []
self._option_dict = {}
for option in opt_list:
self.add_option(option)
def add_option(self, option):
self._options.append(option)
self._option_dict[option.char] = option
def get_option(self, char):
return self._option_dict[char]
def __do_action(self, action, item):
if type(action) is int:
if action == self.QUIT:
self.__quit = True
self.__finished = True
elif action == self.RESTART:
self.__restart = True
self.__finished = False
elif action == self.FINISH:
self.__finished = True
return True
else:
return action(item)
def __select_loop(self):
i = 0
self.start_callback()
while i < len(self.items):
item = self.items[i]
self.item_callback(item, i + 1)
if self.__ask_once(item, i + 1):
i += 1
if self.__quit or self.__finished:
break
def interact(self):
self.__quit = False
self.__finished = False
while not self.__quit and not self.__finished:
self.__restart = False
self.__select_loop()
if self.__quit:
break
if self.end_callback():
break
self.__finished = False
self.__ask_once(None, self.__total_items)
while not self.__finished and not self.__restart:
self.__ask_once(None, -1)
return not self.__quit
def __ask_once(self, item, count):
args = {'count': count, 'total' : self.__total_items}
while True:
sys.stdout.write(self.prompt % args)
sys.stdout.write(' [')
for opt in self._options:
if opt.default:
default = opt
sys.stdout.write(opt.char)
sys.stdout.write('?] (%s): ' % default.char)
response = self.__getchar()
# default, which we see as newline, is 'n'
if response in ['\n', '\r', '\r\n']:
response = default.char
print response # because echo is off
for opt in self._options:
if opt.char == response:
return self.__do_action(opt.action, item)
self.__show_help()
return False # keep pychecker happy
def __show_help(self):
for opt in self._options:
print ' %s - %s' % (opt.char, opt.help)
if sys.platform == "win32":
def __getchar(self):
import msvcrt
return msvcrt.getch()
else:
def __getchar(self):
import tty
import termios
fd = sys.stdin.fileno()
settings = termios.tcgetattr(fd)
try:
tty.setraw(fd)
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, settings)
return ch
|