root/galaxy-central/eggs/twill-0.9-py2.6.egg/twill/shell.py

リビジョン 3, 11.0 KB (コミッタ: kohda, 14 年 前)

Install Unix tools  http://hannonlab.cshl.edu/galaxy_unix_tools/galaxy.html

行番号 
1"""
2A command-line interpreter for twill.
3
4This is an implementation of a command-line interpreter based on the
5'Cmd' class in the 'cmd' package of the default Python distribution.
6"""
7
8import cmd
9from twill import commands, parse, __version__
10import namespaces
11
12try:
13    import readline
14except:
15    readline = None
16
17def make_cmd_fn(cmd):
18    """
19    Dynamically define a twill shell command function based on an imported
20    function name.  (This is where the twill.commands functions actually
21    get executed.)
22    """
23   
24    def do_cmd(rest_of_line, cmd=cmd):
25        global_dict, local_dict = namespaces.get_twill_glocals()
26
27        args = []
28        if rest_of_line.strip() != "":
29            try:
30                args = parse.arguments.parseString(rest_of_line)[0]
31                args = parse.process_args(args, global_dict,local_dict)
32            except Exception, e:
33                print '\nINPUT ERROR: %s\n' % (str(e),)
34                return
35
36        try:
37            parse.execute_command(cmd, args, global_dict, local_dict,
38                                  "<shell>")
39        except SystemExit:
40            raise
41        except Exception, e:
42            print '\nERROR: %s\n' % (str(e),)
43
44    return do_cmd
45
46def make_help_cmd(cmd, docstring):
47    """
48    Dynamically define a twill shell help function for the given
49    command/docstring.
50    """
51    def help_cmd(message=docstring, cmd=cmd):
52        print '=' * 15
53        print '\nHelp for command %s:\n' % (cmd,)
54        print message.strip()
55        print ''
56        print '=' * 15
57        print ''
58       
59    return help_cmd
60
61###
62
63class Singleton(object):
64    def __new__(cls, *args, **kwds):
65        it = cls.__dict__.get("__it__")
66        if it is not None:
67            return it
68        cls.__it__ = it = object.__new__(cls)
69        it.init(*args, **kwds)
70        return it
71   
72    def init(self, *args, **kwds):
73        pass
74
75#
76# TwillCommandLoop
77#
78
79def add_command(cmd, docstring):
80    x = get_command_shell()
81    if x:
82        x.add_command(cmd, docstring)
83       
84def get_command_shell():
85    return getattr(TwillCommandLoop, '__it__', None)
86
87class TwillCommandLoop(Singleton, cmd.Cmd):
88    """
89    Command-line interpreter for twill commands.  Singleton object: you
90    can't create more than one of these at a time.
91
92    Note: most of the do_ and help_ functions are dynamically created
93    by the metaclass.
94    """
95    def init(self, **kw):
96        if kw.has_key('stdin'):
97            cmd.Cmd.__init__(self, None, stdin=kw['stdin'])
98            self.use_rawinput = False
99        else:
100            cmd.Cmd.__init__(self)
101
102        # initialize a new local namespace.
103        namespaces.new_local_dict()
104
105        # import readline history, if available.
106        if readline:
107            try:
108                readline.read_history_file('.twill-history')
109            except IOError:
110                pass
111
112        # fail on unknown commands? for test-shell, primarily.
113        self.fail_on_unknown = kw.get('fail_on_unknown', False)
114
115        # handle initial URL argument
116        if kw.get('initial_url'):
117            commands.go(kw['initial_url'])
118           
119        self._set_prompt()
120
121        self.names = []
122       
123        global_dict, local_dict = namespaces.get_twill_glocals()
124
125        ### add all of the commands from twill.
126        for command in parse.command_list:
127            fn = global_dict.get(command)
128            self.add_command(command, fn.__doc__)
129
130    def add_command(self, command, docstring):
131        """
132        Add the given command into the lexicon of all commands.
133        """
134        do_name = 'do_%s' % (command,)
135        do_cmd = make_cmd_fn(command)
136        setattr(self, do_name, do_cmd)
137
138        if docstring:
139            help_cmd = make_help_cmd(command, docstring)
140            help_name = 'help_%s' % (command,)
141            setattr(self, help_name, help_cmd)
142
143        self.names.append(do_name)
144
145    def get_names(self):
146        """
147        Return the list of commands.
148        """
149        return self.names
150
151    def complete_formvalue(self, text, line, begin, end):
152        # formvalue <formname> <field> <value>
153        cmd, args = parse.parse_command(line + '.', {}, {})
154        place = len(args)
155        if place == 1:
156            return self.provide_formname(text)
157        elif place == 2:
158            formname = args[0]
159            return self.provide_field(formname, text)
160        return []
161    complete_fv = complete_formvalue
162
163    def provide_formname(self, prefix):
164        names = []
165        forms = commands.browser._browser.forms()
166        for f in forms:
167            id = f.attrs.get('id')
168            if id and id.startswith(prefix):
169                names.append(id)
170                continue
171            name = f.name
172            if name and name.startswith(prefix):
173                names.append(name)
174        return names
175
176    def provide_field(self, formname, prefix):
177        names = []
178        form = commands.browser.get_form(formname)
179        if not form:
180            return []
181        for c in form.controls:
182            id = c.id
183            if id and id.startswith(prefix):
184                names.append(id)
185                continue
186            name = c.name
187            if name and name.startswith(prefix):
188                names.append(name)
189        return names
190
191    def _set_prompt(self):
192        "Set the prompt to the current page."
193        url = commands.browser.get_url()
194        if url is None:
195            url = " *empty page* "
196        self.prompt = "current page: %s\n>> " % (url,)
197
198    def precmd(self, line):
199        "Run before each command; save."
200        return line
201
202    def postcmd(self, stop, line):
203        "Run after each command; set prompt."
204        self._set_prompt()
205       
206        return stop
207
208    def default(self, line):
209        "Called when unknown command is executed."
210
211        # empty lines ==> emptyline(); here we just want to remove
212        # leading whitespace.
213        line = line.strip()
214
215        # look for command
216        global_dict, local_dict = namespaces.get_twill_glocals()
217        cmd, args = parse.parse_command(line, global_dict, local_dict)
218
219        # ignore comments & empty stuff
220        if cmd is None:
221            return
222
223        try:
224            parse.execute_command(cmd, args, global_dict, local_dict,
225                                  "<shell>")
226        except SystemExit:
227            raise
228        except Exception, e:
229            print '\nERROR: %s\n' % (str(e),)
230            if self.fail_on_unknown:
231                raise
232
233    def emptyline(self):
234        "Ignore empty lines."
235        pass
236
237    def do_EOF(self, *args):
238        "Exit on CTRL-D"
239        if readline:
240            readline.write_history_file('.twill-history')
241           
242        raise SystemExit()
243
244    def help_help(self):
245        print "\nWhat do YOU think the command 'help' does?!?\n"
246
247    def do_version(self, *args):
248        print "\ntwill version %s.\n" % (__version__,)
249        print "See http://www.idyll.org/~t/www-tools/twill/ for more info."
250        print ""
251
252    def help_version(self):
253        print "\nPrint version information.\n"
254
255    def do_exit(self, *args):
256        raise SystemExit()
257
258    def help_exit(self):
259        print "\nExit twill.\n"
260
261    do_quit = do_exit
262    help_quit = help_exit
263
264####
265
266twillargs = []                          # contains sys.argv *after* last '--'
267interactive = False                     # 'True' if interacting with user
268def main():
269    global twillargs, interactive
270   
271    import sys
272    from twill import TwillCommandLoop, execute_file, __version__
273    from twill.utils import gather_filenames
274    from optparse import OptionParser
275    from cStringIO import StringIO
276
277    ###
278    # make sure that the current working directory is in the path.  does this
279    # work on Windows??
280
281    if not '.' in sys.path:
282        sys.path.append('.')
283    ###
284
285    #### OPTIONS
286
287    parser = OptionParser()
288
289    parser.add_option('-q', '--quiet', action="store_true", dest="quiet",
290                      help = 'do not show normal output')
291
292    parser.add_option('-i', '--interactive', action="store_true", dest="interact",
293              help = 'drop into an interactive shell after running files (if any)')
294
295    parser.add_option('-f', '--fail', action="store_true", dest="fail",
296                      help = 'fail exit on first file to fail')
297
298    parser.add_option('-n', '--never-fail', action="store_true",
299                      dest="never_fail",
300                      help = 'continue executing scripts past errors')
301
302    parser.add_option('-v', '--version', action="store_true", dest="show_version",
303                      help = 'show version information and exit')
304
305    parser.add_option('-u', '--url', nargs=1, action="store", dest="url",
306                      help="start at the given URL before each script")
307
308    ####
309
310    # parse arguments.
311    sysargs = sys.argv[1:]
312    if '--' in sysargs:
313        found = False
314        for last in range(len(sysargs) - 1, -1, -1):
315            if sysargs[last] == '--':
316                found = True
317                break
318
319        if found:
320            twillargs = sysargs[last + 1:]
321            sysargs = sysargs[:last]
322
323    (options, args) = parser.parse_args(sysargs)
324
325    if options.show_version:
326        print 'twill version %s.' % (__version__,)
327        sys.exit(0)
328
329    if options.quiet:
330        assert not options.interact, "interactive mode is incompatible with -q"
331        assert args, "interactive mode is incompatible with -q"
332
333        old_stdout = sys.stdout
334        sys.stdout = StringIO()
335
336    # If run from the command line, find & run any scripts put on the command
337    # line.  If none, drop into an interactive AutoShell.
338
339    failed = False
340    if len(args):
341        success = []
342        failure = []
343
344        filenames = gather_filenames(args)
345
346        for filename in filenames:
347            print '>> EXECUTING FILE', filename
348
349            try:
350                interactive = False
351                execute_file(filename,
352                             initial_url=options.url,
353                             never_fail=options.never_fail)
354                success.append(filename)
355            except Exception, e:
356                if options.fail:
357#                    import pdb
358#                    _, _, tb = sys.exc_info()
359#                    pdb.post_mortem(tb)
360                    raise
361                else:
362                    print '** UNHANDLED EXCEPTION:', str(e)
363                    failure.append(filename)
364
365        print '--'
366        print '%d of %d files SUCCEEDED.' % (len(success),
367                                             len(success) + len(failure),)
368        if len(failure):
369            print 'Failed:\n\t',
370            print "\n\t".join(failure)
371            failed = True
372
373    if not args or options.interact:
374        welcome_msg = ""
375        if not args:
376            welcome_msg = "\n -= Welcome to twill! =-\n"
377
378        interactive = True
379        shell = TwillCommandLoop(initial_url=options.url)
380
381        while 1:
382            try:
383                shell.cmdloop(welcome_msg)
384            except KeyboardInterrupt:
385                sys.stdout.write('\n')
386            except SystemExit:
387                raise
388
389            welcome_msg = ""
390
391    if failed:
392        sys.exit(1)
393    sys.exit(0)
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。