示例#1
0
 def ask_question(self, question, chars='', default='', on_intr=''):
     """Prompt user for input to a question."""
     # add hints of what can be entered
     if chars:
         question += ' (%s)' % ('/'.join(chars.upper()))
     if default:
         question += ' [%s]' % default
     self.in_question = True
     try:
         try:
             # see set_status() for an explanation of the special chars here
             ans = self.readline(
                 '\x01\r\x1b[K' +
                 colorize('bold', '\x02# ' + question + ' \x01') + '\x02',
                 add_history=False)
         except (KeyboardInterrupt, EOFError):
             return on_intr
         if chars:
             # we accept any string; if it's beginning with one of the chars,
             # that is the result, otherwise it's the default value
             ans = ans.lower()
             for char in chars:
                 if ans.startswith(char):
                     return char
             return default
         if not ans:
             ans = default
         return ans
     finally:
         self.in_question = False
示例#2
0
 def print_where(self):
     """Implements the "/where" command."""
     if self.status in ('running', 'paused'):
         self.put_client('Printing current script.')
         for i, line in enumerate(self.current_script):
             if i + 1 == self.current_line:
                 self.put(colorize('darkgreen', '---> ' + line))
             else:
                 self.put('     ' + line)
         self.put_client('End of script.')
         if self.cur_eta:
             self.put_client('Estimated finishing time: ' + self.cur_eta)
     else:
         self.put_client('No script is running.')
示例#3
0
 def ask_input(self, question):
     """Prompt user for a line of input."""
     self.in_question = True
     try:
         try:
             # see set_status() for an explanation of the special chars here
             ans = self.readline('\x01\r\x1b[K' + colorize('bold',
                                 '\x02# ' + question + ' \x01') + '\x02',
                                 add_history=False)
         except (KeyboardInterrupt, EOFError):
             return ''
         return ans
     finally:
         self.in_question = False
示例#4
0
 def debug_repl(self):
     """Called to handle remote debugging via Rpdb."""
     self.in_question = True  # suppress prompt changes
     try:
         while self.debug_mode:
             try:
                 cmd = self.readline('\x01\r\x1b[K' + colorize(
                     'darkred', '\x02# (Rpdb) \x01') + '\x02') + '\n'
             except (EOFError, KeyboardInterrupt):
                 cmd = ''
             except StateChange:
                 if not self.debug_mode:
                     return
             self.tell('debuginput', cmd)
     finally:
         self.in_question = False
示例#5
0
 def set_status(self, status):
     """Update the current execution status, and set a new prompt."""
     self.status = status
     if self.stop_pending:
         pending = ' (stop pending)'
     elif self.pending_requests:
         pending = ' (%d pending)' % len(self.pending_requests)
     else:
         pending = ''
     # \x01/\x02 are markers recognized by readline as "here come"
     # zero-width control characters; ESC[K means "clear whole line"
     self.prompt = '\x01' + colorize(
         self.stcolmap[status], '\r\x1b[K\x02# ' +
         (self.instrument or '') + '[%s%s]%s %s \x01' %
         (self.modemap[self.current_mode], status, pending,
          self.spy_mode and 'spy>' or '>>')) + '\x02'
     os.write(self.wakeup_pipe_w, b' ')
示例#6
0
 def cancel_menu(self, arg):
     if not self.pending_requests:
         self.put_client('No scripts or commands are pending.')
         return
     if arg == '*':
         self.tell('unqueue', '*')
         return
     self.put_client('Showing pending scripts or commands.')
     indices = {}
     for index, (reqid, short) in enumerate(self._iter_pending(), start=1):
         indices[index] = reqid
         self.put('#   %s  %s' % (colorize('blue', '%2d' % index), short))
     res = self.ask_question('Which script to cancel ("*" for all)?')
     if res == '*':
         self.tell('unqueue', '*')
         return
     try:
         reqid = indices[int(res)]
     except (ValueError, KeyError):
         self.put_error('Invalid selection.')
         return
     self.tell('unqueue', reqid)
示例#7
0
 def put_message(self, msg, sim=False):
     """Handles the "message" signal."""
     if msg[0] == 'nicos':
         namefmt = ''
     else:
         namefmt = '%-10s: ' % msg[0]
     levelno = msg[2]
     if levelno == ACTION:
         action = namefmt + msg[3].rstrip()
         self.out.write('\x1b]0;NICOS%s\x07' %
                        (action and ' (%s)' % action or ''))
         return
     else:
         if self.subsec_ts:
             timesuf = '.%.06d] ' % ((msg[1] % 1) * 1000000)
         else:
             timesuf = '] '
         if levelno <= DEBUG:
             timefmt = strftime('[%H:%M:%S', localtime(msg[1]))
             newtext = colorize('lightgray', timefmt + timesuf) + \
                 colorize('darkgray', namefmt + msg[3].rstrip())
         elif levelno <= INFO:
             timefmt = strftime('[%H:%M:%S', localtime(msg[1]))
             newtext = colorize('lightgray', timefmt + timesuf) + \
                 namefmt + msg[3].rstrip()
         elif levelno == INPUT:
             newtext = colorize('darkgreen', msg[3].rstrip())
         elif levelno <= WARNING:
             timefmt = strftime('[%Y-%m-%d %H:%M:%S', localtime(msg[1]))
             newtext = colorize(
                 'purple', timefmt + timesuf + namefmt + levels[levelno] +
                 ': ' + msg[3].rstrip())
         else:
             timefmt = strftime('[%Y-%m-%d %H:%M:%S', localtime(msg[1]))
             newtext = colorize(
                 'red', timefmt + timesuf + namefmt + levels[levelno] +
                 ': ' + msg[3].rstrip())
     if sim:
         newtext = '(sim) ' + newtext
     self.put(newtext)
示例#8
0
 def command(self, cmd, arg):
     """Called when a "/foo" command is entered at the prompt."""
     # try to order elif cases by frequency
     if cmd in ('cmd', 'exec'):
         if cmd == 'cmd' and self.spy_mode:
             return self.command('eval', arg)
         # this is not usually entered as "/cmd foo", but only "foo"
         if self.status in ('running', 'paused'):
             reply = self.ask_question(
                 'A script is already running, '
                 'queue or execute anyway?',
                 chars='qxn')
             if reply == 'x':
                 if self.status != 'idle':
                     self.tell('exec', arg)
                 else:
                     self.run(arg)
             elif reply == 'q':
                 self.run(arg)
                 self.put_client('Command queued.')
         else:
             self.run(arg)
     elif cmd in ('r', 'run', 'run!'):
         if not arg:
             # since we remember the last edited file, we can offer
             # running it here
             if self.last_filename:
                 reply = self.ask_question(
                     'Run last used file %r?' %
                     path.basename(self.last_filename),
                     chars='yn',
                     default='y')
                 if reply == 'y':
                     self.command('run', self.last_filename)
                     return
             self.put_error('Need a file name as argument.')
             return
         fpath = path.join(self.scriptpath, path.expanduser(arg))
         try:
             code = open(fpath).read()
         except Exception as e:
             self.put_error('Unable to open file: %s.' % e)
             return
         if self.status in ('running', 'paused') and cmd != 'run!':
             if self.ask_question(
                     'A script is already running, '
                     'queue script?',
                     chars='yn',
                     default='y') == 'y':
                 self.run(code, fpath)
         else:
             self.run(code, fpath)
     elif cmd == 'update':
         if not arg:
             # always take the current filename, if it still exists
             if path.isfile(self.current_filename):
                 arg = self.current_filename
         if not arg:
             self.put_error('Need a file name as argument.')
             return
         fpath = path.join(self.scriptpath, path.expanduser(arg))
         try:
             code = open(fpath).read()
         except Exception as e:
             self.put_error('Unable to open file: %s.' % e)
             return
         reason = self.ask_input('Reason for updating:')
         self.tell('update', code, reason)
     elif cmd in ('sim', 'simulate'):
         if not arg:
             self.put_error('Need a file name or code as argument.')
             return
         fpath = path.join(self.scriptpath, path.expanduser(arg))
         self.last_filename = fpath
         # detect whether we have a filename or potential Python code
         if path.isfile(fpath) or fpath.endswith(('.py', '.txt')):
             try:
                 code = open(fpath).read()
             except Exception as e:
                 self.put_error('Unable to open file: %s.' % e)
                 return
             self.simulate(fpath, code)
         else:
             self.simulate('', arg)
     elif cmd in ('e', 'edit'):
         self.edit_file(arg)
     elif cmd == 'break':
         self.tell('break', BREAK_AFTER_STEP)
     elif cmd in ('cont', 'continue'):
         self.tell('continue')
     elif cmd in ('s', 'stop'):
         if self.status == 'running':
             self.stop_query('Stop request')
         else:
             self.tell('emergency')
     elif cmd in ('fin', 'finish'):
         self.tell('finish')
     elif cmd == 'pending':
         self.show_pending()
     elif cmd == 'cancel':
         self.cancel_menu(arg)
     elif cmd == 'disconnect':
         if self.isconnected:
             self.disconnect()
     elif cmd == 'connect':
         self.reconnect_count = 0
         if self.isconnected:
             self.put_error('Already connected. Use /disconnect first.')
         else:
             self.ask_connect()
     elif cmd in ('re', 'reconnect'):
         self.reconnect_count = 0  # no automatic reconnect
         if self.isconnected:
             self.disconnect()
         self.ask_connect(ask_all=False)
     elif cmd in ('q', 'quit'):
         if self.isconnected:
             self.disconnect()
         return 0  # i.e. exit with success
     elif cmd in ('h', 'help', '?'):
         self.help(arg)
     elif cmd == 'log':
         if arg:
             n = str(int(arg))  # make sure it's an integer
         else:
             n = '*'  # as a slice index, this means "unlimited"
         # this can take a while to transfer, but we don't want to cache
         # messages in this client just for this command
         messages = self.ask('getmessages', n)
         if messages is None:
             return
         self.put_client('Printing %s previous messages.' %
                         (n if n != '*' else 'all'))
         for msg in messages:
             self.put_message(msg)
         self.put_client('End of messages.')
     elif cmd in ('w', 'where'):
         self.print_where()
     elif cmd == 'wait':
         if arg:
             time.sleep(float(arg))
         else:
             # this command is mainly meant for testing and scripting purposes
             time.sleep(0.1)
             while self.status != 'idle':
                 time.sleep(0.1)
     elif cmd == 'trace':
         trace = self.ask('gettrace')
         if trace is None:
             return
         self.put_client('Current stacktrace of script execution:')
         for line in trace.splitlines():
             if line:
                 self.put('# ' + line)
         self.put_client('End of stacktrace.')
     elif cmd == 'debugclient':
         import pdb
         pdb.set_trace()
     elif cmd == 'debug':
         self.tell('debug', arg)
     elif cmd == 'eval':
         timefmt = colorize('lightgray', strftime('[%H:%M:%S]'))
         self.put('%s -> %s' %
                  (timefmt, self.eval(arg, None, stringify=True)))
     elif cmd == 'spy':
         if not self.spy_mode:
             self.put_client(
                 'Spy mode on: normal input is evaluated as '
                 'an expression, use /exec to execute as script.')
         else:
             self.put_client('Spy mode off.')
         self.spy_mode = not self.spy_mode
         self.set_status(self.status)
     elif cmd == 'plot':
         self.plot_data(xterm_mode=(arg == 'x'))
     elif cmd == 'subsec':
         self.subsec_ts = not self.subsec_ts
     else:
         self.put_error('Unknown command %r.' % cmd)
示例#9
0
 def ask_passwd(self, question):
     """Prompt user for a password."""
     return getpass.getpass(colorize('bold', '# %s ' % question))
示例#10
0
 def put_client(self, string):
     """Put a client info message."""
     self.put(colorize('bold', '# ' + string))
示例#11
0
 def put_error(self, string):
     """Put a client error message."""
     self.put(colorize('red', '# ERROR: ' + string))