5 Aur Shell is simple shell framework.
7 To use it, write some plugins that Aur Shell would use.
19 from showinfo
import Put
24 class AurShell(cmd
.Cmd
):
26 Interactive shell framework.
27 To use it, write some modules, becouse by default it's very poor shell.
30 cmd
.Cmd
.__init
__(self
)
31 # use it instead of plain `print`
34 # prefix for method callable by shell
35 self
.cmdprefix
= "do_"
36 self
.prompt
= conf
.shell_prompt
38 self
.commands
= self
.load_plugins(conf
.modules_path
)
40 self
.intro
= "\n\tWelcome to aurShell v%(__version__)s\n" % globals()
41 # load history, create empty file if history doesn't exist
42 if not os
.path
.isfile(conf
.history_file
):
43 open(conf
.history_file
, "w").close()
44 readline
.read_history_file(conf
.history_file
)
45 readline
.set_history_length(conf
.history_length
)
46 # create build_dir if doesn't exist
47 if not os
.path
.isdir(conf
.build_dir
):
48 os
.mkdir(conf
.build_dir
)
51 def load_plugins(self
, modules_path
):
52 """Load all commands modules from modules_path direcotory."""
54 # adding plugins path to sys.path
55 if modules_path
not in sys
.path
:
56 sys
.path
.append(modules_path
)
57 # importing all modules from modules_path
58 for module_name
in os
.listdir(modules_path
):
59 module_path
= os
.path
.abspath(
60 string
.join(modules_path
, module_name
))
61 (module_name
, module_extension
) = os
.path
.splitext(module_name
)
62 # if it shouldn't be load
63 if os
.path
.islink(module_path
) or \
64 module_path
== __file__
or \
65 module_extension
!= ".py":
67 for key
in sys
.modules
.keys():
68 if key
== module_name
:
70 module
= __import__(module_name
)
71 command_modules
.append({"obj": module_name
, "name": module
,})
72 # search for class in each module
74 for module
in command_modules
:
75 for obj
in dir(module
["name"]):
77 # better class serch 2008-01-27 16:56:42
78 if not obj
.startswith("_"):
80 # check if it's method
81 x
= getattr(module
['name'], obj
)(self
.put
, conf
)
82 # create instance for each class
83 # as agrument give it Put() class instance
85 getattr(module
['name'], obj
)(self
.put
, conf
)
91 def precmd(self
, cmd
):
92 # check if alias exists and if so, replace command
93 for alias
in conf
.alias
.keys():
94 # command should start with alias, but:
95 # - next char should be white space, or
96 # - there's no next char
97 if cmd
.startswith(alias
) and \
98 (len(cmd
) <= len(alias
) or cmd
[len(alias
)] == " "):
99 cmd
= cmd
.replace(alias
, conf
.alias
[alias
], 1)
103 def do_shell(self
, cmd
):
104 """System shell command, for commads which starts with !"""
108 def default(self
, cmd
=None):
111 cmd = (<class>, [method], [arg1], [arg2], ...)
113 # cmd[0] should be class name
114 # cmd[1] should be method name (or arugmet if class is callable)
115 # cmd[1] can be empty
116 # cmd[2:] should be method argumments, can be empty
118 # operations for single command with no arguments
120 # if there's no such command (or plugin class)
121 if not cmd
[0] in self
.commands
.keys():
122 self
.put("%s : command not found." % cmd
[0])
123 # for only one argument, try to run __call__() method with
125 elif "__call__" in dir(self
.commands
[cmd
[0]]):
126 getattr(self
.commands
[cmd
[0]], "__call__")()
128 self
.put("%s : bad usege. Try to run help." % cmd
[0])
129 # if command was called with arguments
131 cmd
[1] = self
.cmdprefix
+ cmd
[1]
132 if not cmd
[0] in self
.commands
.keys():
133 self
.put("%s : command not found." % cmd
[0])
134 # if method named arg[1] exist in class arg[0], try to run it
135 elif cmd
[1] in dir(self
.commands
[cmd
[0]]):
136 #print dir(self.commands[cmd[0]])
138 getattr(self
.commands
[cmd
[0]], cmd
[1])(*cmd
[2:])
140 # show __doc__ if exist
141 doc
= getattr(self
.commands
[cmd
[0]], cmd
[1])
143 self
.put(doc
.__doc
__)
145 self
.put("%s : bad usage" % cmd
[1][3:])
146 # if there's no such method arg[1] in class arg[0],
147 # try to run class.__call__(args..)
150 self
.commands
[cmd
[0]](*cmd
[1:])
152 # object is not callable
153 self
.put("%s : bad usage" % cmd
[0])
156 def completenames(self
, text
, *ignored
):
157 """Complete commands"""
158 dotext
= self
.cmdprefix
+ text
161 [a
[3:] + " " for a
in self
.get_names() if a
.startswith(dotext
)]
162 # + all metrods from modules
164 [a
+ " " for a
in self
.commands
.keys() if a
.startswith(text
)]
167 [a
+ " " for a
in self
.conf
.alias
.keys() if a
.startswith(text
)]
168 return local_cmd_list
+ module_cmd_list
+ aliases_cmd_list
171 def completedefault(self
, text
, line
, begidx
, endidx
):
172 """Complete commands argument"""
173 dotext
= self
.cmdprefix
+ text
175 # if only commands was given
177 cmds
= [a
[3:] + " " for a
in dir(self
.commands
[line
[0]]) \
178 if a
.startswith(dotext
)]
180 cmds
= [a
[3:] + " " for a
in dir(self
.commands
[line
[0]]) \
181 if a
.startswith(dotext
)]
182 # else don't complete (or should I?)
188 def do_help(self
, arg
):
189 """Show help for commands"""
192 self
.put("Usage: help <command>")
194 # first - build-in methods
195 if self
.cmdprefix
+ arg
[0] in dir(self
):
196 doc
= getattr(self
, self
.cmdprefix
+ arg
[0]).__doc
__
202 # try to run help() method
203 self
.put(getattr(self
.commands
[arg
[0]], "help")())
204 except AttributeError:
205 # try to show __doc__
206 if self
.commands
[arg
[0]].__doc
__:
207 self
.put(self
.commands
[arg
[0]].__doc
__)
209 self
.put("No help found.")
211 self
.put("No help found.")
215 if arg
[0] in self
.commands
.keys():
216 arg
[1] = self
.cmdprefix
+ arg
[1]
217 doc
= getattr(self
.commands
[arg
[0]], arg
[1]).__doc
__
219 except AttributeError:
220 self
.put("%s : no help found" % arg
[1][3:])
222 self
.put("Try to do something else.\nThis option doesn't work well now.")
225 def do_clear(self
, *ignored
):
226 """Clear the screen"""
227 # TODO 2008-02-09 20:44:50
228 self
.put("Todo, sorry")
231 def do_history(self
, hnumb
=None, *ignored
):
232 """Show the history"""
233 # TODO better history listing
234 # 2008-01-27 18:51:22
235 # print whole history
237 for number
in range(1, conf
.history_length
):
238 cmd
= readline
.get_history_item(number
)
241 self
.put("%6d %s" % (number
, cmd
))
242 # for history range 12-22 or -22 or 22-
246 if hnumb
[-1] == "-" or hnumb
[0] == "-":
247 start
= int(hnumb
.replace("-", " "))
248 end
= conf
.history_length
250 start
, end
= hnumb
.split("-")
253 for number
in range(start
, end
):
254 cmd
= readline
.get_history_item(number
)
257 self
.put("%6d %s" % (number
, cmd
))
260 self
.put(readline
.get_history_item(hnumb
))
262 self
.put("""Bad value.
263 Usage: history <number or range>
264 history 11-20 -> from 11 to 20
265 history 22- -> from 22 fo the end of history file
266 history -22 -> same as 22-""")
269 def do_quit(self
, *ignored
):
270 """Quit from shell"""
271 if conf
.history_length
:
272 readline
.write_history_file(conf
.history_file
)
282 if __name__
== "__main__":
286 except KeyboardInterrupt:
287 # TODO 2008-01-27 16:56:31
288 sys
.exit(shell
.do_quit())