1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 """Command line interface helper classes.
19
20 It provides some default commands, a help system, a default readline
21 configuration with completion and persistent history.
22
23 Example::
24
25 class BookShell(CLIHelper):
26
27 def __init__(self):
28 # quit and help are builtins
29 # CMD_MAP keys are commands, values are topics
30 self.CMD_MAP['pionce'] = _("Sommeil")
31 self.CMD_MAP['ronfle'] = _("Sommeil")
32 CLIHelper.__init__(self)
33
34 help_do_pionce = ("pionce", "pionce duree", _("met ton corps en veille"))
35 def do_pionce(self):
36 print 'nap is good'
37
38 help_do_ronfle = ("ronfle", "ronfle volume", _("met les autres en veille"))
39 def do_ronfle(self):
40 print 'fuuuuuuuuuuuu rhhhhhrhrhrrh'
41
42 cl = BookShell()
43
44
45
46
47 """
48 __docformat__ = "restructuredtext en"
49
50 import __builtin__
51 if not hasattr(__builtin__, '_'):
52 __builtin__._ = str
53
54
56 """Init the readline library if available."""
57 try:
58 import readline
59 readline.parse_and_bind("tab: complete")
60 readline.set_completer(complete_method)
61 string = readline.get_completer_delims().replace(':', '')
62 readline.set_completer_delims(string)
63 if histfile is not None:
64 try:
65 readline.read_history_file(histfile)
66 except IOError:
67 pass
68 import atexit
69 atexit.register(readline.write_history_file, histfile)
70 except:
71 print 'readline is not available :-('
72
73
75 """Readline completer."""
76
79
81 """Hook called by readline when <tab> is pressed."""
82 n = len(text)
83 matches = []
84 for cmd in self.list :
85 if cmd[:n] == text :
86 matches.append(cmd)
87 try:
88 return matches[state]
89 except IndexError:
90 return None
91
92
94 """An abstract command line interface client which recognize commands
95 and provide an help system.
96 """
97
98 CMD_MAP = {'help' : _("Others"),
99 'quit' : _("Others"),
100 }
101 CMD_PREFIX = ''
102
104 self._topics = {}
105 self.commands = None
106 self._completer = Completer(self._register_commands())
107 init_readline(self._completer.complete, histfile)
108
110 """loop on user input, exit on EOF"""
111 while 1:
112 try:
113 line = raw_input('>>> ')
114 except EOFError:
115 print
116 break
117 s_line = line.strip()
118 if not s_line:
119 continue
120 args = s_line.split()
121 if args[0] in self.commands:
122 try:
123 cmd = 'do_%s' % self.commands[args[0]]
124 getattr(self, cmd)(*args[1:])
125 except EOFError:
126 break
127 except:
128 import traceback
129 traceback.print_exc()
130 else:
131 try:
132 self.handle_line(s_line)
133 except:
134 import traceback
135 traceback.print_exc()
136
138 """Method to overload in the concrete class (should handle
139 lines which are not commands).
140 """
141 raise NotImplementedError()
142
143
144
145
147 """ register available commands method and return the list of
148 commands name
149 """
150 self.commands = {}
151 self._command_help = {}
152 commands = [attr[3:] for attr in dir(self) if attr[:3] == 'do_']
153 for command in commands:
154 topic = self.CMD_MAP[command]
155 help_method = getattr(self, 'help_do_%s' % command)
156 self._topics.setdefault(topic, []).append(help_method)
157 self.commands[self.CMD_PREFIX + command] = command
158 self._command_help[command] = help_method
159 return self.commands.keys()
160
162 print _('Command %s') % cmd
163 print _('Syntax: %s') % syntax
164 print '\t', explanation
165 print
166
167
168
169
171 """base input of the help system"""
172 if command in self._command_help:
173 self._print_help(*self._command_help[command])
174 elif command is None or command not in self._topics:
175 print _("Use help <topic> or help <command>.")
176 print _("Available topics are:")
177 topics = self._topics.keys()
178 topics.sort()
179 for topic in topics:
180 print '\t', topic
181 print
182 print _("Available commands are:")
183 commands = self.commands.keys()
184 commands.sort()
185 for command in commands:
186 print '\t', command[len(self.CMD_PREFIX):]
187
188 else:
189 print _('Available commands about %s:') % command
190 print
191 for command_help_method in self._topics[command]:
192 try:
193 if callable(command_help_method):
194 self._print_help(*command_help_method())
195 else:
196 self._print_help(*command_help_method)
197 except:
198 import traceback
199 traceback.print_exc()
200 print 'ERROR in help method %s'% (
201 command_help_method.func_name)
202
203 help_do_help = ("help", "help [topic|command]",
204 _("print help message for the given topic/command or \
205 available topics when no argument"))
206
208 """quit the CLI"""
209 raise EOFError()
210
212 return ("quit", "quit", _("quit the application"))
213