~ubuntu-branches/ubuntu/utopic/pida/utopic

« back to all changes in this revision

Viewing changes to pida/utils/gprocess.py

  • Committer: Bazaar Package Importer
  • Author(s): Jan Luebbe
  • Date: 2007-04-17 16:08:06 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20070417160806-3ttlb6igf94x9i03
Tags: 0.4.4-1
* New upstream release (closes: #419129)
* Add dependency on python-glade2 (closes: #418716)
* Update copyright

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import subprocess
 
2
import sys
 
3
import os
 
4
import gobject
 
5
 
 
6
__all__ = ("SelectProcess", "ThreadedProcess", "GProcess")
 
7
 
 
8
def gsignature(*args, **kwargs):
 
9
    run_when = kwargs.pop("run_when", gobject.SIGNAL_RUN_FIRST)
 
10
    return_type = kwargs.pop("return_type", gobject.TYPE_NONE)
 
11
    return (run_when, return_type, args)
 
12
 
 
13
def read_all_iter(buff, block_size=2048):
 
14
    """Auxiliar function that reads all data it cans"""
 
15
    chunk = read_some(buff, block_size)
 
16
    yield chunk
 
17
    #return chunk 
 
18
    while len(chunk) == block_size:
 
19
        chunk = read_some(buff, block_size)
 
20
        yield chunk
 
21
 
 
22
def read_all(sock, block_size=2048):
 
23
    return "".join(read_all_iter(sock, block_size))
 
24
 
 
25
def read_some(buff, block_size=2048):
 
26
    return os.read(buff.fileno(), block_size)
 
27
 
 
28
class AbstractGProcess(gobject.GObject):
 
29
    __gsignals__ = {
 
30
        "started": gsignature(gobject.TYPE_INT),
 
31
        "finished": gsignature(gobject.TYPE_INT),
 
32
        "stdout-data": gsignature(gobject.TYPE_STRING),
 
33
        "stderr-data": gsignature(gobject.TYPE_STRING),
 
34
    }
 
35
    
 
36
    def __init__(self, args):
 
37
        self.args = args
 
38
        gobject.GObject.__init__(self)
 
39
 
 
40
    def stop(self):
 
41
        if self.proc is None:
 
42
            return
 
43
        
 
44
        if self.proc.poll() is not None:
 
45
            return
 
46
            
 
47
        try:
 
48
            os.kill(self.proc.pid, 15)
 
49
        except OSError:
 
50
            try:
 
51
                os.kill(self.proc.pid, 9)
 
52
            except OSError:
 
53
                pass
 
54
        
 
55
 
 
56
    def do_finished(self, pid):
 
57
        self.proc = None
 
58
 
 
59
class PolledProcess(AbstractGProcess):
 
60
    polling_time = 50
 
61
 
 
62
    def start(self):
 
63
        self.proc = subprocess.Popen(
 
64
            self.args,
 
65
            stdout=subprocess.PIPE,
 
66
            stderr=subprocess.PIPE,
 
67
            
 
68
        )
 
69
        self.emit("started", self.proc.pid)
 
70
        gobject.timeout_add(self.polling_time, self.on_tick)
 
71
 
 
72
    def on_tick(self):
 
73
        val = self.proc.poll()
 
74
        if val is not None:
 
75
            # TODO: make this smoother, data should be read in
 
76
            # chunks in order to avoid flooding the UI with info
 
77
            self.emit("stdout-data", self.proc.stdout.read())
 
78
            self.emit("stderr-data", self.proc.stderr.read())
 
79
            self.emit("finished", val)
 
80
 
 
81
        return val is None
 
82
 
 
83
class SelectProcess(AbstractGProcess):
 
84
 
 
85
    def start(self):
 
86
        self.proc = subprocess.Popen(
 
87
            self.args,
 
88
            stdout=subprocess.PIPE,
 
89
            stderr=subprocess.PIPE,
 
90
        )
 
91
 
 
92
        self._out = gobject.io_add_watch(self.proc.stdout,
 
93
            gobject.IO_IN, self.on_buff_read, "stdout-data")
 
94
        self._err = gobject.io_add_watch(self.proc.stderr,
 
95
            gobject.IO_IN, self.on_buff_read, "stderr-data")
 
96
        gobject.child_watch_add(self.proc.pid, self.on_finished)
 
97
        self.emit("started", self.proc.pid)
 
98
 
 
99
    def on_buff_read(self, fd, cond, signame):
 
100
        data = read_some(fd)
 
101
        self.emit(signame, data)
 
102
 
 
103
    def on_finished(self, pid, condition):
 
104
        def _delayed_stop():
 
105
            gobject.source_remove(self._out)
 
106
            gobject.source_remove(self._err)
 
107
            self.emit('stdout-data', read_all(self.proc.stdout))
 
108
            self.emit('stderr-data', read_all(self.proc.stderr))
 
109
            self.emit("finished", condition / 256)
 
110
        _delayed_stop()
 
111
        #gobject.idle_add(_delayed_stop)
 
112
 
 
113
if sys.platform == "win32":
 
114
    GProcess = PolledProcess
 
115
else:
 
116
    GProcess = SelectProcess
 
117
 
 
118
if __name__ == '__main__':
 
119
    import gtk
 
120
 
 
121
    def on_read(proc, data):
 
122
        print data,
 
123
 
 
124
    def on_finished(obj, err):
 
125
        print err,
 
126
        gtk.main_quit()
 
127
 
 
128
    #gproc = GProcess
 
129
    gproc = PolledProcess
 
130
 
 
131
 
 
132
    proc = gproc(sys.argv[1:])
 
133
    proc.start()
 
134
    proc.connect("finished", on_finished)
 
135
    proc.connect("stdout-data", on_read)
 
136
    proc.connect("stderr-data", on_read)
 
137
    gtk.main()
 
138
 
 
139