[Supervisor-checkins] r782 - supervisor/branches/foreground/src/supervisor

Siddhant Goel siddhantgoel at gmail.com
Wed Jul 23 12:56:59 EDT 2008


Author: Siddhant Goel <siddhantgoel at gmail.com>
Date: Wed Jul 23 12:56:58 2008
New Revision: 782

Log:
replaced curses with signal

Modified:
   supervisor/branches/foreground/src/supervisor/supervisorctl.py

Modified: supervisor/branches/foreground/src/supervisor/supervisorctl.py
==============================================================================
--- supervisor/branches/foreground/src/supervisor/supervisorctl.py	(original)
+++ supervisor/branches/foreground/src/supervisor/supervisorctl.py	Wed Jul 23 12:56:58 2008
@@ -42,13 +42,18 @@
 import asyncore
 import errno
 import urlparse
-import curses
-
+import signal
+import time
+import tty
+import termios
 
 from supervisor.options import ClientOptions
 from supervisor.options import split_namespec
 from supervisor import xmlrpc
 
+def alarm_handler(*args):
+    raise Exception
+
 class Controller(cmd.Cmd):
 
     def __init__(self, options, completekey='tab', stdin=None,
@@ -722,143 +727,102 @@
             "version\t\t\tShow the version of the remote supervisord "
             "process")
 
-    def _foreground(self,program,supervisor):
-        # initialise curses
-        stdscr=curses.initscr()
-        stdscr.scrollok(True)
-	stdscr.keypad(1)
-	# put a curses.mousemask(curses.ALL_MOUSE_EVENTS)
-        # whenever handling mouse events becomes clearer
-        stdscr.move(0,0)
-        stdscr.addstr('Entered foreground mode for process %s'%program)
-        # print out any initial output/error messages
-        if self.outputs[-1]:
-            stdscr.addstr(self.outputs[-1])
-        if self.errors[-1]:
-            stdscr.addstr(self.errors[-1])
-        stdscr.refresh()
-        try:
-            while True:
-                # check whether the window should be scrolled
-                # scrolling down is perfect, scrolling up needs to be checked
-                # a mouse event should scroll the window up
-                maxy,maxx = stdscr.getmaxyx()
-                y,x = stdscr.getyx()
-                if y == maxy:
-                    stdscr.scroll()
-                curses.noecho()
-                # set a timer on getch, so that
-                # it stops blocking after 0.5 seconds
-                curses.halfdelay(5)
-                a=stdscr.getch()
-                curses.nocbreak() # quit halfdelay mode
-                # a=curses.ERR when user does not press a key within 0.5s
-                if not a == curses.ERR:
-                    # user pressed a key
-                    # take inputs, send it to supervisor
-                    # receive outputs, and display the output (if necessary)
-                    curses.echo()
-		    # add the mouse event handling code (for scrolling) later on
-                    # stdscr.addstr('\n\rEnter the input string\n\r')  (never mind this one)
-                    stdscr.refresh()
-                    inp=stdscr.getstr() 
-                    # inp=r'%s'%inp
-                    supervisor.sendProcessStdin(program,inp)
-                    output=supervisor.tailProcessStdoutLog(program,0,1600)[0]
-                    error=supervisor.tailProcessStderrLog(program,0,1600)[0]
-                    if output:
-                        stdscr.addstr(output)
-                        self.outputs.append(output)
-                    if error:
-                        stdscr.addstr(error)
-                        self.errors.append(error)
-                    stdscr.refresh()
-                    supervisor.clearProcessLogs(program)
-                else:
-                    # user didn't press a key, so check for any
-                    # updates on output/error messages from the process
-                    output=supervisor.tailProcessStdoutLog(program,0,1600)[0]
-                    error=supervisor.tailProcessStderrLog(program,0,1600)[0]
-                    if output:
-                        stdscr.addstr(output)
-                        self.outputs.append(output)
-                    if error:
-                        stdscr.addstr(error)
-                        self.errors.append(error)
-                    stdscr.refresh()
-                    supervisor.clearProcessLogs(program)
-                if supervisor.getProcessInfo(program)['pid'] == 0:
-                    stdscr.addstr('Process got killed\n')
-                    stdscr.addstr('Exiting foreground\n')
-                    stdscr.addstr('Press any key to exit\n')
-                    stdscr.getch()
-                    break
-        except KeyboardInterrupt:
-            stdscr.addstr('Exiting foreground\n')
-            stdscr.addstr('Press any key to exit\n')
-            curses.nocbreak()
-            stdscr.getch()
-            curses.echo()
-	    stdscr.keypad(0)
-            curses.endwin()
-            del stdscr
-            return
-        except:
-            stdscr.addstr('An error occured\n')
-            stdscr.addstr('Exiting foreground\n')
-            stdscr.addstr('Press any key to exit\n')
-            stdscr.getch()
-            curses.echo()
-	    stdscr.keypad(0)
-            curses.endwin()
-            del stdscr
-            return
-        curses.echo()
-        curses.nocbreak()
-	stdscr.keypad(0)
-        curses.endwin()
-        del stdscr
-        return
-
-    def do_fg(self, args=None):
+    def do_fg(self,args=None):
         if not self.ctl.upcheck():
             return
         if not args:
             self.help_fg()
             return
-        args=args.strip().split()
+        args=args.split()
         if len(args)>1:
-            self.ctl.output('ERROR: Multiple process names entered\n')
-            self.help_fg()
+            self.ctl.output('ERROR : too many process names supplied')
             return
-        # check whether the process name is sane
         program=args[0]
         supervisor=self.ctl.get_supervisor()
         try:
             info=supervisor.getProcessInfo(program)
         except xmlrpclib.Fault, msg:
             if msg.faultString == 'BAD_NAME: %s' % program:
-                self.ctl.output('ERROR -- Bad process name supplied')
-            else:
-                self.ctl.output('ERROR -- %s' % msg)
+                self.ctl.output('Bad process name supplied')
+                return
+            # for any other fault,
+            self.ctl.output(str(msg))
             return
         if info['pid'] == 0:
-            self.ctl.output('ERROR -- Process not running')
+            self.ctl.output('ERROR : Process not running')
             return
         # everything good, continue
+        self.ctl.output('Entered foreground mode for %s ' % program)
+        self.ctl.output('Press any key to start entering the input string for the process')
         self.outputs=[supervisor.tailProcessStdoutLog(program,0,1600)[0]]
         self.errors=[supervisor.tailProcessStderrLog(program,0,1600)[0]]
         supervisor.clearProcessLogs(program)
-        self._foreground(program,supervisor)
-        
+        if self.outputs[-1]:
+            self.ctl.output(self.outputs[-1])
+        if self.errors[-1]:
+            self.ctl.output(self.errors[-1])
+        signal.signal(signal.SIGALRM, alarm_handler)
+        original_settings=termios.tcgetattr(sys.stdin.fileno())
+        while True:
+            try:
+                try:
+                    # put the terminal in raw mode
+                    tty.setraw(sys.stdin.fileno())
+                    signal.alarm(1)
+                    ready = sys.stdin.read(1)
+                    signal.alarm(0)
+                finally:
+                    # restore the terminal to its original state
+                    termios.tcsetattr(sys.stdin.fileno(),termios.TCSADRAIN,original_settings)
+                if ready:
+                    self.ctl.output('Enter the input string')
+                    inp=sys.stdin.readline()
+                    supervisor.sendProcessStdin(program,inp)
+                    time.sleep(0.5)
+                    # check if there is any useful output/error message
+                    output=supervisor.tailProcessStdoutLog(program,0,1600)[0]
+                    error=supervisor.tailProcessStderrLog(program,0,1600)[0]
+                    if output:
+                        self.outputs.append(output)
+                        self.ctl.output(output)
+                    if error:
+                        self.errors.append(error)
+                        self.ctl.output(error)
+                    supervisor.clearProcessLogs(program)
+                if supervisor.getProcessInfo(program)['pid'] == 0:
+                    self.ctl.output('Process got killed')
+                    self.ctl.output('Exiting foreground')
+                    return
+                continue
+            except KeyboardInterrupt:
+                signal.alarm(0)
+                self.ctl.output('Exiting foreground')
+                return
+            except:
+                signal.alarm(0)
+                if supervisor.getProcessInfo(program)['pid'] == 0:
+                    self.ctl.output('Process got killed')
+                    self.ctl.output('Exiting foreground')
+                    return
+                output=supervisor.tailProcessStdoutLog(program,0,1600)[0]
+                error=supervisor.tailProcessStderrLog(program,0,1600)[0]
+                if output:
+                    self.outputs.append(output)
+                    self.ctl.output(output)
+                if error:
+                    self.errors.append(error)
+                    self.ctl.output(error)
+                supervisor.clearProcessLogs(program)
+                continue
+
     def help_fg(self,args=None):
         self.ctl.output('fg <process_name> : Connect to a process in foreground mode')
-        self.ctl.output('While in foreground mode, press any key to start entering')
-        self.ctl.output('the input string for the process.')
-        self.ctl.output('Press any key within 0.5 seconds to enter an input')
-        self.ctl.output('After which, the process would be checked for any')
-        self.ctl.output('output/error messages available')
-        self.ctl.output('Press Ctrl+C to exit foreground')
+        self.ctl.output('While in foreground, press any key to start entering the')
+        self.ctl.output('input string for the process.')
+        self.ctl.output('This input string would be sent to the process, and any')
+        self.ctl.output('interesting output/error messages will be displayed.')
+        self.ctl.output('Press Ctrl+C to exit foreground mode')
+
 
 def main(args=None, options=None):
     if options is None:


More information about the Supervisor-checkins mailing list