class ANSIGUI(GUI): def __init__(self, config, workflow): config.set('report', 'BasicReport BarReport') (self._stored_stdout, self._stored_stderr) = (sys.stdout, sys.stderr) GUI.__init__(self, config, workflow) self._reportHeight = 0 self._statusHeight = 1 self._old_message = None self._lock = GCLock(threading.RLock()) # drawing lock self._last_report = 0 self._old_size = None def _draw(self, fun): new_size = self._console.getmaxyx() if self._old_size != new_size: self._old_size = new_size self._schedule_update_layout() self._lock.acquire() self._console.hideCursor() self._console.savePos() try: fun() finally: self._console.loadPos() self._console.showCursor() self._lock.release() # Event handling for resizing def _update_layout(self): (sizey, sizex) = self._console.getmaxyx() self._old_size = (sizey, sizex) self._reportHeight = self._report.getHeight() self._console.erase() self._console.setscrreg( min(self._reportHeight + self._statusHeight + 1, sizey), sizey) utils.printTabular.wraplen = sizex - 5 self._update_all() def _schedule_update_layout(self, sig=None, frame=None): start_thread( 'update layout', self._draw, self._update_layout) # using new thread to ensure RLock is free def _wait(self, timeout): oldHandler = signal.signal(signal.SIGWINCH, self._schedule_update_layout) result = utils.wait(timeout) signal.signal(signal.SIGWINCH, oldHandler) return result def _update_report(self): if time.time() - self._last_report < 1: return self._last_report = time.time() self._console.move(0, 0) self._new_stdout.logged = False self._report.display() self._new_stdout.logged = True def _update_status(self): activity_message = None for activity in Activity.root.get_children(): activity_message = activity.getMessage() + '...' if len(activity_message) > 75: activity_message = activity_message[: 37] + '...' + activity_message[ -35:] self._console.move(self._reportHeight + 1, 0) self._new_stdout.logged = False if self._old_message: self._stored_stdout.write(self._old_message.center(65) + '\r') self._stored_stdout.flush() self._old_message = activity_message if activity_message: self._stored_stdout.write('%s' % activity_message.center(65)) self._stored_stdout.flush() self._new_stdout.logged = True def _update_log(self): self._console.move(self._reportHeight + 2, 0) self._console.eraseDown() self._new_stdout.dump() def _update_all(self): self._last_report = 0 self._update_report() self._update_status() self._update_log() def _schedule_update_report_status(self): self._draw(self._update_report) self._draw(self._update_status) def displayWorkflow(self): if not sys.stdout.isatty(): return self._workflow.process(self._wait) self._console = Console(sys.stdout) self._new_stdout = GUIStream(sys.stdout, self._console, self._lock) self._new_stderr = GUIStream(sys.stderr, self._console, self._lock) Activity.callbacks.append(self._schedule_update_report_status) try: # Main cycle - GUI mode (sys.stdout, sys.stderr) = (self._new_stdout, self._new_stderr) self._console.erase() self._schedule_update_layout() self._workflow.process(self._wait) finally: (sys.stdout, sys.stderr) = (self._stored_stdout, self._stored_stderr) self._console.setscrreg() self._console.erase() self._update_all()
class ANSIGUI(GUI): def __init__(self, config, workflow): config.set('report', 'BasicReport BarReport') (self._stored_stdout, self._stored_stderr) = (sys.stdout, sys.stderr) GUI.__init__(self, config, workflow) self._reportHeight = 0 self._statusHeight = 1 self._old_message = None self._lock = GCLock(threading.RLock()) # drawing lock self._last_report = 0 self._old_size = None def _draw(self, fun): new_size = self._console.getmaxyx() if self._old_size != new_size: self._old_size = new_size self._schedule_update_layout() self._lock.acquire() self._console.hideCursor() self._console.savePos() try: fun() finally: self._console.loadPos() self._console.showCursor() self._lock.release() # Event handling for resizing def _update_layout(self): (sizey, sizex) = self._console.getmaxyx() self._old_size = (sizey, sizex) self._reportHeight = self._report.getHeight() self._console.erase() self._console.setscrreg(min(self._reportHeight + self._statusHeight + 1, sizey), sizey) utils.printTabular.wraplen = sizex - 5 self._update_all() def _schedule_update_layout(self, sig = None, frame = None): start_thread('update layout', self._draw, self._update_layout) # using new thread to ensure RLock is free def _wait(self, timeout): oldHandler = signal.signal(signal.SIGWINCH, self._schedule_update_layout) result = utils.wait(timeout) signal.signal(signal.SIGWINCH, oldHandler) return result def _update_report(self): if time.time() - self._last_report < 1: return self._last_report = time.time() self._console.move(0, 0) self._new_stdout.logged = False self._report.display() self._new_stdout.logged = True def _update_status(self): activity_message = None for activity in Activity.root.get_children(): activity_message = activity.getMessage() + '...' if len(activity_message) > 75: activity_message = activity_message[:37] + '...' + activity_message[-35:] self._console.move(self._reportHeight + 1, 0) self._new_stdout.logged = False if self._old_message: self._stored_stdout.write(self._old_message.center(65) + '\r') self._stored_stdout.flush() self._old_message = activity_message if activity_message: self._stored_stdout.write('%s' % activity_message.center(65)) self._stored_stdout.flush() self._new_stdout.logged = True def _update_log(self): self._console.move(self._reportHeight + 2, 0) self._console.eraseDown() self._new_stdout.dump() def _update_all(self): self._last_report = 0 self._update_report() self._update_status() self._update_log() def _schedule_update_report_status(self): self._draw(self._update_report) self._draw(self._update_status) def displayWorkflow(self): if not sys.stdout.isatty(): return self._workflow.process(self._wait) self._console = Console(sys.stdout) self._new_stdout = GUIStream(sys.stdout, self._console, self._lock) self._new_stderr = GUIStream(sys.stderr, self._console, self._lock) Activity.callbacks.append(self._schedule_update_report_status) try: # Main cycle - GUI mode (sys.stdout, sys.stderr) = (self._new_stdout, self._new_stderr) self._console.erase() self._schedule_update_layout() self._workflow.process(self._wait) finally: (sys.stdout, sys.stderr) = (self._stored_stdout, self._stored_stderr) self._console.setscrreg() self._console.erase() self._update_all()