2
# -*- coding: utf-8 -*-
3
# vi:si:et:sw=4:sts=4:ts=4
6
## This program is free software; you can redistribute it and/or modify
7
## it under the terms of the GNU General Public License as published by
8
## the Free Software Foundation; either version 2 of the License, or
9
## (at your option) any later version.
11
## This program is distributed in the hope that it will be useful,
12
## but WITHOUT ANY WARRANTY; without even the implied warranty of
13
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
## GNU Lesser General Public License for more details.
16
## You should have received a copy of the GNU General Public License
17
## along with this program; if not, write to the Free Software
18
## Foundation, Inc., or visit: http://www.gnu.org/.
20
## Author(s): Ronaldo Maia <romaia@async.com.br>
37
from kiwi.utils import gsignal
39
ROUND_TIME = 1 # minutes
41
class DojoMonitor(gobject.GObject):
45
STATUS_LOAD_ERROR) = range(4)
47
gsignal('status-changed', int, object)
49
def __init__(self, name):
50
gobject.GObject.__init__(self)
52
uri = gnomevfs.make_uri_from_shell_arg(name)
53
gnomevfs.monitor_add(uri,
54
gnomevfs.MONITOR_FILE,
59
def _load_module(self):
61
self.module = imp.load_source('tests', self.name)
63
self.traceback = traceback.format_exc()
66
def _on_monitor(self, dir, file, event):
67
if event == gnomevfs.MONITOR_EVENT_CHANGED:
73
if self.module is None:
74
self.emit('status-changed',
75
self.STATUS_LOAD_ERROR,
79
loader = unittest.TestLoader()
80
suit = loader.loadTestsFromTestCase(self.module.StubTests)
81
results = unittest.TestResult()
85
self.emit('status-changed', self.STATUS_FAIL, results)
87
self.emit('status-changed', self.STATUS_PASS, results)
90
class DojoNotification(pynotify.Notification):
92
pynotify.init('DojoTools')
93
pynotify.Notification.__init__(self, 'DojoTools', 'Foo Bar')
95
#self.set_property('icon-name', gtk.STOCK_DIALOG_WARNING)
97
self._waiting_next = False
99
def _add_timeout(self):
100
self.round_start = time.time()
101
self._timeout = gobject.timeout_add(ROUND_TIME * 60 * 1000,
104
def _on_timeout(self):
105
self.notify_timeout()
112
def notify_failure(self, results):
113
if self._waiting_next:
119
for test, trace in results.failures:
121
lines = trace.split('\n')
122
line_number = lines[-4].split(', ')[1]
123
message += "<b>%s</b>: %s \n%s" % (test, line_number, lines[-2])
125
messages.append(message)
127
message = '\n'.join(messages)
129
self.set_property('summary',
130
'%s Failures' % len(results.failures))
131
self.set_property('body',
135
def notify_error(self, message):
136
if self._waiting_next:
140
self.set_property('summary', 'Error')
141
self.set_property('body', message)
144
def notify_load_error(self, message):
145
if self._waiting_next:
149
self.set_property('summary', 'Load Error')
150
self.set_property('body', message)
153
def notify_timeout(self):
156
self.add_action('continue', 'Continue', self._on_continue)
157
self.set_property('summary', 'Next, please')
158
self.set_property('body', 'Get your ass out of there!')
159
self.set_property('icon-name', gtk.STOCK_DIALOG_WARNING)
162
self._waiting_next = True
164
def _on_continue(self, notification, action):
166
self._waiting_next = False
171
class DojoTray(gtk.StatusIcon):
172
def __init__(self, monitor, notification):
173
gtk.StatusIcon.__init__(self)
175
self.notification = notification
176
notification.attach_to_status_icon(self)
177
self.set_status(monitor.STATUS_PASS)
179
monitor.connect('status-changed', self._on_status_changed)
180
gobject.timeout_add(1000, self._update_tooltip)
182
def _update_tooltip(self):
183
elapsed = int(time.time() - self.notification.round_start)
185
minutes = int(elapsed/60.0)
186
seconds = elapsed - minutes*60
188
self.set_tooltip("time elapsed: %d:%02d" % (minutes, seconds))
191
def _on_status_changed(self, monitor, status, results):
192
self.set_status(status, results)
194
def set_status(self, status, results=None):
195
if status == DojoMonitor.STATUS_PASS:
196
self.set_from_stock(gtk.STOCK_YES)
197
self.notification.close()
199
elif status == DojoMonitor.STATUS_FAIL:
200
self.set_from_stock(gtk.STOCK_NO)
201
self.notification.notify_failure(results)
203
elif status == DojoMonitor.STATUS_ERROR:
204
self.set_from_stock(gtk.STOCK_DIALOG_WARNING)
205
self.notification.notify_error(results)
207
elif status == DojoMonitor.STATUS_LOAD_ERROR:
208
self.set_from_stock(gtk.STOCK_DIALOG_WARNING)
209
self.notification.notify_load_error(results)
213
def __init__(self, name):
214
self.monitor = DojoMonitor(name)
215
self.notification = DojoNotification()
216
self.tray = DojoTray(self.monitor, self.notification)
219
if __name__ == '__main__':
220
if len(sys.argv) < 2:
224
dojo = DojoTools(name)