5 Aur Shell is simple shell framework.
7 To use it, write some plugins that Aur Shell would use.
20 from showinfo
import Put
25 class AurShell(cmd
.Cmd
):
27 Interactive shell framework.
28 To use it, write some modules, becouse by default it's very poor shell.
30 def __init__(self
, init_message
=""):
31 cmd
.Cmd
.__init
__(self
)
33 # prefix for method callable by shell
34 self
.cmdprefix
= "do_"
35 self
.prompt
= conf
.shell_prompt
36 self
.commands
= self
.load_plugins(conf
.modules_path
)
37 # load history, create empty file if history doesn't exist
38 if not os
.path
.isfile(conf
.history_file
):
39 open(conf
.history_file
, "w").close()
40 readline
.read_history_file(conf
.history_file
)
41 readline
.set_history_length(conf
.history_length
)
44 self
.intro
= init_message
46 self
.intro
= "\n\tWelcome to aurShell v%(__version__)s\n" % globals()
49 def load_plugins(self
, modules_path
):
50 """Load all commands modules from modules_path direcotory."""
52 # adding plugins path to sys.path
53 if modules_path
not in sys
.path
:
54 sys
.path
.append(modules_path
)
55 # importing all modules from modules_path
56 for module_name
in os
.listdir(modules_path
):
57 module_path
= os
.path
.abspath(
58 string
.join(modules_path
, module_name
))
59 (module_name
, module_extension
) = os
.path
.splitext(module_name
)
60 # if it shouldn't be load
61 if os
.path
.islink(module_path
) or \
62 module_path
== __file__
or \
63 module_extension
!= ".py":
65 for key
in sys
.modules
.keys():
66 if key
== module_name
:
68 module
= __import__(module_name
)
69 command_modules
.append({"obj": module_name
, "name": module
,})
70 # search for class in each module
72 for module
in command_modules
:
73 for obj
in dir(module
["name"]):
75 # better class serch 2008-01-27 16:56:42
76 if not obj
.startswith("_"):
78 # check if it's method
79 x
= getattr(module
['name'], obj
)(self
.put
)
80 # create instance for each class
81 # as agrument give it Put() class instance
83 getattr(module
['name'], obj
)(self
.put
)
88 def default(self
, cmd
=None):
91 cmd = (<class>, [method], [arg1], [arg2], ...)
93 # cmd[0] should be class name
94 # cmd[1] should be method name (or arugmet if class is callable)
96 # cmd[2:] should be method argumments, can be empty
98 # check if alias exists and if so, replace command
99 if cmd
[0] in conf
.alias
.keys():
100 cmd
[0] = conf
.alias
[cmd
[0]]
101 self
.onecmd(" ".join(cmd
))
102 # operations for single command with no arguments
104 # if there's no such command (or plugin class)
105 if not cmd
[0] in self
.commands
.keys():
106 self
.put("%s : command not found." % cmd
[0])
107 # for only one argument, try to run __call__() method with
109 elif "__call__" in dir(self
.commands
[cmd
[0]]):
110 getattr(self
.commands
[cmd
[0]], "__call__")()
112 self
.put("%s : bad usege. Try to run help." % cmd
[0])
113 # if command was called with arguments
115 cmd
[1] = self
.cmdprefix
+ cmd
[1]
116 if not cmd
[0] in self
.commands
.keys():
117 self
.put("%s : command not found." % cmd
[0])
118 # if method named arg[1] exist in class arg[0], try to run it
119 elif cmd
[1] in dir(self
.commands
[cmd
[0]]):
120 #print dir(self.commands[cmd[0]])
122 getattr(self
.commands
[cmd
[0]], cmd
[1])(*cmd
[2:])
124 # show __doc__ if exist
125 doc
= getattr(self
.commands
[cmd
[0]], cmd
[1])
127 self
.put(doc
.__doc
__)
129 self
.put("%s : bad usage" % cmd
[1][3:])
130 # if there's no such method arg[1] in class arg[0],
131 # try to run class.__call__(args..)
134 self
.commands
[cmd
[0]](*cmd
[1:])
136 # object is not callable
137 self
.put("%s : bad usage" % cmd
[0])
140 def completenames(self
, text
, *ignored
):
141 """Complete commands"""
142 dotext
= self
.cmdprefix
+ text
144 local_cmd_list
= [a
[3:] + " " for a
in self
.get_names() if a
.startswith(dotext
)]
145 # + all metrods from modules
146 module_cmd_list
= [a
+ " " for a
in self
.commands
.keys() if a
.startswith(text
)]
147 return local_cmd_list
+ module_cmd_list
150 def completedefault(self
, text
, line
, begidx
, endidx
):
151 """Complete commands argument"""
152 dotext
= self
.cmdprefix
+ text
154 # if only commands was given
156 cmds
= [a
[3:] + " " for a
in dir(self
.commands
[line
[0]]) \
157 if a
.startswith(dotext
)]
159 cmds
= [a
[3:] + " " for a
in dir(self
.commands
[line
[0]]) \
160 if a
.startswith(dotext
)]
161 # else don't complete (or should I?)
167 def do_help(self
, arg
):
168 """Show help for commands"""
171 self
.put("Usage: help <command>")
174 # try to run help() method
175 self
.put(getattr(self
.commands
[arg
[0]], "help")())
176 except AttributeError:
177 # try to show __doc__
178 if self
.commands
[arg
[0]].__doc
__:
179 self
.put(self
.commands
[arg
[0]].__doc
__)
181 self
.put("No help found.")
183 self
.put("No help found.")
186 def do_clear(self
, *ignored
):
187 """Clear the screen"""
188 # TODO 2008-02-09 20:44:50
189 self
.put("Todo, sorry")
192 def do_history(self
, hnumb
=None, *ignored
):
193 """Show the history"""
194 # TODO better history listing
195 # 2008-01-27 18:51:22
196 # print whole history
198 for number
in range(1, conf
.history_length
):
199 cmd
= readline
.get_history_item(number
)
202 self
.put("%6d %s" % (number
, cmd
))
203 # for history range 12-22 or -22 or 22-
207 if hnumb
[-1] == "-" or hnumb
[0] == "-":
208 start
= int(hnumb
.replace("-", " "))
209 end
= conf
.history_length
211 start
, end
= hnumb
.split("-")
214 for number
in range(start
, end
):
215 cmd
= readline
.get_history_item(number
)
218 self
.put("%6d %s" % (number
, cmd
))
221 self
.put(readline
.get_history_item(hnumb
))
223 self
.put("""Bad value.
224 Usage: history <number or range>
225 history 11-20 -> from 11 to 20
226 history 22- -> from 22 fo the end of history file
227 history -22 -> same as 22-""")
230 def do_quit(self
, *ignored
):
231 """Quit from shell"""
232 if conf
.history_length
:
233 readline
.write_history_file(conf
.history_file
)
243 if __name__
== "__main__":
247 except KeyboardInterrupt:
248 # TODO 2008-01-27 16:56:31
249 sys
.exit(shell
.do_quit())