util/ProcessLogger.py
changeset 1407 cf3d2b53dd68
parent 958 511bf048b8b7
child 1415 c411fc7246eb
equal deleted inserted replaced
1406:82db84fe88ea 1407:cf3d2b53dd68
     1 #!/usr/bin/env python
     1 #!/usr/bin/env python
     2 # -*- coding: utf-8 -*-
     2 # -*- coding: utf-8 -*-
     3 
     3 
     4 #This file is part of Beremiz, a Integrated Development Environment for
     4 #This file is part of Beremiz, a Integrated Development Environment for
     5 #programming IEC 61131-3 automates supporting plcopen standard and CanFestival. 
     5 #programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
     6 #
     6 #
     7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
     7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
     8 #
     8 #
     9 #See COPYING file for copyrights details.
     9 #See COPYING file for copyrights details.
    10 #
    10 #
    29 from threading import Timer, Lock, Thread, Semaphore
    29 from threading import Timer, Lock, Thread, Semaphore
    30 import os, sys
    30 import os, sys
    31 if os.name == 'posix':
    31 if os.name == 'posix':
    32     from signal import SIGTERM, SIGKILL
    32     from signal import SIGTERM, SIGKILL
    33 
    33 
    34     
    34 
    35 class outputThread(Thread):
    35 class outputThread(Thread):
    36     """
    36     """
    37     Thread is used to print the output of a command to the stdout
    37     Thread is used to print the output of a command to the stdout
    38     """
    38     """
    39     def __init__(self, Proc, fd, callback=None, endcallback=None):
    39     def __init__(self, Proc, fd, callback=None, endcallback=None):
    64                 err = self.Proc.wait()
    64                 err = self.Proc.wait()
    65             except:
    65             except:
    66                 err = self.retval
    66                 err = self.retval
    67             self.finished = True
    67             self.finished = True
    68             self.endcallback(self.Proc.pid, err)
    68             self.endcallback(self.Proc.pid, err)
    69         
    69 
    70 class ProcessLogger:
    70 class ProcessLogger:
    71     def __init__(self, logger, Command, finish_callback = None, 
    71     def __init__(self, logger, Command, finish_callback = None,
    72                  no_stdout = False, no_stderr = False, no_gui = True, 
    72                  no_stdout = False, no_stderr = False, no_gui = True,
    73                  timeout = None, outlimit = None, errlimit = None,
    73                  timeout = None, outlimit = None, errlimit = None,
    74                  endlog = None, keyword = None, kill_it = False, cwd = None):
    74                  endlog = None, keyword = None, kill_it = False, cwd = None):
    75         self.logger = logger
    75         self.logger = logger
    76         if not isinstance(Command, list):
    76         if not isinstance(Command, list):
    77             self.Command_str = Command
    77             self.Command_str = Command
    84                 else:
    84                 else:
    85                     self.Command.append(word)
    85                     self.Command.append(word)
    86         else:
    86         else:
    87             self.Command = Command
    87             self.Command = Command
    88             self.Command_str = subprocess.list2cmdline(self.Command)
    88             self.Command_str = subprocess.list2cmdline(self.Command)
    89         
    89 
    90         self.Command = map(lambda x: x.encode(sys.getfilesystemencoding()),
    90         self.Command = map(lambda x: x.encode(sys.getfilesystemencoding()),
    91                            self.Command)
    91                            self.Command)
    92         
    92 
    93         self.finish_callback = finish_callback
    93         self.finish_callback = finish_callback
    94         self.no_stdout = no_stdout
    94         self.no_stdout = no_stdout
    95         self.no_stderr = no_stderr
    95         self.no_stderr = no_stderr
    96         self.startupinfo = None
    96         self.startupinfo = None
    97         self.errlen = 0
    97         self.errlen = 0
   103         self.errdata = []
   103         self.errdata = []
   104         self.keyword = keyword
   104         self.keyword = keyword
   105         self.kill_it = kill_it
   105         self.kill_it = kill_it
   106         self.finishsem = Semaphore(0)
   106         self.finishsem = Semaphore(0)
   107         self.endlock = Lock()
   107         self.endlock = Lock()
   108         
   108 
   109         popenargs= {
   109         popenargs= {
   110                "cwd":os.getcwd() if cwd is None else cwd,
   110                "cwd":os.getcwd() if cwd is None else cwd,
   111                "stdin":subprocess.PIPE, 
   111                "stdin":subprocess.PIPE,
   112                "stdout":subprocess.PIPE, 
   112                "stdout":subprocess.PIPE,
   113                "stderr":subprocess.PIPE}
   113                "stderr":subprocess.PIPE}
   114         
   114 
   115         if no_gui == True and wx.Platform == '__WXMSW__':
   115         if no_gui == True and wx.Platform == '__WXMSW__':
   116             self.startupinfo = subprocess.STARTUPINFO()
   116             self.startupinfo = subprocess.STARTUPINFO()
   117             self.startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
   117             self.startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
   118             popenargs["startupinfo"] = self.startupinfo
   118             popenargs["startupinfo"] = self.startupinfo
   119         elif wx.Platform == '__WXGTK__':
   119         elif wx.Platform == '__WXGTK__':
   120             popenargs["shell"] = False
   120             popenargs["shell"] = False
   121         
   121 
   122         self.Proc = subprocess.Popen( self.Command, **popenargs )
   122         self.Proc = subprocess.Popen( self.Command, **popenargs )
   123 
   123 
   124         self.outt = outputThread(
   124         self.outt = outputThread(
   125                       self.Proc,
   125                       self.Proc,
   126                       self.Proc.stdout,
   126                       self.Proc.stdout,
   127                       self.output,
   127                       self.output,
   128                       self.finish) 
   128                       self.finish)
   129         self.outt.start()
   129         self.outt.start()
   130 
   130 
   131         self.errt = outputThread(
   131         self.errt = outputThread(
   132                       self.Proc,
   132                       self.Proc,
   133                       self.Proc.stderr,
   133                       self.Proc.stderr,
   145         self.outlen += 1
   145         self.outlen += 1
   146         if not self.no_stdout:
   146         if not self.no_stdout:
   147             self.logger.write(v)
   147             self.logger.write(v)
   148         if (self.keyword and v.find(self.keyword)!=-1) or (self.outlimit and self.outlen > self.outlimit):
   148         if (self.keyword and v.find(self.keyword)!=-1) or (self.outlimit and self.outlen > self.outlimit):
   149             self.endlog()
   149             self.endlog()
   150             
   150 
   151     def errors(self,v):
   151     def errors(self,v):
   152         self.errdata.append(v)
   152         self.errdata.append(v)
   153         self.errlen += 1
   153         self.errlen += 1
   154         if not self.no_stderr:
   154         if not self.no_stderr:
   155             self.logger.write_warning(v)
   155             self.logger.write_warning(v)
   193         if self.endlock.acquire(False):
   193         if self.endlock.acquire(False):
   194             self.finishsem.release()
   194             self.finishsem.release()
   195             if not self.outt.finished and self.kill_it:
   195             if not self.outt.finished and self.kill_it:
   196                self.kill()
   196                self.kill()
   197 
   197 
   198         
   198 
   199     def spin(self):
   199     def spin(self):
   200         self.finishsem.acquire()
   200         self.finishsem.acquire()
   201         return [self.exitcode, "".join(self.outdata), "".join(self.errdata)]
   201         return [self.exitcode, "".join(self.outdata), "".join(self.errdata)]
   202 
   202