summaryrefslogtreecommitdiffstats
path: root/runin-gtk
blob: 6e435ed458bb004613cc00e6f79e2224f8147e4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#!/usr/bin/python
# a mostly output-only ui for runin tests

import os
import signal
from gi.repository import Gtk, Gdk, GObject


class Monitor:

    """ a status file monitor, sets up a signal handler so that the
    parent runin-tests can notify us of a new status file, then on the
    next update cycle we read the status file and delete it"""

    def __init__(self):
        self.dirty = True

        self._name = os.getenv('RUNIN_STATUS')
        if not self._name:
            self._name = '/tmp/runin.status'

        signal.signal(signal.SIGUSR1, self._monitor_signal_cb)

    def _monitor_signal_cb(self, a, b):
        self.dirty = True

    def readlines(self):
        self.dirty = False
        try:
            f = open(self._name, 'r')
            x = f.readlines()
            f.close()
            os.remove(self._name)
        except IOError:
            x = []
            pass
        return x


class Window:

    def __init__(self):
        self.window = Gtk.Window(Gtk.WindowType.POPUP)
        self.window.set_default_size(1200, 900 - 480 - 2)
        self.window.set_border_width(10)

        # a heading, identifying the program
        self.heading = Gtk.Label(self.make_heading())

        # a progress bar
        self.progress = Gtk.ProgressBar()

        # a table for progress detail
        self.rows = 8
        self.columns = 2
        self.table = Gtk.Table(rows=self.rows, columns=self.columns)
        self.table.set_col_spacings(6)

        self.table.labels = {}
        for row in range(self.rows):
            for column in range(self.columns):
                label = Gtk.Label('(%d,%d) ####################' %
                                  (column, row))
                if column == 0:
                    label.set_alignment(1.0, 0.5)
                else:
                    label.set_alignment(0.0, 0.5)
                label.show()
                self.table.labels[row, column] = label
                self.table.attach(label, column, column+1, row, row+1)

        # lay the above out vertically
        self.box = Gtk.VBox()
        self.box.set_spacing(10)
        self.box.add(self.heading)
        self.box.add(self.progress)
        self.box.add(self.table)

        self.heading.show()
        self.progress.show()
        self.table.show()
        self.box.show()

        self.window.add(self.box)

        self.window.connect("key-press-event", self._key_press_event_cb)
        self.window.connect("delete_event", self._delete_event_cb)
        self.window.connect("destroy", self._destroy_cb)

        # position the window against the lower right of screen
        self.window.set_gravity(Gdk.Gravity.SOUTH_EAST)
        width, height = self.window.get_size()
        self.window.move(Gdk.Screen.width() - width,
                         Gdk.Screen.height() - height)

        self.window.show()

        self._monitor = Monitor()
        GObject.timeout_add(100, self._monitor_timeout_cb)

        self.progress.grab_focus()

    def make_heading(self):
        """ generate heading text """
        package = 'olpc-runin-tests'
        version = os.getenv('RUNIN_VERSION')
        if not version:
            try:
                version = open('/runin/runin-tests', 'r').readlines()[5].split('"')[1]
            except IOError:
                version = ''

        # olpc-os-builder.git:modules/base/kspost.10.version_number.sh
        # "$majver.$minver.$relver for ${platform}${custstr} (build $buildnr)"
        try:
            build = open('/boot/olpc_build', 'r').readline().rstrip().split('(')[1].split(')')[0]
        except (IndexError,IOError):
            build = ''

        try:
            kernel = 'kernel ' + open('/proc/sys/kernel/osrelease', 'r').readline().rstrip().split('-')[2]
        except (IndexError,IOError):
            kernel = ''

        if kernel == '':
            try:
                kernel = 'kernel ' + open('/proc/sys/kernel/osrelease', 'r').readline().rstrip().split('-')[1].split('.')[3]
            except (IndexError,IOError):
                kernel = ''

	try:
	    ofw = 'firmware ' + open('/proc/device-tree/openprom/model','r').readline()[6:13].rstrip()
	except (IndexError,IOError):
	    ofw = ''

	try:
	    ec = 'EC ' + open('/proc/device-tree/ec-name','r').readline()[:-1]
	except IOError:
	    ec = ''

        text = '%s %s %s %s %s %s ' % (package, version, build, kernel, ofw, ec)
        return text

    def main(self):
        try:
            Gtk.main()
        except KeyboardInterrupt:
            pass

    def stop(self):
        ENABLE_STOP = os.getenv('ENABLE_STOP')
        if (ENABLE_STOP is None) or ('TRUE' not in ENABLE_STOP.upper()):
            return False
        RUNIN_PATH = os.getenv('RUNIN_PATH')
	if not RUNIN_PATH:
	    RUNIN_PATH = '/runin'
        open(os.path.join(RUNIN_PATH, 'stop'), 'w').close()
        return True

    def _key_press_event_cb(self, window, event, data=None):
        if event.keyval == 32:  # space bar
            self.stop()
        return False

    def _delete_event_cb(self, widget, event, data=None):
        Gtk.main_quit()
        return False

    def _destroy_cb(self, widget, data=None):
        Gtk.main_quit()

    def _monitor_timeout_cb(self):
        if self._monitor.dirty:
            # read the data from the file
            lines = self._monitor.readlines()

            # process the data
            row = 0
            for line in lines:
                line = line.rstrip()
                if not line.startswith('@@'):
                    # put the data into the table rows
                    if row < self.rows:
                        (name, value) = line.split('@', 2)[0:2]
                        self.table.labels[row, 0].set_text(name)
                        self.table.labels[row, 1].set_text(value)
                    row += 1
                else:
                    # update the progress bar
                    (here, there) = line.split(' ', 3)[1:3]
                    self.progress.set_fraction(float(here) / float(there))
            # erase the remainder of the table rows
            while row < self.rows:
                self.table.labels[row, 0].set_text('')
                self.table.labels[row, 1].set_text('')
                row += 1
        return True

if __name__ == "__main__":
    window = Window()
    window.main()