Source code for stoqlib.gui.widgets.processview

# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4

##
## Copyright (C) 2011 Async Open Source <http://www.async.com.br>
## All rights reserved
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU Lesser General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., or visit: http://www.gnu.org/.
##
## Author(s): Stoq Team <stoq-devel@async.com.br>
##
##

"""Process View a simple view of a process' stdout or stderr"""

import platform

import glib
import gtk
from kiwi.utils import gsignal

from stoqlib.lib.process import Process, PIPE
from stoqlib.lib.threadutils import threadit, schedule_in_main_thread

CHILD_TIMEOUT = 100  # in ms
N_BYTES = 4096  # a page


[docs]class ProcessView(gtk.ScrolledWindow): gsignal('read-line', str) gsignal('finished', object) def __init__(self): gtk.ScrolledWindow.__init__(self) self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) self.set_shadow_type(gtk.SHADOW_ETCHED_IN) self.listen_stdout = True self.listen_stderr = False self._create_view() def _create_view(self): self._textview = gtk.TextView() self._textview.set_editable(False) self._textview.set_cursor_visible(False) self._textview.set_wrap_mode(gtk.WRAP_WORD) self._textview.set_property('width-request', 1) self.add(self._textview) self.show() self._textview.show() def _watch_fd(self, fd): for l in iter(fd.readline, ''): # os-independent form of stripping newline from the end of # the fine. We want to add it manually bellow line = l.splitlines()[0] schedule_in_main_thread(self.emit, 'read-line', line) schedule_in_main_thread(self.feed, line + '\r\n') def _check_child_finished(self): self.retval = self.proc.poll() finished = self.retval is not None if finished: self._finished() return not finished def _finished(self): self.emit('finished', self.retval)
[docs] def execute_command(self, args): self.feed('Executing: %s\r\n' % (' '.join(args))) kwargs = {} # On Windows you have to passin stdout/stdin = PIPE or # it will result in an invalid handle, see # * CR2012071248 # * http://bugs.python.org/issue3905 if self.listen_stdout or platform.system() == 'Windows': kwargs['stdout'] = PIPE if self.listen_stderr or platform.system() == 'Windows': kwargs['stderr'] = PIPE self.proc = Process(args, **kwargs) if self.listen_stdout: threadit(self._watch_fd, self.proc.stdout) if self.listen_stderr: threadit(self._watch_fd, self.proc.stderr) # We could probably listen to SIGCHLD here instead glib.timeout_add(CHILD_TIMEOUT, self._check_child_finished)
[docs] def feed(self, line): tbuffer = self._textview.get_buffer() tbuffer.insert(tbuffer.get_end_iter(), line) self._textview.scroll_to_iter(tbuffer.get_end_iter(), 0.0, False, 0, 0)
@property def terminal(self): return self._terminal