Package node_manager_fkie :: Module supervised_popen
[frames] | no frames]

Source Code for Module node_manager_fkie.supervised_popen

  1  # Software License Agreement (BSD License) 
  2  # 
  3  # Copyright (c) 2012, Fraunhofer FKIE/US, Alexander Tiderko 
  4  # All rights reserved. 
  5  # 
  6  # Redistribution and use in source and binary forms, with or without 
  7  # modification, are permitted provided that the following conditions 
  8  # are met: 
  9  # 
 10  #  * Redistributions of source code must retain the above copyright 
 11  #    notice, this list of conditions and the following disclaimer. 
 12  #  * Redistributions in binary form must reproduce the above 
 13  #    copyright notice, this list of conditions and the following 
 14  #    disclaimer in the documentation and/or other materials provided 
 15  #    with the distribution. 
 16  #  * Neither the name of Fraunhofer nor the names of its 
 17  #    contributors may be used to endorse or promote products derived 
 18  #    from this software without specific prior written permission. 
 19  # 
 20  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 21  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 22  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 23  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 24  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 25  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 26  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 27  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 28  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 29  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 30  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 31  # POSSIBILITY OF SUCH DAMAGE. 
 32   
 33  from python_qt_binding.QtCore import QObject, Signal 
 34  import subprocess 
 35  import threading 
 36   
 37  from .detailed_msg_box import MessageBox 
38 39 40 -class SupervisedPopen(QObject):
41 ''' 42 The class overrides the subprocess.Popen and waits in a thread for its finish. 43 If an error is printed out, it will be shown in a message dialog. 44 ''' 45 error = Signal(str, str, str) 46 '''@ivar: the signal is emitted if error output was detected (id, decription, message)''' 47 48 finished = Signal(str) 49 '''@ivar: the signal is emitted on exit (id)''' 50
51 - def __init__(self, args, bufsize=0, executable=None, stdin=None, stdout=None, 52 stderr=subprocess.PIPE, preexec_fn=None, close_fds=False, 53 shell=False, cwd=None, env=None, universal_newlines=False, 54 startupinfo=None, creationflags=0, object_id='', description=''):
55 ''' 56 For arguments see https://docs.python.org/2/library/subprocess.html 57 Additional arguments: 58 :param object_id: the identification string of this object and title of the 59 error message dialog 60 :type object_id: str 61 :param description: the description string used as addiotional information 62 in dialog if an error was occured 63 :type description: str 64 ''' 65 try: 66 QObject.__init__(self) 67 self._args = args 68 self._object_id = object_id 69 self._description = description 70 self.error.connect(self.on_error) 71 # wait for process to avoid 'defunct' processes 72 self.popen = subprocess.Popen(args=args, bufsize=bufsize, executable=executable, stdin=stdin, stdout=stdout, 73 stderr=stderr, preexec_fn=preexec_fn, close_fds=close_fds, shell=shell, cwd=cwd, env=env, 74 universal_newlines=universal_newlines, startupinfo=startupinfo, creationflags=creationflags) 75 thread = threading.Thread(target=self._supervise) 76 thread.setDaemon(True) 77 thread.start() 78 except Exception as _: 79 raise
80 81 # def __del__(self): 82 # print "Deleted:", self._description 83 84 @property
85 - def stdout(self):
86 return self.popen.stdout
87 88 @property
89 - def stderr(self):
90 return self.popen.stderr
91 92 @property
93 - def stdin(self):
94 return self.popen.stdin
95
96 - def _supervise(self):
97 ''' 98 Wait for process to avoid 'defunct' processes 99 ''' 100 self.popen.wait() 101 result_err = '' 102 if self.stderr is not None: 103 result_err = self.stderr.read() 104 if result_err: 105 self.error.emit(self._object_id, self._description, result_err) 106 self.finished.emit(self._object_id)
107
108 - def on_error(self, object_id, descr, msg):
109 MessageBox.warning(None, object_id, '%s\n\n' 110 '%s' % (descr, msg), ' '.join(self._args))
111