import sys from threading import (Thread, Event) from lib.string_queue import StringQueue from time import (sleep) class StdioRedirect: def __init__(self): self.redirect_enabled = False self.spy_enabled = False self.ini_stdout = sys.stdout self.ini_stderr = sys.stderr self.stream = self.ini_stdout def redirect(self, stream): if not self.spy_enabled: self.out_stream = stream self.stream = self.out_stream sys.stdout = self.out_stream sys.stderr = self.out_stream self.redirect_enabled = True def restore(self): if not self.spy_enabled and self.redirect_enabled: sys.stdout = self.ini_stdout sys.stderr = self.ini_stderr self.redirect_enabled = False def intercept(self): if not self.spy_enabled: self.thr_started = Event() self.log_buf = StringQueue() self.in_stream = StringQueue() self.stop_output = Event() self.thrd_out = Thread(target=self.interceptStdOut) self.thrd_out.daemon = True sys.stdout = self.in_stream sys.stderr = self.in_stream self.stream = self.in_stream self.thrd_out.start() self.thr_started.wait() self.spy_enabled = True def stop(self): if self.spy_enabled: sys.stdout = self.out_stream sys.stderr = self.out_stream self.stream = self.out_stream self.stop_output.set() self.thrd_out.join() del self.log_buf del self.in_stream del self.stop_output del self.thrd_out del self.thr_started self.spy_enabled = False def interceptStdOut(self): self.thr_started.set() while not self.stop_output.is_set(): data = self.in_stream.read() self.log_buf.write(data) self.out_stream.write(data) if data == '': sleep(0.1) def read(self): ret = '' if self.spy_enabled: ret = self.log_buf.read() return ret stdio_redir = StdioRedirect()